From 6d07d3a863af98ac36fea3b48c1cf57c788b1173 Mon Sep 17 00:00:00 2001 From: tbreuss Date: Tue, 27 Dec 2022 14:48:54 +0100 Subject: [PATCH 1/8] feat: rename file and link_file tiwg functions Signed-off-by: tbreuss --- plugins/twig/TwigExtension.php | 10 +++++----- tests/_data/site/pages/index.html | 10 +++++----- tests/_data/site/pages/plugins/dummy.html | 2 +- tests/acceptance/HerbieInfoCest.php | 2 +- .../TwigCore/Functions/FileLinkFunctionTest.php | 4 ++-- .../TwigCore/Functions/PageLinkFunctionTest.php | 2 +- .../SysPlugins/TwigPlus/TwigPlusSmokeTest.php | 2 +- website/site/data/twig_functions.yml | 8 ++++---- 8 files changed, 20 insertions(+), 20 deletions(-) diff --git a/plugins/twig/TwigExtension.php b/plugins/twig/TwigExtension.php index 57576999..3417b1be 100644 --- a/plugins/twig/TwigExtension.php +++ b/plugins/twig/TwigExtension.php @@ -92,12 +92,12 @@ public function getFunctions(): array new TwigFunction('css_add', [$this, 'cssAdd']), new TwigFunction('css_classes', [$this, 'cssClasses'], ['needs_context' => true]), new TwigFunction('css_out', [$this, 'cssOut'], ['is_safe' => ['html']]), - new TwigFunction('file', [$this, 'file'], ['is_safe' => ['html']]), new TwigFunction('image', [$this, 'image'], ['is_safe' => ['html']]), new TwigFunction('js_add', [$this, 'jsAdd']), new TwigFunction('js_out', [$this, 'jsOut'], ['is_safe' => ['html']]), new TwigFunction('link_file', [$this, 'linkFile'], ['is_safe' => ['html']]), new TwigFunction('link_mail', [$this, 'linkMail'], ['is_safe' => ['html']]), + new TwigFunction('link_media', [$this, 'linkMedia'], ['is_safe' => ['html']]), new TwigFunction('link_page', [$this, 'linkPage'], ['is_safe' => ['html']]), new TwigFunction('menu_ascii_tree', [$this, 'menuAsciiTree'], ['is_safe' => ['html']]), new TwigFunction('menu_breadcrumb', [$this, 'menuBreadcrumb'], ['is_safe' => ['html']]), @@ -218,7 +218,7 @@ public function cssClasses(array $context): string return str_replace(['/', '.'], '-', $class); } - public function linkFile( + public function linkMedia( string $path, string $label = '', bool $info = false, @@ -244,7 +244,7 @@ public function linkFile( '{label}' => empty($label) ? basename($path) : $label, '{info}' => empty($fileInfo) ? '' : sprintf('%s', $fileInfo) ]; - return strtr('{label}{info}', $replace); + return strtr('{label}{info}', $replace); } public function linkMail( @@ -527,7 +527,7 @@ public function linkPage(string $route, string $label, array $attribs = []): str { $scheme = parse_url($route, PHP_URL_SCHEME); if ($scheme === null) { - $class = 'link--internal'; + $class = 'link--page'; $href = $this->urlManager->createUrl($route); } else { $class = 'link--external'; @@ -606,7 +606,7 @@ public function urlAbsolute(string $route = ''): string return $this->urlManager->createAbsoluteUrl($route); } - public function file(string $path, string $label = '', bool $info = false, array $attribs = []): string + public function linkFile(string $path, string $label = '', bool $info = false, array $attribs = []): string { $attribs['class'] = $attribs['class'] ?? 'link__label'; diff --git a/tests/_data/site/pages/index.html b/tests/_data/site/pages/index.html index 94e41200..2a25e638 100644 --- a/tests/_data/site/pages/index.html +++ b/tests/_data/site/pages/index.html @@ -10,15 +10,15 @@

Herbie Tests

Downloads

-{{ link_file('favicon.ico', 'File', true) }} +{{ link_media('favicon.ico', 'File', true) }} Download

Imagine

diff --git a/tests/_data/site/pages/plugins/dummy.html b/tests/_data/site/pages/plugins/dummy.html index 1cc9e53f..e66a1613 100644 --- a/tests/_data/site/pages/plugins/dummy.html +++ b/tests/_data/site/pages/plugins/dummy.html @@ -9,4 +9,4 @@

Dummy Plugin

{{ dummy("This is from") }}.

{% if "dummy" is dummy %}This is from Dummy Test.{% endif %}

{% apply dummy_dynamic %}This is from {% endapply %}.

-

{{ link_file('dummy.pdf', 'Dummy', true) }}

+

{{ link_media('dummy.pdf', 'Dummy', true) }}

diff --git a/tests/acceptance/HerbieInfoCest.php b/tests/acceptance/HerbieInfoCest.php index 724a5c7e..944ed9ed 100644 --- a/tests/acceptance/HerbieInfoCest.php +++ b/tests/acceptance/HerbieInfoCest.php @@ -411,12 +411,12 @@ public function testNumberAndSortingOfTwigFunctions(AcceptanceTester $I) 'css_add', 'css_classes', 'css_out', - 'file', 'image', 'js_add', 'js_out', 'link_file', 'link_mail', + 'link_media', 'link_page', 'menu_ascii_tree', 'menu_breadcrumb', diff --git a/tests/integration/SysPlugins/TwigCore/Functions/FileLinkFunctionTest.php b/tests/integration/SysPlugins/TwigCore/Functions/FileLinkFunctionTest.php index ba193a7a..2137d990 100644 --- a/tests/integration/SysPlugins/TwigCore/Functions/FileLinkFunctionTest.php +++ b/tests/integration/SysPlugins/TwigCore/Functions/FileLinkFunctionTest.php @@ -22,8 +22,8 @@ private function twig(): TwigRenderer public function testPowerOn(): void { $this->assertEquals( - 'dummy.pdf', - $this->twig()->renderString('{{ link_file("dummy.pdf") }}') + 'dummy.pdf', + $this->twig()->renderString('{{ link_media("dummy.pdf") }}') ); } diff --git a/tests/integration/SysPlugins/TwigCore/Functions/PageLinkFunctionTest.php b/tests/integration/SysPlugins/TwigCore/Functions/PageLinkFunctionTest.php index 8774b80b..67a4b6fa 100644 --- a/tests/integration/SysPlugins/TwigCore/Functions/PageLinkFunctionTest.php +++ b/tests/integration/SysPlugins/TwigCore/Functions/PageLinkFunctionTest.php @@ -22,7 +22,7 @@ private function twig(): TwigRenderer public function testPowerOn(): void { $this->assertEquals( - 'label', + 'label', $this->twig()->renderString('{{ link_page("route", "label") }}') ); } diff --git a/tests/integration/SysPlugins/TwigPlus/TwigPlusSmokeTest.php b/tests/integration/SysPlugins/TwigPlus/TwigPlusSmokeTest.php index bb03a083..e4c7fd2e 100644 --- a/tests/integration/SysPlugins/TwigPlus/TwigPlusSmokeTest.php +++ b/tests/integration/SysPlugins/TwigPlus/TwigPlusSmokeTest.php @@ -41,7 +41,7 @@ public function testMenuBreadcrumbFunction(): void public function testMenuListFunction(): void { - $expected = ''; + $expected = ''; $actual = $this->twig()->renderString('{{ menu_list(filter="route|alpha") }}'); $this->assertEquals($expected, $actual); } diff --git a/website/site/data/twig_functions.yml b/website/site/data/twig_functions.yml index e529e863..4d66ec0d 100644 --- a/website/site/data/twig_functions.yml +++ b/website/site/data/twig_functions.yml @@ -74,9 +74,9 @@ return: - string - The string with CSS classes. -- name: file +- name: link_file code: >- - {{ file("media/download.pdf", "Download", true, {class:"download"}) }} + {{ link_file("media/download.pdf", "Download", true, {class:"download"}) }} desc: Returns a link to a file with additional info like file type and size. params: - name: path @@ -326,9 +326,9 @@ return: - string - The JavaScript assets -- name: link_file +- name: link_media code: >- - {{ link_file("dummy.pdf", "My dummy file", true, {class: "link-file"}) }} + {{ link_media("dummy.pdf", "My dummy file", true, {class: "link-file"}) }} desc: Returns a HTML link with a file from site/media folder. params: - name: path From b97107c42730ae73158585636ab0045f4365bfd8 Mon Sep 17 00:00:00 2001 From: tbreuss Date: Tue, 27 Dec 2022 15:12:05 +0100 Subject: [PATCH 2/8] fix: remove herbie\TwigFilter, herbie\TwigFunction, and herbie\TwigTest, since they're just simple wrapper classes Signed-off-by: tbreuss --- system/PluginInterface.php | 6 +++--- system/PluginManager.php | 6 ------ system/TwigFilter.php | 29 ----------------------------- system/TwigFunction.php | 29 ----------------------------- system/TwigTest.php | 29 ----------------------------- 5 files changed, 3 insertions(+), 96 deletions(-) delete mode 100644 system/TwigFilter.php delete mode 100644 system/TwigFunction.php delete mode 100644 system/TwigTest.php diff --git a/system/PluginInterface.php b/system/PluginInterface.php index 8894352f..e573ba39 100644 --- a/system/PluginInterface.php +++ b/system/PluginInterface.php @@ -31,7 +31,7 @@ public function applicationMiddlewares(): array; public function routeMiddlewares(): array; /** - * @return array}> + * @return array}> */ public function twigFilters(): array; @@ -41,12 +41,12 @@ public function twigFilters(): array; public function twigGlobals(): array; /** - * @return array}> + * @return array}> */ public function twigFunctions(): array; /** - * @return array}> + * @return array}> */ public function twigTests(): array; } diff --git a/system/PluginManager.php b/system/PluginManager.php index 339eda02..7dc1a5dd 100644 --- a/system/PluginManager.php +++ b/system/PluginManager.php @@ -175,8 +175,6 @@ private function loadInstallablePlugin(InstallablePlugin $installablePlugin): vo foreach ($plugin->twigFilters() as $twigFilter) { if ($twigFilter instanceof \Twig\TwigFilter) { $this->addTwigFilter($twigFilter); - } elseif ($twigFilter instanceof \herbie\TwigFilter) { - $this->addTwigFilter($twigFilter->createTwigFilter()); } else { $this->addTwigFilter(new \Twig\TwigFilter(...$twigFilter)); } @@ -189,8 +187,6 @@ private function loadInstallablePlugin(InstallablePlugin $installablePlugin): vo foreach ($plugin->twigFunctions() as $twigFunction) { if ($twigFunction instanceof \Twig\TwigFunction) { $this->addTwigFunction($twigFunction); - } elseif ($twigFunction instanceof \herbie\TwigFunction) { - $this->addTwigFunction($twigFunction->createTwigFunction()); } else { $this->addTwigFunction(new \Twig\TwigFunction(...$twigFunction)); } @@ -199,8 +195,6 @@ private function loadInstallablePlugin(InstallablePlugin $installablePlugin): vo foreach ($plugin->twigTests() as $twigTest) { if ($twigTest instanceof \Twig\TwigTest) { $this->addTwigTest($twigTest); - } elseif ($twigTest instanceof \herbie\TwigTest) { - $this->addTwigTest($twigTest->createTwigTest()); } else { $this->addTwigTest(new \Twig\TwigTest(...$twigTest)); } diff --git a/system/TwigFilter.php b/system/TwigFilter.php deleted file mode 100644 index 52b10688..00000000 --- a/system/TwigFilter.php +++ /dev/null @@ -1,29 +0,0 @@ - */ - private array $options; - - /** - * @param array $options - */ - public function __construct(string $name, callable $callable, array $options = []) - { - $this->name = $name; - $this->callable = $callable; - $this->options = $options; - } - - public function createTwigFilter(): \Twig\TwigFilter - { - return new \Twig\TwigFilter($this->name, $this->callable, $this->options); - } -} diff --git a/system/TwigFunction.php b/system/TwigFunction.php deleted file mode 100644 index c6a77c04..00000000 --- a/system/TwigFunction.php +++ /dev/null @@ -1,29 +0,0 @@ - */ - private array $options; - - /** - * @param array $options - */ - public function __construct(string $name, callable $callable, array $options = []) - { - $this->name = $name; - $this->callable = $callable; - $this->options = $options; - } - - public function createTwigFunction(): \Twig\TwigFunction - { - return new \Twig\TwigFunction($this->name, $this->callable, $this->options); - } -} diff --git a/system/TwigTest.php b/system/TwigTest.php deleted file mode 100644 index 84270160..00000000 --- a/system/TwigTest.php +++ /dev/null @@ -1,29 +0,0 @@ - */ - private array $options; - - /** - * @param array $options - */ - public function __construct(string $name, callable $callable, array $options = []) - { - $this->name = $name; - $this->callable = $callable; - $this->options = $options; - } - - public function createTwigTest(): \Twig\TwigTest - { - return new \Twig\TwigTest($this->name, $this->callable, $this->options); - } -} From 1e6605aad3023c703ed773d7212ee6fb2d0c0602 Mon Sep 17 00:00:00 2001 From: tbreuss Date: Wed, 28 Dec 2022 10:15:20 +0100 Subject: [PATCH 3/8] refactor: rename event folder to events Signed-off-by: tbreuss --- plugins/dummy/DummySysPlugin.php | 18 ++-- plugins/markdown/MarkdownSysPlugin.php | 2 +- plugins/rest/RestSysPlugin.php | 2 +- plugins/textile/TextileSysPlugin.php | 2 +- plugins/twig/TwigPlugin.php | 2 +- system/Application.php | 10 +- system/CorePlugin.php | 6 +- system/PageRendererMiddleware.php | 10 +- system/PluginManager.php | 4 +- system/TwigRenderer.php | 2 +- .../ContentRenderedEvent.php | 2 +- .../{event => events}/LayoutRenderedEvent.php | 2 +- .../PluginsInitializedEvent.php | 2 +- .../{event => events}/RenderLayoutEvent.php | 2 +- system/{event => events}/RenderPageEvent.php | 2 +- .../{event => events}/RenderSegmentEvent.php | 2 +- .../ResponseEmittedEvent.php | 2 +- .../ResponseGeneratedEvent.php | 2 +- .../TranslatorInitializedEvent.php | 2 +- .../TwigInitializedEvent.php | 2 +- .../site/extend/events/twig_initialized.php | 2 +- tests/_data/site/extend/filters/layout.php | 2 +- tests/_data/site/extend/filters/segment.php | 2 +- .../site/extend/plugins/dummy2/plugin.php | 6 +- tests/_data/src/TestFilter.php | 2 +- tests/_data/web/index.php | 6 +- tests/acceptance/HerbieInfoCest.php | 96 +++++++++---------- .../SysPlugins/DummySysPluginTest.php | 14 +-- website/site/extend/events/doc_toc.php | 2 +- 29 files changed, 105 insertions(+), 105 deletions(-) rename system/{event => events}/ContentRenderedEvent.php (96%) rename system/{event => events}/LayoutRenderedEvent.php (94%) rename system/{event => events}/PluginsInitializedEvent.php (97%) rename system/{event => events}/RenderLayoutEvent.php (97%) rename system/{event => events}/RenderPageEvent.php (96%) rename system/{event => events}/RenderSegmentEvent.php (97%) rename system/{event => events}/ResponseEmittedEvent.php (94%) rename system/{event => events}/ResponseGeneratedEvent.php (95%) rename system/{event => events}/TranslatorInitializedEvent.php (93%) rename system/{event => events}/TwigInitializedEvent.php (94%) diff --git a/plugins/dummy/DummySysPlugin.php b/plugins/dummy/DummySysPlugin.php index 64344ea3..3789a741 100644 --- a/plugins/dummy/DummySysPlugin.php +++ b/plugins/dummy/DummySysPlugin.php @@ -4,15 +4,15 @@ namespace herbie\sysplugin\dummy; -use herbie\event\ContentRenderedEvent; -use herbie\event\LayoutRenderedEvent; -use herbie\event\PluginsInitializedEvent; -use herbie\event\RenderLayoutEvent; -use herbie\event\RenderSegmentEvent; -use herbie\event\ResponseEmittedEvent; -use herbie\event\ResponseGeneratedEvent; -use herbie\event\TranslatorInitializedEvent; -use herbie\event\TwigInitializedEvent; +use herbie\events\ContentRenderedEvent; +use herbie\events\LayoutRenderedEvent; +use herbie\events\PluginsInitializedEvent; +use herbie\events\RenderLayoutEvent; +use herbie\events\RenderSegmentEvent; +use herbie\events\ResponseEmittedEvent; +use herbie\events\ResponseGeneratedEvent; +use herbie\events\TranslatorInitializedEvent; +use herbie\events\TwigInitializedEvent; use herbie\PluginInterface; use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; diff --git a/plugins/markdown/MarkdownSysPlugin.php b/plugins/markdown/MarkdownSysPlugin.php index 0695e474..45d966f6 100755 --- a/plugins/markdown/MarkdownSysPlugin.php +++ b/plugins/markdown/MarkdownSysPlugin.php @@ -5,7 +5,7 @@ namespace herbie\sysplugin\markdown; use herbie\Config; -use herbie\event\RenderSegmentEvent; +use herbie\events\RenderSegmentEvent; use herbie\Plugin; use Parsedown; use ParsedownExtra; diff --git a/plugins/rest/RestSysPlugin.php b/plugins/rest/RestSysPlugin.php index c96e7780..1b8fd0ca 100755 --- a/plugins/rest/RestSysPlugin.php +++ b/plugins/rest/RestSysPlugin.php @@ -5,7 +5,7 @@ namespace herbie\sysplugin\rest; use herbie\Config; -use herbie\event\RenderSegmentEvent; +use herbie\events\RenderSegmentEvent; use herbie\Plugin; final class RestSysPlugin extends Plugin diff --git a/plugins/textile/TextileSysPlugin.php b/plugins/textile/TextileSysPlugin.php index 0ee40e52..4907799d 100755 --- a/plugins/textile/TextileSysPlugin.php +++ b/plugins/textile/TextileSysPlugin.php @@ -5,7 +5,7 @@ namespace herbie\sysplugin\textile; use herbie\Config; -use herbie\event\RenderSegmentEvent; +use herbie\events\RenderSegmentEvent; use herbie\Plugin; use Netcarver\Textile\Parser; use Psr\Log\LoggerInterface; diff --git a/plugins/twig/TwigPlugin.php b/plugins/twig/TwigPlugin.php index 8fdcd61f..c8a384a5 100644 --- a/plugins/twig/TwigPlugin.php +++ b/plugins/twig/TwigPlugin.php @@ -8,7 +8,7 @@ use herbie\Alias; use herbie\Assets; use herbie\Config; -use herbie\event\TwigInitializedEvent; +use herbie\events\TwigInitializedEvent; use herbie\PageRepositoryInterface; use herbie\Plugin; use herbie\Translator; diff --git a/system/Application.php b/system/Application.php index 867ff23b..dd81b64f 100644 --- a/system/Application.php +++ b/system/Application.php @@ -5,11 +5,11 @@ namespace herbie; use Ausi\SlugGenerator\SlugGenerator; -use herbie\event\PluginsInitializedEvent; -use herbie\event\ResponseEmittedEvent; -use herbie\event\ResponseGeneratedEvent; -use herbie\event\TranslatorInitializedEvent; -use herbie\event\TwigInitializedEvent; +use herbie\events\PluginsInitializedEvent; +use herbie\events\ResponseEmittedEvent; +use herbie\events\ResponseGeneratedEvent; +use herbie\events\TranslatorInitializedEvent; +use herbie\events\TwigInitializedEvent; use Psr\Container\ContainerInterface; use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; diff --git a/system/CorePlugin.php b/system/CorePlugin.php index 896bfa32..797705bb 100644 --- a/system/CorePlugin.php +++ b/system/CorePlugin.php @@ -4,9 +4,9 @@ namespace herbie; -use herbie\event\RenderLayoutEvent; -use herbie\event\RenderPageEvent; -use herbie\event\RenderSegmentEvent; +use herbie\events\RenderLayoutEvent; +use herbie\events\RenderPageEvent; +use herbie\events\RenderSegmentEvent; final class CorePlugin extends Plugin { diff --git a/system/PageRendererMiddleware.php b/system/PageRendererMiddleware.php index 066de115..e4c0add0 100644 --- a/system/PageRendererMiddleware.php +++ b/system/PageRendererMiddleware.php @@ -4,11 +4,11 @@ namespace herbie; -use herbie\event\ContentRenderedEvent; -use herbie\event\LayoutRenderedEvent; -use herbie\event\RenderLayoutEvent; -use herbie\event\RenderPageEvent; -use herbie\event\RenderSegmentEvent; +use herbie\events\ContentRenderedEvent; +use herbie\events\LayoutRenderedEvent; +use herbie\events\RenderLayoutEvent; +use herbie\events\RenderPageEvent; +use herbie\events\RenderSegmentEvent; use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Server\MiddlewareInterface; diff --git a/system/PluginManager.php b/system/PluginManager.php index 7dc1a5dd..dacdea83 100644 --- a/system/PluginManager.php +++ b/system/PluginManager.php @@ -4,8 +4,8 @@ namespace herbie; -use herbie\event\PluginsInitializedEvent; -use herbie\event\TwigInitializedEvent; +use herbie\events\PluginsInitializedEvent; +use herbie\events\TwigInitializedEvent; use Psr\Container\ContainerInterface; use Psr\Http\Server\MiddlewareInterface; use Psr\Log\LoggerInterface; diff --git a/system/TwigRenderer.php b/system/TwigRenderer.php index 4fbc72af..bd1e9536 100644 --- a/system/TwigRenderer.php +++ b/system/TwigRenderer.php @@ -4,7 +4,7 @@ namespace herbie; -use herbie\event\TwigInitializedEvent; +use herbie\events\TwigInitializedEvent; use Psr\Log\LoggerInterface; use Twig\Error\LoaderError; use Twig\Error\RuntimeError; diff --git a/system/event/ContentRenderedEvent.php b/system/events/ContentRenderedEvent.php similarity index 96% rename from system/event/ContentRenderedEvent.php rename to system/events/ContentRenderedEvent.php index 08ae0a21..f0776eac 100644 --- a/system/event/ContentRenderedEvent.php +++ b/system/events/ContentRenderedEvent.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace herbie\event; +namespace herbie\events; use herbie\AbstractEvent; diff --git a/system/event/LayoutRenderedEvent.php b/system/events/LayoutRenderedEvent.php similarity index 94% rename from system/event/LayoutRenderedEvent.php rename to system/events/LayoutRenderedEvent.php index ae77e87a..d2091219 100644 --- a/system/event/LayoutRenderedEvent.php +++ b/system/events/LayoutRenderedEvent.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace herbie\event; +namespace herbie\events; use herbie\AbstractEvent; diff --git a/system/event/PluginsInitializedEvent.php b/system/events/PluginsInitializedEvent.php similarity index 97% rename from system/event/PluginsInitializedEvent.php rename to system/events/PluginsInitializedEvent.php index 4199e0be..66f78ac6 100644 --- a/system/event/PluginsInitializedEvent.php +++ b/system/events/PluginsInitializedEvent.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace herbie\event; +namespace herbie\events; use herbie\AbstractEvent; use herbie\InstallablePlugin; diff --git a/system/event/RenderLayoutEvent.php b/system/events/RenderLayoutEvent.php similarity index 97% rename from system/event/RenderLayoutEvent.php rename to system/events/RenderLayoutEvent.php index bf611483..057b209a 100644 --- a/system/event/RenderLayoutEvent.php +++ b/system/events/RenderLayoutEvent.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace herbie\event; +namespace herbie\events; use herbie\AbstractEvent; diff --git a/system/event/RenderPageEvent.php b/system/events/RenderPageEvent.php similarity index 96% rename from system/event/RenderPageEvent.php rename to system/events/RenderPageEvent.php index 001f2168..63a6afc4 100644 --- a/system/event/RenderPageEvent.php +++ b/system/events/RenderPageEvent.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace herbie\event; +namespace herbie\events; use herbie\AbstractEvent; use herbie\Page; diff --git a/system/event/RenderSegmentEvent.php b/system/events/RenderSegmentEvent.php similarity index 97% rename from system/event/RenderSegmentEvent.php rename to system/events/RenderSegmentEvent.php index 8182b499..ef0f7012 100644 --- a/system/event/RenderSegmentEvent.php +++ b/system/events/RenderSegmentEvent.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace herbie\event; +namespace herbie\events; use herbie\AbstractEvent; use herbie\Page; diff --git a/system/event/ResponseEmittedEvent.php b/system/events/ResponseEmittedEvent.php similarity index 94% rename from system/event/ResponseEmittedEvent.php rename to system/events/ResponseEmittedEvent.php index a4fd5989..cdae5ea9 100644 --- a/system/event/ResponseEmittedEvent.php +++ b/system/events/ResponseEmittedEvent.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace herbie\event; +namespace herbie\events; use herbie\AbstractEvent; use herbie\Application; diff --git a/system/event/ResponseGeneratedEvent.php b/system/events/ResponseGeneratedEvent.php similarity index 95% rename from system/event/ResponseGeneratedEvent.php rename to system/events/ResponseGeneratedEvent.php index 9dd83dc6..88caa159 100644 --- a/system/event/ResponseGeneratedEvent.php +++ b/system/events/ResponseGeneratedEvent.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace herbie\event; +namespace herbie\events; use herbie\AbstractEvent; use Psr\Http\Message\ResponseInterface; diff --git a/system/event/TranslatorInitializedEvent.php b/system/events/TranslatorInitializedEvent.php similarity index 93% rename from system/event/TranslatorInitializedEvent.php rename to system/events/TranslatorInitializedEvent.php index bed90b44..aebbe2dc 100644 --- a/system/event/TranslatorInitializedEvent.php +++ b/system/events/TranslatorInitializedEvent.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace herbie\event; +namespace herbie\events; use herbie\AbstractEvent; use herbie\Translator; diff --git a/system/event/TwigInitializedEvent.php b/system/events/TwigInitializedEvent.php similarity index 94% rename from system/event/TwigInitializedEvent.php rename to system/events/TwigInitializedEvent.php index 02682afa..dd6e7332 100644 --- a/system/event/TwigInitializedEvent.php +++ b/system/events/TwigInitializedEvent.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace herbie\event; +namespace herbie\events; use herbie\AbstractEvent; use Twig\Environment; diff --git a/tests/_data/site/extend/events/twig_initialized.php b/tests/_data/site/extend/events/twig_initialized.php index 79aa4b1f..4820519f 100644 --- a/tests/_data/site/extend/events/twig_initialized.php +++ b/tests/_data/site/extend/events/twig_initialized.php @@ -4,7 +4,7 @@ namespace tests\_data\site\extend\events; -use herbie\event\TwigInitializedEvent; +use herbie\events\TwigInitializedEvent; use Twig\TwigFilter; return [TwigInitializedEvent::class, function (TwigInitializedEvent $event): void { diff --git a/tests/_data/site/extend/filters/layout.php b/tests/_data/site/extend/filters/layout.php index da044756..12d99463 100644 --- a/tests/_data/site/extend/filters/layout.php +++ b/tests/_data/site/extend/filters/layout.php @@ -4,7 +4,7 @@ namespace tests\_data\site\extend\filters; -use herbie\event\RenderLayoutEvent; +use herbie\events\RenderLayoutEvent; return [RenderLayoutEvent::class, function (RenderLayoutEvent $event): void { $content = str_replace( diff --git a/tests/_data/site/extend/filters/segment.php b/tests/_data/site/extend/filters/segment.php index 57ba63d2..c7bba006 100644 --- a/tests/_data/site/extend/filters/segment.php +++ b/tests/_data/site/extend/filters/segment.php @@ -4,7 +4,7 @@ namespace tests\_data\site\extend\filters; -use herbie\event\RenderSegmentEvent; +use herbie\events\RenderSegmentEvent; return [RenderSegmentEvent::class, function (RenderSegmentEvent $event): void { $segment = $event->getSegment() diff --git a/tests/_data/site/extend/plugins/dummy2/plugin.php b/tests/_data/site/extend/plugins/dummy2/plugin.php index 369fae8b..99b5a872 100644 --- a/tests/_data/site/extend/plugins/dummy2/plugin.php +++ b/tests/_data/site/extend/plugins/dummy2/plugin.php @@ -4,9 +4,9 @@ namespace tests\_data\site\extend\plugins\dummy2; -use herbie\event\ContentRenderedEvent; -use herbie\event\RenderLayoutEvent; -use herbie\event\RenderSegmentEvent; +use herbie\events\ContentRenderedEvent; +use herbie\events\RenderLayoutEvent; +use herbie\events\RenderSegmentEvent; use herbie\PluginInterface; use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; diff --git a/tests/_data/src/TestFilter.php b/tests/_data/src/TestFilter.php index 5d501d42..60fdc87c 100644 --- a/tests/_data/src/TestFilter.php +++ b/tests/_data/src/TestFilter.php @@ -4,7 +4,7 @@ namespace tests\_data\src; -use herbie\event\RenderSegmentEvent; +use herbie\events\RenderSegmentEvent; class TestFilter { diff --git a/tests/_data/web/index.php b/tests/_data/web/index.php index 1d574ead..d6cd4411 100644 --- a/tests/_data/web/index.php +++ b/tests/_data/web/index.php @@ -14,9 +14,9 @@ use herbie\Application; use herbie\ApplicationPaths; -use herbie\event\RenderLayoutEvent; -use herbie\event\RenderSegmentEvent; -use herbie\event\TwigInitializedEvent; +use herbie\events\RenderLayoutEvent; +use herbie\events\RenderSegmentEvent; +use herbie\events\TwigInitializedEvent; use herbie\HttpBasicAuthMiddleware; use herbie\ResponseTimeMiddleware; use tests\_data\src\CustomCommand; diff --git a/tests/acceptance/HerbieInfoCest.php b/tests/acceptance/HerbieInfoCest.php index 944ed9ed..5889144c 100644 --- a/tests/acceptance/HerbieInfoCest.php +++ b/tests/acceptance/HerbieInfoCest.php @@ -99,11 +99,11 @@ public function testNumberAndSortingOfPhpClasses(AcceptanceTester $I) 'herbie\UncaughtExceptionHandler', 'herbie\UrlManager', 'herbie\Yaml', - 'herbie\event\PluginsInitializedEvent', - 'herbie\event\RenderPageEvent', - 'herbie\event\RenderSegmentEvent', - 'herbie\event\TranslatorInitializedEvent', - 'herbie\event\TwigInitializedEvent', + 'herbie\events\PluginsInitializedEvent', + 'herbie\events\RenderPageEvent', + 'herbie\events\RenderSegmentEvent', + 'herbie\events\TranslatorInitializedEvent', + 'herbie\events\TwigInitializedEvent', 'herbie\sysplugin\dummy\DummySysPlugin', 'herbie\sysplugin\imagine\ImagineSysPlugin', 'herbie\sysplugin\markdown\MarkdownSysPlugin', @@ -472,49 +472,49 @@ public function testNumberAndSortingOfTwigTests(AcceptanceTester $I) public function testNumberAndSortingOfEvents(AcceptanceTester $I) { $events = [ - 'herbie\event\TwigInitializedEvent', - 'herbie\event\TwigInitializedEvent', - 'herbie\event\TwigInitializedEvent', - 'herbie\event\TwigInitializedEvent', - 'herbie\event\TwigInitializedEvent', - 'herbie\event\TwigInitializedEvent', - 'herbie\event\TwigInitializedEvent', - 'herbie\event\TwigInitializedEvent', - 'herbie\event\TwigInitializedEvent', - 'herbie\event\TwigInitializedEvent', - 'herbie\event\TwigInitializedEvent', - 'herbie\event\TwigInitializedEvent', - 'herbie\event\TwigInitializedEvent', - 'herbie\event\TwigInitializedEvent', - 'herbie\event\TwigInitializedEvent', - 'herbie\event\TwigInitializedEvent', - 'herbie\event\TwigInitializedEvent', - 'herbie\event\TwigInitializedEvent', - 'herbie\event\TwigInitializedEvent', - 'herbie\event\TwigInitializedEvent', - 'herbie\event\TwigInitializedEvent', - 'herbie\event\TwigInitializedEvent', - 'herbie\event\TwigInitializedEvent', - 'herbie\event\TwigInitializedEvent', - 'herbie\event\TwigInitializedEvent', - 'herbie\event\TwigInitializedEvent', - 'herbie\event\RenderLayoutEvent', - 'herbie\event\RenderLayoutEvent', - 'herbie\event\RenderLayoutEvent', - 'herbie\event\RenderPageEvent', - 'herbie\event\RenderSegmentEvent', - 'herbie\event\RenderSegmentEvent', - 'herbie\event\RenderSegmentEvent', - 'herbie\event\RenderSegmentEvent', - 'herbie\event\RenderSegmentEvent', - 'herbie\event\RenderSegmentEvent', - 'herbie\event\RenderSegmentEvent', - 'herbie\event\ContentRenderedEvent', - 'herbie\event\LayoutRenderedEvent', - 'herbie\event\PluginsInitializedEvent', - 'herbie\event\ResponseEmittedEvent', - 'herbie\event\ResponseGeneratedEvent', - 'herbie\event\TranslatorInitializedEvent', + 'herbie\events\TwigInitializedEvent', + 'herbie\events\TwigInitializedEvent', + 'herbie\events\TwigInitializedEvent', + 'herbie\events\TwigInitializedEvent', + 'herbie\events\TwigInitializedEvent', + 'herbie\events\TwigInitializedEvent', + 'herbie\events\TwigInitializedEvent', + 'herbie\events\TwigInitializedEvent', + 'herbie\events\TwigInitializedEvent', + 'herbie\events\TwigInitializedEvent', + 'herbie\events\TwigInitializedEvent', + 'herbie\events\TwigInitializedEvent', + 'herbie\events\TwigInitializedEvent', + 'herbie\events\TwigInitializedEvent', + 'herbie\events\TwigInitializedEvent', + 'herbie\events\TwigInitializedEvent', + 'herbie\events\TwigInitializedEvent', + 'herbie\events\TwigInitializedEvent', + 'herbie\events\TwigInitializedEvent', + 'herbie\events\TwigInitializedEvent', + 'herbie\events\TwigInitializedEvent', + 'herbie\events\TwigInitializedEvent', + 'herbie\events\TwigInitializedEvent', + 'herbie\events\TwigInitializedEvent', + 'herbie\events\TwigInitializedEvent', + 'herbie\events\TwigInitializedEvent', + 'herbie\events\RenderLayoutEvent', + 'herbie\events\RenderLayoutEvent', + 'herbie\events\RenderLayoutEvent', + 'herbie\events\RenderPageEvent', + 'herbie\events\RenderSegmentEvent', + 'herbie\events\RenderSegmentEvent', + 'herbie\events\RenderSegmentEvent', + 'herbie\events\RenderSegmentEvent', + 'herbie\events\RenderSegmentEvent', + 'herbie\events\RenderSegmentEvent', + 'herbie\events\RenderSegmentEvent', + 'herbie\events\ContentRenderedEvent', + 'herbie\events\LayoutRenderedEvent', + 'herbie\events\PluginsInitializedEvent', + 'herbie\events\ResponseEmittedEvent', + 'herbie\events\ResponseGeneratedEvent', + 'herbie\events\TranslatorInitializedEvent', ]; $I->amOnPage('/herbie-info'); $I->see('Event Listeners (' . count($events) . ')', 'h2'); diff --git a/tests/integration/SysPlugins/DummySysPluginTest.php b/tests/integration/SysPlugins/DummySysPluginTest.php index 17b52210..e8ae418c 100644 --- a/tests/integration/SysPlugins/DummySysPluginTest.php +++ b/tests/integration/SysPlugins/DummySysPluginTest.php @@ -40,12 +40,12 @@ public function testTextileFilter(): void // https://stackoverflow.com/a/70355297/6161354 $logContent = file_read($logFile); - $this->assertStringContainsString('Event herbie\event\ContentRenderedEvent was triggered', $logContent); - $this->assertStringContainsString('Event herbie\event\LayoutRenderedEvent was triggered', $logContent); - $this->assertStringContainsString('Event herbie\event\PluginsInitializedEvent was triggered', $logContent); - $this->assertStringContainsString('Event herbie\event\ResponseEmittedEvent was triggered', $logContent); - $this->assertStringContainsString('Event herbie\event\ResponseGeneratedEvent was triggered', $logContent); - $this->assertStringContainsString('Event herbie\event\TranslatorInitializedEvent was triggered', $logContent); - $this->assertStringContainsString('Event herbie\event\TwigInitializedEvent was triggered', $logContent); + $this->assertStringContainsString('Event herbie\events\ContentRenderedEvent was triggered', $logContent); + $this->assertStringContainsString('Event herbie\events\LayoutRenderedEvent was triggered', $logContent); + $this->assertStringContainsString('Event herbie\events\PluginsInitializedEvent was triggered', $logContent); + $this->assertStringContainsString('Event herbie\events\ResponseEmittedEvent was triggered', $logContent); + $this->assertStringContainsString('Event herbie\events\ResponseGeneratedEvent was triggered', $logContent); + $this->assertStringContainsString('Event herbie\events\TranslatorInitializedEvent was triggered', $logContent); + $this->assertStringContainsString('Event herbie\events\TwigInitializedEvent was triggered', $logContent); } } diff --git a/website/site/extend/events/doc_toc.php b/website/site/extend/events/doc_toc.php index 272414b5..c0b7e217 100644 --- a/website/site/extend/events/doc_toc.php +++ b/website/site/extend/events/doc_toc.php @@ -1,6 +1,6 @@ getPage(); From 6d5245508d838a85de9797bcd2cd9e153d332eab Mon Sep 17 00:00:00 2001 From: tbreuss Date: Wed, 28 Dec 2022 10:36:42 +0100 Subject: [PATCH 4/8] refactor: Rename herbie\sysplugin namespace to herbie\sysplugins Signed-off-by: tbreuss --- composer.json | 2 +- plugins/dummy/DummyCommand.php | 2 +- plugins/dummy/DummySysPlugin.php | 2 +- plugins/dummy/config.php | 2 +- plugins/imagine/ImagineSysPlugin.php | 2 +- plugins/imagine/config.php | 2 +- plugins/markdown/MarkdownSysPlugin.php | 2 +- plugins/markdown/config.php | 2 +- plugins/rest/RestSysPlugin.php | 2 +- plugins/rest/config.php | 2 +- plugins/textile/TextileSysPlugin.php | 2 +- plugins/textile/config.php | 2 +- plugins/twig/TwigExtension.php | 2 +- plugins/twig/TwigPlugin.php | 2 +- plugins/twig/config.php | 2 +- tests/acceptance/HerbieInfoCest.php | 22 +++++++++++----------- 16 files changed, 26 insertions(+), 26 deletions(-) diff --git a/composer.json b/composer.json index b5b3b203..700d1a21 100644 --- a/composer.json +++ b/composer.json @@ -38,7 +38,7 @@ "autoload": { "psr-4": { "herbie\\": "system", - "herbie\\sysplugin\\": "plugins" + "herbie\\sysplugins\\": "plugins" }, "files": [ "system/functions.php" diff --git a/plugins/dummy/DummyCommand.php b/plugins/dummy/DummyCommand.php index 4a63bd33..a115c155 100644 --- a/plugins/dummy/DummyCommand.php +++ b/plugins/dummy/DummyCommand.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace herbie\sysplugin\dummy; +namespace herbie\sysplugins\dummy; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; diff --git a/plugins/dummy/DummySysPlugin.php b/plugins/dummy/DummySysPlugin.php index 3789a741..1cdafbbd 100644 --- a/plugins/dummy/DummySysPlugin.php +++ b/plugins/dummy/DummySysPlugin.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace herbie\sysplugin\dummy; +namespace herbie\sysplugins\dummy; use herbie\events\ContentRenderedEvent; use herbie\events\LayoutRenderedEvent; diff --git a/plugins/dummy/config.php b/plugins/dummy/config.php index 793dfd44..25b46102 100755 --- a/plugins/dummy/config.php +++ b/plugins/dummy/config.php @@ -2,7 +2,7 @@ declare(strict_types=1); -use herbie\sysplugin\dummy\DummySysPlugin; +use herbie\sysplugins\dummy\DummySysPlugin; return [ 'apiVersion' => 2, diff --git a/plugins/imagine/ImagineSysPlugin.php b/plugins/imagine/ImagineSysPlugin.php index 728ab080..b096ff07 100755 --- a/plugins/imagine/ImagineSysPlugin.php +++ b/plugins/imagine/ImagineSysPlugin.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace herbie\sysplugin\imagine; +namespace herbie\sysplugins\imagine; use herbie\Alias; use herbie\Config; diff --git a/plugins/imagine/config.php b/plugins/imagine/config.php index d25f0fce..46891591 100644 --- a/plugins/imagine/config.php +++ b/plugins/imagine/config.php @@ -1,6 +1,6 @@ 2, diff --git a/plugins/markdown/MarkdownSysPlugin.php b/plugins/markdown/MarkdownSysPlugin.php index 45d966f6..d593b891 100755 --- a/plugins/markdown/MarkdownSysPlugin.php +++ b/plugins/markdown/MarkdownSysPlugin.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace herbie\sysplugin\markdown; +namespace herbie\sysplugins\markdown; use herbie\Config; use herbie\events\RenderSegmentEvent; diff --git a/plugins/markdown/config.php b/plugins/markdown/config.php index aab7db21..5472d02f 100755 --- a/plugins/markdown/config.php +++ b/plugins/markdown/config.php @@ -1,6 +1,6 @@ 2, diff --git a/plugins/rest/RestSysPlugin.php b/plugins/rest/RestSysPlugin.php index 1b8fd0ca..ae79ddc9 100755 --- a/plugins/rest/RestSysPlugin.php +++ b/plugins/rest/RestSysPlugin.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace herbie\sysplugin\rest; +namespace herbie\sysplugins\rest; use herbie\Config; use herbie\events\RenderSegmentEvent; diff --git a/plugins/rest/config.php b/plugins/rest/config.php index 0ee43c30..c63e8f6a 100755 --- a/plugins/rest/config.php +++ b/plugins/rest/config.php @@ -1,6 +1,6 @@ 2, diff --git a/plugins/textile/TextileSysPlugin.php b/plugins/textile/TextileSysPlugin.php index 4907799d..2dc0a199 100755 --- a/plugins/textile/TextileSysPlugin.php +++ b/plugins/textile/TextileSysPlugin.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace herbie\sysplugin\textile; +namespace herbie\sysplugins\textile; use herbie\Config; use herbie\events\RenderSegmentEvent; diff --git a/plugins/textile/config.php b/plugins/textile/config.php index b80895c9..a0b27156 100755 --- a/plugins/textile/config.php +++ b/plugins/textile/config.php @@ -1,6 +1,6 @@ 2, diff --git a/plugins/twig/TwigExtension.php b/plugins/twig/TwigExtension.php index 3417b1be..9f6f0d9d 100644 --- a/plugins/twig/TwigExtension.php +++ b/plugins/twig/TwigExtension.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace herbie\sysplugin\twig; +namespace herbie\sysplugins\twig; use Ausi\SlugGenerator\SlugGenerator; use herbie\Alias; diff --git a/plugins/twig/TwigPlugin.php b/plugins/twig/TwigPlugin.php index c8a384a5..944784c5 100644 --- a/plugins/twig/TwigPlugin.php +++ b/plugins/twig/TwigPlugin.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace herbie\sysplugin\twig; +namespace herbie\sysplugins\twig; use Ausi\SlugGenerator\SlugGenerator; use herbie\Alias; diff --git a/plugins/twig/config.php b/plugins/twig/config.php index 2744e481..4a51f128 100755 --- a/plugins/twig/config.php +++ b/plugins/twig/config.php @@ -1,6 +1,6 @@ 2, diff --git a/tests/acceptance/HerbieInfoCest.php b/tests/acceptance/HerbieInfoCest.php index 5889144c..eb68d855 100644 --- a/tests/acceptance/HerbieInfoCest.php +++ b/tests/acceptance/HerbieInfoCest.php @@ -104,13 +104,13 @@ public function testNumberAndSortingOfPhpClasses(AcceptanceTester $I) 'herbie\events\RenderSegmentEvent', 'herbie\events\TranslatorInitializedEvent', 'herbie\events\TwigInitializedEvent', - 'herbie\sysplugin\dummy\DummySysPlugin', - 'herbie\sysplugin\imagine\ImagineSysPlugin', - 'herbie\sysplugin\markdown\MarkdownSysPlugin', - 'herbie\sysplugin\rest\RestSysPlugin', - 'herbie\sysplugin\textile\TextileSysPlugin', - 'herbie\sysplugin\twig\TwigExtension', - 'herbie\sysplugin\twig\TwigPlugin', + 'herbie\sysplugins\dummy\DummySysPlugin', + 'herbie\sysplugins\imagine\ImagineSysPlugin', + 'herbie\sysplugins\markdown\MarkdownSysPlugin', + 'herbie\sysplugins\rest\RestSysPlugin', + 'herbie\sysplugins\textile\TextileSysPlugin', + 'herbie\sysplugins\twig\TwigExtension', + 'herbie\sysplugins\twig\TwigPlugin', ]; $I->amOnPage('/herbie-info'); $I->see('PHP Classes (' . count($classes) . ')', 'h2'); @@ -122,14 +122,14 @@ public function testNumberAndSortingOfMiddlewares(AcceptanceTester $I) $middlewares = [ 'herbie\ErrorHandlerMiddleware', 'herbie\PageResolverMiddleware', - 'herbie\sysplugin\dummy\DummySysPlugin->appMiddleware', + 'herbie\sysplugins\dummy\DummySysPlugin->appMiddleware', 'tests\_data\src\CustomHeader', 'herbie\ResponseTimeMiddleware', 'tests\_data\src\CustomHeader', 'tests\_data\src\CustomHeader', 'tests\_data\src\CustomHeader', - 'herbie\sysplugin\dummy\DummySysPlugin->routeMiddleware', - 'herbie\sysplugin\dummy\DummySysPlugin->routeMiddleware', + 'herbie\sysplugins\dummy\DummySysPlugin->routeMiddleware', + 'herbie\sysplugins\dummy\DummySysPlugin->routeMiddleware', 'tests\_data\src\CustomHeader', 'tests\_data\src\CustomHeader', 'tests\_data\src\CustomHeader', @@ -544,7 +544,7 @@ public function testNumberAndSortingOfCommands(AcceptanceTester $I) { $commands = [ 'herbie\ClearFilesCommand', - 'herbie\sysplugin\dummy\DummyCommand', + 'herbie\sysplugins\dummy\DummyCommand', 'tests\_data\site\extend\commands\CustomCommand', 'tests\_data\src\CustomCommand', 'tests\_data\src\CustomCommand' From 879f1b2c108d771a33dc8c72fc482c010cbcb24d Mon Sep 17 00:00:00 2001 From: tbreuss Date: Wed, 28 Dec 2022 10:49:29 +0100 Subject: [PATCH 5/8] refactor: Rename tests namespace to herbie\tests Signed-off-by: tbreuss --- composer.json | 2 +- tests/_data/site/extend/commands/custom1.php | 2 +- tests/_data/site/extend/commands/custom2.php | 4 +-- .../site/extend/events/twig_initialized.php | 2 +- tests/_data/site/extend/filters/layout.php | 2 +- tests/_data/site/extend/filters/segment.php | 2 +- .../site/extend/middlewares_app/custom.php | 4 +-- .../site/extend/middlewares_route/custom.php | 4 +-- .../site/extend/plugins/dummy2/plugin.php | 2 +- .../site/extend/twig_filters/reverse.php | 2 +- .../site/extend/twig_functions/hello.php | 2 +- tests/_data/site/extend/twig_tests/odd.php | 2 +- tests/_data/src/CustomCommand.php | 2 +- tests/_data/src/CustomHeader.php | 2 +- tests/_data/src/TestFilter.php | 2 +- tests/_data/web/index.php | 6 ++--- tests/acceptance/DummySysPluginCest.php | 2 +- tests/acceptance/HerbieInfoCest.php | 25 +++++++++++-------- tests/acceptance/ImagineSysPluginCest.php | 2 +- tests/acceptance/PageFormatterCest.php | 2 +- .../SysPlugins/DummySysPluginTest.php | 2 +- .../SysPlugins/MarkdownSysPluginTest.php | 2 +- .../SysPlugins/TextileSysPluginTest.php | 2 +- .../TwigCore/Filters/FilesizeFilterTest.php | 2 +- .../TwigCore/Filters/SlugifyFilterTest.php | 2 +- .../TwigCore/Filters/VisibleFilterTest.php | 2 +- .../TwigCore/Functions/AbsUrlFunctionTest.php | 2 +- .../TwigCore/Functions/AddCssFunctionTest.php | 2 +- .../TwigCore/Functions/AddJsFunctionTest.php | 2 +- .../Functions/CssClassesFunctionTest.php | 2 +- .../Functions/FileLinkFunctionTest.php | 2 +- .../TwigCore/Functions/ImageFunctionTest.php | 2 +- .../Functions/MailLinkFunctionTest.php | 2 +- .../Functions/OutputCssFunctionTest.php | 2 +- .../Functions/OutputJsFunctionTest.php | 2 +- .../Functions/PageLinkFunctionTest.php | 2 +- .../Functions/PageTitleFunctionTest.php | 2 +- .../Functions/SnippetFunctionTest.php | 2 +- .../Functions/TranslateFunctionTest.php | 2 +- .../TwigCore/Functions/UrlFunctionTest.php | 2 +- .../TwigCore/Tests/ReadableTest.php | 2 +- .../TwigCore/Tests/WritableTest.php | 2 +- .../SysPlugins/TwigPlus/TwigPlusSmokeTest.php | 2 +- tests/unit/AliasTest.php | 2 +- tests/unit/ConfigTest.php | 2 +- tests/unit/FunctionsTest.php | 2 +- tests/unit/PageTest.php | 2 +- 47 files changed, 65 insertions(+), 62 deletions(-) diff --git a/composer.json b/composer.json index 700d1a21..e963c7ee 100644 --- a/composer.json +++ b/composer.json @@ -47,7 +47,7 @@ "autoload-dev": { "psr-4": { "website\\site\\": "website/site", - "tests\\": "tests" + "herbie\\tests\\": "tests" } }, "require-dev": { diff --git a/tests/_data/site/extend/commands/custom1.php b/tests/_data/site/extend/commands/custom1.php index ba7a667f..c9ae6177 100644 --- a/tests/_data/site/extend/commands/custom1.php +++ b/tests/_data/site/extend/commands/custom1.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace tests\_data\site\extend\commands; +namespace herbie\tests\_data\site\extend\commands; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; diff --git a/tests/_data/site/extend/commands/custom2.php b/tests/_data/site/extend/commands/custom2.php index e416c9f5..102f0fce 100644 --- a/tests/_data/site/extend/commands/custom2.php +++ b/tests/_data/site/extend/commands/custom2.php @@ -2,8 +2,8 @@ declare(strict_types=1); -namespace tests\_data\site\extend\commands; +namespace herbie\tests\_data\site\extend\commands; -use tests\_data\src\CustomCommand; +use herbie\tests\_data\src\CustomCommand; return CustomCommand::class; diff --git a/tests/_data/site/extend/events/twig_initialized.php b/tests/_data/site/extend/events/twig_initialized.php index 4820519f..8963adf6 100644 --- a/tests/_data/site/extend/events/twig_initialized.php +++ b/tests/_data/site/extend/events/twig_initialized.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace tests\_data\site\extend\events; +namespace herbie\tests\_data\site\extend\events; use herbie\events\TwigInitializedEvent; use Twig\TwigFilter; diff --git a/tests/_data/site/extend/filters/layout.php b/tests/_data/site/extend/filters/layout.php index 12d99463..0190264c 100644 --- a/tests/_data/site/extend/filters/layout.php +++ b/tests/_data/site/extend/filters/layout.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace tests\_data\site\extend\filters; +namespace herbie\tests\_data\site\extend\filters; use herbie\events\RenderLayoutEvent; diff --git a/tests/_data/site/extend/filters/segment.php b/tests/_data/site/extend/filters/segment.php index c7bba006..2d840a46 100644 --- a/tests/_data/site/extend/filters/segment.php +++ b/tests/_data/site/extend/filters/segment.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace tests\_data\site\extend\filters; +namespace herbie\tests\_data\site\extend\filters; use herbie\events\RenderSegmentEvent; diff --git a/tests/_data/site/extend/middlewares_app/custom.php b/tests/_data/site/extend/middlewares_app/custom.php index 1d3babeb..f9531f10 100644 --- a/tests/_data/site/extend/middlewares_app/custom.php +++ b/tests/_data/site/extend/middlewares_app/custom.php @@ -1,7 +1,7 @@ amOnPage('/herbie-info'); $I->see('PHP Classes (' . count($classes) . ')', 'h2'); @@ -123,16 +126,16 @@ public function testNumberAndSortingOfMiddlewares(AcceptanceTester $I) 'herbie\ErrorHandlerMiddleware', 'herbie\PageResolverMiddleware', 'herbie\sysplugins\dummy\DummySysPlugin->appMiddleware', - 'tests\_data\src\CustomHeader', + 'herbie\tests\_data\src\CustomHeader', 'herbie\ResponseTimeMiddleware', - 'tests\_data\src\CustomHeader', - 'tests\_data\src\CustomHeader', - 'tests\_data\src\CustomHeader', + 'herbie\tests\_data\src\CustomHeader', + 'herbie\tests\_data\src\CustomHeader', + 'herbie\tests\_data\src\CustomHeader', 'herbie\sysplugins\dummy\DummySysPlugin->routeMiddleware', 'herbie\sysplugins\dummy\DummySysPlugin->routeMiddleware', - 'tests\_data\src\CustomHeader', - 'tests\_data\src\CustomHeader', - 'tests\_data\src\CustomHeader', + 'herbie\tests\_data\src\CustomHeader', + 'herbie\tests\_data\src\CustomHeader', + 'herbie\tests\_data\src\CustomHeader', 'herbie\HttpBasicAuthMiddleware', 'herbie\DownloadMiddleware', 'herbie\PageRendererMiddleware', @@ -545,9 +548,9 @@ public function testNumberAndSortingOfCommands(AcceptanceTester $I) $commands = [ 'herbie\ClearFilesCommand', 'herbie\sysplugins\dummy\DummyCommand', - 'tests\_data\site\extend\commands\CustomCommand', - 'tests\_data\src\CustomCommand', - 'tests\_data\src\CustomCommand' + 'herbie\tests\_data\site\extend\commands\CustomCommand', + 'herbie\tests\_data\src\CustomCommand', + 'herbie\tests\_data\src\CustomCommand' ]; $I->amOnPage('/herbie-info'); $I->see('Commands (' . count($commands) . ')', 'h2'); diff --git a/tests/acceptance/ImagineSysPluginCest.php b/tests/acceptance/ImagineSysPluginCest.php index 0341e4b6..7cdd31c8 100644 --- a/tests/acceptance/ImagineSysPluginCest.php +++ b/tests/acceptance/ImagineSysPluginCest.php @@ -1,6 +1,6 @@ Date: Wed, 28 Dec 2022 11:02:42 +0100 Subject: [PATCH 6/8] refactor: Code re-formatting according to PSR-12 Signed-off-by: tbreuss --- plugins/dummy/DummyCommand.php | 3 +- plugins/dummy/DummySysPlugin.php | 18 +- plugins/imagine/ImagineSysPlugin.php | 87 ++--- plugins/rest/RestSysPlugin.php | 3 +- plugins/textile/TextileSysPlugin.php | 3 +- plugins/twig/TwigExtension.php | 161 ++++---- plugins/twig/TwigPlugin.php | 22 +- system/AbstractNode.php | 25 +- system/Alias.php | 36 +- system/Application.php | 191 +++++----- system/Assets.php | 163 +++++---- system/ClearFilesCommand.php | 8 +- system/Config.php | 44 +-- system/Container.php | 44 +-- system/CorePlugin.php | 15 +- system/DataRepositoryInterface.php | 2 + system/ErrorHandlerMiddleware.php | 5 +- system/FatalErrorHandler.php | 4 +- system/FileCache.php | 125 +++---- system/FileInfoSortableIterator.php | 13 +- system/FileLogger.php | 133 +++---- system/FlatFilePagePersistence.php | 183 +++++----- system/FlatFilePageRepository.php | 16 +- system/JsonDataRepository.php | 18 +- system/LocalExtensionsPlugin.php | 114 +++--- system/Page.php | 344 +++++++++--------- system/PageFactory.php | 14 +- system/PageList.php | 93 ++--- system/PageTrail.php | 5 +- system/PageTreeHtmlRenderer.php | 21 +- system/PageTreeTextRenderer.php | 3 +- system/Pagination.php | 34 +- system/PluginInterface.php | 9 +- system/PluginManager.php | 231 ++++++------ system/QueryBuilder.php | 146 ++++---- system/Site.php | 12 +- system/SystemInfoPlugin.php | 80 ++-- system/Translator.php | 32 +- system/TwigRenderer.php | 108 +++--- system/TwigStringLoader.php | 26 +- system/UncaughtExceptionHandler.php | 4 +- system/UrlManager.php | 17 +- system/Yaml.php | 12 +- system/YamlDataRepository.php | 18 +- system/events/ContentRenderedEvent.php | 2 +- system/functions.php | 37 +- tests/_data/site/extend/commands/custom1.php | 3 +- .../site/extend/events/twig_initialized.php | 15 +- tests/_data/site/extend/filters/layout.php | 19 +- tests/_data/site/extend/filters/segment.php | 17 +- .../site/extend/plugins/dummy2/plugin.php | 10 +- tests/_data/web/index.php | 8 +- tests/_support/AcceptanceTester.php | 6 +- tests/_support/FunctionalTester.php | 6 +- tests/_support/Helper/Acceptance.php | 4 +- tests/_support/Helper/Functional.php | 4 +- tests/_support/Helper/Unit.php | 4 +- tests/_support/UnitTester.php | 16 +- tests/acceptance/DummySysPluginCest.php | 3 +- tests/acceptance/ImagineSysPluginCest.php | 3 +- .../SysPlugins/DummySysPluginTest.php | 31 +- .../SysPlugins/MarkdownSysPluginTest.php | 57 +-- .../SysPlugins/TextileSysPluginTest.php | 52 +-- .../TwigCore/Filters/FilesizeFilterTest.php | 41 ++- .../TwigCore/Filters/SlugifyFilterTest.php | 34 +- .../TwigCore/Filters/VisibleFilterTest.php | 31 +- .../TwigCore/Functions/AbsUrlFunctionTest.php | 21 +- .../TwigCore/Functions/AddCssFunctionTest.php | 13 +- .../TwigCore/Functions/AddJsFunctionTest.php | 13 +- .../Functions/CssClassesFunctionTest.php | 17 +- .../Functions/FileLinkFunctionTest.php | 19 +- .../TwigCore/Functions/ImageFunctionTest.php | 19 +- .../Functions/MailLinkFunctionTest.php | 35 +- .../Functions/OutputCssFunctionTest.php | 19 +- .../Functions/OutputJsFunctionTest.php | 19 +- .../Functions/PageLinkFunctionTest.php | 19 +- .../Functions/PageTitleFunctionTest.php | 17 +- .../Functions/SnippetFunctionTest.php | 17 +- .../Functions/TranslateFunctionTest.php | 24 +- .../TwigCore/Functions/UrlFunctionTest.php | 15 +- .../TwigCore/Tests/ReadableTest.php | 23 +- .../TwigCore/Tests/WritableTest.php | 22 +- .../SysPlugins/TwigPlus/TwigPlusSmokeTest.php | 22 +- tests/unit/AliasTest.php | 33 +- tests/unit/ConfigTest.php | 28 +- tests/unit/FunctionsTest.php | 4 +- tests/unit/PageTest.php | 124 ++++--- .../extend/twig_functions/git_commits.php | 93 ++--- 88 files changed, 1923 insertions(+), 1741 deletions(-) diff --git a/plugins/dummy/DummyCommand.php b/plugins/dummy/DummyCommand.php index a115c155..3f95fe98 100644 --- a/plugins/dummy/DummyCommand.php +++ b/plugins/dummy/DummyCommand.php @@ -16,8 +16,7 @@ final class DummyCommand extends Command protected function configure(): void { $this - ->setHelp('This command allows you to create a user...') - ; + ->setHelp('This command allows you to create a user...'); } protected function execute(InputInterface $input, OutputInterface $output): int diff --git a/plugins/dummy/DummySysPlugin.php b/plugins/dummy/DummySysPlugin.php index 1cdafbbd..0672b0e0 100644 --- a/plugins/dummy/DummySysPlugin.php +++ b/plugins/dummy/DummySysPlugin.php @@ -109,11 +109,6 @@ public function twigTests(): array ]; } - private function wrapHtmlBlock(string $class, string $content): string - { - return ""; - } - public function onRenderLayout(RenderLayoutEvent $event): void { $this->logger->debug(__METHOD__); @@ -125,6 +120,11 @@ public function onRenderLayout(RenderLayoutEvent $event): void $event->setContent($content); } + private function wrapHtmlBlock(string $class, string $content): string + { + return ""; + } + public function onRenderSegment(RenderSegmentEvent $event): void { $this->logger->debug(__METHOD__); @@ -171,9 +171,11 @@ public function onTwigInitialized(TwigInitializedEvent $event): void public function onTwigInitializedAddFilter(TwigInitializedEvent $event): void { $this->logger->debug(__METHOD__); - $event->getEnvironment()->addFilter(new TwigFilter('dummy_dynamic', function (string $content): string { - return $content . 'Dummy Filter Dynamic'; - })); + $event->getEnvironment()->addFilter( + new TwigFilter('dummy_dynamic', function (string $content): string { + return $content . 'Dummy Filter Dynamic'; + }) + ); } public function appMiddleware(ServerRequestInterface $request, RequestHandlerInterface $next): ResponseInterface diff --git a/plugins/imagine/ImagineSysPlugin.php b/plugins/imagine/ImagineSysPlugin.php index b096ff07..0426c8cf 100755 --- a/plugins/imagine/ImagineSysPlugin.php +++ b/plugins/imagine/ImagineSysPlugin.php @@ -7,13 +7,14 @@ use herbie\Alias; use herbie\Config; use herbie\Plugin; +use Imagine\Filter\Advanced\RelativeResize; +use Imagine\Filter\Basic\Resize; use Imagine\Gd\Imagine; -use Imagine\Image\ImageInterface; use Imagine\Image\Box; use Imagine\Image\Color; +use Imagine\Image\ImageInterface; use Imagine\Image\Point; -use Imagine\Filter\Advanced\RelativeResize; -use Imagine\Filter\Basic\Resize; +use InvalidArgumentException; use Twig\Markup; use function herbie\str_trailing_slash; @@ -92,27 +93,16 @@ private function getTransparentOnePixelSrc(): string { // see http://png-pixel.com return 'data:image/png;' - . 'base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII='; + . 'base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII='; } - /** - * Gets the browser path for the image and filter to apply. - */ - public function imagineFilter(string $path, string $collection = 'default'): Markup + protected function buildHtmlAttributes(array $htmlOptions = []): string { - $absolutePath = $this->alias->get('@media/' . $path); - - if (!is_file($absolutePath)) { - $dataSrc = $this->getTransparentOnePixelSrc(); - return new Markup($dataSrc, 'utf8'); + $attributes = ''; + foreach ($htmlOptions as $key => $value) { + $attributes .= ' ' . $key . '="' . $value . '"'; } - - $sanitizedFilterSet = $this->sanitizeFilterName($collection); - - return new Markup( - $this->basePath . $this->applyFilterSet($path, $sanitizedFilterSet), - 'utf8' - ); + return rtrim($attributes); } private function sanitizeFilterName(string $filterSet): string @@ -125,18 +115,6 @@ private function sanitizeFilterName(string $filterSet): string return $filterSet; } - private function getImageSize(string $cachePath): array - { - if (!is_file($cachePath)) { - return []; - } - $size = getimagesize($cachePath); - if ($size === false) { - return [0, 0]; - } - return [$size[0], $size[1]]; - } - protected function applyFilterSet(string $relpath, string $filterSet): string { $path = $this->alias->get('@media/' . $relpath); @@ -202,6 +180,38 @@ protected function resolveCachePath(string $path, string $filter): string ); } + private function getImageSize(string $cachePath): array + { + if (!is_file($cachePath)) { + return []; + } + $size = getimagesize($cachePath); + if ($size === false) { + return [0, 0]; + } + return [$size[0], $size[1]]; + } + + /** + * Gets the browser path for the image and filter to apply. + */ + public function imagineFilter(string $path, string $collection = 'default'): Markup + { + $absolutePath = $this->alias->get('@media/' . $path); + + if (!is_file($absolutePath)) { + $dataSrc = $this->getTransparentOnePixelSrc(); + return new Markup($dataSrc, 'utf8'); + } + + $sanitizedFilterSet = $this->sanitizeFilterName($collection); + + return new Markup( + $this->basePath . $this->applyFilterSet($path, $sanitizedFilterSet), + 'utf8' + ); + } + protected function applyResizeFilter(ImageInterface $image, array $options): ImageInterface { // Defaults @@ -302,7 +312,7 @@ protected function applyColorizeFilter(ImageInterface $image, array $options): I protected function applyRotateFilter(ImageInterface $image, array $options): ImageInterface { if (isset($options['angle'])) { - $angle = (int) $options['angle']; + $angle = (int)$options['angle']; $image->rotate($angle); } return $image; @@ -326,7 +336,7 @@ protected function applyFlipVerticallyFilter(ImageInterface $image): ImageInterf protected function applyUpscaleFilter(ImageInterface $image, array $options): ImageInterface { if (!isset($options['min'])) { - throw new \InvalidArgumentException('Missing min option.'); + throw new InvalidArgumentException('Missing min option.'); } [$width, $height] = $options['min']; @@ -356,13 +366,4 @@ protected function applyRelativeResizeFilter(ImageInterface $image, array $optio $filter = new RelativeResize($method, $parameter); return $filter->apply($image); } - - protected function buildHtmlAttributes(array $htmlOptions = []): string - { - $attributes = ''; - foreach ($htmlOptions as $key => $value) { - $attributes .= ' ' . $key . '="' . $value . '"'; - } - return rtrim($attributes); - } } diff --git a/plugins/rest/RestSysPlugin.php b/plugins/rest/RestSysPlugin.php index ae79ddc9..c9274a95 100755 --- a/plugins/rest/RestSysPlugin.php +++ b/plugins/rest/RestSysPlugin.php @@ -4,6 +4,7 @@ namespace herbie\sysplugins\rest; +use Doctrine\RST\Parser; use herbie\Config; use herbie\events\RenderSegmentEvent; use herbie\Plugin; @@ -61,7 +62,7 @@ public function parseRest(string $string): string if (!$this->parserClassExists) { return $string; } - $parser = new \Doctrine\RST\Parser(); + $parser = new Parser(); $document = $parser->parse($string); return $document->render(); } diff --git a/plugins/textile/TextileSysPlugin.php b/plugins/textile/TextileSysPlugin.php index 2dc0a199..050544f6 100755 --- a/plugins/textile/TextileSysPlugin.php +++ b/plugins/textile/TextileSysPlugin.php @@ -9,6 +9,7 @@ use herbie\Plugin; use Netcarver\Textile\Parser; use Psr\Log\LoggerInterface; +use Throwable; final class TextileSysPlugin extends Plugin { @@ -67,7 +68,7 @@ public function parseTextile(string $value): string try { $parser = new Parser(); return $parser->parse($value); - } catch (\Throwable $t) { + } catch (Throwable $t) { return $value; } } diff --git a/plugins/twig/TwigExtension.php b/plugins/twig/TwigExtension.php index 9f6f0d9d..f48105d0 100644 --- a/plugins/twig/TwigExtension.php +++ b/plugins/twig/TwigExtension.php @@ -5,6 +5,7 @@ namespace herbie\sysplugins\twig; use Ausi\SlugGenerator\SlugGenerator; +use Exception; use herbie\Alias; use herbie\Assets; use herbie\Config; @@ -32,10 +33,8 @@ use Twig\TwigFunction; use Twig\TwigTest; -use function herbie\date_format; use function herbie\file_size; use function herbie\str_trailing_slash; -use function herbie\time_format; final class TwigExtension extends AbstractExtension { @@ -125,34 +124,6 @@ public function getTests(): array ]; } - /** - * @param array $attribs - */ - private function buildHtmlAttributes(array $attribs = []): string - { - $attribsAsString = ''; - foreach ($attribs as $key => $value) { - $attribsAsString .= $key . '="' . $value . '" '; - } - return trim($attribsAsString); - } - - public function filterFilesize(int $size): string - { - if ($size <= 0) { - return '0'; - } - if ($size === 1) { - return '1 Byte'; - } - $mod = 1024; - $units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB']; - for ($i = 0; $size > $mod && $i < count($units) - 1; ++$i) { - $size /= $mod; - } - return str_replace(',', '.', (string)round($size, 1)) . ' ' . $units[$i]; - } - /** * Creates a web friendly URL (slug) from a string. */ @@ -247,6 +218,46 @@ public function linkMedia( return strtr('{label}{info}', $replace); } + private function getFileInfo(string $path): string + { + if (!is_readable($path)) { + return ''; + } + $replace = [ + '{size}' => $this->filterFilesize(file_size($path)), + '{extension}' => strtoupper(pathinfo($path, PATHINFO_EXTENSION)) + ]; + return strtr(' ({extension}, {size})', $replace); + } + + public function filterFilesize(int $size): string + { + if ($size <= 0) { + return '0'; + } + if ($size === 1) { + return '1 Byte'; + } + $mod = 1024; + $units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB']; + for ($i = 0; $size > $mod && $i < count($units) - 1; ++$i) { + $size /= $mod; + } + return str_replace(',', '.', (string)round($size, 1)) . ' ' . $units[$i]; + } + + /** + * @param array $attribs + */ + private function buildHtmlAttributes(array $attribs = []): string + { + $attribsAsString = ''; + foreach ($attribs as $key => $value) { + $attribsAsString .= $key . '="' . $value . '" '; + } + return trim($attribsAsString); + } + public function linkMail( string $email, ?string $label = null, @@ -334,6 +345,16 @@ public function menuBreadcrumb( return $html; } + /** + * @param array $attribs + */ + protected function createLink(string $route, string $label, array $attribs = []): string + { + $url = $this->urlManager->createUrl($route); + $attribsAsString = $this->buildHtmlAttributes($attribs); + return sprintf('%s', $url, $attribsAsString, $label); + } + /** * @throws LoaderError * @throws RuntimeError @@ -376,36 +397,8 @@ public function menuList( return $this->environment->render($template, ['pagination' => $pagination]); } - public function menuTree( - string $route = '', - int $depth = -1, - bool $hidden = false, - string $class = 'menu' - ): string { - // NOTE duplicated code, see function sitemap - $branch = $this->pageRepository->findAll()->getPageTree()->findByRoute($route); - if ($branch === null) { - return ''; - } - - $treeIterator = new PageTreeIterator($branch); - $filterIterator = new PageTreeFilterIterator($treeIterator, !$hidden); - - $htmlTree = new PageTreeHtmlRenderer($filterIterator); - $htmlTree->setMaxDepth($depth); - $htmlTree->setClass($class); - $htmlTree->setItemCallback(function (PageTree $node) { - $menuItem = $node->getMenuItem(); - $href = $this->urlManager->createUrl($menuItem->getRoute()); - return sprintf('%s', $href, $menuItem->getMenuTitle()); - }); - - [$currenRoute] = $this->urlManager->parseRequest(); - return $htmlTree->render($currenRoute); - } - /** - * @throws \Exception + * @throws Exception */ public function menuPager( string $limit = '', @@ -480,6 +473,34 @@ public function menuSitemap( return $this->menuTree($route, $depth, $hidden, $class); } + public function menuTree( + string $route = '', + int $depth = -1, + bool $hidden = false, + string $class = 'menu' + ): string { + // NOTE duplicated code, see function sitemap + $branch = $this->pageRepository->findAll()->getPageTree()->findByRoute($route); + if ($branch === null) { + return ''; + } + + $treeIterator = new PageTreeIterator($branch); + $filterIterator = new PageTreeFilterIterator($treeIterator, !$hidden); + + $htmlTree = new PageTreeHtmlRenderer($filterIterator); + $htmlTree->setMaxDepth($depth); + $htmlTree->setClass($class); + $htmlTree->setItemCallback(function (PageTree $node) { + $menuItem = $node->getMenuItem(); + $href = $this->urlManager->createUrl($menuItem->getRoute()); + return sprintf('%s', $href, $menuItem->getMenuTitle()); + }); + + [$currenRoute] = $this->urlManager->parseRequest(); + return $htmlTree->render($currenRoute); + } + public function cssOut(?string $group = null, bool $timestamp = false): string { return $this->assets->outputCss($group, $timestamp); @@ -623,18 +644,6 @@ public function linkFile(string $path, string $label = '', bool $info = false, a return strtr('{label}{info}', $replace); } - private function getFileInfo(string $path): string - { - if (!is_readable($path)) { - return ''; - } - $replace = [ - '{size}' => $this->filterFilesize(file_size($path)), - '{extension}' => strtoupper(pathinfo($path, PATHINFO_EXTENSION)) - ]; - return strtr(' ({extension}, {size})', $replace); - } - public function testIsReadable(string $alias): bool { if ($alias === '') { @@ -652,14 +661,4 @@ public function testIsWritable(string $alias): bool $filename = $this->alias->get($alias); return is_writable($filename); } - - /** - * @param array $attribs - */ - protected function createLink(string $route, string $label, array $attribs = []): string - { - $url = $this->urlManager->createUrl($route); - $attribsAsString = $this->buildHtmlAttributes($attribs); - return sprintf('%s', $url, $attribsAsString, $label); - } } diff --git a/plugins/twig/TwigPlugin.php b/plugins/twig/TwigPlugin.php index 944784c5..586a6549 100644 --- a/plugins/twig/TwigPlugin.php +++ b/plugins/twig/TwigPlugin.php @@ -51,15 +51,17 @@ public function eventListeners(): array public function onTwigInitialized(TwigInitializedEvent $event): void { - $event->getEnvironment()->addExtension(new TwigExtension( - $this->alias, - $this->assets, - $this->config, - $event->getEnvironment(), - $this->pageRepository, - $this->slugGenerator, - $this->translator, - $this->urlManager - )); + $event->getEnvironment()->addExtension( + new TwigExtension( + $this->alias, + $this->assets, + $this->config, + $event->getEnvironment(), + $this->pageRepository, + $this->slugGenerator, + $this->translator, + $this->urlManager + ) + ); } } diff --git a/system/AbstractNode.php b/system/AbstractNode.php index 73e60e3a..0b561309 100644 --- a/system/AbstractNode.php +++ b/system/AbstractNode.php @@ -4,6 +4,7 @@ namespace herbie; +use ArrayIterator; use IteratorAggregate; abstract class AbstractNode implements IteratorAggregate @@ -30,25 +31,25 @@ public function __construct($value = null) $this->children = []; } - public function getIterator(): \ArrayIterator + public function getIterator(): ArrayIterator { - return new \ArrayIterator($this->children); + return new ArrayIterator($this->children); } /** - * @param mixed $value + * @return mixed */ - public function setValue($value): void + public function getValue() { - $this->value = $value; + return $this->value; } /** - * @return mixed + * @param mixed $value */ - public function getValue() + public function setValue($value): void { - return $this->value; + $this->value = $value; } public function isRoot(): bool @@ -56,14 +57,14 @@ public function isRoot(): bool return null === $this->parent; } - public function setParent(AbstractNode $parent): void + public function getParent(): ?AbstractNode { - $this->parent = $parent; + return $this->parent; } - public function getParent(): ?AbstractNode + public function setParent(AbstractNode $parent): void { - return $this->parent; + $this->parent = $parent; } public function hasParent(): bool diff --git a/system/Alias.php b/system/Alias.php index 5a9e2b6d..eb46a7ce 100644 --- a/system/Alias.php +++ b/system/Alias.php @@ -4,6 +4,8 @@ namespace herbie; +use InvalidArgumentException; + final class Alias { private array $aliases; @@ -22,11 +24,26 @@ public function __construct(array $aliases = []) public function set(string $alias, string $path): void { if (array_key_exists($alias, $this->aliases)) { - throw new \InvalidArgumentException("Alias {$alias} already set, use update instead."); + throw new InvalidArgumentException("Alias {$alias} already set, use update instead."); } $this->setInternal($alias, $path); } + private function setInternal(string $alias, string $path): void + { + $alias = trim($alias); + if (strncmp($alias, '@', 1) <> 0) { + throw new InvalidArgumentException("Invalid alias {$alias}, @ char missing."); + } + if (substr($alias, 1) === '') { + throw new InvalidArgumentException("Alias {$alias} is empty."); + } + if (strpos($alias, '@', 1) !== false) { + throw new InvalidArgumentException("Invalid alias {$alias}, @ char only allowed once."); + } + $this->aliases[$alias] = str_untrailing_slash($path); + } + public function getAll(): array { return $this->aliases; @@ -40,23 +57,8 @@ public function get(string $alias): string public function update(string $alias, string $path): void { if (!array_key_exists($alias, $this->aliases)) { - throw new \InvalidArgumentException("Alias {$alias} not exists, use set instead."); + throw new InvalidArgumentException("Alias {$alias} not exists, use set instead."); } $this->setInternal($alias, $path); } - - private function setInternal(string $alias, string $path): void - { - $alias = trim($alias); - if (strncmp($alias, '@', 1) <> 0) { - throw new \InvalidArgumentException("Invalid alias {$alias}, @ char missing."); - } - if (substr($alias, 1) === '') { - throw new \InvalidArgumentException("Alias {$alias} is empty."); - } - if (strpos($alias, '@', 1) !== false) { - throw new \InvalidArgumentException("Invalid alias {$alias}, @ char only allowed once."); - } - $this->aliases[$alias] = str_untrailing_slash($path); - } } diff --git a/system/Application.php b/system/Application.php index dd81b64f..1fe55aa1 100644 --- a/system/Application.php +++ b/system/Application.php @@ -5,11 +5,9 @@ namespace herbie; use Ausi\SlugGenerator\SlugGenerator; -use herbie\events\PluginsInitializedEvent; use herbie\events\ResponseEmittedEvent; use herbie\events\ResponseGeneratedEvent; use herbie\events\TranslatorInitializedEvent; -use herbie\events\TwigInitializedEvent; use Psr\Container\ContainerInterface; use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; @@ -18,6 +16,7 @@ use Psr\SimpleCache\CacheInterface; use RuntimeException; use Symfony\Component\Console\Command\Command; +use Twig\Error\LoaderError; final class Application { @@ -98,9 +97,65 @@ private function init(?CacheInterface $cache = null, ?LoggerInterface $logger = Page::setSlugGenerator($this->container->get(SlugGenerator::class)); } + public static function isDebug(): bool + { + static $debug; + if ($debug === null) { + $debug = (bool)getenv('HERBIE_DEBUG'); + } + return $debug; + } + + public function getLogger(): LoggerInterface + { + return $this->container->get(LoggerInterface::class); + } + + public function getConfig(): Config + { + return $this->container->get(Config::class); + } + + public static function getHerbiePath(string $append): string + { + static $herbiePath; + if ($herbiePath === null) { + $herbiePath = dirname(__DIR__); + } + return $herbiePath . $append; + } + + public function runCli(): void + { + $this->getPluginManager()->init(); + + $application = new \Symfony\Component\Console\Application(); + $application->setName("-------------------\nHERBIE CLI-Tool\n-------------------"); + + /** @var class-string $command */ + foreach ($this->getPluginManager()->getConsoleCommands() as $command) { + $params = get_constructor_params_to_inject($command, $this->container); + /** @var Command $commandInstance */ + $commandInstance = new $command(...$params); + $application->add($commandInstance); + } + + $application->run(); + } + + public function getPluginManager(): PluginManager + { + return $this->container->get(PluginManager::class); + } + + public function getConsoleCommands(): array + { + return $this->consoleCommands; + } + /** * @throws SystemException - * @throws \Twig\Error\LoaderError + * @throws LoaderError */ public function run(): void { @@ -127,22 +182,29 @@ public function run(): void $this->getEventManager()->dispatch(new ResponseEmittedEvent($this)); } - public function runCli(): void + public function getEventManager(): EventManager { - $this->getPluginManager()->init(); + return $this->container->get(EventManager::class); + } - $application = new \Symfony\Component\Console\Application(); - $application->setName("-------------------\nHERBIE CLI-Tool\n-------------------"); + public function getTwigRenderer(): TwigRenderer + { + return $this->container->get(TwigRenderer::class); + } - /** @var class-string $command */ - foreach ($this->getPluginManager()->getConsoleCommands() as $command) { - $params = get_constructor_params_to_inject($command, $this->container); - /** @var Command $commandInstance */ - $commandInstance = new $command(...$params); - $application->add($commandInstance); - } + public function getTranslator(): Translator + { + return $this->container->get(Translator::class); + } - $application->run(); + public function getMiddlewareDispatcher(): MiddlewareDispatcher + { + return $this->container->get(MiddlewareDispatcher::class); + } + + public function getServerRequest(): ServerRequestInterface + { + return $this->container->get(ServerRequestInterface::class); } private function emitResponse(ResponseInterface $response): void @@ -158,35 +220,18 @@ private function emitResponse(ResponseInterface $response): void echo $response->getBody(); } - public static function isDebug(): bool + public function getBaseUrl(): string { - static $debug; - if ($debug === null) { - $debug = (bool)getenv('HERBIE_DEBUG'); + if ($this->baseUrl === null) { + $this->baseUrl = rtrim(dirname($this->getScriptUrl()), '\\/'); } - return $debug; - } - public static function getHerbiePath(string $append): string - { - static $herbiePath; - if ($herbiePath === null) { - $herbiePath = dirname(__DIR__); - } - return $herbiePath . $append; + return $this->baseUrl; } - public function getScriptFile(): string + public function setBaseUrl(string $baseUrl): void { - if (isset($this->scriptFile)) { - return $this->scriptFile; - } - - if (isset($_SERVER['SCRIPT_FILENAME'])) { - return $_SERVER['SCRIPT_FILENAME']; - } - - throw new RuntimeException('Unable to determine the entry script file path.'); + $this->baseUrl = $baseUrl; } public function getScriptUrl(): string @@ -213,18 +258,22 @@ public function getScriptUrl(): string return $this->scriptUrl; } - public function getBaseUrl(): string + public function setScriptUrl(string $scriptUrl): void { - if ($this->baseUrl === null) { - $this->baseUrl = rtrim(dirname($this->getScriptUrl()), '\\/'); - } - - return $this->baseUrl; + $this->scriptUrl = $scriptUrl; } - public function setBaseUrl(string $baseUrl): void + public function getScriptFile(): string { - $this->baseUrl = $baseUrl; + if (isset($this->scriptFile)) { + return $this->scriptFile; + } + + if (isset($_SERVER['SCRIPT_FILENAME'])) { + return $_SERVER['SCRIPT_FILENAME']; + } + + throw new RuntimeException('Unable to determine the entry script file path.'); } public function setScriptFile(string $scriptFile): void @@ -232,11 +281,6 @@ public function setScriptFile(string $scriptFile): void $this->scriptFile = $scriptFile; } - public function setScriptUrl(string $scriptUrl): void - { - $this->scriptUrl = $scriptUrl; - } - public function getApplicationPath(): string { return $this->applicationPaths->getApp(); @@ -273,11 +317,6 @@ public function addConsoleCommand(string $command): Application return $this; } - public function getConsoleCommands(): array - { - return $this->consoleCommands; - } - /** * @param MiddlewareInterface|string $middleware */ @@ -363,48 +402,8 @@ public function getEventListeners(): array return $this->eventListeners; } - public function getConfig(): Config - { - return $this->container->get(Config::class); - } - public function getCache(): CacheInterface { return $this->container->get(CacheInterface::class); } - - public function getLogger(): LoggerInterface - { - return $this->container->get(LoggerInterface::class); - } - - public function getPluginManager(): PluginManager - { - return $this->container->get(PluginManager::class); - } - - public function getTranslator(): Translator - { - return $this->container->get(Translator::class); - } - - public function getTwigRenderer(): TwigRenderer - { - return $this->container->get(TwigRenderer::class); - } - - public function getMiddlewareDispatcher(): MiddlewareDispatcher - { - return $this->container->get(MiddlewareDispatcher::class); - } - - public function getServerRequest(): ServerRequestInterface - { - return $this->container->get(ServerRequestInterface::class); - } - - public function getEventManager(): EventManager - { - return $this->container->get(EventManager::class); - } } diff --git a/system/Assets.php b/system/Assets.php index e671c977..43d73c5d 100644 --- a/system/Assets.php +++ b/system/Assets.php @@ -12,7 +12,9 @@ final class Assets { private const TYPE_CSS = 0; private const TYPE_JS = 1; - + private static int $counter = 0; + private static bool $sorted = false; + private static array $published = []; private Alias $alias; private array $assets = []; private string $assetsDir = '/assets'; @@ -20,9 +22,6 @@ final class Assets private string $assetsPath; private int $refresh = 86400; private int $permissions = 0755; - private static int $counter = 0; - private static bool $sorted = false; - private static array $published = []; public function __construct(Alias $alias, string $baseUrl) { @@ -42,6 +41,42 @@ public function addCss($paths, array $attr = [], ?string $group = null, bool $ra } } + private function addAsset( + int $type, + string $path, + array $attr, + ?string $group = null, + bool $raw = false, + int $pos = 1 + ): void { + if ($this->search($path)) { + return; + } + $this->assets[] = [ + 'type' => $type, + 'path' => $path, + 'group' => $group, + 'attr' => $attr, + 'raw' => $raw, + 'pos' => $pos, + 'counter' => ++self::$counter, + 'timestamp' => 0, + ]; + } + + /** + * @return bool|int + */ + private function search(string $path) + { + foreach ($this->assets as $index => $asset) { + if ($asset['path'] === $path) { + return $index; + } + } + return false; + } + /** * @param array|string $paths */ @@ -77,53 +112,6 @@ public function outputCss(?string $group = null, bool $addTimestamp = false): st return $return; } - public function outputJs(?string $group = null, bool $addTimestamp = false): string - { - $this->sort(); - $this->publish(); - $return = ''; - foreach ($this->collect(self::TYPE_JS, $group) as $asset) { - if (empty($asset['raw'])) { - $timestamp = $addTimestamp ? '?t=' . $asset['timestamp'] : ''; - $return .= sprintf( - '', - $this->buildUrl($asset['path']) . $timestamp, - $this->buildAttribs($asset['attr']) - ); - } else { - $return .= sprintf( - '%s', - $this->buildAttribs($asset['attr']), - $asset['path'] - ); - } - } - return $return; - } - - private function addAsset( - int $type, - string $path, - array $attr, - ?string $group = null, - bool $raw = false, - int $pos = 1 - ): void { - if ($this->search($path)) { - return; - } - $this->assets[] = [ - 'type' => $type, - 'path' => $path, - 'group' => $group, - 'attr' => $attr, - 'raw' => $raw, - 'pos' => $pos, - 'counter' => ++self::$counter, - 'timestamp' => 0, - ]; - } - private function sort(): void { if (!self::$sorted) { @@ -142,30 +130,6 @@ private function sort(): void } } - private function collect(int $type, ?string $group = null): array - { - $assets = []; - foreach ($this->assets as $asset) { - if (($asset['type'] === $type) && ($asset['group'] === $group)) { - $assets[] = $asset; - } - } - return $assets; - } - - /** - * @return bool|int - */ - private function search(string $path) - { - foreach ($this->assets as $index => $asset) { - if ($asset['path'] === $path) { - return $index; - } - } - return false; - } - private function publish(): void { foreach ($this->assets as $index => $asset) { @@ -200,6 +164,24 @@ private function publish(): void } } + private function removeAlias(string $file): string + { + $parts = explode('/', $file); + array_shift($parts); + return implode('/', $parts); + } + + private function collect(int $type, ?string $group = null): array + { + $assets = []; + foreach ($this->assets as $asset) { + if (($asset['type'] === $type) && ($asset['group'] === $group)) { + $assets[] = $asset; + } + } + return $assets; + } + private function buildUrl(string $file): string { $url = $file; @@ -210,13 +192,6 @@ private function buildUrl(string $file): string return $url; } - private function removeAlias(string $file): string - { - $parts = explode('/', $file); - array_shift($parts); - return implode('/', $parts); - } - private function buildAttribs(array $attribs = []): string { $html = ''; @@ -225,4 +200,28 @@ private function buildAttribs(array $attribs = []): string } return trim($html); } + + public function outputJs(?string $group = null, bool $addTimestamp = false): string + { + $this->sort(); + $this->publish(); + $return = ''; + foreach ($this->collect(self::TYPE_JS, $group) as $asset) { + if (empty($asset['raw'])) { + $timestamp = $addTimestamp ? '?t=' . $asset['timestamp'] : ''; + $return .= sprintf( + '', + $this->buildUrl($asset['path']) . $timestamp, + $this->buildAttribs($asset['attr']) + ); + } else { + $return .= sprintf( + '%s', + $this->buildAttribs($asset['attr']), + $asset['path'] + ); + } + } + return $return; + } } diff --git a/system/ClearFilesCommand.php b/system/ClearFilesCommand.php index 16760c56..6357c565 100644 --- a/system/ClearFilesCommand.php +++ b/system/ClearFilesCommand.php @@ -4,6 +4,7 @@ namespace herbie; +use RecursiveIteratorIterator; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; @@ -11,9 +12,9 @@ final class ClearFilesCommand extends Command { - private Config $config; protected static $defaultName = 'clear-files'; protected static $defaultDescription = 'Clears asset, cache and log files'; + private Config $config; public function __construct(Config $config) { @@ -25,8 +26,7 @@ protected function configure(): void { $this ->setHelp('The clear-files deletes asset, cache and log files from several directories.') - ->addArgument('type', InputArgument::OPTIONAL, 'Type of files to delete', 'all') - ; + ->addArgument('type', InputArgument::OPTIONAL, 'Type of files to delete', 'all'); } protected function execute(InputInterface $input, OutputInterface $output): int @@ -78,7 +78,7 @@ private function getPathsToClear(string $type): array private function clearPath(string $path, array $filesToIgnore): void { $it = new \RecursiveDirectoryIterator($path, \RecursiveDirectoryIterator::SKIP_DOTS); - $files = new \RecursiveIteratorIterator($it, \RecursiveIteratorIterator::CHILD_FIRST); + $files = new RecursiveIteratorIterator($it, RecursiveIteratorIterator::CHILD_FIRST); foreach ($files as $file) { if ($file->isDir()) { rmdir($file->getRealPath()); diff --git a/system/Config.php b/system/Config.php index 596d7f0a..8f762f4b 100644 --- a/system/Config.php +++ b/system/Config.php @@ -6,25 +6,37 @@ use RecursiveArrayIterator; use RecursiveIteratorIterator; +use UnexpectedValueException; final class Config { - private array $data; - private const DELIM = '.'; + private array $data; public function __construct(array $data) { $this->data = $data; } + /** + * @return array + */ + public function getAsArray(string $path, array $default = []): array + { + $arrayValue = $this->get($path, $default); + if (!is_array($arrayValue)) { + throw new UnexpectedValueException("Value for \"$path\" is not an array"); + } + return $arrayValue; + } + /** * Get value by using dot notation for nested arrays. * - * @example $value = $config->get('example.node.value'); - * * @param callable|mixed $default * @return mixed + * @example $value = $config->get('example.node.value'); + * */ public function get(string $name, $default = null) { @@ -48,23 +60,11 @@ public function get(string $name, $default = null) return $current; } - /** - * @return array - */ - public function getAsArray(string $path, array $default = []): array - { - $arrayValue = $this->get($path, $default); - if (!is_array($arrayValue)) { - throw new \UnexpectedValueException("Value for \"$path\" is not an array"); - } - return $arrayValue; - } - public function getAsBool(string $path, bool $default = false): bool { $boolValue = $this->get($path, $default); if (!is_bool($boolValue)) { - throw new \UnexpectedValueException("Value for \"$path\" is not a bool"); + throw new UnexpectedValueException("Value for \"$path\" is not a bool"); } return $boolValue; } @@ -73,7 +73,7 @@ public function getAsFloat(string $path, float $default = 0.0): float { $floatValue = $this->get($path, $default); if (!is_float($floatValue)) { - throw new \UnexpectedValueException("Value for \"$path\" is not a float"); + throw new UnexpectedValueException("Value for \"$path\" is not a float"); } return $floatValue; } @@ -82,7 +82,7 @@ public function getAsInt(string $path, int $default = 0): int { $intValue = $this->get($path, $default); if (!is_int($intValue)) { - throw new \UnexpectedValueException("Value for \"$path\" is not an int"); + throw new UnexpectedValueException("Value for \"$path\" is not an int"); } return $intValue; } @@ -91,7 +91,7 @@ public function getAsString(string $path, string $default = ''): string { $strValue = $this->get($path, $default); if (!is_string($strValue)) { - throw new \UnexpectedValueException("Value for \"$path\" is not a string"); + throw new UnexpectedValueException("Value for \"$path\" is not a string"); } return $strValue; } @@ -100,10 +100,10 @@ public function getAsConfig(string $path): Config { $data = $this->get($path); if ($data === null) { - throw new \UnexpectedValueException("Config for \"$path\" not found"); + throw new UnexpectedValueException("Config for \"$path\" not found"); } if (!is_array($data)) { - throw new \UnexpectedValueException("Config for \"$path\" is not an array"); + throw new UnexpectedValueException("Config for \"$path\" is not an array"); } return new self($data); } diff --git a/system/Container.php b/system/Container.php index c351cb64..eab61ba7 100644 --- a/system/Container.php +++ b/system/Container.php @@ -21,25 +21,6 @@ public function get(string $id) return $this->offsetGet($id); } - public function has(string $id): bool - { - return $this->offsetExists($id); - } - - /** - * @param mixed $service - */ - public function set(string $id, $service): void - { - $this->offsetUnset($id); - $this->offsetSet($id, $service); - } - - private function offsetExists(string $offset): bool - { - return isset($this->frozen[$offset]) || isset($this->values[$offset]); - } - /** * @return mixed */ @@ -64,12 +45,23 @@ private function offsetGet(string $offset) return $this->frozen[$offset]; } + private function offsetExists(string $offset): bool + { + return isset($this->frozen[$offset]) || isset($this->values[$offset]); + } + + public function has(string $id): bool + { + return $this->offsetExists($id); + } + /** - * @param mixed $value + * @param mixed $service */ - private function offsetSet(string $offset, $value): void + public function set(string $id, $service): void { - $this->values[$offset] = $value; + $this->offsetUnset($id); + $this->offsetSet($id, $service); } private function offsetUnset(string $offset): void @@ -77,4 +69,12 @@ private function offsetUnset(string $offset): void unset($this->frozen[$offset]); unset($this->values[$offset]); } + + /** + * @param mixed $value + */ + private function offsetSet(string $offset, $value): void + { + $this->values[$offset] = $value; + } } diff --git a/system/CorePlugin.php b/system/CorePlugin.php index 797705bb..9ce2a73a 100644 --- a/system/CorePlugin.php +++ b/system/CorePlugin.php @@ -7,6 +7,9 @@ use herbie\events\RenderLayoutEvent; use herbie\events\RenderPageEvent; use herbie\events\RenderSegmentEvent; +use Twig\Error\LoaderError; +use Twig\Error\RuntimeError; +use Twig\Error\SyntaxError; final class CorePlugin extends Plugin { @@ -63,9 +66,9 @@ public function onRenderPage(RenderPageEvent $event): void } /** - * @throws \Twig\Error\SyntaxError - * @throws \Twig\Error\RuntimeError - * @throws \Twig\Error\LoaderError + * @throws SyntaxError + * @throws RuntimeError + * @throws LoaderError */ public function onRenderSegment(RenderSegmentEvent $event): void { @@ -78,9 +81,9 @@ public function onRenderSegment(RenderSegmentEvent $event): void } /** - * @throws \Twig\Error\SyntaxError - * @throws \Twig\Error\RuntimeError - * @throws \Twig\Error\LoaderError + * @throws SyntaxError + * @throws RuntimeError + * @throws LoaderError */ public function onRenderLayout(RenderLayoutEvent $event): void { diff --git a/system/DataRepositoryInterface.php b/system/DataRepositoryInterface.php index 82bcef7c..2275982c 100644 --- a/system/DataRepositoryInterface.php +++ b/system/DataRepositoryInterface.php @@ -7,6 +7,8 @@ interface DataRepositoryInterface { public function __construct(string $path); + public function load(string $name): array; + public function loadAll(): array; } diff --git a/system/ErrorHandlerMiddleware.php b/system/ErrorHandlerMiddleware.php index 319cb76b..7ea1c373 100644 --- a/system/ErrorHandlerMiddleware.php +++ b/system/ErrorHandlerMiddleware.php @@ -4,6 +4,7 @@ namespace herbie; +use ErrorException; use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Server\MiddlewareInterface; @@ -70,12 +71,12 @@ public function process(ServerRequestInterface $request, RequestHandlerInterface private function createErrorHandler(): callable { return function (int $errno, string $errstr, string $errfile, int $errline): void { - if (! (error_reporting() & $errno)) { + if (!(error_reporting() & $errno)) { // error_reporting does not include this error return; } - throw new \ErrorException($errstr, 0, $errno, $errfile, $errline); + throw new ErrorException($errstr, 0, $errno, $errfile, $errline); }; } } diff --git a/system/FatalErrorHandler.php b/system/FatalErrorHandler.php index 14fb2350..1a2db652 100644 --- a/system/FatalErrorHandler.php +++ b/system/FatalErrorHandler.php @@ -4,6 +4,8 @@ namespace herbie; +use ErrorException; + final class FatalErrorHandler { public function __invoke(): void @@ -13,7 +15,7 @@ public function __invoke(): void if (!headers_sent()) { header("HTTP/1.1 500"); } - $exception = new \ErrorException( + $exception = new ErrorException( $error['message'], 500, $error['type'], diff --git a/system/FileCache.php b/system/FileCache.php index 30015b1d..1da5333e 100644 --- a/system/FileCache.php +++ b/system/FileCache.php @@ -4,6 +4,7 @@ namespace herbie; +use InvalidArgumentException; use Psr\SimpleCache\CacheInterface; final class FileCache implements CacheInterface @@ -15,20 +16,58 @@ public function __construct(string $path) $path = rtrim($path, DIRECTORY_SEPARATOR); if (empty($path)) { - throw new \InvalidArgumentException('Path was not provided'); + throw new InvalidArgumentException('Path was not provided'); } if (!is_dir($path) && !@mkdir($path, 0644, true) && !is_dir($path)) { - throw new \InvalidArgumentException('Provided path directory does not exist and/or could not be created'); + throw new InvalidArgumentException('Provided path directory does not exist and/or could not be created'); } if (!is_writable($path)) { - throw new \InvalidArgumentException('Provided path is not a writable directory'); + throw new InvalidArgumentException('Provided path is not a writable directory'); } $this->path = $path; // here we have a valid and existing path } + public function clear(): bool + { + $filenames = glob($this->path . '/*.cache'); + if ($filenames === false) { + return false; + } + foreach ($filenames as $filename) { + if (file_exists($filename)) { + unlink($filename); + } + } + + return true; + } + + public function has($key) + { + if (empty($key)) { + return false; + } + + return file_exists($this->getFilename($key)); + } + + protected function getFilename(string $key): string + { + return $this->path . DIRECTORY_SEPARATOR . md5($key) . '.cache'; + } + + public function getMultiple($keys, $default = null) + { + $multiple = []; + foreach ($keys as $key) { + $multiple[$key] = $this->get($key, $default); + } + return $multiple; + } + public function get($key, $default = null) { if (empty($key)) { @@ -56,22 +95,6 @@ public function get($key, $default = null) return $this->unserialize($file['value']) ?? $default; } - public function set($key, $value, $ttl = null) - { - if (empty($key)) { - return false; - } - - $file = [ - 'key' => $key, - 'value' => $this->serialize($value), - 'ttl' => $ttl, - 'ctime' => time(), - ]; - - return (bool)file_put_contents($this->getFilename($key), json_encode($file)); - } - public function delete($key) { $filename = $this->getFilename($key); @@ -83,37 +106,12 @@ public function delete($key) return false; } - public function clear(): bool - { - $filenames = glob($this->path . '/*.cache'); - if ($filenames === false) { - return false; - } - foreach ($filenames as $filename) { - if (file_exists($filename)) { - unlink($filename); - } - } - - return true; - } - - public function has($key) - { - if (empty($key)) { - return false; - } - - return file_exists($this->getFilename($key)); - } - - public function getMultiple($keys, $default = null) + /** + * @return mixed + */ + protected function unserialize(string $data, array $options = []) { - $multiple = []; - foreach ($keys as $key) { - $multiple[$key] = $this->get($key, $default); - } - return $multiple; + return unserialize($data, $options); } public function setMultiple($values, $ttl = null) @@ -125,18 +123,20 @@ public function setMultiple($values, $ttl = null) return true; } - public function deleteMultiple($keys) + public function set($key, $value, $ttl = null) { - foreach ((array)$keys as $key) { - $this->delete($key); + if (empty($key)) { + return false; } - return true; - } + $file = [ + 'key' => $key, + 'value' => $this->serialize($value), + 'ttl' => $ttl, + 'ctime' => time(), + ]; - protected function getFilename(string $key): string - { - return $this->path . DIRECTORY_SEPARATOR . md5($key) . '.cache'; + return (bool)file_put_contents($this->getFilename($key), json_encode($file)); } /** @@ -147,11 +147,12 @@ protected function serialize($data): string return serialize($data); } - /** - * @return mixed - */ - protected function unserialize(string $data, array $options = []) + public function deleteMultiple($keys) { - return unserialize($data, $options); + foreach ((array)$keys as $key) { + $this->delete($key); + } + + return true; } } diff --git a/system/FileInfoSortableIterator.php b/system/FileInfoSortableIterator.php index 28fa3495..ada659a9 100644 --- a/system/FileInfoSortableIterator.php +++ b/system/FileInfoSortableIterator.php @@ -4,7 +4,10 @@ namespace herbie; +use ArrayIterator; +use InvalidArgumentException; use IteratorAggregate; +use Traversable; final class FileInfoSortableIterator implements IteratorAggregate { @@ -14,7 +17,7 @@ final class FileInfoSortableIterator implements IteratorAggregate public const SORT_BY_CHANGED_TIME = 4; public const SORT_BY_MODIFIED_TIME = 5; - private \Traversable $iterator; + private Traversable $iterator; /** * @var callable @@ -24,7 +27,7 @@ final class FileInfoSortableIterator implements IteratorAggregate /** * @param int|callable $sort */ - public function __construct(\Traversable $iterator, $sort) + public function __construct(Traversable $iterator, $sort) { $this->iterator = $iterator; @@ -57,15 +60,15 @@ public function __construct(\Traversable $iterator, $sort) $this->sort = $sort; } else { $message = 'The SortableIterator takes a PHP callable or a valid built-in sort algorithm as an argument.'; - throw new \InvalidArgumentException($message); + throw new InvalidArgumentException($message); } } - public function getIterator(): \ArrayIterator + public function getIterator(): ArrayIterator { $array = iterator_to_array($this->iterator, true); uasort($array, $this->sort); - return new \ArrayIterator($array); + return new ArrayIterator($array); } } diff --git a/system/FileLogger.php b/system/FileLogger.php index 2662b8b4..17077c7e 100644 --- a/system/FileLogger.php +++ b/system/FileLogger.php @@ -4,8 +4,15 @@ namespace herbie; +use DateTimeImmutable; +use DomainException; use Psr\Log\LoggerInterface; use Psr\Log\LogLevel; +use RuntimeException; +use Throwable; + +use const JSON_UNESCAPED_SLASHES; +use const PHP_EOL; final class FileLogger implements LoggerInterface { @@ -36,7 +43,7 @@ public function setLevel(string $level): void if (!array_key_exists($level, self::LEVELS)) { $message = "Log level $level is not a valid log level."; $message .= " Must be one of (" . implode(', ', array_keys(self::LEVELS)) . ')'; - throw new \DomainException($message); + throw new DomainException($message); } $this->level = self::LEVELS[$level]; @@ -49,53 +56,9 @@ public function debug($message, array $context = []) } } - public function info($message, array $context = []) - { - if ($this->logAtThisLevel(LogLevel::INFO)) { - $this->log(LogLevel::INFO, $message, $context); - } - } - - public function notice($message, array $context = []) - { - if ($this->logAtThisLevel(LogLevel::NOTICE)) { - $this->log(LogLevel::NOTICE, $message, $context); - } - } - - public function warning($message, array $context = []) - { - if ($this->logAtThisLevel(LogLevel::WARNING)) { - $this->log(LogLevel::WARNING, $message, $context); - } - } - - public function error($message, array $context = []) - { - if ($this->logAtThisLevel(LogLevel::ERROR)) { - $this->log(LogLevel::ERROR, $message, $context); - } - } - - public function critical($message, array $context = []) - { - if ($this->logAtThisLevel(LogLevel::CRITICAL)) { - $this->log(LogLevel::CRITICAL, $message, $context); - } - } - - public function alert($message, array $context = []) - { - if ($this->logAtThisLevel(LogLevel::ALERT)) { - $this->log(LogLevel::ALERT, $message, $context); - } - } - - public function emergency($message, array $context = []) + private function logAtThisLevel(string $level): bool { - if ($this->logAtThisLevel(LogLevel::EMERGENCY)) { - $this->log(LogLevel::EMERGENCY, $message, $context); - } + return self::LEVELS[$level] >= $this->level; } public function log($level, $message, array $context = []) @@ -103,7 +66,7 @@ public function log($level, $message, array $context = []) // Build log line $pid = (int)getmypid(); [$exception, $data] = $this->handleException($context); - $data = $data ? json_encode($data, \JSON_UNESCAPED_SLASHES) : '{}'; + $data = $data ? json_encode($data, JSON_UNESCAPED_SLASHES) : '{}'; $data = $data ?: '{}'; // Fail-safe in case json_encode fails. $line = $this->formatLine($level, $pid, $message, $data, $exception); @@ -111,24 +74,19 @@ public function log($level, $message, array $context = []) try { $fh = fopen($this->file, 'a'); if (!$fh) { - throw new \RuntimeException('File open failed.'); + throw new RuntimeException('File open failed.'); } fwrite($fh, $line); fclose($fh); - } catch (\Throwable $e) { + } catch (Throwable $e) { $message = "Could not open log file {$this->file} for writing to channel {$this->channel}!"; - throw new \RuntimeException($message, 0, $e); + throw new RuntimeException($message, 0, $e); } } - private function logAtThisLevel(string $level): bool - { - return self::LEVELS[$level] >= $this->level; - } - private function handleException(array $data = []): array { - if (isset($data['exception']) && $data['exception'] instanceof \Throwable) { + if (isset($data['exception']) && $data['exception'] instanceof Throwable) { $exception = $data['exception']; $exceptionData = $this->buildExceptionData($exception); unset($data['exception']); @@ -139,7 +97,7 @@ private function handleException(array $data = []): array return [$exceptionData, $data]; } - private function buildExceptionData(\Throwable $e): string + private function buildExceptionData(Throwable $e): string { $exceptionData = json_encode( [ @@ -149,7 +107,7 @@ private function buildExceptionData(\Throwable $e): string 'line' => $e->getLine(), 'trace' => $e->getTrace() ], - \JSON_UNESCAPED_SLASHES + JSON_UNESCAPED_SLASHES ); // Fail-safe in case json_encode failed @@ -163,13 +121,62 @@ private function formatLine(string $level, int $pid, string $message, string $da "[$level]" . self::TAB . "[{$this->channel}]" . self::TAB . "[pid:$pid]" . self::TAB . - str_replace(\PHP_EOL, ' ', trim($message)) . self::TAB . - str_replace(\PHP_EOL, ' ', $data) . self::TAB . - str_replace(\PHP_EOL, ' ', $exception_data) . \PHP_EOL; + str_replace(PHP_EOL, ' ', trim($message)) . self::TAB . + str_replace(PHP_EOL, ' ', $data) . self::TAB . + str_replace(PHP_EOL, ' ', $exception_data) . PHP_EOL; } private function getTime(): string { - return (new \DateTimeImmutable('now'))->format('Y-m-d H:i:s.u'); + return (new DateTimeImmutable('now'))->format('Y-m-d H:i:s.u'); + } + + public function info($message, array $context = []) + { + if ($this->logAtThisLevel(LogLevel::INFO)) { + $this->log(LogLevel::INFO, $message, $context); + } + } + + public function notice($message, array $context = []) + { + if ($this->logAtThisLevel(LogLevel::NOTICE)) { + $this->log(LogLevel::NOTICE, $message, $context); + } + } + + public function warning($message, array $context = []) + { + if ($this->logAtThisLevel(LogLevel::WARNING)) { + $this->log(LogLevel::WARNING, $message, $context); + } + } + + public function error($message, array $context = []) + { + if ($this->logAtThisLevel(LogLevel::ERROR)) { + $this->log(LogLevel::ERROR, $message, $context); + } + } + + public function critical($message, array $context = []) + { + if ($this->logAtThisLevel(LogLevel::CRITICAL)) { + $this->log(LogLevel::CRITICAL, $message, $context); + } + } + + public function alert($message, array $context = []) + { + if ($this->logAtThisLevel(LogLevel::ALERT)) { + $this->log(LogLevel::ALERT, $message, $context); + } + } + + public function emergency($message, array $context = []) + { + if ($this->logAtThisLevel(LogLevel::EMERGENCY)) { + $this->log(LogLevel::EMERGENCY, $message, $context); + } } } diff --git a/system/FlatFilePagePersistence.php b/system/FlatFilePagePersistence.php index 38652d4a..3b951005 100644 --- a/system/FlatFilePagePersistence.php +++ b/system/FlatFilePagePersistence.php @@ -4,7 +4,10 @@ namespace herbie; +use Exception; use Psr\SimpleCache\CacheInterface; +use RecursiveIteratorIterator; +use UnexpectedValueException; /** * Loads the whole page. @@ -37,38 +40,11 @@ public function findById(string $id): ?array { try { return $this->readFile($id); - } catch (\Exception $e) { + } catch (Exception $e) { return null; } } - public function findAll(): array - { - $items = []; - - if ($this->cacheEnable && $this->cacheTTL > 0) { - $cached = $this->cache->get(__METHOD__); - if (is_array($cached)) { - return $cached; - } - } - - foreach ($this->flatFileIterator as $fileInfo) { - try { - /** @var FileInfo $fileInfo */ - $aliasedPath = '@page/' . $fileInfo->getRelativePathname(); - $items[] = $this->readFile($aliasedPath); - } catch (\Exception $e) { - } - } - - if ($this->cacheEnable && $this->cacheTTL > 0) { - $this->cache->set(__METHOD__, $items, $this->cacheTTL); - } - - return $items; - } - /** * @return array */ @@ -130,66 +106,6 @@ private function readFile(string $alias): array ]; } - private function determineParentId(string $alias): string - { - $parents = $this->findParents($this->alias->get('@page'), '@page'); - $filename = $this->getFilenameWithoutPrefix($alias); - - if ($filename === 'index') { - $segment = dirname(dirname($alias)); - } else { - $segment = dirname($alias); - } - - if ($segment === '.') { - return ''; - } - - $segmentDepth = substr_count($segment, '/'); - - foreach ($parents as $parent) { - if (strpos($parent, $segment) !== 0) { - continue; - } - $parentDepth = substr_count($parent, '/'); - if ($parentDepth > ($segmentDepth + 1)) { - continue; - } - $basename = basename($parent); - if (preg_match('/^([0-9]+[-]+)?index\.[A-Za-z0-9]+$/', $basename) === 1) { - return $parent; - } - } - - return ''; - } - - private function findParents(string $folder, string $alias): array - { - static $parents; - if (!isset($parents)) { - $parents = []; - $iterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($folder)); - foreach ($iterator as $file) { - if (!$file->isDir()) { - $filename = pathinfo($file->getFilename(), PATHINFO_FILENAME); - $filename = preg_replace('/^([0-9]+[-]+)?(.+)$/', '\\2', $filename); - if ($filename === 'index') { - $parents[] = str_replace($folder, $alias, $file->getPathname()); - } - } - } - sort($parents); - } - return $parents; - } - - private function getFilenameWithoutPrefix(string $filepath): string - { - $filename = pathinfo($filepath, PATHINFO_FILENAME); - return (string)preg_replace('/^([0-9]+[-]+)(.+)$/', '\\2', $filename); - } - public static function parseFileContent(string $content): array { if (!defined('UTF8_BOM')) { @@ -206,12 +122,12 @@ public static function parseFileContent(string $content): array $splitContent = preg_split('/^-{3} (.+) -{3}\R?$/m', $matches[2], -1, PREG_SPLIT_DELIM_CAPTURE); if ($splitContent === false) { - throw new \UnexpectedValueException('Error at reading file content'); + throw new UnexpectedValueException('Error at reading file content'); } $count = count($splitContent); if ($count % 2 === 0) { - throw new \UnexpectedValueException('Error at reading file content'); + throw new UnexpectedValueException('Error at reading file content'); } $segments['default'] = array_shift($splitContent); @@ -277,4 +193,91 @@ private function createRoute(string $path, bool $trimExtension = false): string // handle index route return ($route === null || $route === 'index') ? '' : $route; } + + private function determineParentId(string $alias): string + { + $parents = $this->findParents($this->alias->get('@page'), '@page'); + $filename = $this->getFilenameWithoutPrefix($alias); + + if ($filename === 'index') { + $segment = dirname(dirname($alias)); + } else { + $segment = dirname($alias); + } + + if ($segment === '.') { + return ''; + } + + $segmentDepth = substr_count($segment, '/'); + + foreach ($parents as $parent) { + if (strpos($parent, $segment) !== 0) { + continue; + } + $parentDepth = substr_count($parent, '/'); + if ($parentDepth > ($segmentDepth + 1)) { + continue; + } + $basename = basename($parent); + if (preg_match('/^([0-9]+[-]+)?index\.[A-Za-z0-9]+$/', $basename) === 1) { + return $parent; + } + } + + return ''; + } + + private function findParents(string $folder, string $alias): array + { + static $parents; + if (!isset($parents)) { + $parents = []; + $iterator = new RecursiveIteratorIterator(new \RecursiveDirectoryIterator($folder)); + foreach ($iterator as $file) { + if (!$file->isDir()) { + $filename = pathinfo($file->getFilename(), PATHINFO_FILENAME); + $filename = preg_replace('/^([0-9]+[-]+)?(.+)$/', '\\2', $filename); + if ($filename === 'index') { + $parents[] = str_replace($folder, $alias, $file->getPathname()); + } + } + } + sort($parents); + } + return $parents; + } + + private function getFilenameWithoutPrefix(string $filepath): string + { + $filename = pathinfo($filepath, PATHINFO_FILENAME); + return (string)preg_replace('/^([0-9]+[-]+)(.+)$/', '\\2', $filename); + } + + public function findAll(): array + { + $items = []; + + if ($this->cacheEnable && $this->cacheTTL > 0) { + $cached = $this->cache->get(__METHOD__); + if (is_array($cached)) { + return $cached; + } + } + + foreach ($this->flatFileIterator as $fileInfo) { + try { + /** @var FileInfo $fileInfo */ + $aliasedPath = '@page/' . $fileInfo->getRelativePathname(); + $items[] = $this->readFile($aliasedPath); + } catch (Exception $e) { + } + } + + if ($this->cacheEnable && $this->cacheTTL > 0) { + $this->cache->set(__METHOD__, $items, $this->cacheTTL); + } + + return $items; + } } diff --git a/system/FlatFilePageRepository.php b/system/FlatFilePageRepository.php index 5e64d5e5..00935682 100644 --- a/system/FlatFilePageRepository.php +++ b/system/FlatFilePageRepository.php @@ -29,6 +29,14 @@ public function find(string $id): ?Page return $data ? $this->createPage($data) : null; } + private function createPage(array $data): Page + { + return $this->pageFactory->newPage( + $data['data'], + $data['segments'] + ); + } + public function findAll(): PageList { if ($this->pageList === null) { @@ -52,12 +60,4 @@ public function delete(Page $page): bool // TODO: Implement remove() method. return false; } - - private function createPage(array $data): Page - { - return $this->pageFactory->newPage( - $data['data'], - $data['segments'] - ); - } } diff --git a/system/JsonDataRepository.php b/system/JsonDataRepository.php index 44166402..ae0da005 100644 --- a/system/JsonDataRepository.php +++ b/system/JsonDataRepository.php @@ -30,15 +30,6 @@ public function load(string $name): array return $this->parseDataFile($dataFiles[$name]); } - public function loadAll(): array - { - $data = []; - foreach ($this->scanDataDir() as $name => $dataFile) { - $data[$name] = $this->parseDataFile($dataFile); - } - return $data; - } - /** * @throws SystemException */ @@ -88,4 +79,13 @@ private function parseDataFile(string $filepath): array $contents = file_read($filepath); return json_decode($contents, true); } + + public function loadAll(): array + { + $data = []; + foreach ($this->scanDataDir() as $name => $dataFile) { + $data[$name] = $this->parseDataFile($dataFile); + } + return $data; + } } diff --git a/system/LocalExtensionsPlugin.php b/system/LocalExtensionsPlugin.php index a225281e..8eb01f5c 100644 --- a/system/LocalExtensionsPlugin.php +++ b/system/LocalExtensionsPlugin.php @@ -31,6 +31,31 @@ public function consoleCommands(): array return $commands; } + /** + * @return string[] + */ + private function findPhpFilesInDir(string $dir): array + { + $dir = str_untrailing_slash($dir); + if (empty($dir) || !is_readable($dir)) { + return []; + } + $pattern = $dir . '/*.php'; + $files = glob($pattern); + if ($files === false) { + return []; + } + return $files; + } + + /** + * @return mixed + */ + private function includePhpFile(string $file) + { + return include $file; + } + public function eventListeners(): array { $dir = $this->config->getAsString('plugins.LOCAL_EXT.pathEventListeners'); @@ -57,6 +82,14 @@ public function applicationMiddlewares(): array return $middlewares; } + /** + * @return MiddlewareInterface|callable|string + */ + private function includeAppMiddleware(string $file) + { + return $this->includePhpFile($file); + } + public function routeMiddlewares(): array { $dir = $this->config->getAsString('plugins.LOCAL_EXT.pathRouteMiddlewares'); @@ -70,6 +103,14 @@ public function routeMiddlewares(): array return $middlewares; } + /** + * @return array{string, MiddlewareInterface|callable|string} + */ + private function includeRouteMiddleware(string $file): array + { + return $this->includePhpFile($file); + } + public function twigFilters(): array { $dir = $this->config->getAsString('plugins.LOCAL_EXT.pathTwigFilters'); @@ -83,6 +124,14 @@ public function twigFilters(): array return $filters; } + /** + * @return array{string, callable}|TwigFilter + */ + private function includeTwigFilter(string $file) + { + return $this->includePhpFile($file); + } + public function twigGlobals(): array { $dir = $this->config->getAsString('plugins.LOCAL_EXT.pathTwigGlobals'); @@ -109,6 +158,14 @@ public function twigFunctions(): array return $functions; } + /** + * @return array{string, callable}|TwigFunction + */ + private function includeTwigFunction(string $file) + { + return $this->includePhpFile($file); + } + public function twigTests(): array { $dir = $this->config->getAsString('plugins.LOCAL_EXT.pathTwigTests'); @@ -122,38 +179,6 @@ public function twigTests(): array return $tests; } - /** - * @return MiddlewareInterface|callable|string - */ - private function includeAppMiddleware(string $file) - { - return $this->includePhpFile($file); - } - - /** - * @return array{string, MiddlewareInterface|callable|string} - */ - private function includeRouteMiddleware(string $file): array - { - return $this->includePhpFile($file); - } - - /** - * @return array{string, callable}|TwigFilter - */ - private function includeTwigFilter(string $file) - { - return $this->includePhpFile($file); - } - - /** - * @return array{string, callable}|TwigFunction - */ - private function includeTwigFunction(string $file) - { - return $this->includePhpFile($file); - } - /** * @return array{string, callable}|TwigTest */ @@ -161,29 +186,4 @@ private function includeTwigTests(string $file) { return $this->includePhpFile($file); } - - /** - * @return mixed - */ - private function includePhpFile(string $file) - { - return include $file; - } - - /** - * @return string[] - */ - private function findPhpFilesInDir(string $dir): array - { - $dir = str_untrailing_slash($dir); - if (empty($dir) || !is_readable($dir)) { - return []; - } - $pattern = $dir . '/*.php'; - $files = glob($pattern); - if ($files === false) { - return []; - } - return $files; - } } diff --git a/system/Page.php b/system/Page.php index 2aff03d7..5f5c3ed0 100644 --- a/system/Page.php +++ b/system/Page.php @@ -7,6 +7,8 @@ use ArrayAccess; use Ausi\SlugGenerator\SlugGenerator; use BadMethodCallException; +use InvalidArgumentException; +use ReturnTypeWillChange; /** * @property string[] $authors @@ -38,6 +40,7 @@ */ final class Page implements ArrayAccess { + private static ?SlugGenerator $slugGenerator = null; /** @var string[] */ private array $authors; private bool $cached; @@ -69,8 +72,6 @@ final class Page implements ArrayAccess private bool $twig; private string $type; - private static ?SlugGenerator $slugGenerator = null; - public function __construct(array $data = [], ?array $segments = null) { // set defaults @@ -106,13 +107,30 @@ public function __construct(array $data = [], ?array $segments = null) } } - public function getSegments(): array + /** + * Overwrites PageItemTrait::setData() + */ + public function setData(array $data): void { - if ($this->segments === null) { - $content = file_read($this->getPath()); - [, $this->segments] = FlatFilePagePersistence::parseFileContent($content); + if (array_key_exists('data', $data)) { + throw new InvalidArgumentException("Field data is not allowed."); } - return $this->segments; + if (array_key_exists('segments', $data)) { + throw new InvalidArgumentException("Field segments is not allowed."); + } + foreach ($data as $key => $value) { + $this->__set($key, $value); + } + } + + public static function setSlugGenerator(SlugGenerator $slugGenerator): void + { + self::$slugGenerator = $slugGenerator; + } + + public static function unsetSlugGenerator(): void + { + self::$slugGenerator = null; } public function getSegment(string $id): string @@ -124,6 +142,15 @@ public function getSegment(string $id): string return ''; } + public function getSegments(): array + { + if ($this->segments === null) { + $content = file_read($this->getPath()); + [, $this->segments] = FlatFilePagePersistence::parseFileContent($content); + } + return $this->segments; + } + /** * @param string[] $segments */ @@ -132,20 +159,14 @@ public function setSegments(array $segments = []): void $this->segments = $segments; } - /** - * Overwrites PageItemTrait::setData() - */ - public function setData(array $data): void + public function getPath(): string { - if (array_key_exists('data', $data)) { - throw new \InvalidArgumentException("Field data is not allowed."); - } - if (array_key_exists('segments', $data)) { - throw new \InvalidArgumentException("Field segments is not allowed."); - } - foreach ($data as $key => $value) { - $this->__set($key, $value); - } + return $this->path; + } + + public function setPath(string $path): void + { + $this->path = trim($path); } public function getTitle(): string @@ -207,61 +228,46 @@ public function getRedirect(): array public function setRedirect($redirect): void { if (!is_array($redirect) && !is_string($redirect)) { - throw new \InvalidArgumentException('Redirect must be a string or an array{string,int}.'); + throw new InvalidArgumentException('Redirect must be a string or an array{string,int}.'); } if (is_string($redirect)) { $redirect = trim($redirect); if ($redirect === '') { - throw new \InvalidArgumentException('Redirect must be a non-empty string.'); + throw new InvalidArgumentException('Redirect must be a non-empty string.'); } $redirect = [$redirect, 302]; } $count = count($redirect); if ($count === 0) { - throw new \InvalidArgumentException('Redirect must be a non-empty array.'); + throw new InvalidArgumentException('Redirect must be a non-empty array.'); } if ($count <> 2) { - throw new \InvalidArgumentException('Redirect array must be an array{string,int}.'); + throw new InvalidArgumentException('Redirect array must be an array{string,int}.'); } if (!is_string($redirect[0])) { - throw new \InvalidArgumentException('Redirect array[0] must be a string.'); + throw new InvalidArgumentException('Redirect array[0] must be a string.'); } $redirect[0] = trim($redirect[0]); if ($redirect[0] === '') { - throw new \InvalidArgumentException('Redirect array[0] must be a non-empty string.'); + throw new InvalidArgumentException('Redirect array[0] must be a non-empty string.'); } if (!is_natural($redirect[1])) { - throw new \InvalidArgumentException('Redirect array[1] must be a integer.'); + throw new InvalidArgumentException('Redirect array[1] must be a integer.'); } if ($redirect[1] < 300 || $redirect[1] > 308) { - throw new \InvalidArgumentException('Redirect array[1] must be a status code between 300 and 308.'); + throw new InvalidArgumentException('Redirect array[1] must be a status code between 300 and 308.'); } $this->redirect = $redirect; } - public function getRoute(): string - { - return trim($this->route); - } - - public function setRoute(string $route): void - { - $this->route = trim($route); - } - - public function setId(string $id): void - { - $this->id = trim($id); - } - public function getId(): string { return $this->id; } - public function setParentId(string $parentId): void + public function setId(string $id): void { - $this->parent_id = trim($parentId); + $this->id = trim($id); } public function getParentId(): string @@ -269,9 +275,9 @@ public function getParentId(): string return $this->parent_id; } - public function setParentRoute(string $parentRoute): void + public function setParentId(string $parentId): void { - $this->parent_route = trim($parentRoute); + $this->parent_id = trim($parentId); } public function getParentRoute(): string @@ -279,14 +285,9 @@ public function getParentRoute(): string return $this->parent_route; } - public function getPath(): string - { - return $this->path; - } - - public function setPath(string $path): void + public function setParentRoute(string $parentRoute): void { - $this->path = trim($path); + $this->parent_route = trim($parentRoute); } public function getFormat(): string @@ -326,6 +327,25 @@ public function setCreated($date): void $this->created = $this->formatDate($date); } + /** + * @param int|string $date + */ + private function formatDate($date): string + { + if (is_string($date)) { + $date = trim($date); + } + if (is_natural($date, true)) { + return date_format('c', (int)$date); + } elseif (is_string($date)) { + $time = time_from_string($date); + if ($time > 0) { + return date_format('c', $time); + } + } + return ''; + } + public function getDate(): string { return $this->date; @@ -350,9 +370,12 @@ public function getAuthor(string $author): string return ''; } - public function getAuthors(): array + private function slugify(string $slug): string { - return $this->authors; + if (self::$slugGenerator === null) { + throw new BadMethodCallException('SlugGenerator not set.'); + } + return self::$slugGenerator->generate($slug); } public function getCategory(string $category): string @@ -366,16 +389,6 @@ public function getCategory(string $category): string return ''; } - public function getCategories(): array - { - return $this->categories; - } - - public function getTags(): array - { - return $this->tags; - } - public function getTag(string $tag): string { $tag = $this->slugify($tag); @@ -387,22 +400,9 @@ public function getTag(string $tag): string return ''; } - /** - * @param string[] $categories - */ - public function setCategories(array $categories): void - { - foreach ($categories as $category) { - $this->setCategory($category); - } - } - - public function setCategory(string $category): void + public function getTags(): array { - $category = trim($category); - if (!in_array($category, $this->categories)) { - $this->categories[] = $category; - } + return $this->tags; } /** @@ -423,6 +423,22 @@ public function setTag(string $tag): void } } + public function hasAuthor(string $author): bool + { + $author = $this->slugify($author); + foreach ($this->getAuthors() as $c) { + if ($this->slugify($c) === $author) { + return true; + } + } + return false; + } + + public function getAuthors(): array + { + return $this->authors; + } + /** * @param string[] $authors */ @@ -441,17 +457,6 @@ public function setAuthor(string $author): void } } - public function hasAuthor(string $author): bool - { - $author = $this->slugify($author); - foreach ($this->getAuthors() as $c) { - if ($this->slugify($c) === $author) { - return true; - } - } - return false; - } - public function hasCategory(string $category): bool { $category = $this->slugify($category); @@ -463,6 +468,29 @@ public function hasCategory(string $category): bool return false; } + public function getCategories(): array + { + return $this->categories; + } + + /** + * @param string[] $categories + */ + public function setCategories(array $categories): void + { + foreach ($categories as $category) { + $this->setCategory($category); + } + } + + public function setCategory(string $category): void + { + $category = trim($category); + if (!in_array($category, $this->categories)) { + $this->categories[] = $category; + } + } + public function hasTag(string $tag): bool { $tag = $this->slugify($tag); @@ -474,6 +502,11 @@ public function hasTag(string $tag): bool return false; } + public function getModified(): string + { + return $this->modified; + } + /** * @param int|string $modified */ @@ -482,11 +515,6 @@ public function setModified($modified): void $this->modified = $this->formatDate($modified); } - public function getModified(): string - { - return $this->modified; - } - public function getTwig(): bool { return $this->twig; @@ -552,6 +580,16 @@ public function isStartPage(): bool return $this->getRoute() === ''; } + public function getRoute(): string + { + return trim($this->route); + } + + public function setRoute(string $route): void + { + $this->route = trim($route); + } + public function routeEquals(string $route): bool { return $this->getRoute() === $route; @@ -571,46 +609,6 @@ public function isStaticPage(): bool return 0 === strpos($this->getPath(), '@page'); } - /** - * @return mixed - */ - public function __get(string $name) - { - $getter = 'get' . str_replace('_', '', $name); - if (method_exists($this, $getter)) { - return $this->$getter(); - } elseif (array_key_exists($name, $this->customData)) { - return $this->customData[$name]; - } else { - throw new \InvalidArgumentException("Field {$name} does not exist."); - } - } - - public function __isset(string $name): bool - { - $getter = 'get' . str_replace('_', '', $name); - if (method_exists($this, $getter)) { - return $this->$getter() !== null; - } elseif (array_key_exists($name, $this->customData)) { - return $this->customData[$name] !== null; - } else { - return false; - } - } - - /** - * @param mixed $value - */ - public function __set(string $name, $value): void - { - $setter = 'set' . str_replace('_', '', $name); - if (method_exists($this, $setter)) { - $this->$setter($value); - } else { - $this->customData[$name] = $value; - } - } - public function __toString(): string { return $this->title; @@ -628,58 +626,62 @@ public function toArray(): array return array_merge($array, $this->customData); } - private function slugify(string $slug): string - { - if (self::$slugGenerator === null) { - throw new BadMethodCallException('SlugGenerator not set.'); - } - return self::$slugGenerator->generate($slug); - } - - public static function setSlugGenerator(SlugGenerator $slugGenerator): void + /** + * @param mixed $offset + */ + public function offsetExists($offset): bool { - self::$slugGenerator = $slugGenerator; + return $this->__isset($offset); } - public static function unsetSlugGenerator(): void + public function __isset(string $name): bool { - self::$slugGenerator = null; + $getter = 'get' . str_replace('_', '', $name); + if (method_exists($this, $getter)) { + return $this->$getter() !== null; + } elseif (array_key_exists($name, $this->customData)) { + return $this->customData[$name] !== null; + } else { + return false; + } } /** - * @param int|string $date + * @param mixed $offset + * @return mixed */ - private function formatDate($date): string + #[ReturnTypeWillChange] + public function offsetGet($offset) { - if (is_string($date)) { - $date = trim($date); - } - if (is_natural($date, true)) { - return date_format('c', (int)$date); - } elseif (is_string($date)) { - $time = time_from_string($date); - if ($time > 0) { - return date_format('c', $time); - } - } - return ''; + return $this->__get($offset); } + /** - * @param mixed $offset + * @return mixed */ - public function offsetExists($offset): bool + public function __get(string $name) { - return $this->__isset($offset); + $getter = 'get' . str_replace('_', '', $name); + if (method_exists($this, $getter)) { + return $this->$getter(); + } elseif (array_key_exists($name, $this->customData)) { + return $this->customData[$name]; + } else { + throw new InvalidArgumentException("Field {$name} does not exist."); + } } /** - * @param mixed $offset - * @return mixed + * @param mixed $value */ - #[\ReturnTypeWillChange] - public function offsetGet($offset) + public function __set(string $name, $value): void { - return $this->__get($offset); + $setter = 'set' . str_replace('_', '', $name); + if (method_exists($this, $setter)) { + $this->$setter($value); + } else { + $this->customData[$name] = $value; + } } /** diff --git a/system/PageFactory.php b/system/PageFactory.php index 33f64bf6..3af66bf4 100644 --- a/system/PageFactory.php +++ b/system/PageFactory.php @@ -21,13 +21,6 @@ public function newPageList(array $items = []): PageList return new PageList($items); } - private function isIndexPage(string $path): bool - { - $filename = pathinfo($path, PATHINFO_FILENAME); - $filenameWithoutPrefix = preg_replace('/^([0-9])+-/', '', $filename); - return $filenameWithoutPrefix === 'index'; - } - public function newPageTree(PageList $pageList): PageTree { $tree = new PageTree(); @@ -59,6 +52,13 @@ public function newPageTree(PageList $pageList): PageTree return $tree; } + private function isIndexPage(string $path): bool + { + $filename = pathinfo($path, PATHINFO_FILENAME); + $filenameWithoutPrefix = preg_replace('/^([0-9])+-/', '', $filename); + return $filenameWithoutPrefix === 'index'; + } + public function newPageTrail(array $pages): PageTrail { return new PageTrail($pages); diff --git a/system/PageList.php b/system/PageList.php index f373ca33..208a821b 100644 --- a/system/PageList.php +++ b/system/PageList.php @@ -4,6 +4,7 @@ namespace herbie; +use ArrayIterator; use Countable; use IteratorAggregate; @@ -43,19 +44,9 @@ public function getItems(): array return $this->items; } - public function getItem(string $route): ?Page - { - return isset($this->items[$route]) ? $this->items[$route] : null; - } - - public function getIterator(): \ArrayIterator + public function getIterator(): ArrayIterator { - return new \ArrayIterator($this->items); - } - - public function count(): int - { - return count($this->items); + return new ArrayIterator($this->items); } public function getRandom(): Page @@ -66,6 +57,11 @@ public function getRandom(): Page return $this->items[$route]; } + public function count(): int + { + return count($this->items); + } + public function find(string $value, string $key): ?Page { foreach ($this->items as $item) { @@ -93,12 +89,14 @@ public function filter($key = null, $value = null): PageList return new self(array_filter($this->items, $key)); } if (is_string($key) && is_scalar($value)) { - return new self(array_filter($this->items, function ($val) use ($key, $value) { - if ($val->{$key} === $value) { - return true; - } - return false; - })); + return new self( + array_filter($this->items, function ($val) use ($key, $value) { + if ($val->{$key} === $value) { + return true; + } + return false; + }) + ); } return new self(array_filter($this->items)); } @@ -154,6 +152,33 @@ public function getAuthors(?string $type = null): array return $authors; } + private function createTaxonomyFor(string $dataType): array + { + $items = ['__all__' => []]; + foreach ($this->items as $page) { + $pageType = $page->getType(); + foreach ($page->{$dataType} as $item) { + // for all + if (isset($items['__all__'][$item])) { + $items['__all__'][$item]++; + } else { + $items['__all__'][$item] = 1; + } + + if (!isset($items[$pageType])) { + $items[$pageType] = []; + } + // per type + if (isset($items[$pageType][$item])) { + $items[$pageType][$item]++; + } else { + $items[$pageType][$item] = 1; + } + } + } + return $items; + } + public function getCategories(?string $type = null): array { $type = $type === null ? '__all__' : $type; @@ -300,33 +325,6 @@ public function filterItems(string $type, string $parentRoute, array $params): P return new self($items); } - private function createTaxonomyFor(string $dataType): array - { - $items = ['__all__' => []]; - foreach ($this->items as $page) { - $pageType = $page->getType(); - foreach ($page->{$dataType} as $item) { - // for all - if (isset($items['__all__'][$item])) { - $items['__all__'][$item]++; - } else { - $items['__all__'][$item] = 1; - } - - if (!isset($items[$pageType])) { - $items[$pageType] = []; - } - // per type - if (isset($items[$pageType][$item])) { - $items[$pageType][$item]++; - } else { - $items[$pageType][$item] = 1; - } - } - } - return $items; - } - public function getPageTree(): PageTree { if ($this->pageTree === null) { @@ -360,4 +358,9 @@ public function getPageTrail(string $requestRoute): PageTrail return $this->pageTrail = (new PageFactory())->newPageTrail($items); } + + public function getItem(string $route): ?Page + { + return isset($this->items[$route]) ? $this->items[$route] : null; + } } diff --git a/system/PageTrail.php b/system/PageTrail.php index 1d2fc599..832f37ba 100644 --- a/system/PageTrail.php +++ b/system/PageTrail.php @@ -4,6 +4,7 @@ namespace herbie; +use ArrayIterator; use Countable; use IteratorAggregate; @@ -25,9 +26,9 @@ public function __construct(array $items) $this->items = $items; } - public function getIterator(): \ArrayIterator + public function getIterator(): ArrayIterator { - return new \ArrayIterator($this->items); + return new ArrayIterator($this->items); } public function count(): int diff --git a/system/PageTreeHtmlRenderer.php b/system/PageTreeHtmlRenderer.php index 2b4596d1..f39cfcbf 100644 --- a/system/PageTreeHtmlRenderer.php +++ b/system/PageTreeHtmlRenderer.php @@ -4,6 +4,7 @@ namespace herbie; +use RecursiveIterator; use RecursiveIteratorIterator; /** @@ -29,7 +30,7 @@ final class PageTreeHtmlRenderer extends RecursiveIteratorIterator private $itemCallback; public function __construct( - \RecursiveIterator $iterator, + RecursiveIterator $iterator, int $mode = RecursiveIteratorIterator::SELF_FIRST, int $flags = 0 ) { @@ -63,6 +64,15 @@ public function beginIteration(): void $this->output .= $this->getTemplate('beginIteration'); } + private function getTemplate(string $key): string + { + $replacements = [ + '{class}' => $this->class, + '{level}' => $this->getDepth() + 1 + ]; + return strtr($this->template[$key], $replacements); + } + public function endIteration(): void { $this->output .= $this->getTemplate('endIteration'); @@ -95,15 +105,6 @@ public function render(string $route = ''): string return $this->output; } - private function getTemplate(string $key): string - { - $replacements = [ - '{class}' => $this->class, - '{level}' => $this->getDepth() + 1 - ]; - return strtr($this->template[$key], $replacements); - } - private function addCssClasses(string $beginCurrent, string $route): string { $menuItemRoute = $this->getMenuItem()->getRoute(); diff --git a/system/PageTreeTextRenderer.php b/system/PageTreeTextRenderer.php index 4ed40bc5..9bd9f5f8 100644 --- a/system/PageTreeTextRenderer.php +++ b/system/PageTreeTextRenderer.php @@ -4,13 +4,14 @@ namespace herbie; +use RecursiveIterator; use RecursiveTreeIterator; final class PageTreeTextRenderer extends RecursiveTreeIterator { public string $emptyTitle = '[]'; - public function __construct(\RecursiveIterator $iterator) + public function __construct(RecursiveIterator $iterator) { parent::__construct($iterator); $this->setPrefixPart(self::PREFIX_LEFT, ''); diff --git a/system/Pagination.php b/system/Pagination.php index fe78bdca..8e67a825 100644 --- a/system/Pagination.php +++ b/system/Pagination.php @@ -4,8 +4,12 @@ namespace herbie; +use ArrayIterator; use Countable; +use Exception; +use InvalidArgumentException; use IteratorAggregate; +use LogicException; final class Pagination implements IteratorAggregate, Countable { @@ -18,8 +22,8 @@ final class Pagination implements IteratorAggregate, Countable /** * @param array $items - * @throws \Exception - * @throws \LogicException + * @throws Exception + * @throws LogicException */ public function __construct(iterable $items, int $limit = 10, string $name = 'page') { @@ -30,12 +34,19 @@ public function __construct(iterable $items, int $limit = 10, string $name = 'pa $this->items = (array)$items->getIterator(); } else { $message = 'The param $items must be an array or an object implementing IteratorAggregate.'; - throw new \InvalidArgumentException($message, 500); + throw new InvalidArgumentException($message, 500); } $this->setLimit($limit); $this->name = $name; } + public function getIterator(): ArrayIterator + { + $offset = ($this->getPage() - 1) * $this->limit; + $items = array_slice($this->items, $offset, $this->limit); + return new ArrayIterator($items); + } + public function getPage(): int { $page = isset($_GET[$this->name]) ? (int)$_GET[$this->name] : 1; @@ -46,6 +57,11 @@ public function getPage(): int return (int)$page; } + public function count(): int + { + return count($this->items); + } + public function getLimit(): int { return $this->limit; @@ -57,18 +73,6 @@ public function setLimit(int $limit): void $this->limit = $limit; } - public function getIterator(): \ArrayIterator - { - $offset = ($this->getPage() - 1) * $this->limit; - $items = array_slice($this->items, $offset, $this->limit); - return new \ArrayIterator($items); - } - - public function count(): int - { - return count($this->items); - } - public function hasNextPage(): bool { return ($this->limit * $this->getPage()) < $this->count(); diff --git a/system/PluginInterface.php b/system/PluginInterface.php index e573ba39..d576c767 100644 --- a/system/PluginInterface.php +++ b/system/PluginInterface.php @@ -5,6 +5,9 @@ namespace herbie; use Psr\Http\Server\MiddlewareInterface; +use Twig\TwigFilter; +use Twig\TwigFunction; +use Twig\TwigTest; interface PluginInterface { @@ -31,7 +34,7 @@ public function applicationMiddlewares(): array; public function routeMiddlewares(): array; /** - * @return array}> + * @return array}> */ public function twigFilters(): array; @@ -41,12 +44,12 @@ public function twigFilters(): array; public function twigGlobals(): array; /** - * @return array}> + * @return array}> */ public function twigFunctions(): array; /** - * @return array}> + * @return array}> */ public function twigTests(): array; } diff --git a/system/PluginManager.php b/system/PluginManager.php index dacdea83..27f3bfdd 100644 --- a/system/PluginManager.php +++ b/system/PluginManager.php @@ -9,6 +9,9 @@ use Psr\Container\ContainerInterface; use Psr\Http\Server\MiddlewareInterface; use Psr\Log\LoggerInterface; +use Twig\TwigFilter; +use Twig\TwigFunction; +use Twig\TwigTest; final class PluginManager { @@ -66,12 +69,14 @@ public function init(): void return; } - $this->loadInstallablePlugin(new InstallablePlugin( - 'CORE', - __DIR__, - CorePlugin::class, - 'virtual', - )); + $this->loadInstallablePlugin( + new InstallablePlugin( + 'CORE', + __DIR__, + CorePlugin::class, + 'virtual', + ) + ); $enabledSystemPlugins = str_explode_filtered($this->config->getAsString('enabledSysPlugins'), ','); $enabledComposerOrLocalPlugins = str_explode_filtered($this->config->getAsString('enabledPlugins'), ','); @@ -91,26 +96,32 @@ public function init(): void $this->loadInstallablePlugin($plugin); } - $this->loadInstallablePlugin(new InstallablePlugin( - 'LOCAL_EXT', - __DIR__, - LocalExtensionsPlugin::class, - 'virtual', - )); - - $this->loadInstallablePlugin(new InstallablePlugin( - 'APP_EXT', - __DIR__, - ApplicationExtensionsPlugin::class, - 'virtual', - )); - - $this->loadInstallablePlugin(new InstallablePlugin( - 'SYS_INFO', - __DIR__, - SystemInfoPlugin::class, - 'virtual', - )); + $this->loadInstallablePlugin( + new InstallablePlugin( + 'LOCAL_EXT', + __DIR__, + LocalExtensionsPlugin::class, + 'virtual', + ) + ); + + $this->loadInstallablePlugin( + new InstallablePlugin( + 'APP_EXT', + __DIR__, + ApplicationExtensionsPlugin::class, + 'virtual', + ) + ); + + $this->loadInstallablePlugin( + new InstallablePlugin( + 'SYS_INFO', + __DIR__, + SystemInfoPlugin::class, + 'virtual', + ) + ); $this->eventManager->dispatch(new PluginsInitializedEvent($this->loadedPlugins, $this->pluginPaths)); @@ -122,36 +133,6 @@ public function isInitialized(): bool return $this->initialized; } - /** - * @param string[] $enabledPlugins - * @return InstallablePlugin[] - */ - private function getInstallablePlugins(array $enabledPlugins, string $type): array - { - $plugins = []; - foreach ($enabledPlugins as $pluginKey) { - $pluginConfigPath = sprintf('plugins.%s', $pluginKey); - $pluginConfig = $this->config->getAsArray($pluginConfigPath); - if ( - empty($pluginConfig) - || ($pluginConfig['location'] !== $type) - || empty($pluginConfig['pluginName']) - || empty($pluginConfig['pluginClass']) - || empty($pluginConfig['pluginPath']) - ) { - continue; - } - $plugins[] = new InstallablePlugin( - $pluginConfig['pluginName'], - $pluginConfig['pluginPath'], - $pluginConfig['pluginClass'], - $type - ); - } - - return $plugins; - } - private function loadInstallablePlugin(InstallablePlugin $installablePlugin): void { $plugin = $installablePlugin->createPluginInstance($this->container); @@ -173,10 +154,10 @@ private function loadInstallablePlugin(InstallablePlugin $installablePlugin): vo } foreach ($plugin->twigFilters() as $twigFilter) { - if ($twigFilter instanceof \Twig\TwigFilter) { + if ($twigFilter instanceof TwigFilter) { $this->addTwigFilter($twigFilter); } else { - $this->addTwigFilter(new \Twig\TwigFilter(...$twigFilter)); + $this->addTwigFilter(new TwigFilter(...$twigFilter)); } } @@ -185,18 +166,18 @@ private function loadInstallablePlugin(InstallablePlugin $installablePlugin): vo } foreach ($plugin->twigFunctions() as $twigFunction) { - if ($twigFunction instanceof \Twig\TwigFunction) { + if ($twigFunction instanceof TwigFunction) { $this->addTwigFunction($twigFunction); } else { - $this->addTwigFunction(new \Twig\TwigFunction(...$twigFunction)); + $this->addTwigFunction(new TwigFunction(...$twigFunction)); } } foreach ($plugin->twigTests() as $twigTest) { - if ($twigTest instanceof \Twig\TwigTest) { + if ($twigTest instanceof TwigTest) { $this->addTwigTest($twigTest); } else { - $this->addTwigTest(new \Twig\TwigTest(...$twigTest)); + $this->addTwigTest(new TwigTest(...$twigTest)); } } @@ -219,46 +200,6 @@ private function loadInstallablePlugin(InstallablePlugin $installablePlugin): vo $this->logger->debug($message); } - /** - * @return array - */ - public function getLoadedPlugins(): array - { - return $this->loadedPlugins; - } - - /** - * @return string[] - */ - public function getConsoleCommands(): array - { - return $this->consoleCommands; - } - - /** - * @return array - */ - public function getApplicationMiddlewares(): array - { - return $this->applicationMiddlewares; - } - - /** - * @return array - */ - public function getRouteMiddlewares(): array - { - return $this->routeMiddlewares; - } - - /** - * @return array - */ - public function getPluginPaths(): array - { - return $this->pluginPaths; - } - private function addConsoleCommand(string $command): void { $this->consoleCommands[] = $command; @@ -282,12 +223,7 @@ private function addRouteMiddleware(array $routeWithMiddleware): void $this->routeMiddlewares[] = $routeWithMiddleware; } - private function addEventListener(string $name, callable $callable, int $priority = 1): void - { - $this->eventManager->addListener($name, $callable, $priority); - } - - private function addTwigFilter(\Twig\TwigFilter $filter): void + private function addTwigFilter(TwigFilter $filter): void { $closure = function (TwigInitializedEvent $event) use ($filter) { $event->getEnvironment()->addFilter($filter); @@ -306,7 +242,7 @@ private function addTwigGlobal(string $name, $mixed): void $this->eventManager->addListener(TwigInitializedEvent::class, $closure); } - private function addTwigFunction(\Twig\TwigFunction $function): void + private function addTwigFunction(TwigFunction $function): void { $closure = function (TwigInitializedEvent $event) use ($function) { $event->getEnvironment()->addFunction($function); @@ -314,11 +250,86 @@ private function addTwigFunction(\Twig\TwigFunction $function): void $this->eventManager->addListener(TwigInitializedEvent::class, $closure); } - private function addTwigTest(\Twig\TwigTest $test): void + private function addTwigTest(TwigTest $test): void { $closure = function (TwigInitializedEvent $event) use ($test) { $event->getEnvironment()->addTest($test); }; $this->eventManager->addListener(TwigInitializedEvent::class, $closure); } + + private function addEventListener(string $name, callable $callable, int $priority = 1): void + { + $this->eventManager->addListener($name, $callable, $priority); + } + + /** + * @param string[] $enabledPlugins + * @return InstallablePlugin[] + */ + private function getInstallablePlugins(array $enabledPlugins, string $type): array + { + $plugins = []; + foreach ($enabledPlugins as $pluginKey) { + $pluginConfigPath = sprintf('plugins.%s', $pluginKey); + $pluginConfig = $this->config->getAsArray($pluginConfigPath); + if ( + empty($pluginConfig) + || ($pluginConfig['location'] !== $type) + || empty($pluginConfig['pluginName']) + || empty($pluginConfig['pluginClass']) + || empty($pluginConfig['pluginPath']) + ) { + continue; + } + $plugins[] = new InstallablePlugin( + $pluginConfig['pluginName'], + $pluginConfig['pluginPath'], + $pluginConfig['pluginClass'], + $type + ); + } + + return $plugins; + } + + /** + * @return array + */ + public function getLoadedPlugins(): array + { + return $this->loadedPlugins; + } + + /** + * @return string[] + */ + public function getConsoleCommands(): array + { + return $this->consoleCommands; + } + + /** + * @return array + */ + public function getApplicationMiddlewares(): array + { + return $this->applicationMiddlewares; + } + + /** + * @return array + */ + public function getRouteMiddlewares(): array + { + return $this->routeMiddlewares; + } + + /** + * @return array + */ + public function getPluginPaths(): array + { + return $this->pluginPaths; + } } diff --git a/system/QueryBuilder.php b/system/QueryBuilder.php index 0e284d13..416b4b0f 100644 --- a/system/QueryBuilder.php +++ b/system/QueryBuilder.php @@ -6,6 +6,8 @@ use ArrayAccess; use ArrayIterator; +use Exception; +use InvalidArgumentException; use IteratorAggregate; use Traversable; @@ -65,7 +67,7 @@ public function from(iterable $iterator): self public function where(...$conditions): self { if (empty($conditions)) { - throw new \InvalidArgumentException('Empty where conditions'); + throw new InvalidArgumentException('Empty where conditions'); } foreach ($conditions as $condition) { if (is_string($condition)) { @@ -82,7 +84,7 @@ public function where(...$conditions): self continue; } } - throw new \InvalidArgumentException('Unsupported where conditions'); + throw new InvalidArgumentException('Unsupported where conditions'); } return $this; } @@ -114,28 +116,13 @@ private function parseCondition(string $condition): array return [$name, $value1, $value2]; } } - throw new \InvalidArgumentException('Unsupported operator'); - } - - private function convertType(mixed $value1, mixed $value2): mixed - { - if (is_bool($value1) && is_string($value2)) { - $lowered = strtolower($value2); - if ($lowered === 'true') { - return true; - } - if ($lowered === 'false') { - return false; - } - return $value2; - } - return $value2; + throw new InvalidArgumentException('Unsupported operator'); } private function parseConditionsInOperatorFormat(array $conditions): array { if (!isset($conditions[0]) || !in_array(strtoupper($conditions[0]), self::WHERE_CLAUSE_OPERATORS)) { - throw new \InvalidArgumentException('Missing where clause operator'); + throw new InvalidArgumentException('Missing where clause operator'); } $whereClauseOperator = [strtoupper(array_shift($conditions))]; $items = []; @@ -154,7 +141,7 @@ private function parseConditionsInHashFormat(array $conditions): array $items = []; foreach ($conditions as $key => $value) { if (is_scalar($value)) { - $type = \herbie\get_type($value); + $type = get_type($value); $items[] = ['match' . ucfirst($type), $key, $value]; } } @@ -185,7 +172,7 @@ public function count(): int } /** - * @throws \Exception + * @throws Exception */ public function paginate(int $size): Pagination { @@ -194,29 +181,6 @@ public function paginate(int $size): Pagination return new Pagination($this->processed, $this->limit); } - public function all(): iterable - { - $this->processData(); - return $this->processed; - } - - public function one(): array|object|null - { - $this->limit = 1; - $this->processData(); - $item = reset($this->processed); - if ($item === false) { - return null; - } - return $item; - } - - public function getIterator(): Traversable - { - $this->processData(); - return new ArrayIterator($this->processed); - } - private function processData(): void { $i = 0; @@ -238,6 +202,42 @@ private function processData(): void } } + private function sort(): bool + { + if (is_callable($this->order)) { + return uasort($this->data, $this->order); + } + + if (trim($this->order, '-+') === '') { + return false; + } + + $field = ''; + if (!empty($this->order)) { + $field = trim($this->order, '+'); + } + + $direction = 'asc'; + if (str_starts_with($field, '-')) { + $field = substr($field, 1); + $direction = 'desc'; + } + + return uasort($this->data, function ($value1, $value2) use ($field, $direction) { + if (!isset($value1[$field]) || !isset($value2[$field])) { + return 0; + } + if ($value1[$field] === $value2[$field]) { + return 0; + } + if ($direction === 'asc') { + return ($value1[$field] < $value2[$field]) ? -1 : 1; + } else { + return ($value2[$field] < $value1[$field]) ? -1 : 1; + } + }); + } + private function processItem(ArrayAccess|array|int|float|string|bool $item, array $conditions): bool { $whereClauseOperator = array_shift($conditions); @@ -291,40 +291,42 @@ private function processItem(ArrayAccess|array|int|float|string|bool $item, arra return $uniqueStatusCount === 1 && in_array(true, $uniqueStatus, true); } - private function sort(): bool + private function convertType(mixed $value1, mixed $value2): mixed { - if (is_callable($this->order)) { - return uasort($this->data, $this->order); - } - - if (trim($this->order, '-+') === '') { - return false; + if (is_bool($value1) && is_string($value2)) { + $lowered = strtolower($value2); + if ($lowered === 'true') { + return true; + } + if ($lowered === 'false') { + return false; + } + return $value2; } + return $value2; + } - $field = ''; - if (!empty($this->order)) { - $field = trim($this->order, '+'); - } + public function all(): iterable + { + $this->processData(); + return $this->processed; + } - $direction = 'asc'; - if (str_starts_with($field, '-')) { - $field = substr($field, 1); - $direction = 'desc'; + public function one(): array|object|null + { + $this->limit = 1; + $this->processData(); + $item = reset($this->processed); + if ($item === false) { + return null; } + return $item; + } - return uasort($this->data, function ($value1, $value2) use ($field, $direction) { - if (!isset($value1[$field]) || !isset($value2[$field])) { - return 0; - } - if ($value1[$field] === $value2[$field]) { - return 0; - } - if ($direction === 'asc') { - return ($value1[$field] < $value2[$field]) ? -1 : 1; - } else { - return ($value2[$field] < $value1[$field]) ? -1 : 1; - } - }); + public function getIterator(): Traversable + { + $this->processData(); + return new ArrayIterator($this->processed); } protected function matchString(string $value1, string $value2): bool diff --git a/system/Site.php b/system/Site.php index a96ae8c9..c7396b70 100644 --- a/system/Site.php +++ b/system/Site.php @@ -4,6 +4,8 @@ namespace herbie; +use InvalidArgumentException; + /** * Stores the site. */ @@ -42,14 +44,14 @@ public function getData(): array return $this->dataRepository->loadAll(); } - public function getPageList(): PageList + public function getPageTree(): PageTree { - return $this->pageRepository->findAll(); + return $this->getPageList()->getPageTree(); } - public function getPageTree(): PageTree + public function getPageList(): PageList { - return $this->getPageList()->getPageTree(); + return $this->pageRepository->findAll(); } public function getPageTrail(): PageTrail @@ -119,7 +121,7 @@ public function __get(string $name) if (method_exists($this, $getter)) { return $this->$getter(); } else { - throw new \InvalidArgumentException("Field {$name} does not exist."); + throw new InvalidArgumentException("Field {$name} does not exist."); } } diff --git a/system/SystemInfoPlugin.php b/system/SystemInfoPlugin.php index dfb69b72..a8f6bc7a 100644 --- a/system/SystemInfoPlugin.php +++ b/system/SystemInfoPlugin.php @@ -4,6 +4,10 @@ namespace herbie; +use Twig\Error\LoaderError; +use Twig\Error\RuntimeError; +use Twig\Error\SyntaxError; + final class SystemInfoPlugin extends Plugin { private Alias $alias; @@ -43,9 +47,9 @@ public function twigFunctions(): array /** * @param array $context - * @throws \Twig\Error\LoaderError - * @throws \Twig\Error\RuntimeError - * @throws \Twig\Error\SyntaxError + * @throws LoaderError + * @throws RuntimeError + * @throws SyntaxError */ public function herbieInfo(array $context, string $template = '@snippet/herbie_info.twig'): string { @@ -76,6 +80,38 @@ private function getAlias(): array return $items; } + /** + * @param mixed $value + * @return mixed + */ + private function filterValue($value) + { + if (!is_string($value)) { + return $value; + } + + $replaceIfEquals = [$this->appPath => '/']; + foreach ($replaceIfEquals as $k => $v) { + if ($k === $value) { + $value = $v; + } + } + + $stripFromBeginning = [$this->appPath]; + foreach ($stripFromBeginning as $v) { + if (strpos($value, $v) === 0) { + $value = substr($value, strlen($v)); + } + } + + // filter emails + if (strpos($value, '@') > 0) { + $value = '~filtered~'; + } + + return $value; + } + /** * @return string[] */ @@ -97,7 +133,7 @@ private function getConfig(): array foreach ($this->config->flatten() as $key => $value) { $configs[] = [ $key, - \herbie\get_type($value), + get_type($value), $this->filterValue($value) ]; } @@ -187,13 +223,13 @@ private function getTwigGlobalsFromContext(array $context): array foreach ($context as $string => $mixed) { if (is_scalar($mixed)) { $value = $mixed; - $type = \herbie\get_type($mixed); + $type = get_type($mixed); } elseif (is_object($mixed)) { $value = get_class($mixed); $type = 'class'; } else { $value = json_encode($mixed); - $type = \herbie\get_type($mixed); + $type = get_type($mixed); } $globals[] = [$string, $value, $type]; } @@ -247,36 +283,4 @@ private function getTwigTests(): array } return $items; } - - /** - * @param mixed $value - * @return mixed - */ - private function filterValue($value) - { - if (!is_string($value)) { - return $value; - } - - $replaceIfEquals = [$this->appPath => '/']; - foreach ($replaceIfEquals as $k => $v) { - if ($k === $value) { - $value = $v; - } - } - - $stripFromBeginning = [$this->appPath]; - foreach ($stripFromBeginning as $v) { - if (strpos($value, $v) === 0) { - $value = substr($value, strlen($v)); - } - } - - // filter emails - if (strpos($value, '@') > 0) { - $value = '~filtered~'; - } - - return $value; - } } diff --git a/system/Translator.php b/system/Translator.php index fd2959cb..3a1febb4 100644 --- a/system/Translator.php +++ b/system/Translator.php @@ -4,6 +4,8 @@ namespace herbie; +use InvalidArgumentException; + final class Translator { private string $language; @@ -37,6 +39,19 @@ public function init(): self return $this; } + private function loadMessages(): void + { + foreach ($this->paths as $category => $paths) { + foreach ($paths as $path) { + $messagePath = sprintf('%s/%s.php', $path, $this->language); + if (file_exists($messagePath)) { + // NOTE this must be "require" here, not only "require_once" + $this->messages[$this->language][$category] = require $messagePath; + } + } + } + } + /** * @param array $params */ @@ -72,19 +87,6 @@ private function replacePlaceholders(string $message, array $params): string return strtr($message, $paramsWithBrackets); } - private function loadMessages(): void - { - foreach ($this->paths as $category => $paths) { - foreach ($paths as $path) { - $messagePath = sprintf('%s/%s.php', $path, $this->language); - if (file_exists($messagePath)) { - // NOTE this must be "require" here, not only "require_once" - $this->messages[$this->language][$category] = require $messagePath; - } - } - } - } - /** * @param string[]|string $path */ @@ -96,8 +98,8 @@ public function addPath(string $category, $path): void if (is_string($path)) { $path = [$path]; } elseif (!is_array($path)) { - $message = sprintf('Argument $path has to be an array or a string, %s given.', \herbie\get_type($path)); - throw new \InvalidArgumentException($message); + $message = sprintf('Argument $path has to be an array or a string, %s given.', get_type($path)); + throw new InvalidArgumentException($message); } $this->paths[$category] = array_merge($this->paths[$category], $path); } diff --git a/system/TwigRenderer.php b/system/TwigRenderer.php index bd1e9536..415b16fa 100644 --- a/system/TwigRenderer.php +++ b/system/TwigRenderer.php @@ -6,6 +6,7 @@ use herbie\events\TwigInitializedEvent; use Psr\Log\LoggerInterface; +use Twig\Environment as TwigEnvironment; use Twig\Error\LoaderError; use Twig\Error\RuntimeError; use Twig\Error\SyntaxError; @@ -15,7 +16,6 @@ use Twig\TwigFilter; use Twig\TwigFunction; use Twig\TwigTest; -use Twig\Environment as TwigEnvironment; final class TwigRenderer { @@ -65,10 +65,10 @@ public function init(): void // see \Twig\Environment default options $twigOptions = [ - 'autoescape' => $this->config->getAsString('components.twigRenderer.autoescape', 'html'), - 'cache' => $cache, - 'charset' => $this->config->getAsString('components.twigRenderer.charset', 'UTF-8'), - 'debug' => $this->config->getAsBool('components.twigRenderer.debug'), + 'autoescape' => $this->config->getAsString('components.twigRenderer.autoescape', 'html'), + 'cache' => $cache, + 'charset' => $this->config->getAsString('components.twigRenderer.charset', 'UTF-8'), + 'debug' => $this->config->getAsBool('components.twigRenderer.debug'), 'strict_variables' => $this->config->getAsBool('components.twigRenderer.strictVariables'), ]; @@ -86,54 +86,9 @@ public function init(): void $this->eventManager->dispatch(new TwigInitializedEvent($this->twig)); } - public function getTwigEnvironment(): TwigEnvironment - { - return $this->twig; - } - - /** - * @param array $context - * @throws LoaderError - * @throws RuntimeError - * @throws SyntaxError - */ - public function renderString(string $string, array $context = []): string - { - return $this->twig->render($string, $context); - } - - /** - * @param array $context - * @throws LoaderError - * @throws RuntimeError - * @throws SyntaxError - */ - public function renderTemplate(string $name, array $context = []): string - { - return $this->twig->render($name, $context); - } - - public function addFunction(TwigFunction $function): void - { - $this->twig->addFunction($function); - } - - public function addFilter(TwigFilter $filter): void - { - $this->twig->addFilter($filter); - } - - /** - * @param mixed $mixed - */ - public function addGlobal(string $name, $mixed): void - { - $this->twig->addGlobal($name, $mixed); - } - - public function addTest(TwigTest $test): void + public function isInitialized(): bool { - $this->twig->addTest($test); + return $this->initialized; } /** @@ -188,8 +143,53 @@ private function validatePaths(array $paths): array return array_values($paths); } - public function isInitialized(): bool + /** + * @param mixed $mixed + */ + public function addGlobal(string $name, $mixed): void { - return $this->initialized; + $this->twig->addGlobal($name, $mixed); + } + + public function getTwigEnvironment(): TwigEnvironment + { + return $this->twig; + } + + /** + * @param array $context + * @throws LoaderError + * @throws RuntimeError + * @throws SyntaxError + */ + public function renderString(string $string, array $context = []): string + { + return $this->twig->render($string, $context); + } + + /** + * @param array $context + * @throws LoaderError + * @throws RuntimeError + * @throws SyntaxError + */ + public function renderTemplate(string $name, array $context = []): string + { + return $this->twig->render($name, $context); + } + + public function addFunction(TwigFunction $function): void + { + $this->twig->addFunction($function); + } + + public function addFilter(TwigFilter $filter): void + { + $this->twig->addFilter($filter); + } + + public function addTest(TwigTest $test): void + { + $this->twig->addTest($test); } } diff --git a/system/TwigStringLoader.php b/system/TwigStringLoader.php index 3ff7e2d5..4af312df 100644 --- a/system/TwigStringLoader.php +++ b/system/TwigStringLoader.php @@ -21,6 +21,19 @@ public function getSourceContext(string $name): Source return new Source($name, $name); } + public function isLayoutTemplate(string $name): bool + { + $pos = strrpos($name, '.'); + if ($pos !== false) { + $length = strlen($name) - $pos - 1; + $extension = substr($name, -$length); + if (in_array($extension, ['twig', 'html'])) { + return true; + } + } + return false; + } + public function exists(string $name): bool { $bool = $this->isLayoutTemplate($name); @@ -36,17 +49,4 @@ public function isFresh(string $name, int $time): bool { return true; } - - public function isLayoutTemplate(string $name): bool - { - $pos = strrpos($name, '.'); - if ($pos !== false) { - $length = strlen($name) - $pos - 1; - $extension = substr($name, -$length); - if (in_array($extension, ['twig', 'html'])) { - return true; - } - } - return false; - } } diff --git a/system/UncaughtExceptionHandler.php b/system/UncaughtExceptionHandler.php index 945b7fd7..8c3558b3 100644 --- a/system/UncaughtExceptionHandler.php +++ b/system/UncaughtExceptionHandler.php @@ -4,9 +4,11 @@ namespace herbie; +use Throwable; + final class UncaughtExceptionHandler { - public function __invoke(\Throwable $exception): void + public function __invoke(Throwable $exception): void { if (!headers_sent()) { header("HTTP/1.1 " . $exception->getCode()); diff --git a/system/UrlManager.php b/system/UrlManager.php index dbc21c81..e5cd6b79 100644 --- a/system/UrlManager.php +++ b/system/UrlManager.php @@ -5,6 +5,7 @@ namespace herbie; use Psr\Http\Message\ServerRequestInterface; +use UnexpectedValueException; final class UrlManager { @@ -26,6 +27,13 @@ public function __construct(ServerRequestInterface $serverRequest, array $option $this->parsedRequest = null; } + public function createAbsoluteUrl(string $route): string + { + $path = $this->createUrl($route); + $absUrl = $this->serverRequest->getUri()->withPath($path); + return (string)$absUrl; + } + public function createUrl(string $route): string { // TODO add support for following routes @@ -42,13 +50,6 @@ public function createUrl(string $route): string return $this->filterUrl($url); } - public function createAbsoluteUrl(string $route): string - { - $path = $this->createUrl($route); - $absUrl = $this->serverRequest->getUri()->withPath($path); - return (string)$absUrl; - } - /** * Filters a generated URL. * @param string $url The URL. @@ -78,7 +79,7 @@ public function parseRequest(): array $route = $this->cleanPath($path); foreach ($this->rules as $rule) { if (count($rule) < 2) { - throw new \UnexpectedValueException(sprintf('Invalid rule %s', $rule[0])); + throw new UnexpectedValueException(sprintf('Invalid rule %s', $rule[0])); } $constraints = $rule[2] ?? []; $regex = $this->getRegex($rule[0], $constraints); diff --git a/system/Yaml.php b/system/Yaml.php index 7c67a684..2c0a8f17 100644 --- a/system/Yaml.php +++ b/system/Yaml.php @@ -11,18 +11,18 @@ */ final class Yaml { - public static function parse(string $input): array - { - $parsed = sfYaml::parse($input); - return (array)$parsed; - } - public static function parseFile(string $file): array { $input = file_read($file); return self::parse($input); } + public static function parse(string $input): array + { + $parsed = sfYaml::parse($input); + return (array)$parsed; + } + public static function dump(array $array): string { return sfYaml::dump($array, 100); diff --git a/system/YamlDataRepository.php b/system/YamlDataRepository.php index 70712a72..d6ae431e 100644 --- a/system/YamlDataRepository.php +++ b/system/YamlDataRepository.php @@ -37,15 +37,6 @@ public function load(string $name): array return $this->parseDataFile($dataFiles[$name]); } - public function loadAll(): array - { - $data = []; - foreach ($this->scanDataDir() as $name => $dataFile) { - $data[$name] = $this->parseDataFile($dataFile); - } - return $data; - } - private function scanDataDir(): array { $dataFiles = []; @@ -77,4 +68,13 @@ private function parseDataFile(string $filepath): array $yaml = file_read($filepath); return Yaml::parse($yaml); } + + public function loadAll(): array + { + $data = []; + foreach ($this->scanDataDir() as $name => $dataFile) { + $data[$name] = $this->parseDataFile($dataFile); + } + return $data; + } } diff --git a/system/events/ContentRenderedEvent.php b/system/events/ContentRenderedEvent.php index f0776eac..dd2b7e1b 100644 --- a/system/events/ContentRenderedEvent.php +++ b/system/events/ContentRenderedEvent.php @@ -28,7 +28,7 @@ public function getSegments(): array } /** - * @param array $segments + * @param array $segments */ public function setSegments(array $segments): void { diff --git a/system/functions.php b/system/functions.php index af41e57e..65ae1dce 100644 --- a/system/functions.php +++ b/system/functions.php @@ -6,9 +6,18 @@ use Closure; use Composer\InstalledVersions; +use Psr\Container\ContainerExceptionInterface; use Psr\Container\ContainerInterface; +use Psr\Container\NotFoundExceptionInterface; +use ReflectionClass; +use ReflectionException; use ReflectionFunction; use ReflectionNamedType; +use RuntimeException; +use Throwable; +use UnexpectedValueException; + +use function gettype; /** * @throws SystemException @@ -64,9 +73,9 @@ function str_untrailing_slash(string $string): string } /** - * @param \Throwable $exception + * @param Throwable $exception */ -function render_exception(\Throwable $exception): string +function render_exception(Throwable $exception): string { if (Application::isDebug()) { $format = "%s [%s] in %s on line %s\n\n%s\n\nStack trace:\n%s"; @@ -134,13 +143,13 @@ function load_plugin_config(string $path, string $pluginLocation, ?callable $pro load_php_config($path, $processor) ); if (!isset($config['apiVersion'])) { - throw new \UnexpectedValueException(sprintf('Required config "apiVersion" is missing in %s', $path)); + throw new UnexpectedValueException(sprintf('Required config "apiVersion" is missing in %s', $path)); } if (!isset($config['pluginName'])) { - throw new \UnexpectedValueException(sprintf('Required config "pluginName" is missing in %s', $path)); + throw new UnexpectedValueException(sprintf('Required config "pluginName" is missing in %s', $path)); } if (!isset($config['pluginPath'])) { - throw new \UnexpectedValueException(sprintf('Required config "pluginPath" is missing in %s', $path)); + throw new UnexpectedValueException(sprintf('Required config "pluginPath" is missing in %s', $path)); } return $config; } @@ -321,9 +330,9 @@ function get_callable_name($callable): array case is_string($callable): return ['function', $callable]; case is_array($callable) && is_object($callable[0]): - return ['method', get_class($callable[0]) . '->' . $callable[1]]; + return ['method', get_class($callable[0]) . '->' . $callable[1]]; case is_array($callable): - return ['static', $callable[0] . '::' . $callable[1]]; + return ['static', $callable[0] . '::' . $callable[1]]; case $callable instanceof Closure: try { $reflectionClosure = new ReflectionFunction($callable); @@ -331,7 +340,7 @@ function get_callable_name($callable): array $class = $reflectionClosure->getClosureScopeClass(); $className = $class ? $class->getName() : null; return ['closure', $className ? $className . '--' . $closureName : $closureName]; - } catch (\ReflectionException $e) { + } catch (ReflectionException $e) { return ['unknown', '']; } case is_object($callable): @@ -347,13 +356,13 @@ function get_callable_name($callable): array /** * @param class-string $pluginClassName * @return array - * @throws \Psr\Container\ContainerExceptionInterface - * @throws \Psr\Container\NotFoundExceptionInterface - * @throws \ReflectionException + * @throws ContainerExceptionInterface + * @throws NotFoundExceptionInterface + * @throws ReflectionException */ function get_constructor_params_to_inject(string $pluginClassName, ContainerInterface $container): array { - $reflectedClass = new \ReflectionClass($pluginClassName); + $reflectedClass = new ReflectionClass($pluginClassName); $constructor = $reflectedClass->getConstructor(); if (!$constructor) { return []; @@ -401,7 +410,7 @@ function file_read(string $path): string } if (false === $content) { - throw new \RuntimeException($error); + throw new RuntimeException($error); } return $content; @@ -478,7 +487,7 @@ function array_is_assoc(array $array): bool function get_type(mixed $value): string { - $type = \gettype($value); + $type = gettype($value); // for historical reasons "double" is returned in case of a float, and not simply "float" // see https://www.php.net/manual/en/function.gettype if ($type === 'double') { diff --git a/tests/_data/site/extend/commands/custom1.php b/tests/_data/site/extend/commands/custom1.php index c9ae6177..180b3f34 100644 --- a/tests/_data/site/extend/commands/custom1.php +++ b/tests/_data/site/extend/commands/custom1.php @@ -16,8 +16,7 @@ class CustomCommand extends Command protected function configure(): void { $this - ->setHelp('This command does nothing.') - ; + ->setHelp('This command does nothing.'); } protected function execute(InputInterface $input, OutputInterface $output): int diff --git a/tests/_data/site/extend/events/twig_initialized.php b/tests/_data/site/extend/events/twig_initialized.php index 8963adf6..95ae08fd 100644 --- a/tests/_data/site/extend/events/twig_initialized.php +++ b/tests/_data/site/extend/events/twig_initialized.php @@ -7,8 +7,13 @@ use herbie\events\TwigInitializedEvent; use Twig\TwigFilter; -return [TwigInitializedEvent::class, function (TwigInitializedEvent $event): void { - $event->getEnvironment()->addFilter(new TwigFilter('my_filter2', function (string $content): string { - return $content . ' My Filter 2'; - })); -}]; +return [ + TwigInitializedEvent::class, + function (TwigInitializedEvent $event): void { + $event->getEnvironment()->addFilter( + new TwigFilter('my_filter2', function (string $content): string { + return $content . ' My Filter 2'; + }) + ); + } +]; diff --git a/tests/_data/site/extend/filters/layout.php b/tests/_data/site/extend/filters/layout.php index 0190264c..3f64a0d5 100644 --- a/tests/_data/site/extend/filters/layout.php +++ b/tests/_data/site/extend/filters/layout.php @@ -6,13 +6,16 @@ use herbie\events\RenderLayoutEvent; -return [RenderLayoutEvent::class, function (RenderLayoutEvent $event): void { - $content = str_replace( - '', - '