Skip to content

Commit

Permalink
Modernize internal
Browse files Browse the repository at this point in the history
  • Loading branch information
janbarasek committed Jan 13, 2022
1 parent 76f10a2 commit 18c662a
Show file tree
Hide file tree
Showing 6 changed files with 70 additions and 48 deletions.
32 changes: 21 additions & 11 deletions src/Api.php
Original file line number Diff line number Diff line change
Expand Up @@ -76,19 +76,19 @@ public function getHtmlInit(string $route): string
*/
public function run(): void
{
if (preg_match('/^assets\/web-loader\/(.+?)(?:\?v=[0-9a-f]{6})?$/', Url::get()->getRelativeUrl(), $parser)) { // 1.
if (preg_match('/^assets\/web-loader\/(.+?)(?:\?v=[0-9a-f]{6})?$/', Url::get()->getRelativeUrl(), $parser) === 1) { // 1.
if (preg_match(
'/^global-(?<module>[a-zA-Z0-9]+)\.(?<format>[a-zA-Z0-9]+)$/',
$parser[1],
$globalRouteParser,
)) {
) === 1) {
$format = $globalRouteParser['format'];
$data = $this->findGlobalData($globalRouteParser['module'] . ':Homepage:default');
} elseif (preg_match(
'/^(?<module>[a-zA-Z0-9]+)-(?<presenter>[a-zA-Z0-9]+)-(?<action>[a-zA-Z0-9]+)\.(?<format>[a-zA-Z0-9]+)$/',
$parser[1],
$routeParser,
)) {
) === 1) {
$format = $routeParser['format'];
$data = $this->findLocalData(
Helpers::formatRoute($routeParser['module'], $routeParser['presenter'], $routeParser['action']),
Expand All @@ -110,7 +110,7 @@ public function run(): 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) === 1) { // do not accept URL
continue;
}
$filePath = $this->basePath . '/' . trim($file, '/');
Expand All @@ -125,7 +125,7 @@ public function run(): void
}
}
}
$topModTime = $topModTime ?: time();
$topModTime = $topModTime === 0 ? time() : $topModTime;

$tsString = gmdate('D, d M Y H:i:s ', $topModTime) . 'GMT';
$etag = 'EN' . $topModTime;
Expand Down Expand Up @@ -165,7 +165,7 @@ private function renderInjectTagsByData(string $route, array $data): array
foreach (array_keys($data) as $format) {
$topModTime = 0;
foreach ($data[$format] ?? [] as $item) {
if (preg_match('/^((?:https?:)?\/\/)(.+)$/', $item, $itemParser)) {
if (preg_match('/^((?:https?:)?\/\/)(.+)$/', $item, $itemParser) === 1) {
$return[] = str_replace(
'%path%',
($itemParser[1] === '//' ? 'https://' : $itemParser[1]) . $itemParser[2],
Expand All @@ -182,8 +182,13 @@ private function renderInjectTagsByData(string $route, array $data): array
if (isset($this->formatHtmlInjects[$format]) === true) {
$return[] = str_replace(
'%path%',
Url::get()->getBaseUrl() . '/assets/web-loader/' . $route . '.' . $format
. ($topModTime > 0 ? '?v=' . substr(md5((string) $topModTime), 0, 6) : ''),
sprintf(
'%s/assets/web-loader/%s.%s%s',
Url::get()->getBaseUrl(),
$route,
$format,
$topModTime > 0 ? '?v=' . substr(md5((string) $topModTime), 0, 6) : '',
),
$this->formatHtmlInjects[$format],
);
}
Expand Down Expand Up @@ -243,12 +248,13 @@ private function findDataBySelectors(array $selectors): array
$return[] = $this->data[$selector] ?? [];
}

/** @phpstan-ignore-next-line */
return array_merge_recursive([], ...$return);
}


/**
* @return string[]
* @return array{module: string, presenter: string, action: string}
*/
private function parseRoute(string $route): array
{
Expand All @@ -259,7 +265,11 @@ private function parseRoute(string $route): array
'action' => 'default',
];
}
if (preg_match('/^(?<module>[^:]+):(?<presenter>[^:]+):(?<action>[^:]+)$/', trim($route, ':'), $routeParser)) {
if (preg_match(
'/^(?<module>[^:]+):(?<presenter>[^:]+):(?<action>[^:]+)$/',
trim($route, ':'),
$routeParser,
) === 1) {
return [
'module' => Helpers::firstUpper($routeParser['module'] ?? '*'),
'presenter' => Helpers::firstUpper($routeParser['presenter'] ?? '*'),
Expand All @@ -268,7 +278,7 @@ private function parseRoute(string $route): array
}

throw new AssetLoaderException(
'Route "' . $route . '" is invalid. '
sprintf('Route "%s" is invalid. ', $route)
. 'Route must be absolute "Module:Presenter:action" or end '
. 'with dynamic part in format "Module:*" or "Module:Presenter:*".',
);
Expand Down
8 changes: 3 additions & 5 deletions src/Helpers.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,8 @@

final class Helpers
{
/** @throws \Error */
public function __construct()
private function __construct()
{
throw new \Error('Class ' . static::class . ' is static and cannot be instantiated.');
}


Expand All @@ -28,13 +26,13 @@ public static function formatRouteToPath(string $route): string
if ($route === 'Error4xx:default') {
return 'error4xx-default';
}
if (preg_match('/^(?<module>[^:]+):(?<presenter>[^:]+):(?<action>[^:]+)$/', $route, $parser)) {
if (preg_match('/^(?<module>[^:]+):(?<presenter>[^:]+):(?<action>[^:]+)$/', $route, $parser) === 1) {
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.');
throw new \InvalidArgumentException(sprintf('Can not parse route format, because haystack "%s" given.', $route));
}


Expand Down
60 changes: 38 additions & 22 deletions src/LoaderExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,35 +40,33 @@ public function getConfigSchema(): Schema

public function beforeCompile(): void
{
/** @var mixed[] $config */
/** @var array{
* basePath: string|null,
* routing: mixed[],
* base: mixed[],
* formatHeaders: array<string, string>,
* formatHtmlInjects: array<string, string>,
* } $config
*/
$config = $this->getConfig();
$files = $config['routing'] ?? [];

if ($config['base'] !== []) {
$files = array_merge_recursive($files, ['*' => $config['base']]);
}

$assets = [];
foreach ($files as $route => $assetFiles) {
foreach ($this->formatRoutingFiles($config['routing'], $config['base']) as $route => $assetFiles) {
$this->validateRouteFormat($route);
foreach ($assetFiles as $assetFormat => $assetFile) {
if (is_array($assetFile)) {
if (isset($assetFile['format'], $assetFile['source'])) {
$format = $assetFile['format'];
$assetFile = $assetFile['source'];
} else {
throw new \RuntimeException('Invalid asset structure, expected keys "format" and "source".');
}
$format = $assetFile['format'];
$assetFile = $assetFile['source'];
} elseif (is_string($assetFormat)) {
if (!preg_match('/^[a-zA-Z0-9]+$/', $assetFile)) {
throw new \RuntimeException('Invalid asset format for file "' . $assetFormat . '", because "' . $assetFile . '" given.');
if (preg_match('/^[a-zA-Z0-9]+$/', $assetFile) !== 1) {
throw new \RuntimeException(sprintf('Invalid asset format for file "%s", because "%s" given.', $assetFormat, $assetFile));
}
$format = $assetFile;
$assetFile = $assetFormat;
} elseif (preg_match('/^(?<name>.+)\.(?<format>[a-zA-Z0-9]+)(?:\?.*)?$/', $assetFile, $fileParser)) {
} elseif (preg_match('/^(?<name>.+)\.(?<format>[a-zA-Z0-9]+)(?:\?.*)?$/', $assetFile, $fileParser) === 1) {
$format = $fileParser['format'];
} else {
throw new \RuntimeException('Invalid asset filename "' . $assetFile . '". Did you mean "' . $assetFile . '.js"?');
throw new \RuntimeException(sprintf('Invalid asset filename "%s". Did you mean "%s.js"?', $assetFile, $assetFile));
}
if (isset($assets[$route][$format]) === false) {
$assets[$route][$format] = [];
Expand All @@ -77,8 +75,8 @@ public function beforeCompile(): void
}
}

foreach (($config['formatHtmlInjects'] ?? []) as $formatHtmlInject) {
if (!str_contains($formatHtmlInject, '%path%')) {
foreach ($config['formatHtmlInjects'] as $formatHtmlInject) {
if (str_contains($formatHtmlInject, '%path%') === false) {
throw new \RuntimeException('HTML inject format must contains variable "%path%", but "' . $formatHtmlInject . '" given.');
}
}
Expand All @@ -95,11 +93,11 @@ public function beforeCompile(): void
->setArgument('formatHeaders', array_merge([
'js' => 'application/javascript',
'css' => 'text/css',
], $config['formatHeaders'] ?? []))
], $config['formatHeaders']))
->setArgument('formatHtmlInjects', array_merge([
'js' => '<script src="%path%"></script>',
'css' => '<link href="%path%" rel="stylesheet">',
], $config['formatHtmlInjects'] ?? []));
], $config['formatHtmlInjects']));
}


Expand Down Expand Up @@ -128,10 +126,28 @@ private function validateRouteFormat(string $route): void
}
if (preg_match('/^[A-Z0-9][A-Za-z0-9]*:(?:\*|[A-Z0-9][A-Za-z0-9]*:(?:\*|[a-z0-9][A-Za-z0-9]*))$/', trim($route, ':')) === 0) {
throw new AssetLoaderException(
'Route "' . $route . '" is invalid. '
sprintf('Route "%s" is invalid. ', $route)
. 'Route must be absolute "Module:Presenter:action" or end '
. 'with dynamic part in format "Module:*" or "Module:Presenter:*".',
);
}
}


/**
* @param mixed[] $files
* @param mixed[] $base
* @return array<string,
* array<int, string>|array<int|string, array{format: string, source: string}>|array<string, string>
* >
*/
private function formatRoutingFiles(array $files, array $base = []): array
{
if ($base !== []) {
$files = array_merge_recursive($files, ['*' => $base]);
}

/** @phpstan-ignore-next-line */
return $files;
}
}
2 changes: 1 addition & 1 deletion src/Minifier/DefaultCssMinifier.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ public function minify(string $haystack): string
{
$return = (string) preg_replace_callback(
'#[ \t\r\n]+|<(/)?(textarea|pre)(?=\W)#i',
static fn(array $match): string => empty($match[2]) ? ' ' : $match[0],
static fn(array $match): string => isset($match[2]) && $match[2] !== '' ? $match[0] : ' ',
$haystack,
);
$return = (string) preg_replace('/(\w|;)\s+({|})\s+(\w|\.|#)/', '$1$2$3', $return);
Expand Down
4 changes: 2 additions & 2 deletions src/Minifier/JShrinkMinifier.php
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ class JShrinkMinifier
* Contains lock ids which are used to replace certain code patterns and
* prevent them from being minified
*
* @var mixed[]
* @var array<string, string>
*/
protected array $locks = [];

Expand Down Expand Up @@ -544,7 +544,7 @@ protected function lock(string $js): string
return $js;
}

$this->locks[$lock] = $matches[2];
$this->locks[$lock] = (string) $matches[2];

return (string) preg_replace('/([+-])\s+([+-])/S', '$1' . $lock . '$2', $js);
}
Expand Down
12 changes: 5 additions & 7 deletions src/Minifier/Minifier.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

final class Minifier
{
/** @var AssetMinifier[] (format => service) */
/** @var array<string, AssetMinifier> (format => service) */
private array $services = [];

private ?Cache $cache = null;
Expand All @@ -28,11 +28,11 @@ public function __construct(?Storage $storage = null)

public function minify(string $haystack, string $format): string
{
$key = $format . '-' . md5($haystack);
$key = sprintf('%s-%s', $format, md5($haystack));
if ($this->cache !== null) {
$cache = $this->cache->load($key);
if ($cache !== null) {
return (string) $cache;
if (is_string($cache)) {
return $cache;
}
}
$return = $this->getMinifier($format)->minify($haystack);
Expand Down Expand Up @@ -66,9 +66,7 @@ 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 (' . $this->services[$format]::class . ').',
);
throw new \LogicException(sprintf('Minifier for "%s" has been defined (%s).', $format, $this->services[$format]::class));
}

$this->services[$format] = $minifier;
Expand Down

0 comments on commit 18c662a

Please sign in to comment.