1
+ <?php declare (strict_types=1 );
2
+
3
+ namespace Dbalabka \StaticConstructorLoader ;
4
+
5
+ use Composer \Autoload \ClassLoader ;
6
+ use Dbalabka \StaticConstructorLoader \Exception \StaticConstructorLoaderException ;
7
+
8
+ class DebugStaticConstructorLoader extends ClassLoader /* extending for an contract */
9
+ {
10
+ /**
11
+ * @var ClassLoader
12
+ */
13
+ private $ classLoader ;
14
+
15
+ public function __construct (ClassLoader $ classLoader )
16
+ {
17
+ $ this ->classLoader = $ classLoader ;
18
+
19
+ // find Composer autoloader
20
+ $ loaders = spl_autoload_functions ();
21
+ $ otherLoaders = [];
22
+ $ composerLoader = null ;
23
+ foreach ($ loaders as $ loader ) {
24
+ if (is_array ($ loader )) {
25
+ if ($ loader [0 ] === $ classLoader ) {
26
+ $ composerLoader = $ loader ;
27
+ break ;
28
+ }
29
+ if ($ loader [0 ] instanceof self) {
30
+ throw new StaticConstructorLoaderException (sprintf ('%s already registered ' , self ::class));
31
+ }
32
+ }
33
+ $ otherLoaders [] = $ loader ;
34
+ }
35
+
36
+ if (!$ composerLoader ) {
37
+ throw new StaticConstructorLoaderException (sprintf ('%s was not found in registered autoloaders ' , ClassLoader::class));
38
+ }
39
+
40
+ // unregister Composer autoloader and all preceding autoloaders
41
+ array_map ('spl_autoload_unregister ' , array_merge ($ otherLoaders , [$ composerLoader ]));
42
+
43
+ // restore the original queue order
44
+ $ loadersToRestore = array_merge ([[$ this , 'loadClass ' ]], array_reverse ($ otherLoaders ));
45
+ $ flagTrue = array_fill (0 , count ($ loadersToRestore ), true );
46
+ array_map ('spl_autoload_register ' , $ loadersToRestore , $ flagTrue , $ flagTrue );
47
+ }
48
+
49
+ public function loadClass ($ className ): ?bool
50
+ {
51
+ return $ this ->classLoader ->loadClass ($ className );
52
+ }
53
+
54
+ public function getPrefixes ()
55
+ {
56
+ return $ this ->classLoader ->getPrefixes ();
57
+ }
58
+
59
+ public function getPrefixesPsr4 ()
60
+ {
61
+ return $ this ->classLoader ->getPrefixesPsr4 ();
62
+ }
63
+
64
+ public function getFallbackDirs ()
65
+ {
66
+ return $ this ->classLoader ->getFallbackDirs ();
67
+ }
68
+
69
+ public function getFallbackDirsPsr4 ()
70
+ {
71
+ return $ this ->classLoader ->getFallbackDirsPsr4 ();
72
+ }
73
+
74
+ public function getClassMap ()
75
+ {
76
+ return $ this ->classLoader ->getClassMap ();
77
+ }
78
+
79
+ public function addClassMap (array $ classMap )
80
+ {
81
+ $ this ->classLoader ->addClassMap ($ classMap );
82
+ }
83
+
84
+ public function add ($ prefix , $ paths , $ prepend = false )
85
+ {
86
+ $ this ->classLoader ->add ($ prefix , $ paths , $ prepend );
87
+ }
88
+
89
+ public function addPsr4 ($ prefix , $ paths , $ prepend = false )
90
+ {
91
+ $ this ->classLoader ->addPsr4 ($ prefix , $ paths , $ prepend );
92
+ }
93
+
94
+ public function set ($ prefix , $ paths )
95
+ {
96
+ $ this ->classLoader ->set ($ prefix , $ paths );
97
+ }
98
+
99
+ public function setPsr4 ($ prefix , $ paths )
100
+ {
101
+ $ this ->classLoader ->setPsr4 ($ prefix , $ paths );
102
+ }
103
+
104
+ public function setUseIncludePath ($ useIncludePath )
105
+ {
106
+ $ this ->classLoader ->setUseIncludePath ($ useIncludePath );
107
+ }
108
+
109
+ public function getUseIncludePath ()
110
+ {
111
+ return $ this ->classLoader ->getUseIncludePath ();
112
+ }
113
+
114
+ public function setClassMapAuthoritative ($ classMapAuthoritative )
115
+ {
116
+ $ this ->classLoader ->setClassMapAuthoritative ($ classMapAuthoritative );
117
+ }
118
+
119
+ public function isClassMapAuthoritative ()
120
+ {
121
+ return $ this ->classLoader ->isClassMapAuthoritative ();
122
+ }
123
+
124
+ public function setApcuPrefix ($ apcuPrefix )
125
+ {
126
+ $ this ->classLoader ->setApcuPrefix ($ apcuPrefix );
127
+ }
128
+
129
+ public function getApcuPrefix ()
130
+ {
131
+ return $ this ->classLoader ->getApcuPrefix ();
132
+ }
133
+
134
+ public function register ($ prepend = false )
135
+ {
136
+ $ this ->classLoader ->register ($ prepend );
137
+ }
138
+
139
+ public function unregister ()
140
+ {
141
+ $ this ->classLoader ->unregister ();
142
+ }
143
+
144
+ public function findFile ($ class )
145
+ {
146
+ $ path = $ this ->classLoader ->findFile ($ class );
147
+
148
+ if (
149
+ class_exists (\Symfony \Component \ErrorHandler \DebugClassLoader::class, false )
150
+ || class_exists (\Symfony \Component \Debug \DebugClassLoader::class, false )
151
+ ) {
152
+ return $ this ->handleDebugClassLoader ($ class , $ path );
153
+ }
154
+
155
+ return $ path ;
156
+ }
157
+
158
+ private function handleDebugClassLoader ($ class , $ path )
159
+ {
160
+ $ backtrace = debug_backtrace (DEBUG_BACKTRACE_IGNORE_ARGS , 3 );
161
+ $ debugClassLoader = ($ backtrace [2 ] ?? null );
162
+
163
+ if ($ path
164
+ && is_file ($ path )
165
+ && \in_array (
166
+ $ debugClassLoader ['class ' ] ?? null ,
167
+ [
168
+ \Symfony \Component \Debug \DebugClassLoader::class,
169
+ \Symfony \Component \ErrorHandler \DebugClassLoader::class
170
+ ],
171
+ true
172
+ )
173
+ ) {
174
+ include $ path ;
175
+
176
+ if (
177
+ $ class !== StaticConstructorInterface::class
178
+ && is_a ($ class , StaticConstructorInterface::class, true )
179
+ ) {
180
+ $ class ::__constructStatic ();
181
+ }
182
+
183
+ return false ;
184
+ }
185
+
186
+ return $ path ;
187
+ }
188
+ }
0 commit comments