From f029f017254ccaea3e72748a42ce38dc42c218ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20Andrieu?= Date: Thu, 7 Jun 2018 16:16:14 +0200 Subject: [PATCH 1/5] Registered all namespaces in ModuleTemplateLoader class --- .../Resources/config/services/services.yml | 10 ++++- .../Twig/Locator/ModuleTemplateLoader.php | 41 +++++++++++++++++-- 2 files changed, 47 insertions(+), 4 deletions(-) diff --git a/src/PrestaShopBundle/Resources/config/services/services.yml b/src/PrestaShopBundle/Resources/config/services/services.yml index ff3cea738ea2d..4b0d2d18e649c 100644 --- a/src/PrestaShopBundle/Resources/config/services/services.yml +++ b/src/PrestaShopBundle/Resources/config/services/services.yml @@ -325,6 +325,14 @@ services: prestashop.twig.modules.loader: class: 'PrestaShopBundle\Twig\Locator\ModuleTemplateLoader' - arguments: ['@=service("prestashop.module_kernel.repository").getActiveModulesPaths()'] + arguments: + - '@=service("prestashop.module_kernel.repository").getActiveModulesPaths()' + - ~ + - + 'PrestaShop': '' + 'Product': '/Admin/Product' + 'Twig': '/Admin/TwigTemplateForm' + 'AdvancedParameters': '/Admin/Configure/AdvancedParameters' + 'ShopParameters': '/Admin/Configure/ShopParameters' tags: - { name: twig.loader, priority: 1} diff --git a/src/PrestaShopBundle/Twig/Locator/ModuleTemplateLoader.php b/src/PrestaShopBundle/Twig/Locator/ModuleTemplateLoader.php index 6a4ca58c1fd0b..ebcd52b62afdf 100644 --- a/src/PrestaShopBundle/Twig/Locator/ModuleTemplateLoader.php +++ b/src/PrestaShopBundle/Twig/Locator/ModuleTemplateLoader.php @@ -38,12 +38,18 @@ class ModuleTemplateLoader extends FilesystemLoader */ private $rootPath; + /** + * @var array $registeredPaths The list of Paths and namespaces registered in configuration. + * @see app/config/config.yml + */ + private $registeredPaths; + /** * @param string|array $paths A path or an array of paths where to look for templates * @param string|null $rootPath The root path common to all relative paths (null for getcwd()) - * @param string|null $namespace A path namespace + * @param array $namespaces A collection of path namespaces with namespace names. */ - public function __construct($paths = array(), $rootPath = null, $namespace = 'PrestaShop') + public function __construct($paths = array(), $rootPath = null, array $namespaces) { $this->rootPath = (null === $rootPath ? getcwd() : $rootPath).DIRECTORY_SEPARATOR; if (false !== $realPath = realpath($rootPath)) { @@ -51,14 +57,43 @@ public function __construct($paths = array(), $rootPath = null, $namespace = 'Pr } if ($paths) { + $this->registerNamespacesFromConfig($paths, $namespaces); + } + } + + /** + * Register namespaces in module and link them to the right paths. + * @param $paths + * @param array $namespaces + */ + private function registerNamespacesFromConfig($paths, array $namespaces) + { + foreach($namespaces as $namespace => $namespacePath) { $templatePaths = array(); foreach ($paths as $path) { - if (is_dir($dir = $path . '/views/'. $namespace)) { + if (is_dir($dir = $path . '/views/PrestaShop/' . $namespacePath)) { $templatePaths[] = $dir; } } $this->setPaths($templatePaths, $namespace); } } + + /** + * @return array + */ + public function getRegisteredPaths() + { + return $this->registeredPaths; + } + + /** + * @param array $registeredPaths + */ + public function setRegisteredPaths($registeredPaths) + { + dump($registeredPaths); + $this->registeredPaths = $registeredPaths; + } } From fd2284a5e507532a51d681dc96256615bebfd472 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20Andrieu?= Date: Thu, 7 Jun 2018 17:06:09 +0200 Subject: [PATCH 2/5] Allow override of a product line row only --- .../Resources/config/services/services.yml | 3 +- .../Product/CatalogPage/Lists/list.html.twig | 137 +++++++++--------- .../Twig/Locator/ModuleTemplateLoader.php | 27 +--- 3 files changed, 72 insertions(+), 95 deletions(-) diff --git a/src/PrestaShopBundle/Resources/config/services/services.yml b/src/PrestaShopBundle/Resources/config/services/services.yml index 4b0d2d18e649c..6091a312ac72d 100644 --- a/src/PrestaShopBundle/Resources/config/services/services.yml +++ b/src/PrestaShopBundle/Resources/config/services/services.yml @@ -326,13 +326,12 @@ services: prestashop.twig.modules.loader: class: 'PrestaShopBundle\Twig\Locator\ModuleTemplateLoader' arguments: - - '@=service("prestashop.module_kernel.repository").getActiveModulesPaths()' - - ~ - 'PrestaShop': '' 'Product': '/Admin/Product' 'Twig': '/Admin/TwigTemplateForm' 'AdvancedParameters': '/Admin/Configure/AdvancedParameters' 'ShopParameters': '/Admin/Configure/ShopParameters' + - '@=service("prestashop.module_kernel.repository").getActiveModulesPaths()' tags: - { name: twig.loader, priority: 1} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Product/CatalogPage/Lists/list.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Product/CatalogPage/Lists/list.html.twig index b22a880494096..680fa8dae8613 100644 --- a/src/PrestaShopBundle/Resources/views/Admin/Product/CatalogPage/Lists/list.html.twig +++ b/src/PrestaShopBundle/Resources/views/Admin/Product/CatalogPage/Lists/list.html.twig @@ -23,117 +23,118 @@ * International Registered Trademark & Property of PrestaShop SA *#} - {% for product in products %} + {% for product in products %} + {% block product_catalog_form_table_row %} -
- -
+
+ +
- {{ product.image|raw }} + {{ product.image|raw }} - {{ product.name|default('N/A'|trans({}, 'Admin.Global')) }} + {{ product.name|default('N/A'|trans({}, 'Admin.Global')) }} - {{ product.reference|default('') }} + {{ product.reference|default('') }} - {{ product.name_category|default('') }} + {{ product.name_category|default('') }} - {{ product.price|default('N/A'|trans({}, 'Admin.Global')) }} + {{ product.price|default('N/A'|trans({}, 'Admin.Global')) }} {% if 'PS_STOCK_MANAGEMENT'|configuration %} - - - {% if product.sav_quantity is defined and product.sav_quantity > 0 %} - {{ product.sav_quantity }} - {% else %} - {{ product.sav_quantity|default('N/A'|trans({}, 'Admin.Global')) }} - {% endif %} - - + + + {% if product.sav_quantity is defined and product.sav_quantity > 0 %} + {{ product.sav_quantity }} + {% else %} + {{ product.sav_quantity|default('N/A'|trans({}, 'Admin.Global')) }} + {% endif %} + + {% else %} {% endif %} - {% if product.active|default(0) == 0 %} - - clear - - {% else %} - - check - - {% endif %} + {% if product.active|default(0) == 0 %} + + clear + + {% else %} + + check + + {% endif %} {% if product.position is defined %} - - {% if activate_drag_and_drop %} - - {% endif %} - {{ product.position }} - - - + + {% if activate_drag_and_drop %} + + {% endif %} + {{ product.position }} + + + {% endif %}
{% set buttons_action = [ - { - "href": product.preview_url|default('#'), - "target": "_blank", - "icon": "remove_red_eye", - "label": "Preview"|trans({}, 'Admin.Actions') - } + { + "href": product.preview_url|default('#'), + "target": "_blank", + "icon": "remove_red_eye", + "label": "Preview"|trans({}, 'Admin.Actions') + } ] %} {% set buttons_action = buttons_action|merge([ - { - "onclick": "unitProductAction(this, 'duplicate');", - "icon": "content_copy", - "label": "Duplicate"|trans({}, 'Admin.Actions') - } + { + "onclick": "unitProductAction(this, 'duplicate');", + "icon": "content_copy", + "label": "Duplicate"|trans({}, 'Admin.Actions') + } ]) %} {% set buttons_action = buttons_action|merge([ - { - "onclick": "unitProductAction(this, 'delete');", - "icon": "delete", - "label": "Delete"|trans({}, 'Admin.Actions') - } + { + "onclick": "unitProductAction(this, 'delete');", + "icon": "delete", + "label": "Delete"|trans({}, 'Admin.Actions') + } ]) %} {% include '@Product/CatalogPage/Forms/form_edit_dropdown.html.twig' with { - 'button_id': "product_list_id_" ~ product.id_product ~ "_menu", - 'default_item': { - "href": product.url|default('#'), - "icon": "mode_edit" - }, - 'right': true, - 'items': buttons_action + 'button_id': "product_list_id_" ~ product.id_product ~ "_menu", + 'default_item': { + "href": product.url|default('#'), + "icon": "mode_edit" + }, + 'right': true, + 'items': buttons_action } %}
- {% else %} - + {% endblock %} +{% else %} + {{ "There is no result for this search. Update your filters to view other products."|trans({}, 'Admin.Catalog.Notification') }} - {% endfor %} - +{% endfor %} diff --git a/src/PrestaShopBundle/Twig/Locator/ModuleTemplateLoader.php b/src/PrestaShopBundle/Twig/Locator/ModuleTemplateLoader.php index ebcd52b62afdf..75fc1af8f8328 100644 --- a/src/PrestaShopBundle/Twig/Locator/ModuleTemplateLoader.php +++ b/src/PrestaShopBundle/Twig/Locator/ModuleTemplateLoader.php @@ -39,17 +39,11 @@ class ModuleTemplateLoader extends FilesystemLoader private $rootPath; /** - * @var array $registeredPaths The list of Paths and namespaces registered in configuration. - * @see app/config/config.yml - */ - private $registeredPaths; - - /** + * @param array $namespaces A collection of path namespaces with namespace names. * @param string|array $paths A path or an array of paths where to look for templates * @param string|null $rootPath The root path common to all relative paths (null for getcwd()) - * @param array $namespaces A collection of path namespaces with namespace names. */ - public function __construct($paths = array(), $rootPath = null, array $namespaces) + public function __construct(array $namespaces, $paths = array(), $rootPath = null) { $this->rootPath = (null === $rootPath ? getcwd() : $rootPath).DIRECTORY_SEPARATOR; if (false !== $realPath = realpath($rootPath)) { @@ -79,21 +73,4 @@ private function registerNamespacesFromConfig($paths, array $namespaces) $this->setPaths($templatePaths, $namespace); } } - - /** - * @return array - */ - public function getRegisteredPaths() - { - return $this->registeredPaths; - } - - /** - * @param array $registeredPaths - */ - public function setRegisteredPaths($registeredPaths) - { - dump($registeredPaths); - $this->registeredPaths = $registeredPaths; - } } From ff01f530e9f49f1836ea4b71c7a403db311091ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20Andrieu?= Date: Sun, 10 Jun 2018 03:15:08 +0200 Subject: [PATCH 3/5] Added unit tests --- .../PrestaShop/Admin/Product/test.html.twig | 1 + .../module2/views/PrestaShop/test.html.twig | 1 + .../Product/ProductPage/Lists/list.html.twig | 1 + .../PrestaShop/Admin/Product/test.html.twig | 1 + .../Twig/Locator/ModuleTemplateLoaderTest.php | 133 ++++++++++++++++++ 5 files changed, 137 insertions(+) create mode 100644 tests/PrestaShopBundle/Twig/Fixtures/module1/views/PrestaShop/Admin/Product/test.html.twig create mode 100644 tests/PrestaShopBundle/Twig/Fixtures/module2/views/PrestaShop/test.html.twig create mode 100644 tests/PrestaShopBundle/Twig/Fixtures/module3/views/PrestaShop/Admin/Product/ProductPage/Lists/list.html.twig create mode 100644 tests/PrestaShopBundle/Twig/Fixtures/module3/views/PrestaShop/Admin/Product/test.html.twig create mode 100644 tests/PrestaShopBundle/Twig/Locator/ModuleTemplateLoaderTest.php diff --git a/tests/PrestaShopBundle/Twig/Fixtures/module1/views/PrestaShop/Admin/Product/test.html.twig b/tests/PrestaShopBundle/Twig/Fixtures/module1/views/PrestaShop/Admin/Product/test.html.twig new file mode 100644 index 0000000000000..0f0f366fe5d05 --- /dev/null +++ b/tests/PrestaShopBundle/Twig/Fixtures/module1/views/PrestaShop/Admin/Product/test.html.twig @@ -0,0 +1 @@ +module1 diff --git a/tests/PrestaShopBundle/Twig/Fixtures/module2/views/PrestaShop/test.html.twig b/tests/PrestaShopBundle/Twig/Fixtures/module2/views/PrestaShop/test.html.twig new file mode 100644 index 0000000000000..6a8f8b71c5459 --- /dev/null +++ b/tests/PrestaShopBundle/Twig/Fixtures/module2/views/PrestaShop/test.html.twig @@ -0,0 +1 @@ +module2 diff --git a/tests/PrestaShopBundle/Twig/Fixtures/module3/views/PrestaShop/Admin/Product/ProductPage/Lists/list.html.twig b/tests/PrestaShopBundle/Twig/Fixtures/module3/views/PrestaShop/Admin/Product/ProductPage/Lists/list.html.twig new file mode 100644 index 0000000000000..f260424ca1cd7 --- /dev/null +++ b/tests/PrestaShopBundle/Twig/Fixtures/module3/views/PrestaShop/Admin/Product/ProductPage/Lists/list.html.twig @@ -0,0 +1 @@ +List from module 3 diff --git a/tests/PrestaShopBundle/Twig/Fixtures/module3/views/PrestaShop/Admin/Product/test.html.twig b/tests/PrestaShopBundle/Twig/Fixtures/module3/views/PrestaShop/Admin/Product/test.html.twig new file mode 100644 index 0000000000000..bb7fff7f199dd --- /dev/null +++ b/tests/PrestaShopBundle/Twig/Fixtures/module3/views/PrestaShop/Admin/Product/test.html.twig @@ -0,0 +1 @@ +module3 diff --git a/tests/PrestaShopBundle/Twig/Locator/ModuleTemplateLoaderTest.php b/tests/PrestaShopBundle/Twig/Locator/ModuleTemplateLoaderTest.php new file mode 100644 index 0000000000000..f41680dc506f6 --- /dev/null +++ b/tests/PrestaShopBundle/Twig/Locator/ModuleTemplateLoaderTest.php @@ -0,0 +1,133 @@ + + * @copyright 2007-2018 PrestaShop SA + * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) + * International Registered Trademark & Property of PrestaShop SA + */ + +namespace Tests\PrestaShopBundle\Twig\Locator; + +use PrestaShopBundle\Twig\Locator\ModuleTemplateLoader; +use PHPUnit\Framework\TestCase; + +/** + * @group sf + */ +class ModuleTemplateLoaderTest extends TestCase +{ + /** + * @var TemplateModuleLoader + */ + private $loader; + + /** + * {@inheritdoc} + */ + protected function setUp() + { + $namespaces = [ + 'Product' => 'Admin/Product', + 'PrestaShop' => '', + ]; + + $paths = [ + __DIR__.'/../Fixtures/module1', + __DIR__.'/../Fixtures/module2', + __DIR__.'/../Fixtures/module3', + ]; + + $rootPath = null; + + $this->loader = new ModuleTemplateLoader($namespaces, $paths, $rootPath); + } + + /** + * {@inheritdoc} + */ + protected function tearDown() + { + $this->loader = null; + } + + public function testGetPaths() + { + self::assertCount( + 2, + $this->loader->getPaths('Product'), + 'Two templates for the namespace "Product" should be found.' + ); + + self::assertCount( + 3, + $this->loader->getPaths('PrestaShop'), + 'One templates should be found.'); + } + + /** + * @dataProvider getSourceContextsProvider + * @param string $sourceContent The template file content. + * @param string $twigPathAsked The Twig path asked during Twig template rendering. + * @param string $successMessage In case of failure, describe what is expected. + */ + public function testGetSourceContext($sourceContent, $twigPathAsked, $successMessage) + { + self::assertEquals( + $sourceContent, + $this->loader->getSourceContext($twigPathAsked)->getCode() . PHP_EOL, + $successMessage + ); + } + + /** + * @return array + */ + public function getSourceContextsProvider() + { + return [ + ['module1', '@Product/test.html.twig', 'Module 1 wins as Module 3 is loaded after.'], + ['module1', '@PrestaShop/Admin/Product/test.html.twig', 'PrestaShop is the main namespace.'], + ['List from module 3', '@Product/ProductPage/Lists/list.html.twig', 'Module 3 templates are available.'], + ['module2', '@PrestaShop/test.html.twig', 'Module 2 templates are availables.'], + ]; + } + + public function testEmptyConstructor() + { + $loader = new ModuleTemplateLoader([]); + + self::assertEquals(array(), $loader->getPaths()); + } + + /** + * @throws \Twig_Error_Loader + */ + public function testGetNamespaces() + { + $loader = new ModuleTemplateLoader([]); + + self::assertEquals([], $loader->getNamespaces()); + + $loader->addPath(sys_get_temp_dir(), 'named'); + + self::assertEquals(['named'], $loader->getNamespaces()); + } +} From 04967f9f580a101419bd5d38ea6baaa61e905670 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20Andrieu?= Date: Mon, 11 Jun 2018 10:09:17 +0200 Subject: [PATCH 4/5] Fixed CS --- src/PrestaShopBundle/Twig/Locator/ModuleTemplateLoader.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/PrestaShopBundle/Twig/Locator/ModuleTemplateLoader.php b/src/PrestaShopBundle/Twig/Locator/ModuleTemplateLoader.php index 75fc1af8f8328..dae1c6ef982da 100644 --- a/src/PrestaShopBundle/Twig/Locator/ModuleTemplateLoader.php +++ b/src/PrestaShopBundle/Twig/Locator/ModuleTemplateLoader.php @@ -62,7 +62,7 @@ public function __construct(array $namespaces, $paths = array(), $rootPath = nul */ private function registerNamespacesFromConfig($paths, array $namespaces) { - foreach($namespaces as $namespace => $namespacePath) { + foreach ($namespaces as $namespace => $namespacePath) { $templatePaths = array(); foreach ($paths as $path) { From 8e3eaf03fc27712d50a4a69498c9313b586fa480 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20Andrieu?= Date: Mon, 11 Jun 2018 10:30:28 +0200 Subject: [PATCH 5/5] Fixed PHP_EOL position --- .../Twig/Locator/ModuleTemplateLoaderTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/PrestaShopBundle/Twig/Locator/ModuleTemplateLoaderTest.php b/tests/PrestaShopBundle/Twig/Locator/ModuleTemplateLoaderTest.php index f41680dc506f6..25bf2e9e3b05a 100644 --- a/tests/PrestaShopBundle/Twig/Locator/ModuleTemplateLoaderTest.php +++ b/tests/PrestaShopBundle/Twig/Locator/ModuleTemplateLoaderTest.php @@ -91,8 +91,8 @@ public function testGetPaths() public function testGetSourceContext($sourceContent, $twigPathAsked, $successMessage) { self::assertEquals( - $sourceContent, - $this->loader->getSourceContext($twigPathAsked)->getCode() . PHP_EOL, + $sourceContent . PHP_EOL, + $this->loader->getSourceContext($twigPathAsked)->getCode(), $successMessage ); }