@@ -32,13 +32,13 @@ class RobotLoader
3232 /** @var array */
3333 private $ scanPaths = [];
3434
35- /** @var array of lowered-class => [file, time, orig] or num-of-retry */
35+ /** @var array of lowered-class => [file, time, orig] */
3636 private $ classes = [];
3737
3838 /** @var bool */
3939 private $ refreshed = FALSE ;
4040
41- /** @var array of missing classes in this request */
41+ /** @var array of missing classes */
4242 private $ missing = [];
4343
4444 /** @var string|NULL */
@@ -75,35 +75,35 @@ public function tryLoad($type)
7575 {
7676 $ type = $ orig = ltrim ($ type , '\\' ); // PHP namespace bug #49143
7777 $ type = strtolower ($ type );
78-
79- $ info = &$ this ->classes [$ type ];
80- if (isset ($ this ->missing [$ type ]) || (is_int ($ info ) && $ info >= self ::RETRY_LIMIT )) {
81- return ;
82- }
78+ $ info = isset ($ this ->classes [$ type ]) ? $ this ->classes [$ type ] : NULL ;
8379
8480 if ($ this ->autoRebuild ) {
85- if (!is_array ($ info ) || !is_file ($ info ['file ' ])) {
86- $ info = is_int ($ info ) ? $ info + 1 : 0 ;
87- if (!$ this ->refreshed ) {
81+ if (!$ info || !is_file ($ info ['file ' ])) {
82+ $ missing = & $ this ->missing [$ type ];
83+ $ missing ++;
84+ if (!$ this ->refreshed && $ missing <= self ::RETRY_LIMIT ) {
8885 $ this ->refresh ();
86+ $ this ->saveCache ();
87+ } elseif ($ info ) {
88+ unset($ this ->classes [$ type ]);
89+ $ this ->saveCache ();
8990 }
90- $ this -> saveCache ();
91+
9192 } elseif (!$ this ->refreshed && filemtime ($ info ['file ' ]) !== $ info ['time ' ]) {
9293 $ this ->updateFile ($ info ['file ' ]);
93- if (! isset ($ this ->classes [$ type ])) {
94- $ this ->classes [$ type ] = 0 ;
94+ if (empty ($ this ->classes [$ type ])) {
95+ $ this ->missing [$ type ] = 0 ;
9596 }
9697 $ this ->saveCache ();
9798 }
99+ $ info = isset ($ this ->classes [$ type ]) ? $ this ->classes [$ type ] : NULL ;
98100 }
99101
100- if (isset ( $ this -> classes [ $ type ][ ' file ' ]) ) {
101- if ($ this -> classes [ $ type ] ['orig ' ] !== $ orig ) {
102- trigger_error ("Case mismatch on class name ' $ orig', correct name is ' {$ this -> classes [ $ type ] ['orig ' ]}'. " , E_USER_WARNING );
102+ if ($ info ) {
103+ if ($ info ['orig ' ] !== $ orig ) {
104+ trigger_error ("Case mismatch on class name ' $ orig', correct name is ' {$ info ['orig ' ]}'. " , E_USER_WARNING );
103105 }
104- call_user_func (function ($ file ) { require $ file ; }, $ this ->classes [$ type ]['file ' ]);
105- } else {
106- $ this ->missing [$ type ] = TRUE ;
106+ call_user_func (function ($ file ) { require $ file ; }, $ info ['file ' ]);
107107 }
108108 }
109109
@@ -127,9 +127,7 @@ public function getIndexedClasses()
127127 {
128128 $ res = [];
129129 foreach ($ this ->classes as $ info ) {
130- if (is_array ($ info )) {
131- $ res [$ info ['orig ' ]] = $ info ['file ' ];
132- }
130+ $ res [$ info ['orig ' ]] = $ info ['file ' ];
133131 }
134132 return $ res ;
135133 }
@@ -155,14 +153,10 @@ public function rebuild()
155153 private function refresh ()
156154 {
157155 $ this ->refreshed = TRUE ; // prevents calling refresh() or updateFile() in tryLoad()
158- $ files = $ missing = [];
159- foreach ($ this ->classes as $ class => $ info ) {
160- if (is_array ($ info )) {
161- $ files [$ info ['file ' ]]['time ' ] = $ info ['time ' ];
162- $ files [$ info ['file ' ]]['classes ' ][] = $ info ['orig ' ];
163- } else {
164- $ missing [$ class ] = $ info ;
165- }
156+ $ files = [];
157+ foreach ($ this ->classes as $ info ) {
158+ $ files [$ info ['file ' ]]['time ' ] = $ info ['time ' ];
159+ $ files [$ info ['file ' ]]['classes ' ][] = $ info ['orig ' ];
166160 }
167161
168162 $ this ->classes = [];
@@ -177,15 +171,16 @@ private function refresh()
177171 $ files [$ file ] = ['classes ' => [], 'time ' => filemtime ($ file )];
178172
179173 foreach ($ classes as $ class ) {
180- $ info = &$ this ->classes [strtolower ($ class )];
174+ $ lower = strtolower ($ class );
175+ $ info = &$ this ->classes [$ lower ];
181176 if (isset ($ info ['file ' ])) {
182177 throw new Nette \InvalidStateException ("Ambiguous class $ class resolution; defined in {$ info ['file ' ]} and in $ file. " );
183178 }
184179 $ info = ['file ' => $ file , 'time ' => filemtime ($ file ), 'orig ' => $ class ];
180+ unset($ this ->missing [$ lower ]);
185181 }
186182 }
187183 }
188- $ this ->classes += $ missing ;
189184 }
190185
191186
@@ -242,26 +237,25 @@ private function updateFile($file)
242237 }
243238 }
244239
245- if (is_file ($ file )) {
246- foreach ($ this ->scanPhp (file_get_contents ($ file )) as $ class ) {
240+ $ classes = is_file ($ file ) ? $ this ->scanPhp (file_get_contents ($ file )) : [];
241+ foreach ($ classes as $ class ) {
242+ $ info = &$ this ->classes [strtolower ($ class )];
243+ if (isset ($ info ['file ' ]) && @filemtime ($ info ['file ' ]) !== $ info ['time ' ]) { // @ file may not exists
244+ $ this ->updateFile ($ info ['file ' ]);
247245 $ info = &$ this ->classes [strtolower ($ class )];
248- if (isset ($ info ['file ' ]) && @filemtime ($ info ['file ' ]) !== $ info ['time ' ]) { // @ file may not exists
249- $ this ->updateFile ($ info ['file ' ]);
250- $ info = &$ this ->classes [strtolower ($ class )];
251- }
252- if (isset ($ info ['file ' ])) {
253- throw new Nette \InvalidStateException ("Ambiguous class $ class resolution; defined in {$ info ['file ' ]} and in $ file. " );
254- }
255- $ info = ['file ' => $ file , 'time ' => filemtime ($ file ), 'orig ' => $ class ];
256246 }
247+ if (isset ($ info ['file ' ])) {
248+ throw new Nette \InvalidStateException ("Ambiguous class $ class resolution; defined in {$ info ['file ' ]} and in $ file. " );
249+ }
250+ $ info = ['file ' => $ file , 'time ' => filemtime ($ file ), 'orig ' => $ class ];
257251 }
258252 }
259253
260254
261255 /**
262256 * Searches classes, interfaces and traits in PHP file.
263257 * @param string
264- * @return array
258+ * @return string[]
265259 */
266260 private function scanPhp ($ code )
267261 {
@@ -368,7 +362,7 @@ public function setTempDirectory($dir)
368362 private function loadCache ()
369363 {
370364 $ file = $ this ->getCacheFile ();
371- $ this ->classes = @include $ file ; // @ file may not exist
365+ list ( $ this ->classes , $ this -> missing ) = @include $ file ; // @ file may not exist
372366 if (is_array ($ this ->classes )) {
373367 return ;
374368 }
@@ -378,7 +372,7 @@ private function loadCache()
378372 throw new \RuntimeException ("Unable to create or acquire exclusive lock on file ' $ file.lock'. " );
379373 }
380374
381- $ this ->classes = @include $ file ; // @ file may not exist
375+ list ( $ this ->classes , $ this -> missing ) = @include $ file ; // @ file may not exist
382376 if (!is_array ($ this ->classes )) {
383377 $ this ->classes = [];
384378 $ this ->refresh ();
@@ -398,7 +392,7 @@ private function loadCache()
398392 private function saveCache ()
399393 {
400394 $ file = $ this ->getCacheFile ();
401- $ code = "<?php \nreturn " . var_export ($ this ->classes , TRUE ) . "; \n" ;
395+ $ code = "<?php \nreturn " . var_export ([ $ this ->classes , $ this -> missing ] , TRUE ) . "; \n" ;
402396 if (file_put_contents ("$ file.tmp " , $ code ) !== strlen ($ code ) || !rename ("$ file.tmp " , $ file )) {
403397 @unlink ("$ file.tmp " ); // @ - file may not exist
404398 throw new \RuntimeException ("Unable to create ' $ file'. " );
0 commit comments