diff --git a/src/Api.php b/src/Api.php index f22d1f6..79f156d 100644 --- a/src/Api.php +++ b/src/Api.php @@ -41,18 +41,28 @@ public function __construct( public function isAssetsAvailable(string $route): bool { - return $this->findGlobalData($route = trim($route, ':')) !== [] || $this->findLocalData($route) !== []; + $route = trim($route, ':'); + + return $this->findGlobalData($route) !== [] + || $this->findLocalData($route) !== []; } public function getHtmlInit(string $route): string { - $routePath = Helpers::formatRouteToPath($route = trim($route, ':')); - - return implode("\n", array_merge( - $this->renderInjectTagsByData('global-' . preg_replace('/^([^-]+)-(.*)$/', '$1', $routePath), $this->findGlobalData($route)), - $this->renderInjectTagsByData($routePath, $this->findLocalData($route)), - )); + $route = trim($route, ':'); + $routePath = Helpers::formatRouteToPath($route); + + return implode( + "\n", + array_merge( + $this->renderInjectTagsByData( + 'global-' . preg_replace('/^([^-]+)-(.*)$/', '$1', $routePath), + $this->findGlobalData($route) + ), + $this->renderInjectTagsByData($routePath, $this->findLocalData($route)), + ) + ); } @@ -67,12 +77,22 @@ public function getHtmlInit(string $route): string public function run(string $path): void { if (preg_match('/^assets\/web-loader\/(.+?)(?:\?v=[0-9a-f]{6})?$/', $path, $parser)) { // 1. - if (preg_match('/^global-(?[a-zA-Z0-9]+)\.(?[a-zA-Z0-9]+)$/', $parser[1], $globalRouteParser)) { + if (preg_match( + '/^global-(?[a-zA-Z0-9]+)\.(?[a-zA-Z0-9]+)$/', + $parser[1], + $globalRouteParser + )) { $format = $globalRouteParser['format']; $data = $this->findGlobalData($globalRouteParser['module'] . ':Homepage:default'); - } elseif (preg_match('/^(?[a-zA-Z0-9]+)-(?[a-zA-Z0-9]+)-(?[a-zA-Z0-9]+)\.(?[a-zA-Z0-9]+)$/', $parser[1], $routeParser)) { + } elseif (preg_match( + '/^(?[a-zA-Z0-9]+)-(?[a-zA-Z0-9]+)-(?[a-zA-Z0-9]+)\.(?[a-zA-Z0-9]+)$/', + $parser[1], + $routeParser + )) { $format = $routeParser['format']; - $data = $this->findLocalData(Helpers::formatRoute($routeParser['module'], $routeParser['presenter'], $routeParser['action'])); + $data = $this->findLocalData( + Helpers::formatRoute($routeParser['module'], $routeParser['presenter'], $routeParser['action']) + ); } else { echo '/* empty body */'; die; @@ -90,7 +110,7 @@ public function run(string $path): void $topModTime = 0; if ($data !== []) { // 3. foreach ($data[$format] ?? [] as $file) { - if (preg_match('~^(?:https?:)//~', $file)) { // do not accept URL + if (preg_match('~^https?://~', $file)) { // do not accept URL continue; } $filePath = $this->basePath . '/' . trim($file, '/'); @@ -121,7 +141,10 @@ public function run(string $path): void header('Last-Modified: ' . $tsString); header('ETag: "' . md5($etag) . '"'); - echo '/* Path "' . htmlspecialchars($parser[1]) . '" was automatically generated ' . date('Y-m-d H:i:s', $topModTime) . ' */' . "\n\n"; // 4. + echo '/* Path "' . htmlspecialchars($parser[1]) . '" was automatically generated ' + . date('Y-m-d H:i:s', $topModTime) + . ' */' . "\n\n"; // 4. + foreach ($filePaths as $file => $filePath) { echo '/* ' . $file . ' */' . "\n"; echo $this->minifier->minify(FileSystem::read($filePath), $format); @@ -143,7 +166,11 @@ private function renderInjectTagsByData(string $route, array $data): array $topModTime = 0; foreach ($data[$format] ?? [] as $item) { if (preg_match('/^((?:https?:)?\/\/)(.+)$/', $item, $itemParser)) { - $return[] = str_replace('%path%', ($itemParser[1] === '//' ? 'https://' : $itemParser[1]) . $itemParser[2], $this->formatHtmlInjects[$format]); + $return[] = str_replace( + '%path%', + ($itemParser[1] === '//' ? 'https://' : $itemParser[1]) . $itemParser[2], + $this->formatHtmlInjects[$format] + ); } elseif ( is_file($filePath = $this->basePath . '/' . trim($item, '/')) === true && ($modificationTime = (int) filemtime($filePath)) > 0 @@ -174,10 +201,12 @@ private function findLocalData(string $route): array if ($this->data !== []) { $routeParser = $this->parseRoute($route); - return $this->findDataBySelectors([ - $routeParser['module'] . ':' . $routeParser['presenter'] . ':*', - $routeParser['module'] . ':' . $routeParser['presenter'] . ':' . $routeParser['action'], - ]); + return $this->findDataBySelectors( + [ + $routeParser['module'] . ':' . $routeParser['presenter'] . ':*', + $routeParser['module'] . ':' . $routeParser['presenter'] . ':' . $routeParser['action'], + ] + ); } return $this->data; @@ -190,10 +219,12 @@ private function findLocalData(string $route): array private function findGlobalData(string $route): array { if ($this->data !== []) { - return $this->findDataBySelectors([ - '*', - $this->parseRoute($route)['module'] . ':*', - ]); + return $this->findDataBySelectors( + [ + '*', + $this->parseRoute($route)['module'] . ':*', + ] + ); } return []; diff --git a/src/Helpers.php b/src/Helpers.php index c1bccea..2386585 100644 --- a/src/Helpers.php +++ b/src/Helpers.php @@ -23,7 +23,14 @@ public function __construct() */ public static function processPath(Request $httpRequest): string { - return trim(str_replace(rtrim($httpRequest->getUrl()->withoutUserInfo()->getBaseUrl(), '/'), '', Url::get()->getCurrentUrl()), '/'); + return trim( + str_replace( + rtrim($httpRequest->getUrl()->withoutUserInfo()->getBaseUrl(), '/'), + '', + Url::get()->getCurrentUrl() + ), + '/' + ); } @@ -42,7 +49,9 @@ public static function formatRouteToPath(string $route): string return 'error4xx-default'; } if (preg_match('/^(?[^:]+):(?[^:]+):(?[^:]+)$/', $route, $parser)) { - return self::firstLower($parser['module']) . '-' . self::firstLower($parser['presenter']) . '-' . self::firstLower($parser['action']); + return self::firstLower($parser['module']) + . '-' . self::firstLower($parser['presenter']) + . '-' . self::firstLower($parser['action']); } throw new \InvalidArgumentException('Can not parse route format, because haystack "' . $route . '" given.'); @@ -51,30 +60,12 @@ public static function formatRouteToPath(string $route): string public static function firstUpper(string $s): string { - return strtoupper($s[0] ?? '') . (function_exists('mb_substr') - ? mb_substr($s, 1, null, 'UTF-8') - : iconv_substr($s, 1, self::length($s), 'UTF-8') - ); + return strtoupper($s[0] ?? '') . mb_substr($s, 1, null, 'UTF-8'); } public static function firstLower(string $s): string { - return strtolower($s[0] ?? '') . (function_exists('mb_substr') - ? mb_substr($s, 1, null, 'UTF-8') - : iconv_substr($s, 1, self::length($s), 'UTF-8') - ); - } - - - /** - * Returns number of characters (not bytes) in UTF-8 string. - * That is the number of Unicode code points which may differ from the number of graphemes. - */ - public static function length(string $s): int - { - return function_exists('mb_strlen') - ? mb_strlen($s, 'UTF-8') - : strlen(utf8_decode($s)); + return strtolower($s[0] ?? '') . mb_substr($s, 1, null, 'UTF-8'); } } diff --git a/src/LoaderExtension.php b/src/LoaderExtension.php index 40b2f47..984f6b6 100644 --- a/src/LoaderExtension.php +++ b/src/LoaderExtension.php @@ -59,7 +59,7 @@ public function beforeCompile(): void } foreach (($config['formatHtmlInjects'] ?? []) as $formatHtmlInject) { - if (strpos($formatHtmlInject, '%path%') === false) { + if (!str_contains($formatHtmlInject, '%path%')) { throw new \RuntimeException('HTML inject format must contains variable "%path%", but "' . $formatHtmlInject . '" given.'); } } diff --git a/src/Minifier/JShrinkMinifier.php b/src/Minifier/JShrinkMinifier.php index bab24ee..fa55de1 100644 --- a/src/Minifier/JShrinkMinifier.php +++ b/src/Minifier/JShrinkMinifier.php @@ -22,7 +22,7 @@ class JShrinkMinifier * the one passed in by the user to create the request specific set of * options (stored in the $options attribute). * - * @var bool[] + * @var array */ protected static array $defaultOptions = ['flaggedComments' => true]; @@ -54,7 +54,7 @@ class JShrinkMinifier /** * These characters are used to define strings. * - * @var bool[] + * @var array */ protected array $stringDelimiters = ['\'' => true, '"' => true, '`' => true]; @@ -69,7 +69,7 @@ class JShrinkMinifier /** * Characters that can't stand alone preserve the newline. * - * @var bool[] + * @var array */ protected array $noNewLineCharacters = [ '(' => true, @@ -90,25 +90,25 @@ class JShrinkMinifier */ public static function minify(string $js, array $options = []): ?string { - $jshrink = null; + $self = null; try { ob_start(); - $jshrink = new self; - $js = $jshrink->lock($js); - $jshrink->minifyDirectToOutput($js, $options); + $self = new self; + $js = $self->lock($js); + $self->minifyDirectToOutput($js, $options); // Sometimes there's a leading new line, so we trim that out here. $js = ltrim((string) ob_get_clean()); - $js = $jshrink->unlock($js); - unset($jshrink); + $js = $self->unlock($js); + unset($self); return $js; } catch (\Throwable $e) { // Since the breakdownScript function probably wasn't finished // we clean it out before discarding it. - $jshrink->clean(); - unset($jshrink); + $self->clean(); + unset($self); // without this call things get weird, with partially outputted js. ob_end_clean(); @@ -206,7 +206,7 @@ protected function loop(): void default: switch ($this->b) { case "\n": - if (strpos('}])+-"\'', $this->a) !== false) { + if (str_contains('}])+-"\'', $this->a)) { echo $this->a; $this->saveString(); break; @@ -239,7 +239,7 @@ protected function loop(): void // do reg check of doom $this->b = $this->getReal(); - if (($this->b === '/' && strpos('(,=:[!&|?', (string) $this->a) !== false)) { + if (($this->b === '/' && str_contains('(,=:[!&|?', (string) $this->a))) { $this->saveRegex(); } } @@ -311,7 +311,6 @@ protected function getReal(): ?string } $this->c = $this->getChar(); - if ($this->c === '/') { $this->processOneLineComments($startIndex); diff --git a/src/Minifier/Minifier.php b/src/Minifier/Minifier.php index 9b00123..5703702 100644 --- a/src/Minifier/Minifier.php +++ b/src/Minifier/Minifier.php @@ -29,8 +29,11 @@ public function __construct(?Storage $storage = null) public function minify(string $haystack, string $format): string { $key = $format . '-' . md5($haystack); - if ($this->cache !== null && ($cache = $this->cache->load($key)) !== null) { - return (string) $cache; + if ($this->cache !== null) { + $cache = $this->cache->load($key); + if ($cache !== null) { + return (string) $cache; + } } $return = $this->getMinifier($format)->minify($haystack); if ($this->cache !== null) { @@ -63,7 +66,9 @@ public function getMinifier(string $format): AssetMinifier public function addMinifier(AssetMinifier $minifier, string $format): void { if (isset($this->services[$format]) === true && !$this->services[$format] instanceof $minifier) { - throw new \LogicException('Minifier for "' . $format . '" has been defined (' . \get_class($this->services[$format]) . ').'); + throw new \LogicException( + 'Minifier for "' . $format . '" has been defined (' . $this->services[$format]::class . ').', + ); } $this->services[$format] = $minifier;