From 6d315bb4206b30744ad5acaebb4cb7e7c14810a1 Mon Sep 17 00:00:00 2001 From: Alexander Schranz Date: Tue, 20 Sep 2022 13:32:00 +0200 Subject: [PATCH 1/7] Make plates engine service available Signed-off-by: Alexander Schranz --- src/ConfigProvider.php | 2 ++ src/PlatesEngineFactory.php | 22 ++++++++++++++++++++ src/PlatesRendererFactory.php | 39 ++++++++++++----------------------- 3 files changed, 37 insertions(+), 26 deletions(-) diff --git a/src/ConfigProvider.php b/src/ConfigProvider.php index 7e87a43..0e6df2b 100644 --- a/src/ConfigProvider.php +++ b/src/ConfigProvider.php @@ -5,6 +5,7 @@ namespace Mezzio\Plates; use Mezzio\Template\TemplateRendererInterface; +use League\Plates\Engine as PlatesEngine; class ConfigProvider { @@ -27,6 +28,7 @@ public function getDependencies(): array 'Zend\Expressive\Plates\PlatesRenderer' => PlatesRenderer::class, ], 'factories' => [ + PlatesEngine::class => PlatesEngineFactory::class, PlatesRenderer::class => PlatesRendererFactory::class, ], ]; diff --git a/src/PlatesEngineFactory.php b/src/PlatesEngineFactory.php index 3301b7b..b31f5f0 100644 --- a/src/PlatesEngineFactory.php +++ b/src/PlatesEngineFactory.php @@ -56,6 +56,28 @@ public function __invoke(ContainerInterface $container): PlatesEngine $this->injectExtensions($container, $engine, $config['extensions']); } + $config = $container->has('config') ? $container->get('config') : []; + $config = $config['templates'] ?? []; + + // Set file extension + if (isset($config['extension'])) { + $engine->setFileExtension($config['extension']); + } + + // Add template paths + $allPaths = isset($config['paths']) && is_array($config['paths']) ? $config['paths'] : []; + foreach ($allPaths as $namespace => $paths) { + $namespace = is_numeric($namespace) ? null : $namespace; + foreach ((array) $paths as $path) { + if (! $namespace && ! $engine->getDirectory()) { + $engine->setDirectory($path); + continue; + } + + $engine->addFolder($path, $namespace, true); + } + } + return $engine; } diff --git a/src/PlatesRendererFactory.php b/src/PlatesRendererFactory.php index e18b59b..b63794f 100644 --- a/src/PlatesRendererFactory.php +++ b/src/PlatesRendererFactory.php @@ -36,30 +36,9 @@ class PlatesRendererFactory { public function __invoke(ContainerInterface $container): PlatesRenderer { - $config = $container->has('config') ? $container->get('config') : []; - $config = $config['templates'] ?? []; + $engine = $this->getEngine($container); - // Create the engine instance: - $engine = $this->createEngine($container); - - // Set file extension - if (isset($config['extension'])) { - $engine->setFileExtension($config['extension']); - } - - // Inject engine - $plates = new PlatesRenderer($engine); - - // Add template paths - $allPaths = isset($config['paths']) && is_array($config['paths']) ? $config['paths'] : []; - foreach ($allPaths as $namespace => $paths) { - $namespace = is_numeric($namespace) ? null : $namespace; - foreach ((array) $paths as $path) { - $plates->addPath($path, $namespace); - } - } - - return $plates; + return new PlatesRenderer($engine); } /** @@ -70,13 +49,21 @@ public function __invoke(ContainerInterface $container): PlatesRenderer * Otherwise, invokes the PlatesEngineFactory with the $container to create * and return the instance. */ - private function createEngine(ContainerInterface $container): PlatesEngine + private function getEngine(ContainerInterface $container): PlatesEngine { if ($container->has(PlatesEngine::class)) { return $container->get(PlatesEngine::class); } - $engineFactory = new PlatesEngineFactory(); - return $engineFactory($container); + trigger_error(sprintf( + '%s now expects you to register the factory %s for the service %s; ' + . 'please update your dependency configuration.', + self::class, + PlatesEngineFactory::class, + PlatesEngine::class + ), E_USER_DEPRECATED); + + $factory = new PlatesEngineFactory(); + return $factory($container); } } From 61c332e5b3f79357cc1315cb376b511afa17b37f Mon Sep 17 00:00:00 2001 From: Alexander Schranz Date: Tue, 20 Sep 2022 13:42:29 +0200 Subject: [PATCH 2/7] Drop part when engine is not available Signed-off-by: Alexander Schranz --- src/PlatesRendererFactory.php | 29 ++--------------------------- 1 file changed, 2 insertions(+), 27 deletions(-) diff --git a/src/PlatesRendererFactory.php b/src/PlatesRendererFactory.php index b63794f..8fa7d10 100644 --- a/src/PlatesRendererFactory.php +++ b/src/PlatesRendererFactory.php @@ -36,34 +36,9 @@ class PlatesRendererFactory { public function __invoke(ContainerInterface $container): PlatesRenderer { - $engine = $this->getEngine($container); + /** @var PlatesEngine $engine */ + $engine = $container->get(PlatesEngine::class); return new PlatesRenderer($engine); } - - /** - * Create and return a Plates Engine instance. - * - * If the container has the League\Plates\Engine service, returns it. - * - * Otherwise, invokes the PlatesEngineFactory with the $container to create - * and return the instance. - */ - private function getEngine(ContainerInterface $container): PlatesEngine - { - if ($container->has(PlatesEngine::class)) { - return $container->get(PlatesEngine::class); - } - - trigger_error(sprintf( - '%s now expects you to register the factory %s for the service %s; ' - . 'please update your dependency configuration.', - self::class, - PlatesEngineFactory::class, - PlatesEngine::class - ), E_USER_DEPRECATED); - - $factory = new PlatesEngineFactory(); - return $factory($container); - } } From f94962abd2f8092e63d9102ff555bc485f1a819b Mon Sep 17 00:00:00 2001 From: Alexander Schranz Date: Tue, 20 Sep 2022 14:11:14 +0200 Subject: [PATCH 3/7] Move some PlatesRendererFactory tests to PlatesEngineFactory tests Signed-off-by: Alexander Schranz --- src/PlatesEngineFactory.php | 8 ++++- test/PlatesEngineFactoryTest.php | 46 +++++++++++++++++++++++++++ test/PlatesRendererFactoryTest.php | 51 +++--------------------------- 3 files changed, 57 insertions(+), 48 deletions(-) diff --git a/src/PlatesEngineFactory.php b/src/PlatesEngineFactory.php index b31f5f0..e47ee5a 100644 --- a/src/PlatesEngineFactory.php +++ b/src/PlatesEngineFactory.php @@ -66,6 +66,7 @@ public function __invoke(ContainerInterface $container): PlatesEngine // Add template paths $allPaths = isset($config['paths']) && is_array($config['paths']) ? $config['paths'] : []; + foreach ($allPaths as $namespace => $paths) { $namespace = is_numeric($namespace) ? null : $namespace; foreach ((array) $paths as $path) { @@ -74,7 +75,12 @@ public function __invoke(ContainerInterface $container): PlatesEngine continue; } - $engine->addFolder($path, $namespace, true); + if (! $namespace) { + trigger_error('Cannot add duplicate un-namespaced path in Plates template adapter', E_USER_WARNING); + continue; + } + + $engine->addFolder($namespace, $path, true); } } diff --git a/test/PlatesEngineFactoryTest.php b/test/PlatesEngineFactoryTest.php index 17cad80..838ac6a 100644 --- a/test/PlatesEngineFactoryTest.php +++ b/test/PlatesEngineFactoryTest.php @@ -6,12 +6,14 @@ use League\Plates\Engine as PlatesEngine; use League\Plates\Extension\ExtensionInterface; +use LogicException; use Mezzio\Helper\ServerUrlHelper; use Mezzio\Helper\UrlHelper; use Mezzio\Plates\Exception\InvalidExtensionException; use Mezzio\Plates\Extension\EscaperExtension; use Mezzio\Plates\Extension\UrlExtension; use Mezzio\Plates\PlatesEngineFactory; +use Mezzio\Plates\PlatesRendererFactory; use PHPUnit\Framework\TestCase; use Prophecy\Argument; use Prophecy\PhpUnit\ProphecyTrait; @@ -222,6 +224,50 @@ public function testFactoryRaisesExceptionWhenNonServiceClassIsAnInvalidExtensio $factory($this->container->reveal()); } + public function testExceptionIsRaisedIfMultiplePathsSpecifyDefaultNamespace(): void + { + $config = [ + 'templates' => [ + 'paths' => [ + 0 => __DIR__ . '/TestAsset/bar', + 1 => __DIR__ . '/TestAsset/baz', + ], + ], + ]; + $this->container->has('config')->willReturn(true); + $this->container->get('config')->willReturn($config); + $factory = new PlatesEngineFactory(); + + // phpcs:ignore WebimpressCodingStandard.NamingConventions.ValidVariableName.NotCamelCaps + set_error_handler(function (int $_errno, string $_errstr): void { + $this->errorCaught = true; + }, E_USER_WARNING); + $factory($this->container->reveal()); + restore_error_handler(); + $this->assertTrue($this->errorCaught, 'Did not detect duplicate path for default namespace'); + } + + public function testExceptionIsRaisedIfMultiplePathsInSameNamespace(): void + { + $config = [ + 'templates' => [ + 'paths' => [ + 'bar' => [ + __DIR__ . '/TestAsset/baz', + __DIR__ . '/TestAsset/bat', + ], + ], + ], + ]; + $this->container->has('config')->willReturn(true); + $this->container->get('config')->willReturn($config); + $factory = new PlatesEngineFactory(); + + $this->expectException(LogicException::class); + $this->expectExceptionMessage('already being used'); + $factory($this->container->reveal()); + } + public function provideHelpersToUnregister(): array { return [ diff --git a/test/PlatesRendererFactoryTest.php b/test/PlatesRendererFactoryTest.php index 1d1eccd..ee9cfb7 100644 --- a/test/PlatesRendererFactoryTest.php +++ b/test/PlatesRendererFactoryTest.php @@ -11,6 +11,7 @@ use Mezzio\Helper\UrlHelper; use Mezzio\Plates\Extension\EscaperExtension; use Mezzio\Plates\Extension\UrlExtension; +use Mezzio\Plates\PlatesEngineFactory; use Mezzio\Plates\PlatesRenderer; use Mezzio\Plates\PlatesRendererFactory; use Mezzio\Template\TemplatePath; @@ -44,7 +45,6 @@ public function setUp(): void public function configureEngineService(): void { - $this->container->has(PlatesEngine::class)->willReturn(false); $this->container->has(UrlExtension::class)->willReturn(false); $this->container->has('Zend\Expressive\Plates\Extension\UrlExtension')->willReturn(false); $this->container->has(EscaperExtension::class)->willReturn(false); @@ -53,6 +53,9 @@ public function configureEngineService(): void $this->container->has(ServerUrlHelper::class)->willReturn(true); $this->container->get(UrlHelper::class)->willReturn($this->prophesize(UrlHelper::class)->reveal()); $this->container->get(ServerUrlHelper::class)->willReturn($this->prophesize(ServerUrlHelper::class)->reveal()); + + $engineFactory = new PlatesEngineFactory(); + $this->container->get(PlatesEngine::class)->willReturn($engineFactory($this->container->reveal())); } public function fetchPlatesEngine(PlatesRenderer $plates): Engine @@ -167,52 +170,6 @@ public function testConfiguresTemplateSuffix(): void $this->assertEquals($config['templates']['extension'], $engine->getFileExtension()); } - public function testExceptionIsRaisedIfMultiplePathsSpecifyDefaultNamespace(): void - { - $config = [ - 'templates' => [ - 'paths' => [ - 0 => __DIR__ . '/TestAsset/bar', - 1 => __DIR__ . '/TestAsset/baz', - ], - ], - ]; - $this->container->has('config')->willReturn(true); - $this->container->get('config')->willReturn($config); - $this->configureEngineService(); - $factory = new PlatesRendererFactory(); - - // phpcs:ignore WebimpressCodingStandard.NamingConventions.ValidVariableName.NotCamelCaps - set_error_handler(function (int $_errno, string $_errstr): void { - $this->errorCaught = true; - }, E_USER_WARNING); - $factory($this->container->reveal()); - restore_error_handler(); - $this->assertTrue($this->errorCaught, 'Did not detect duplicate path for default namespace'); - } - - public function testExceptionIsRaisedIfMultiplePathsInSameNamespace(): void - { - $config = [ - 'templates' => [ - 'paths' => [ - 'bar' => [ - __DIR__ . '/TestAsset/baz', - __DIR__ . '/TestAsset/bat', - ], - ], - ], - ]; - $this->container->has('config')->willReturn(true); - $this->container->get('config')->willReturn($config); - $this->configureEngineService(); - $factory = new PlatesRendererFactory(); - - $this->expectException(LogicException::class); - $this->expectExceptionMessage('already being used'); - $factory($this->container->reveal()); - } - public function testConfiguresPaths(): void { $config = [ From 6c4c47b82f98e169d05418820bf78db53fe05f57 Mon Sep 17 00:00:00 2001 From: Alexander Schranz Date: Tue, 20 Sep 2022 14:25:55 +0200 Subject: [PATCH 4/7] Fix code style Signed-off-by: Alexander Schranz --- src/ConfigProvider.php | 4 ++-- src/PlatesEngineFactory.php | 9 ++++++--- src/PlatesRenderer.php | 5 ++--- src/PlatesRendererFactory.php | 3 --- test/PlatesEngineFactoryTest.php | 5 ++++- test/PlatesRendererFactoryTest.php | 5 ----- 6 files changed, 14 insertions(+), 17 deletions(-) diff --git a/src/ConfigProvider.php b/src/ConfigProvider.php index 0e6df2b..f411f2a 100644 --- a/src/ConfigProvider.php +++ b/src/ConfigProvider.php @@ -4,8 +4,8 @@ namespace Mezzio\Plates; -use Mezzio\Template\TemplateRendererInterface; use League\Plates\Engine as PlatesEngine; +use Mezzio\Template\TemplateRendererInterface; class ConfigProvider { @@ -28,7 +28,7 @@ public function getDependencies(): array 'Zend\Expressive\Plates\PlatesRenderer' => PlatesRenderer::class, ], 'factories' => [ - PlatesEngine::class => PlatesEngineFactory::class, + PlatesEngine::class => PlatesEngineFactory::class, PlatesRenderer::class => PlatesRendererFactory::class, ], ]; diff --git a/src/PlatesEngineFactory.php b/src/PlatesEngineFactory.php index e47ee5a..2841196 100644 --- a/src/PlatesEngineFactory.php +++ b/src/PlatesEngineFactory.php @@ -10,12 +10,15 @@ use Psr\Container\ContainerInterface; use function class_exists; -use function get_class; use function gettype; use function is_array; +use function is_numeric; use function is_object; use function is_string; use function sprintf; +use function trigger_error; + +use const E_USER_WARNING; /** * Create and return a Plates engine instance. @@ -170,7 +173,7 @@ private function injectExtension(ContainerInterface $container, PlatesEngine $en throw new Exception\InvalidExtensionException(sprintf( '%s expects extension instances, service names, or class names; received %s', self::class, - is_object($extension) ? get_class($extension) : gettype($extension) + is_object($extension) ? $extension::class : gettype($extension) )); } @@ -191,7 +194,7 @@ private function injectExtension(ContainerInterface $container, PlatesEngine $en '%s expects extension services to implement %s ; received %s', self::class, ExtensionInterface::class, - is_object($extension) ? get_class($extension) : gettype($extension) + is_object($extension) ? $extension::class : gettype($extension) )); } diff --git a/src/PlatesRenderer.php b/src/PlatesRenderer.php index bb13084..234cbc5 100644 --- a/src/PlatesRenderer.php +++ b/src/PlatesRenderer.php @@ -12,7 +12,6 @@ use Mezzio\Template\TemplateRendererInterface; use ReflectionProperty; -use function get_class; use function gettype; use function is_object; use function is_string; @@ -95,14 +94,14 @@ public function addDefaultParam(string $templateName, string $param, $value): vo if (! is_string($templateName) || empty($templateName)) { throw new Exception\InvalidArgumentException(sprintf( '$templateName must be a non-empty string; received %s', - is_object($templateName) ? get_class($templateName) : gettype($templateName) + is_object($templateName) ? $templateName::class : gettype($templateName) )); } if (! is_string($param) || empty($param)) { throw new Exception\InvalidArgumentException(sprintf( '$param must be a non-empty string; received %s', - is_object($param) ? get_class($param) : gettype($param) + is_object($param) ? $param::class : gettype($param) )); } diff --git a/src/PlatesRendererFactory.php b/src/PlatesRendererFactory.php index 8fa7d10..137311a 100644 --- a/src/PlatesRendererFactory.php +++ b/src/PlatesRendererFactory.php @@ -7,9 +7,6 @@ use League\Plates\Engine as PlatesEngine; use Psr\Container\ContainerInterface; -use function is_array; -use function is_numeric; - /** * Create and return a Plates template instance. * diff --git a/test/PlatesEngineFactoryTest.php b/test/PlatesEngineFactoryTest.php index 838ac6a..14574c3 100644 --- a/test/PlatesEngineFactoryTest.php +++ b/test/PlatesEngineFactoryTest.php @@ -13,7 +13,6 @@ use Mezzio\Plates\Extension\EscaperExtension; use Mezzio\Plates\Extension\UrlExtension; use Mezzio\Plates\PlatesEngineFactory; -use Mezzio\Plates\PlatesRendererFactory; use PHPUnit\Framework\TestCase; use Prophecy\Argument; use Prophecy\PhpUnit\ProphecyTrait; @@ -23,6 +22,10 @@ use ZendTest\Expressive\Plates\TestAsset\TestExtension; use function is_string; +use function restore_error_handler; +use function set_error_handler; + +use const E_USER_WARNING; class PlatesEngineFactoryTest extends TestCase { diff --git a/test/PlatesRendererFactoryTest.php b/test/PlatesRendererFactoryTest.php index ee9cfb7..9a6a438 100644 --- a/test/PlatesRendererFactoryTest.php +++ b/test/PlatesRendererFactoryTest.php @@ -6,7 +6,6 @@ use League\Plates\Engine; use League\Plates\Engine as PlatesEngine; -use LogicException; use Mezzio\Helper\ServerUrlHelper; use Mezzio\Helper\UrlHelper; use Mezzio\Plates\Extension\EscaperExtension; @@ -22,12 +21,8 @@ use ReflectionClass; use ReflectionProperty; -use function restore_error_handler; -use function set_error_handler; use function sprintf; -use const E_USER_WARNING; - class PlatesRendererFactoryTest extends TestCase { use ProphecyTrait; From ed8d13a43e0a0e8e06d3b77074c1bfeee84009f5 Mon Sep 17 00:00:00 2001 From: Alexander Schranz Date: Tue, 20 Sep 2022 14:31:02 +0200 Subject: [PATCH 5/7] Update psalm baseline Signed-off-by: Alexander Schranz --- psalm-baseline.xml | 32 +++----------------------------- 1 file changed, 3 insertions(+), 29 deletions(-) diff --git a/psalm-baseline.xml b/psalm-baseline.xml index 5d18397..334dc6d 100644 --- a/psalm-baseline.xml +++ b/psalm-baseline.xml @@ -56,31 +56,6 @@ is_object($templateName) - - - $config['extension'] - $namespace - $path - - - $config['templates'] - - - $allPaths - $config - $config - $namespace - $namespace - $path - $paths - - - PlatesEngine - - - $container->get(PlatesEngine::class) - - assertIsArray @@ -295,8 +270,7 @@ - - + $this->container->reveal() $this->container->reveal() $this->container->reveal() @@ -307,7 +281,7 @@ Engine - + willReturn willReturn willReturn @@ -336,7 +310,7 @@ $namespace ?: null - + get get get From 47d98a8cf2b5a014770d2ca6d96722c2d000a3e2 Mon Sep 17 00:00:00 2001 From: Alexander Schranz Date: Tue, 20 Sep 2022 14:42:08 +0200 Subject: [PATCH 6/7] Use get_class($var) instead of $var::class for php 7.4 support Signed-off-by: Alexander Schranz --- src/PlatesEngineFactory.php | 5 +++-- src/PlatesRenderer.php | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/PlatesEngineFactory.php b/src/PlatesEngineFactory.php index 2841196..628fe1f 100644 --- a/src/PlatesEngineFactory.php +++ b/src/PlatesEngineFactory.php @@ -10,6 +10,7 @@ use Psr\Container\ContainerInterface; use function class_exists; +use function get_class; use function gettype; use function is_array; use function is_numeric; @@ -173,7 +174,7 @@ private function injectExtension(ContainerInterface $container, PlatesEngine $en throw new Exception\InvalidExtensionException(sprintf( '%s expects extension instances, service names, or class names; received %s', self::class, - is_object($extension) ? $extension::class : gettype($extension) + is_object($extension) ? get_class($extension) : gettype($extension) )); } @@ -194,7 +195,7 @@ private function injectExtension(ContainerInterface $container, PlatesEngine $en '%s expects extension services to implement %s ; received %s', self::class, ExtensionInterface::class, - is_object($extension) ? $extension::class : gettype($extension) + is_object($extension) ? get_class($extension) : gettype($extension) )); } diff --git a/src/PlatesRenderer.php b/src/PlatesRenderer.php index 234cbc5..bb13084 100644 --- a/src/PlatesRenderer.php +++ b/src/PlatesRenderer.php @@ -12,6 +12,7 @@ use Mezzio\Template\TemplateRendererInterface; use ReflectionProperty; +use function get_class; use function gettype; use function is_object; use function is_string; @@ -94,14 +95,14 @@ public function addDefaultParam(string $templateName, string $param, $value): vo if (! is_string($templateName) || empty($templateName)) { throw new Exception\InvalidArgumentException(sprintf( '$templateName must be a non-empty string; received %s', - is_object($templateName) ? $templateName::class : gettype($templateName) + is_object($templateName) ? get_class($templateName) : gettype($templateName) )); } if (! is_string($param) || empty($param)) { throw new Exception\InvalidArgumentException(sprintf( '$param must be a non-empty string; received %s', - is_object($param) ? $param::class : gettype($param) + is_object($param) ? get_class($param) : gettype($param) )); } From 32e7c510736c7eda55864cfd98b73f98b99513b6 Mon Sep 17 00:00:00 2001 From: Marco Pivetta Date: Tue, 20 Sep 2022 17:20:28 +0200 Subject: [PATCH 7/7] Re-generated psalm baseline from a clean PHP 7.4 environment Used: ```sh docker run --rm -ti -v $(pwd):/app -w /app php:7.4 vendor/bin/psalm --no-cache --set-baseline=psalm-baseline.xml ``` --- psalm-baseline.xml | 53 ++++++++++++++++++++++++++++++++-------------- 1 file changed, 37 insertions(+), 16 deletions(-) diff --git a/psalm-baseline.xml b/psalm-baseline.xml index 334dc6d..e95de48 100644 --- a/psalm-baseline.xml +++ b/psalm-baseline.xml @@ -23,19 +23,31 @@ new $extension() - + + $config['extension'] $container->get(Extension\EscaperExtension::class) $container->get(Extension\UrlExtension::class) $extension + $namespace + $path + $path - + $config['plates'] + $config['templates'] - + + $allPaths + $config + $config $config $config $extension $extension + $namespace + $namespace + $path + $paths @@ -188,7 +200,8 @@ - + + $helper $this->container->reveal() $this->container->reveal() @@ -197,6 +210,8 @@ $this->container->reveal() $this->container->reveal() $this->container->reveal() + $this->container->reveal() + $this->container->reveal() TestExtension::class \ZendTest\Expressive\Plates\stdClass::class @@ -207,7 +222,11 @@ array array - + + willReturn + willReturn + willReturn + willReturn willReturn willReturn willReturn @@ -232,7 +251,7 @@ willReturn willReturn - + get get get @@ -240,6 +259,9 @@ get get get + get + get + has has has has @@ -256,6 +278,9 @@ has has has + has + reveal + reveal reveal reveal reveal @@ -268,6 +293,12 @@ TestExtension \ZendTest\Expressive\Plates\stdClass + + $this->errorCaught + + + $this->errorCaught + @@ -276,7 +307,6 @@ $this->container->reveal() $this->container->reveal() $this->container->reveal() - $this->container->reveal() Engine @@ -299,10 +329,6 @@ willReturn willReturn willReturn - willReturn - willReturn - willReturn - willReturn $r->getValue($plates) @@ -317,8 +343,6 @@ get get get - get - has has has has @@ -330,9 +354,6 @@ has has has - has - has - reveal reveal reveal reveal