New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Registered all namespaces in ModuleTemplateLoader class #9173
Changes from all commits
f029f01
fd2284a
ff01f53
04967f9
8e3eaf0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -23,117 +23,118 @@ | |
* International Registered Trademark & Property of PrestaShop SA | ||
*#} | ||
<tbody | ||
{% if activate_drag_and_drop and has_category_filter %}class="sortable"{% endif %} | ||
last_sql="{{ last_sql_query|escape('html_attr') }}" | ||
{% if activate_drag_and_drop and has_category_filter %}class="sortable"{% endif %} | ||
last_sql="{{ last_sql_query|escape('html_attr') }}" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe should be a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nope! we dont change anything here: not the scope of this contribution. HALTE AU GRABUGE ! |
||
> | ||
{% for product in products %} | ||
{% for product in products %} | ||
{% block product_catalog_form_table_row %} | ||
<tr data-uniturl="{{ product.unit_action_url|default('#') }}" data-product-id="{{ product.id_product }}"> | ||
<td class="checkbox-column form-group"> | ||
<div class="md-checkbox md-checkbox-inline"> | ||
<label> | ||
<input type="checkbox" id="bulk_action_selected_products-{{ product.id_product }}" name="bulk_action_selected_products[]" value="{{ product.id_product }}"> | ||
<i class="md-checkbox-control"></i> | ||
</label> | ||
</div> | ||
<div class="md-checkbox md-checkbox-inline"> | ||
<label> | ||
<input type="checkbox" id="bulk_action_selected_products-{{ product.id_product }}" name="bulk_action_selected_products[]" value="{{ product.id_product }}"> | ||
<i class="md-checkbox-control"></i> | ||
</label> | ||
</div> | ||
</td> | ||
<td> | ||
<label class="form-check-label" for="bulk_action_selected_products-{{ product.id_product }}"> | ||
{{ product.id_product }} | ||
{{ product.id_product }} | ||
</label> | ||
</td> | ||
<td> | ||
<a href="{{ product.url|default('') }}#tab-step1">{{ product.image|raw }}</a> | ||
<a href="{{ product.url|default('') }}#tab-step1">{{ product.image|raw }}</a> | ||
</td> | ||
<td> | ||
<a href="{{ product.url|default('') }}#tab-step1">{{ product.name|default('N/A'|trans({}, 'Admin.Global')) }}</a> | ||
<a href="{{ product.url|default('') }}#tab-step1">{{ product.name|default('N/A'|trans({}, 'Admin.Global')) }}</a> | ||
</td> | ||
<td> | ||
{{ product.reference|default('') }} | ||
{{ product.reference|default('') }} | ||
</td> | ||
<td> | ||
{{ product.name_category|default('') }} | ||
{{ product.name_category|default('') }} | ||
</td> | ||
<td class="text-center"> | ||
<a href="{{ product.url|default('') }}#tab-step2">{{ product.price|default('N/A'|trans({}, 'Admin.Global')) }}</a> | ||
<a href="{{ product.url|default('') }}#tab-step2">{{ product.price|default('N/A'|trans({}, 'Admin.Global')) }}</a> | ||
</td> | ||
|
||
{% if 'PS_STOCK_MANAGEMENT'|configuration %} | ||
<td class="product-sav-quantity text-center" data-product-quantity-value="{{ product.sav_quantity|default('') }}"> | ||
<a href="{{ product.url|default('') }}#tab-step3"> | ||
{% 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 %} | ||
</a> | ||
</td> | ||
<td class="product-sav-quantity text-center" data-product-quantity-value="{{ product.sav_quantity|default('') }}"> | ||
<a href="{{ product.url|default('') }}#tab-step3"> | ||
{% 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 %} | ||
</a> | ||
</td> | ||
{% else %} | ||
<td></td> | ||
{% endif %} | ||
<td class="text-center"> | ||
{% if product.active|default(0) == 0 %} | ||
<a href="#" onclick="unitProductAction(this, 'activate'); return false;"> | ||
<i class="material-icons action-disabled">clear</i> | ||
</a> | ||
{% else %} | ||
<a href="#" onclick="unitProductAction(this, 'deactivate'); return false;"> | ||
<i class="material-icons action-enabled ">check</i> | ||
</a> | ||
{% endif %} | ||
{% if product.active|default(0) == 0 %} | ||
<a href="#" onclick="unitProductAction(this, 'activate'); return false;"> | ||
<i class="material-icons action-disabled">clear</i> | ||
</a> | ||
{% else %} | ||
<a href="#" onclick="unitProductAction(this, 'deactivate'); return false;"> | ||
<i class="material-icons action-enabled ">check</i> | ||
</a> | ||
{% endif %} | ||
</td> | ||
{% if product.position is defined %} | ||
<td {% if activate_drag_and_drop %}class="placeholder"{% endif %} style="cursor: pointer; cursor: hand;"> | ||
{% if activate_drag_and_drop %} | ||
<big><big>⇅</big></big> | ||
{% endif %} | ||
<span class="position">{{ product.position }}</span> | ||
<input type="hidden" name="mass_edit_action_sorted_products[]" value="{{ product.id_product }}" /> | ||
<input type="hidden" name="mass_edit_action_sorted_positions[]" value="{{ product.position }}" /> | ||
</td> | ||
<td {% if activate_drag_and_drop %}class="placeholder"{% endif %} style="cursor: pointer; cursor: hand;"> | ||
{% if activate_drag_and_drop %} | ||
<big><big>⇅</big></big> | ||
{% endif %} | ||
<span class="position">{{ product.position }}</span> | ||
<input type="hidden" name="mass_edit_action_sorted_products[]" value="{{ product.id_product }}" /> | ||
<input type="hidden" name="mass_edit_action_sorted_positions[]" value="{{ product.position }}" /> | ||
</td> | ||
{% endif %} | ||
<td class="text-right"> | ||
<div class="btn-group-action"> | ||
|
||
{% set buttons_action = [ | ||
{ | ||
"href": product.preview_url|default('#'), | ||
"target": "_blank", | ||
"icon": "remove_red_eye", | ||
"label": "Preview"|trans({}, 'Admin.Actions') | ||
} | ||
{ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 |
||
"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 | ||
} %} | ||
</div> | ||
</td> | ||
</tr> | ||
{% else %} | ||
<tr><td colspan="11"> | ||
{% endblock %} | ||
{% else %} | ||
<tr><td colspan="11"> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Weird indent There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. was here previously, improving it now may make the contribution unreadable |
||
{{ "There is no result for this search. Update your filters to view other products."|trans({}, 'Admin.Catalog.Notification') }} | ||
</td></tr> | ||
{% endfor %} | ||
</tbody> | ||
{% endfor %} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
module1 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
module2 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
List from module 3 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
module3 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,133 @@ | ||
<?php | ||
/** | ||
* 2007-2018 PrestaShop | ||
* | ||
* NOTICE OF LICENSE | ||
* | ||
* This source file is subject to the Open Software License (OSL 3.0) | ||
* that is bundled with this package in the file LICENSE.txt. | ||
* It is also available through the world-wide-web at this URL: | ||
* https://opensource.org/licenses/OSL-3.0 | ||
* If you did not receive a copy of the license and are unable to | ||
* obtain it through the world-wide-web, please send an email | ||
* to license@prestashop.com so we can send you a copy immediately. | ||
* | ||
* DISCLAIMER | ||
* | ||
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer | ||
* versions in the future. If you wish to customize PrestaShop for your | ||
* needs please refer to http://www.prestashop.com for more information. | ||
* | ||
* @author PrestaShop SA <contact@prestashop.com> | ||
* @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 . PHP_EOL, | ||
$this->loader->getSourceContext($twigPathAsked)->getCode(), | ||
$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()); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not store this list elsewhere, like in a config or something?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's used just once, not sure it's necessary
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
because this won't be re-used.
At start, I wanted to re-use the paths used in framework configuration, but thinking about it it's not a good idea. The 'array' look like the same but they have really different purposes.
If we have another place/service when we want to re-use it, of course I'm also in favor of extracting it into a parameter.
Note you can access to all registered Twig paths and namespaces using
php bin/console debug:twig
but not us, cause of weird call of Legacy Context in a Twig extension. This is a really minor issue we should try to fix asap.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But we'll need to add new namespaces as we migrate new sections, won't we?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, so we will append new namespaces here.
But before I need to document which namespaces should be added as there is no real consistency actually: some templates use them, others don't, some namespace refers to a page, others to sections or even categories...
Once we will have consistency, I'm pretty sure we won't even need to configure an Array, but maybe loop into actual folders and declare namespaces dynamically ^^
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As long as it isn't done in runtime...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nope, it's converted in PHP function in container cache: I don't think we can make the process faster 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes everything setting in yml files are automatically converted in string / array in the cache file =)