1111use RuntimeException ;
1212use function apcu_fetch ;
1313use function apcu_store ;
14- use function array_merge ;
1514use function array_unshift ;
1615use function base_convert ;
1716use function count ;
@@ -43,7 +42,7 @@ class ResourceManager
4342
4443 protected $ _type = self ::MAP_RESOURCES ;
4544 protected $ _mapOptions = [];
46- protected $ _baseUri = [] ;
45+ protected $ _baseUri ;
4746 protected $ _componentPath ;
4847 protected $ _options = [];
4948
@@ -69,7 +68,17 @@ public function __construct($type, array $mapOptions = [], array $options = [])
6968 $ this ->setOption ($ option , $ optionValue );
7069 }
7170 $ this ->_options = $ options ;
72- $ this ->_baseUri = array_merge ([$ type ], $ mapOptions );
71+ }
72+
73+ public function getBaseUri ()
74+ {
75+ if ($ this ->_baseUri === null )
76+ {
77+ $ this ->_baseUri = (Dispatch::instance () ? Dispatch::instance ()->getBaseUri () : '/ ' )
78+ . '/ ' . $ this ->_type . '/ ' . implode ('/ ' , $ this ->_mapOptions );
79+ $ this ->_baseUri = trim ($ this ->_baseUri , '/ ' );
80+ }
81+ return $ this ->_baseUri ;
7382 }
7483
7584 /**
@@ -297,20 +306,22 @@ public function getResourceUri($relativeFullPath, bool $allowComponentBubble = t
297306 {
298307 return null ;
299308 }
300- return Path::custom (
301- '/ ' ,
302- array_merge (
303- [Dispatch::instance ()->getBaseUri ()],
304- $ this ->_baseUri ,
305- [$ hash . $ relHash . ($ bits > 0 ? '- ' . base_convert ($ bits , 10 , 36 ) : '' ), $ relativeFullPath ]
306- )
307- );
309+
310+ return $ this ->getBaseUri ()
311+ . '/ ' . $ hash . $ relHash . ($ bits > 0 ? '- ' . base_convert ($ bits , 10 , 36 ) : '' )
312+ . '/ ' . $ relativeFullPath ;
308313 }
309314
315+ protected $ _optimizeWebP ;
316+
310317 protected function _optimisePath ($ path , $ relativeFullPath )
311318 {
312- $ optimise = ValueAs::bool (Dispatch::instance ()->config ()->getItem ('optimisation ' , 'webp ' , false ));
313- if ($ optimise
319+ if ($ this ->_optimizeWebP === null )
320+ {
321+ $ this ->_optimizeWebP = ValueAs::bool (Dispatch::instance ()->config ()->getItem ('optimisation ' , 'webp ' , false ));
322+ }
323+
324+ if ($ this ->_optimizeWebP
314325 && in_array (substr ($ path , -4 ), ['.jpg ' , 'jpeg ' , '.png ' , '.gif ' , '.bmp ' , 'tiff ' , '.svg ' ])
315326 && file_exists ($ path . '.webp ' ))
316327 {
@@ -328,11 +339,11 @@ protected function _optimisePath($path, $relativeFullPath)
328339 */
329340 public function isExternalUrl ($ path )
330341 {
331- return strlen ($ path) > 8 && (
332- Strings:: startsWith ( $ path , ' http:// ' , true , 7 ) ||
333- Strings:: startsWith ($ path, ' https:// ' , true , 8 ) ||
334- Strings:: startsWith ($ path , '// ' , true , 2 )
335- );
342+ return isset ($ path[ 8 ])
343+ && (
344+ ($ path[ 0 ] == ' / ' && $ path [ 1 ] == ' / ' )
345+ || strncasecmp ($ path , 'http: // ' , 7 ) == 0
346+ || strncasecmp ( $ path , ' https:// ' , 8 ) == 0 );
336347 }
337348
338349 /**
@@ -377,16 +388,27 @@ public function getRelativeHash($filePath)
377388 return Dispatch::instance ()->generateHash (Dispatch::instance ()->calculateRelativePath ($ filePath ), 4 );
378389 }
379390
391+ protected static $ _fileHashCache = [];
392+
380393 public function getFileHash ($ fullPath )
381394 {
382- if (!file_exists ($ fullPath ))
395+ $ cached = static ::$ _fileHashCache [$ fullPath ] ?? null ;
396+
397+ if ($ cached === -1 || ($ cached === null && !file_exists ($ fullPath )))
383398 {
399+ self ::$ _fileHashCache [$ fullPath ] = -1 ;
384400 if ($ this ->getOption (self ::OPT_THROW_ON_FILE_NOT_FOUND , true ))
385401 {
386402 throw new RuntimeException ("Unable to find dispatch file ' $ fullPath' " , 404 );
387403 }
388404 return null ;
389405 }
406+
407+ if (!empty ($ cached ))
408+ {
409+ return $ cached ;
410+ }
411+
390412 $ key = 'pdspfh- ' . md5 ($ fullPath ) . '- ' . filectime ($ fullPath );
391413
392414 if (function_exists ("apcu_fetch " ))
@@ -396,12 +418,13 @@ public function getFileHash($fullPath)
396418 if ($ exists && $ hash )
397419 {
398420 // @codeCoverageIgnoreStart
421+ self ::$ _fileHashCache [$ fullPath ] = $ hash ;
399422 return $ hash ;
400423 // @codeCoverageIgnoreEnd
401424 }
402425 }
403426
404- $ hash = Dispatch::instance ()->generateHash (md5_file ($ fullPath ), 8 );
427+ self :: $ _fileHashCache [ $ fullPath ] = $ hash = Dispatch::instance ()->generateHash (md5_file ($ fullPath ), 8 );
405428 if ($ hash && function_exists ('apcu_store ' ))
406429 {
407430 apcu_store ($ key , $ hash , 86400 );
0 commit comments