From 6b3c25d39c9faa6420528538eb41ba91a54783da Mon Sep 17 00:00:00 2001 From: Jonathan Danse Date: Mon, 23 May 2022 22:15:40 +0200 Subject: [PATCH 001/310] Introduce PATCH request into webservice API --- webservice/cheat-sheet.md | 2 +- webservice/getting-started.md | 13 +++++++++---- webservice/resources/images.md | 15 +++++++-------- webservice/tutorials/creating-access.md | 4 ++-- .../prestashop-webservice-lib/setup-library.md | 8 ++++++-- webservice/tutorials/testing-access.md | 12 ++++++------ 6 files changed, 31 insertions(+), 23 deletions(-) diff --git a/webservice/cheat-sheet.md b/webservice/cheat-sheet.md index 657853ab95..470ff2ba8c 100644 --- a/webservice/cheat-sheet.md +++ b/webservice/cheat-sheet.md @@ -12,7 +12,7 @@ All these options can be added to your queries as query parameters (either `GET` | Key | Value | Description | |-----|-------|-------------| | **output_format** | `XML, JSON` | Change the output format | -| **ps_method** | `GET, POST, PUT, DELETE` | Override the HTTP method used for the request | +| **ps_method** | `GET, POST, PUT, PATCH, DELETE` | Override the HTTP method used for the request | ## Resource options diff --git a/webservice/getting-started.md b/webservice/getting-started.md index c5f0937522..e5008307c5 100644 --- a/webservice/getting-started.md +++ b/webservice/getting-started.md @@ -16,13 +16,14 @@ The PrestaShop web service uses the REST architecture in order to be available o [REST](https://en.wikipedia.org/wiki/REST) defines roughly a style of software architecture, which promotes the use of HTTP methods when building web application, instead of custom methods or protocols such as SOAP or WSDL. It defines several rules, including one that is similar to CRUD, which is described below. {{% /notice %}} -HTTP has several methods that can perform processing on data as defined in the REST architecture, among which are [4 main methods](https://en.wikipedia.org/wiki/HTTP#Request_methods): +HTTP has several methods that can perform processing on data as defined in the REST architecture, among which are [5 main methods](https://en.wikipedia.org/wiki/HTTP#Request_methods): | HTTP/REST | CRUD | SQL | |-----------|--------|--------| | POST | Create | INSERT | | GET | Read | SELECT | | PUT | Update | UPDATE | +| PATCH | Update | UPDATE | | DELETE | Delete | DELETE | ## Enabling & Creating an access to the webservice @@ -67,8 +68,8 @@ When you call the root `/api` url you will get a summary of the available APIs y - - + + The Customer, Brand and Customer addresses @@ -192,7 +193,7 @@ This parameter can only be used for listings, not for individual records. If you {{% notice note %}} A response obtained with "display" other than "full" can't be used in a **PUT** (update) request, because the `WebserviceRequest` class validation for fields is the same for **POST** (create) and **PUT** (update). -This should be fixed in a near future with a *yet-to-come-pull-request* introducing the PATCH method! +**PATCH** method allow you to use a partial display ! {{% /notice %}} ##### Control returned items with "filter" @@ -244,6 +245,10 @@ PrestaShop will take care of adding everything in the database, and will return To edit an existing resource: **GET** the full XML file for the resource you want to change (example `/api/addresses/1`), edit its content as needed, then send a **PUT HTTP request** with the whole XML file as a body content to the same URL again. +### Partially update a resource + +To partially edit an existing resource: **GET** a part of the XML file for the resource you want to change (example `/api/addresses/1`), edit its content as needed, then send a **PATCH HTTP request** with the partial XML file as a body content to the same URL again. + ### Using JSON instead of XML The Web services can also output JSON instead of XML. To enable JSON output you have two choices: diff --git a/webservice/resources/images.md b/webservice/resources/images.md index 4d6940c40d..239ab7aabc 100644 --- a/webservice/resources/images.md +++ b/webservice/resources/images.md @@ -22,14 +22,13 @@ title: Images ```xml - - - - - - - + + + + + + + ``` - diff --git a/webservice/tutorials/creating-access.md b/webservice/tutorials/creating-access.md index a43ba75061..b7563956ac 100644 --- a/webservice/tutorials/creating-access.md +++ b/webservice/tutorials/creating-access.md @@ -76,8 +76,8 @@ For instance is we want to give all permissions for customers and orders resourc ```php ['GET' => 1, 'POST' => 1, 'PUT' => 1, 'DELETE' => 1, 'HEAD' => 1], - 'orders' => ['GET' => 1, 'POST' => 1, 'PUT' => 1, 'DELETE' => 1, 'HEAD' => 1], + 'customers' => ['GET' => 1, 'POST' => 1, 'PUT' => 1, 'PATCH' => 1, 'DELETE' => 1, 'HEAD' => 1], + 'orders' => ['GET' => 1, 'POST' => 1, 'PUT' => 1, 'PATCH' => 1, 'DELETE' => 1, 'HEAD' => 1], ]; WebserviceKey::setPermissionForAccount($apiAccess->id, $permissions); diff --git a/webservice/tutorials/prestashop-webservice-lib/setup-library.md b/webservice/tutorials/prestashop-webservice-lib/setup-library.md index 810ec46047..69443af32b 100644 --- a/webservice/tutorials/prestashop-webservice-lib/setup-library.md +++ b/webservice/tutorials/prestashop-webservice-lib/setup-library.md @@ -20,7 +20,7 @@ Now that your webservice is configured and accessible you might want to use it. If you are starting a new project you can init your composer project along with the dependency: ```bash -composer init --require="prestashop/prestashop-webservice-lib:dev-master" -n +composer init --require="prestashop/prestashop-webservice-lib:dev-master" -n composer install ``` @@ -97,6 +97,10 @@ Once the instance is created you can access the following methods: | edit() | PUT | UPDATE | | delete() | DELETE | DELETE | +{{% notice note %}} +**PATCH** method is not yet managed with this library. +{{% /notice %}} + ### Handling errors It is essential that you understand how to handle errors with the webservice library. By implementing error-catch method early, you will more easily detect issues, and be able to correct them on the go. @@ -110,7 +114,7 @@ The error handling is done within a `try...catch` block, with the webservice ins try { // creating webservice access $webService = new PrestaShopWebservice('http://example.com/', 'ZR92FNY5UFRERNI3O9Z5QDHWKTP3YIIT', false); - + // call to retrieve all customers $xml = $webService->get(['resource' => 'customers']); } catch (PrestaShopWebserviceException $ex) { diff --git a/webservice/tutorials/testing-access.md b/webservice/tutorials/testing-access.md index b3f7069b75..776d73579d 100644 --- a/webservice/tutorials/testing-access.md +++ b/webservice/tutorials/testing-access.md @@ -60,18 +60,18 @@ The `/api/` URL gives you the root of all the resources, in the form of an XML f - - + + The Customer, Brand and Customer addresses - - + + The images - - + + The products From 9c83ec8e5e242bee6af8a0751f3a82d32ad3e882 Mon Sep 17 00:00:00 2001 From: Louis AUTHIE <65625876+LouisAUTHIE@users.noreply.github.com> Date: Sun, 10 Jul 2022 22:50:32 +0200 Subject: [PATCH 002/310] Update migration.md --- basics/keeping-up-to-date/migration.md | 1 - 1 file changed, 1 deletion(-) diff --git a/basics/keeping-up-to-date/migration.md b/basics/keeping-up-to-date/migration.md index b5fbc7b0f7..7b270ed4c5 100644 --- a/basics/keeping-up-to-date/migration.md +++ b/basics/keeping-up-to-date/migration.md @@ -636,4 +636,3 @@ automatic, because: Useful links: - [Learning how-to use the webservice API](https://doc.prestashop.com/display/PS16/Using+the+PrestaShop+Web+Service) -- [Getting a list of all available ressources, ready for import/export](https://doc.prestashop.com/display/PS16/Web+service+one-page+documentation#Webserviceone-pagedocumentation-Availableresources) From a90eadb7383e2b6be7cf1cde8204f6472a01514c Mon Sep 17 00:00:00 2001 From: leemyongpakvn Date: Tue, 2 Aug 2022 19:50:23 +0700 Subject: [PATCH 003/310] New images and new catalog-tools since PS 1.7.5.2 Since PS 1.7.5.2, catalog-tools-button is toggled instead of a horizontal list --- modules/concepts/hooks/use-hooks-on-modern-pages.md | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/modules/concepts/hooks/use-hooks-on-modern-pages.md b/modules/concepts/hooks/use-hooks-on-modern-pages.md index 6cbd7314fe..b66b52130c 100644 --- a/modules/concepts/hooks/use-hooks-on-modern-pages.md +++ b/modules/concepts/hooks/use-hooks-on-modern-pages.md @@ -175,7 +175,7 @@ public function hookDisplayDashboardToolbarIcons($hookParams) In Product Catalog Page you should see the list of Products in debug toolbar in "Dump" section: -![Get products in Dump section](https://i.imgur.com/un7NcIL.png) +![Get products in Dump section](../img/Catalog_Products_dump.png) #### Using the Symfony components to create an XML export file @@ -262,10 +262,8 @@ And now, the template: ```twig {# in Foo/views/download_link.twig #} - - - cloud_upload - + + cloudExport XML ``` @@ -273,6 +271,6 @@ And now, the template: We have used a key for translation, making our own translations available in back office when using Twig. {{% /notice %}} -![Export XML action button](https://i.imgur.com/5HExjcC.png) +![Export XML action button](../img/Catalog_Products_2xml.png) And "voila!", the module could be of course improved with so many features, adding filters on export for instance, using the `request` hook parameter and updating the Product repository. From 6c74bcee3500717e561e346de28d9bd9edfb8d2f Mon Sep 17 00:00:00 2001 From: leemyongpakvn Date: Tue, 2 Aug 2022 19:53:35 +0700 Subject: [PATCH 004/310] Images of Export by dump and 2xml in PS 1.7.6.5 --- modules/concepts/img/Catalog_Products_2xml.png | Bin 0 -> 53171 bytes modules/concepts/img/Catalog_Products_dump.png | Bin 0 -> 45922 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 modules/concepts/img/Catalog_Products_2xml.png create mode 100644 modules/concepts/img/Catalog_Products_dump.png diff --git a/modules/concepts/img/Catalog_Products_2xml.png b/modules/concepts/img/Catalog_Products_2xml.png new file mode 100644 index 0000000000000000000000000000000000000000..60b1f12b24e377631b0e74eb292e00e1ecb22993 GIT binary patch literal 53171 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 XmIJThTl{&700000NkvXXu0mjf?%2f9 literal 0 HcmV?d00001 diff --git a/modules/concepts/img/Catalog_Products_dump.png b/modules/concepts/img/Catalog_Products_dump.png new file mode 100644 index 0000000000000000000000000000000000000000..844adb7c1b0b5193c71f1fe642a215008b3620f5 GIT binary patch literal 45922 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 xo0;3Rk3SDHR0645hN2?DqO5XZO Date: Tue, 2 Aug 2022 20:07:47 +0700 Subject: [PATCH 005/310] Keep trans string and some spaces --- modules/concepts/hooks/use-hooks-on-modern-pages.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/concepts/hooks/use-hooks-on-modern-pages.md b/modules/concepts/hooks/use-hooks-on-modern-pages.md index b66b52130c..87a4f787e7 100644 --- a/modules/concepts/hooks/use-hooks-on-modern-pages.md +++ b/modules/concepts/hooks/use-hooks-on-modern-pages.md @@ -262,8 +262,8 @@ And now, the template: ```twig {# in Foo/views/download_link.twig #} - - cloudExport XML + + cloud{{ "Export XML"|trans({}, 'Module.Foo') }} ``` From cb51d3bea9c407268b2aa8f2064a1c103b9fa261 Mon Sep 17 00:00:00 2001 From: leemyongpakvn Date: Thu, 4 Aug 2022 10:31:55 +0700 Subject: [PATCH 006/310] Path from root to avoid Source - Target URL change --- modules/concepts/hooks/use-hooks-on-modern-pages.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/concepts/hooks/use-hooks-on-modern-pages.md b/modules/concepts/hooks/use-hooks-on-modern-pages.md index 87a4f787e7..8a22247551 100644 --- a/modules/concepts/hooks/use-hooks-on-modern-pages.md +++ b/modules/concepts/hooks/use-hooks-on-modern-pages.md @@ -175,7 +175,7 @@ public function hookDisplayDashboardToolbarIcons($hookParams) In Product Catalog Page you should see the list of Products in debug toolbar in "Dump" section: -![Get products in Dump section](../img/Catalog_Products_dump.png) +![Get products in Dump section](/modules/concepts/img/Catalog_Products_dump.png) #### Using the Symfony components to create an XML export file @@ -271,6 +271,6 @@ And now, the template: We have used a key for translation, making our own translations available in back office when using Twig. {{% /notice %}} -![Export XML action button](../img/Catalog_Products_2xml.png) +![Export XML action button](/modules/concepts/img/Catalog_Products_2xml.png) And "voila!", the module could be of course improved with so many features, adding filters on export for instance, using the `request` hook parameter and updating the Product repository. From 8ea4de59b8d91365f020d3271883aafad8c9231e Mon Sep 17 00:00:00 2001 From: leemyongpakvn Date: Thu, 4 Aug 2022 22:05:34 +0700 Subject: [PATCH 007/310] source .md becomes / in target docs so we need one more ../ to make the image show on target docs. --- modules/concepts/hooks/use-hooks-on-modern-pages.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/concepts/hooks/use-hooks-on-modern-pages.md b/modules/concepts/hooks/use-hooks-on-modern-pages.md index 8a22247551..e423f41a0a 100644 --- a/modules/concepts/hooks/use-hooks-on-modern-pages.md +++ b/modules/concepts/hooks/use-hooks-on-modern-pages.md @@ -175,7 +175,7 @@ public function hookDisplayDashboardToolbarIcons($hookParams) In Product Catalog Page you should see the list of Products in debug toolbar in "Dump" section: -![Get products in Dump section](/modules/concepts/img/Catalog_Products_dump.png) +![Get products in Dump section](../../img/Catalog_Products_dump.png) #### Using the Symfony components to create an XML export file @@ -271,6 +271,6 @@ And now, the template: We have used a key for translation, making our own translations available in back office when using Twig. {{% /notice %}} -![Export XML action button](/modules/concepts/img/Catalog_Products_2xml.png) +![Export XML action button](../../img/Catalog_Products_2xml.png) And "voila!", the module could be of course improved with so many features, adding filters on export for instance, using the `request` hook parameter and updating the Product repository. From da1ac1ac3b1ce37315a5a61c8299e34e33d50505 Mon Sep 17 00:00:00 2001 From: leemyongpakvn Date: Sun, 7 Aug 2022 10:14:05 +0700 Subject: [PATCH 008/310] Hugo Page resources must be in the same folder of .md file --- .../concepts/hooks/Catalog_Products_2xml.png | Bin 0 -> 53171 bytes .../concepts/hooks/Catalog_Products_dump.png | Bin 0 -> 45922 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 modules/concepts/hooks/Catalog_Products_2xml.png create mode 100644 modules/concepts/hooks/Catalog_Products_dump.png diff --git a/modules/concepts/hooks/Catalog_Products_2xml.png b/modules/concepts/hooks/Catalog_Products_2xml.png new file mode 100644 index 0000000000000000000000000000000000000000..60b1f12b24e377631b0e74eb292e00e1ecb22993 GIT binary patch literal 53171 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 XmIJThTl{&700000NkvXXu0mjf?%2f9 literal 0 HcmV?d00001 diff --git a/modules/concepts/hooks/Catalog_Products_dump.png b/modules/concepts/hooks/Catalog_Products_dump.png new file mode 100644 index 0000000000000000000000000000000000000000..844adb7c1b0b5193c71f1fe642a215008b3620f5 GIT binary patch literal 45922 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 xo0;3Rk3SDHR0645hN2?DqO5XZO Date: Sun, 7 Aug 2022 10:16:13 +0700 Subject: [PATCH 009/310] Hugo page resources must be in the same folder --- modules/concepts/hooks/use-hooks-on-modern-pages.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/concepts/hooks/use-hooks-on-modern-pages.md b/modules/concepts/hooks/use-hooks-on-modern-pages.md index e423f41a0a..5b71a40653 100644 --- a/modules/concepts/hooks/use-hooks-on-modern-pages.md +++ b/modules/concepts/hooks/use-hooks-on-modern-pages.md @@ -175,7 +175,7 @@ public function hookDisplayDashboardToolbarIcons($hookParams) In Product Catalog Page you should see the list of Products in debug toolbar in "Dump" section: -![Get products in Dump section](../../img/Catalog_Products_dump.png) +![Get products in Dump section](Catalog_Products_dump.png) #### Using the Symfony components to create an XML export file @@ -271,6 +271,6 @@ And now, the template: We have used a key for translation, making our own translations available in back office when using Twig. {{% /notice %}} -![Export XML action button](../../img/Catalog_Products_2xml.png) +![Export XML action button](Catalog_Products_2xml.png) And "voila!", the module could be of course improved with so many features, adding filters on export for instance, using the `request` hook parameter and updating the Product repository. From 35284d99dafb4977fb7830ef377113fc24f7a644 Mon Sep 17 00:00:00 2001 From: leemyongpakvn Date: Sun, 7 Aug 2022 10:18:06 +0700 Subject: [PATCH 010/310] Delete Catalog_Products_2xml.png following Hugo page resource rule --- modules/concepts/img/Catalog_Products_2xml.png | Bin 53171 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 modules/concepts/img/Catalog_Products_2xml.png diff --git a/modules/concepts/img/Catalog_Products_2xml.png b/modules/concepts/img/Catalog_Products_2xml.png deleted file mode 100644 index 60b1f12b24e377631b0e74eb292e00e1ecb22993..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 53171 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 XmIJThTl{&700000NkvXXu0mjf?%2f9 From 1770e230d6ed1d60a5872c4f8abe3d2283eb617b Mon Sep 17 00:00:00 2001 From: leemyongpakvn Date: Sun, 7 Aug 2022 10:18:18 +0700 Subject: [PATCH 011/310] Delete Catalog_Products_dump.png following Hugo page resource rule --- modules/concepts/img/Catalog_Products_dump.png | Bin 45922 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 modules/concepts/img/Catalog_Products_dump.png diff --git a/modules/concepts/img/Catalog_Products_dump.png b/modules/concepts/img/Catalog_Products_dump.png deleted file mode 100644 index 844adb7c1b0b5193c71f1fe642a215008b3620f5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 45922 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 xo0;3Rk3SDHR0645hN2?DqO5XZO Date: Wed, 10 Aug 2022 17:42:01 +0700 Subject: [PATCH 012/310] hoping ./ will keep consistency for markdown preview and hugo live view --- modules/concepts/hooks/use-hooks-on-modern-pages.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/concepts/hooks/use-hooks-on-modern-pages.md b/modules/concepts/hooks/use-hooks-on-modern-pages.md index 5b71a40653..9bf310f325 100644 --- a/modules/concepts/hooks/use-hooks-on-modern-pages.md +++ b/modules/concepts/hooks/use-hooks-on-modern-pages.md @@ -175,7 +175,7 @@ public function hookDisplayDashboardToolbarIcons($hookParams) In Product Catalog Page you should see the list of Products in debug toolbar in "Dump" section: -![Get products in Dump section](Catalog_Products_dump.png) +![Get products in Dump section](./Catalog_Products_dump.png) #### Using the Symfony components to create an XML export file @@ -271,6 +271,6 @@ And now, the template: We have used a key for translation, making our own translations available in back office when using Twig. {{% /notice %}} -![Export XML action button](Catalog_Products_2xml.png) +![Export XML action button](./Catalog_Products_2xml.png) And "voila!", the module could be of course improved with so many features, adding filters on export for instance, using the `request` hook parameter and updating the Product repository. From 65517c61ef2017d01caed7c6174e6c2d6bab450f Mon Sep 17 00:00:00 2001 From: Jonathan Danse Date: Tue, 16 Aug 2022 13:40:13 +0200 Subject: [PATCH 013/310] Apply suggestion (a -> the) Co-authored-by: Matthieu Rolland --- webservice/getting-started.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webservice/getting-started.md b/webservice/getting-started.md index e5008307c5..f22e659e16 100644 --- a/webservice/getting-started.md +++ b/webservice/getting-started.md @@ -247,7 +247,7 @@ To edit an existing resource: **GET** the full XML file for the resource you wan ### Partially update a resource -To partially edit an existing resource: **GET** a part of the XML file for the resource you want to change (example `/api/addresses/1`), edit its content as needed, then send a **PATCH HTTP request** with the partial XML file as a body content to the same URL again. +To partially edit an existing resource: **GET** a part of the XML file for the resource you want to change (example `/api/addresses/1`), edit its content as needed, then send a **PATCH HTTP request** with the partial XML file as the body content to the same URL again. ### Using JSON instead of XML From 4f92b93b6c22eb0d7b9bbb6ccd57f6c9d54ab6d3 Mon Sep 17 00:00:00 2001 From: Jonathan Danse Date: Tue, 16 Aug 2022 13:40:37 +0200 Subject: [PATCH 014/310] Apply suggestion (yet managed with -> available in) Co-authored-by: Krystian Podemski --- webservice/tutorials/prestashop-webservice-lib/setup-library.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webservice/tutorials/prestashop-webservice-lib/setup-library.md b/webservice/tutorials/prestashop-webservice-lib/setup-library.md index 69443af32b..91f7620894 100644 --- a/webservice/tutorials/prestashop-webservice-lib/setup-library.md +++ b/webservice/tutorials/prestashop-webservice-lib/setup-library.md @@ -98,7 +98,7 @@ Once the instance is created you can access the following methods: | delete() | DELETE | DELETE | {{% notice note %}} -**PATCH** method is not yet managed with this library. +**PATCH** method is not available in this library. {{% /notice %}} ### Handling errors From afad205e3ad65e1b188b114311a0e0eb9d22dd33 Mon Sep 17 00:00:00 2001 From: Jonathan Danse Date: Tue, 16 Aug 2022 14:25:36 +0200 Subject: [PATCH 015/310] Apply suggestion Co-authored-by: Matthieu Rolland --- webservice/getting-started.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webservice/getting-started.md b/webservice/getting-started.md index f22e659e16..5dc9f3f3ac 100644 --- a/webservice/getting-started.md +++ b/webservice/getting-started.md @@ -193,7 +193,7 @@ This parameter can only be used for listings, not for individual records. If you {{% notice note %}} A response obtained with "display" other than "full" can't be used in a **PUT** (update) request, because the `WebserviceRequest` class validation for fields is the same for **POST** (create) and **PUT** (update). -**PATCH** method allow you to use a partial display ! +The **PATCH** method allows using a partial display. {{% /notice %}} ##### Control returned items with "filter" From 6ba0f704f237d9c97a8dac9a286b00fb8a8f5cbd Mon Sep 17 00:00:00 2001 From: leemyongpakvn Date: Thu, 25 Aug 2022 17:23:04 +0700 Subject: [PATCH 016/310] switch and tweak for Symfony 4.4 --- modules/concepts/hooks/use-hooks-on-modern-pages.md | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/modules/concepts/hooks/use-hooks-on-modern-pages.md b/modules/concepts/hooks/use-hooks-on-modern-pages.md index 9bf310f325..b1893e62f8 100644 --- a/modules/concepts/hooks/use-hooks-on-modern-pages.md +++ b/modules/concepts/hooks/use-hooks-on-modern-pages.md @@ -12,14 +12,14 @@ Starting from PrestaShop 1.7.3, you can access the modern Services Container int * [Twig](https://twig.symfony.com/), the most popular templating engine; * [Swiftmailer](https://swiftmailer.symfony.com/), a feature-rich mailer; * [Doctrine ORM](https://www.doctrine-project.org/projects/orm.html) and [Doctrine DBAL](https://www.doctrine-project.org/projects/dbal.html) to manage your database; -* [Filesystem](https://symfony.com/doc/3.3/components/filesystem.html) and [Finder](https://symfony.com/doc/3.3/components/finder.html) libraries to manage all filesystem operations; +* [Filesystem](https://symfony.com/doc/4.4/components/filesystem.html) and [Finder](https://symfony.com/doc/4.4/components/finder.html) libraries to manage all filesystem operations; * [Monolog](https://seldaek.github.io/monolog/) for every logging operations; -* [Serializer](https://symfony.com/doc/3.3/components/serializer.html) library for whom who need to manipulate Json and Xml formats... +* [Serializer](https://symfony.com/doc/4.4/components/serializer.html) library for whom who need to manipulate Json and Xml formats... Of course, you also have access to every service used by the Core of PrestaShop. This means that you can rely on all services defined in `PrestaShopBundle/config/` folder, except from the ones declared in `adapter` folder: they will be removed at some point. {{% notice tip %}} -If you don't know what a service is, have a look at the Symfony documentation about the [service container](https://symfony.com/doc/3.3/service_container.html). +If you don't know what a service is, have a look at the Symfony documentation about the [service container](https://symfony.com/doc/4.4/service_container.html). {{% /notice %}} ## Better modules on modern pages @@ -49,7 +49,7 @@ As we need to act on Dashboard but after the header, in the icons toolbar (with ### Second step: create and register the Hook -Create a [new module](https://doc.prestashop.com/display/PS17/Creating+a+first+module) called `foo` and register the hook. You should end up with this kind of code in your module: +Create a [new module](https://devdocs.prestashop.com/8/modules/creation/tutorial) called `foo` and register the hook. You should end up with this kind of code in your module: ```php Date: Thu, 25 Aug 2022 20:51:18 +0700 Subject: [PATCH 017/310] consistency --- modules/concepts/hooks/use-hooks-on-modern-pages.md | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/modules/concepts/hooks/use-hooks-on-modern-pages.md b/modules/concepts/hooks/use-hooks-on-modern-pages.md index b1893e62f8..857565d7da 100644 --- a/modules/concepts/hooks/use-hooks-on-modern-pages.md +++ b/modules/concepts/hooks/use-hooks-on-modern-pages.md @@ -245,8 +245,16 @@ We could (of course) use Smarty to render a template, but it's a chance to disco public function hookDisplayDashboardToolbarIcons($params) { if ($this->isSymfonyContext() && $params['route'] === 'admin_product_catalog') { - $products = $this->getProducts(1); - $productsXml = $this->serializeProducts($products); + $products = $this->get('product_repository')->findAllByLangId(1); + + $productsXml = $this->get('serializer')->serialize( + $products, + 'xml', + [ + 'xml_root_node_name' => 'products', + 'xml_format_output' => true, + ] + ); $filepath = _PS_ROOT_DIR_.'/products.xml'; $this->writeFile($productsXml, $filepath); From 8e3347e9fb1b1f99a5f46dd880e2ced66323f7fa Mon Sep 17 00:00:00 2001 From: leemyongpakvn Date: Fri, 26 Aug 2022 14:46:36 +0700 Subject: [PATCH 018/310] consistent and better export path --- modules/concepts/hooks/use-hooks-on-modern-pages.md | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/modules/concepts/hooks/use-hooks-on-modern-pages.md b/modules/concepts/hooks/use-hooks-on-modern-pages.md index 857565d7da..1277931ebd 100644 --- a/modules/concepts/hooks/use-hooks-on-modern-pages.md +++ b/modules/concepts/hooks/use-hooks-on-modern-pages.md @@ -209,7 +209,7 @@ public function hookDisplayDashboardToolbarIcons($hookParams) 'xml_format_output' => true, ] ); - $this->get('filesystem')->dumpFile(_PS_UPLOAD_DIR_.'products.xml', $productsXml); + $this->get('filesystem')->dumpFile(_PS_UPLOAD_DIR_ . 'products.xml', $productsXml); } } ``` @@ -255,12 +255,10 @@ public function hookDisplayDashboardToolbarIcons($params) 'xml_format_output' => true, ] ); - $filepath = _PS_ROOT_DIR_.'/products.xml'; - - $this->writeFile($productsXml, $filepath); + $this->get('filesystem')->dumpFile(_PS_UPLOAD_DIR_ . 'products.xml', $productsXml); return $this->get('twig')->render('@Modules/Foo/views/download_link.twig', [ - 'filepath' => _PS_BASE_URL_.'/products.xml', + 'filepath' => _PS_BASE_URL_ . '/upload/' . 'products.xml', ]); } } From a97ae917a526ee4a7c0b9f6ef9466d62e31655c1 Mon Sep 17 00:00:00 2001 From: leemyongpakvn Date: Fri, 26 Aug 2022 14:47:45 +0700 Subject: [PATCH 019/310] open in a new tab --- modules/concepts/hooks/use-hooks-on-modern-pages.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/concepts/hooks/use-hooks-on-modern-pages.md b/modules/concepts/hooks/use-hooks-on-modern-pages.md index 1277931ebd..e1f98074f0 100644 --- a/modules/concepts/hooks/use-hooks-on-modern-pages.md +++ b/modules/concepts/hooks/use-hooks-on-modern-pages.md @@ -272,7 +272,7 @@ And now, the template: ```twig {# in Foo/views/download_link.twig #} - + cloud{{ "Export XML"|trans({}, 'Module.Foo') }} ``` From 2edb1eaed7925ef2e71664a7fa203c283f601e03 Mon Sep 17 00:00:00 2001 From: Jonathan Danse Date: Mon, 29 Aug 2022 21:31:15 +0200 Subject: [PATCH 020/310] Fix links with relfref --- .../admin-controllers/override-decorate-controller.md | 2 +- .../extending-sf-form-with-upload-image-field.md | 4 ++-- modules/sample-modules/order-pages-new-hooks/module-base.md | 2 +- .../order-pages-new-hooks/signature-widget.md | 6 +++--- project/release/minor-release-lifecycle.md | 4 ++-- scale/benchmark/front-office.md | 2 +- themes/getting-started/guidelines.md | 2 +- 7 files changed, 11 insertions(+), 11 deletions(-) diff --git a/modules/concepts/controllers/admin-controllers/override-decorate-controller.md b/modules/concepts/controllers/admin-controllers/override-decorate-controller.md index b5b808eb68..c1173e1203 100644 --- a/modules/concepts/controllers/admin-controllers/override-decorate-controller.md +++ b/modules/concepts/controllers/admin-controllers/override-decorate-controller.md @@ -52,7 +52,7 @@ In the above example, the `path` has not been changed, but you can change it to {{% /notice %}} {{% notice warning %}} -Keep the item `_legacy_controller` if your controller relies on it to configure a [AdminSecurity annotation]({{ relref "/8/development/architecture/migration-guide/controller-routing/#access-rules-convention" }}) such as `@AdminSecurity("is_granted('read', request.get('_legacy_controller'))")` +Keep the item `_legacy_controller` if your controller relies on it to configure a [AdminSecurity annotation]({{< relref "/8/development/architecture/migration-guide/controller-routing/#access-rules-convention" >}}) such as `@AdminSecurity("is_granted('read', request.get('_legacy_controller'))")` Keep the items `_legacy_controller` and `_legacy_link` if you want to reroute internal links and legacy URLs like `index.php?controller=AdminOrders` as well. {{% /notice %}} diff --git a/modules/sample-modules/extending-sf-form-with-upload-image-field.md b/modules/sample-modules/extending-sf-form-with-upload-image-field.md index 6ebab6de80..431a2a2f8c 100644 --- a/modules/sample-modules/extending-sf-form-with-upload-image-field.md +++ b/modules/sample-modules/extending-sf-form-with-upload-image-field.md @@ -222,7 +222,7 @@ below to `DemoExtendSymfonyForm2` class. ``` Let's create `SupplierExtraImage` entity class. We use [Doctrine] - ({{ relref "/8/modules/concepts/doctrine/" }}) + ({{< relref "/8/modules/concepts/doctrine/" >}}) which is available for PrestaShop modules since version 1.7.6. ```php @@ -364,7 +364,7 @@ class SupplierExtraImageRepository extends EntityRepository Let's create hook `hookActionSupplierFormBuilderModifier` function inside Main module class. This is a hook available for [CRUD forms] -({{ relref "/8/modules/sample-modules/grid-and-identifiable-object-form-hooks-usage/" }}) in +({{< relref "/8/modules/sample-modules/grid-and-identifiable-object-form-hooks-usage/" >}}) in PrestaShop Symfony pages. ```php diff --git a/modules/sample-modules/order-pages-new-hooks/module-base.md b/modules/sample-modules/order-pages-new-hooks/module-base.md index 7c4621f779..24effc67db 100644 --- a/modules/sample-modules/order-pages-new-hooks/module-base.md +++ b/modules/sample-modules/order-pages-new-hooks/module-base.md @@ -122,7 +122,7 @@ class FixturesInstaller Lets create `Installer` class inside `/demovieworderhooks/src/Install` folder structure. It is responsible only for module installation (hook registration, database creation, population database data). When it comes to database creation we use PrestaShop `DbCore` class -functions because doctrine is [not fully supported for modules installation]({{ relref "/8/modules/concepts/doctrine/#creating-the-database" }}) at 1.7.7.0 release. +functions because doctrine is [not fully supported for modules installation]({{< relref "/8/modules/concepts/doctrine/#creating-the-database" >}}) at 1.7.7.0 release. ```php }}). Also we map this entity with the repository with `repositoryClass="PrestaShop\Module\DemoViewOrderHooks\Repository\OrderSignatureRepository"`. This mapping allows to use functions of `SignatureRepository` instead of only the `EntityRepository`. @@ -445,7 +445,7 @@ class OrderSignaturePresenter ``` Then lets use Symfony Dependency Injection (https://www.freecodecamp.org/news/a-quick-intro-to-dependency-injection-what-it-is-and-when-to-use-it-7578c84fa88f/). -and [create services configuration]({{ relref "/8/modules/concepts/services/#symfony-services" }}) for the above +and [create services configuration]({{< relref "/8/modules/concepts/services/#symfony-services" >}}) for the above classes in `demovieworderhooks/config/services.yml`. The intention behind dependency injection is to achieve Separation of Concerns of construction and use of objects. This can increase readability and code reuse, reduce dependencies, lead to more testable code. @@ -554,7 +554,7 @@ Render a twig template method: For each registered hook, you must create a non-static public method, starting with the “hook” keyword followed by the name of the hook you want to use (starting with either “display” or “action”). In our case: `hookDisplayBackOfficeOrderActions` -([read this article for more information]({{ relref "/8//modules/concepts/hooks/#execution" }})). +([read this article for more information]({{< relref "/8//modules/concepts/hooks/#execution" >}})). We add this code at the bottom of the main module class `demovieworderhooks.php` and also add the missing `use` statements for new classes. diff --git a/project/release/minor-release-lifecycle.md b/project/release/minor-release-lifecycle.md index 8c99f48b62..a2281e617e 100644 --- a/project/release/minor-release-lifecycle.md +++ b/project/release/minor-release-lifecycle.md @@ -56,8 +56,8 @@ For example, if you are a payment module developer, just installing your module If however you find a problem, you can - - [Report this as a bug on GitHub](https://github.com/PrestaShop/PrestaShop/issues) (read [how to report issues]({{ relref "/8/contribute/contribute-reporting-issues/" }})) - - Submit a bug fix by creating a [pull request](https://github.com/PrestaShop/PrestaShop/compare) (read the [contribution guidelines]({{ relref "/8/contribute/contribution-guidelines/" }})) + - [Report this as a bug on GitHub](https://github.com/PrestaShop/PrestaShop/issues) (read [how to report issues]({{< relref "/8/contribute/contribute-reporting-issues/" >}})) + - Submit a bug fix by creating a [pull request](https://github.com/PrestaShop/PrestaShop/compare) (read the [contribution guidelines]({{< relref "/8/contribute/contribution-guidelines/" >}})) ## Release Candidate diff --git a/scale/benchmark/front-office.md b/scale/benchmark/front-office.md index 5c0005ee3f..414d05171f 100755 --- a/scale/benchmark/front-office.md +++ b/scale/benchmark/front-office.md @@ -8,7 +8,7 @@ How to benchmark your PrestaShop Shop (Front-office) ## Automatically benchmark with `Gatling` (recommended) -Follow instruction on **[Back-Office benchmark page]({{ relref "/8/scale/benchmark/back-office/" }})** to get a pre-populated shop and to run Gatling scenarios on it. +Follow instruction on **[Back-Office benchmark page]({{< relref "/8/scale/benchmark/back-office/" >}})** to get a pre-populated shop and to run Gatling scenarios on it. **[PrestaShop performance project](https://github.com/PrestaShop/performance-project)** on Github includes Front-Office scenarios you can edit to get your own scenarios running. diff --git a/themes/getting-started/guidelines.md b/themes/getting-started/guidelines.md index 567b702e16..3b6b05cd92 100644 --- a/themes/getting-started/guidelines.md +++ b/themes/getting-started/guidelines.md @@ -10,7 +10,7 @@ weight: 1 ##### PHP Code -Your PHP code should be compatible with [PHP compatibility chart]({{ relref "8/basics/installation/system-requirements/#php-compatibility-chart" }}) +Your PHP code should be compatible with [PHP compatibility chart]({{< relref "8/basics/installation/system-requirements/#php-compatibility-chart" >}}) ##### HTML / CSS / Javascript From 0560d17f6dc3eef37cb877e46272af53a491458b Mon Sep 17 00:00:00 2001 From: Jonathan Danse Date: Mon, 29 Aug 2022 22:04:55 +0200 Subject: [PATCH 021/310] Remove uneeded / at end of URL --- .../admin-controllers/override-decorate-controller.md | 2 +- .../extending-sf-form-with-upload-image-field.md | 5 +---- .../sample-modules/order-pages-new-hooks/signature-widget.md | 2 +- project/release/minor-release-lifecycle.md | 2 +- scale/benchmark/front-office.md | 4 +--- themes/getting-started/guidelines.md | 2 +- 6 files changed, 6 insertions(+), 11 deletions(-) mode change 100755 => 100644 scale/benchmark/front-office.md diff --git a/modules/concepts/controllers/admin-controllers/override-decorate-controller.md b/modules/concepts/controllers/admin-controllers/override-decorate-controller.md index c1173e1203..352223b77b 100644 --- a/modules/concepts/controllers/admin-controllers/override-decorate-controller.md +++ b/modules/concepts/controllers/admin-controllers/override-decorate-controller.md @@ -52,7 +52,7 @@ In the above example, the `path` has not been changed, but you can change it to {{% /notice %}} {{% notice warning %}} -Keep the item `_legacy_controller` if your controller relies on it to configure a [AdminSecurity annotation]({{< relref "/8/development/architecture/migration-guide/controller-routing/#access-rules-convention" >}}) such as `@AdminSecurity("is_granted('read', request.get('_legacy_controller'))")` +Keep the item `_legacy_controller` if your controller relies on it to configure a [AdminSecurity annotation]({{< relref "8/development/architecture/migration-guide/controller-routing#access-rules-convention" >}}) such as `@AdminSecurity("is_granted('read', request.get('_legacy_controller'))")` Keep the items `_legacy_controller` and `_legacy_link` if you want to reroute internal links and legacy URLs like `index.php?controller=AdminOrders` as well. {{% /notice %}} diff --git a/modules/sample-modules/extending-sf-form-with-upload-image-field.md b/modules/sample-modules/extending-sf-form-with-upload-image-field.md index 431a2a2f8c..59d64a4a8d 100644 --- a/modules/sample-modules/extending-sf-form-with-upload-image-field.md +++ b/modules/sample-modules/extending-sf-form-with-upload-image-field.md @@ -364,7 +364,7 @@ class SupplierExtraImageRepository extends EntityRepository Let's create hook `hookActionSupplierFormBuilderModifier` function inside Main module class. This is a hook available for [CRUD forms] -({{< relref "/8/modules/sample-modules/grid-and-identifiable-object-form-hooks-usage/" >}}) in +({{< relref "/8/modules/sample-modules/grid-and-identifiable-object-form-hooks-usage" >}}) in PrestaShop Symfony pages. ```php @@ -607,6 +607,3 @@ Let's add `UploadImage` function to main class: You can find the ready solution in PrestaShop example-modules github repository: https://github.com/PrestaShop/example-modules/tree/master/demoextendsymfonyform2 {{% /notice %}} - - - diff --git a/modules/sample-modules/order-pages-new-hooks/signature-widget.md b/modules/sample-modules/order-pages-new-hooks/signature-widget.md index 7615c82376..cf2ad9704a 100644 --- a/modules/sample-modules/order-pages-new-hooks/signature-widget.md +++ b/modules/sample-modules/order-pages-new-hooks/signature-widget.md @@ -554,7 +554,7 @@ Render a twig template method: For each registered hook, you must create a non-static public method, starting with the “hook” keyword followed by the name of the hook you want to use (starting with either “display” or “action”). In our case: `hookDisplayBackOfficeOrderActions` -([read this article for more information]({{< relref "/8//modules/concepts/hooks/#execution" >}})). +([read this article for more information]({{< relref "/8/modules/concepts/hooks#execution" >}})). We add this code at the bottom of the main module class `demovieworderhooks.php` and also add the missing `use` statements for new classes. diff --git a/project/release/minor-release-lifecycle.md b/project/release/minor-release-lifecycle.md index a2281e617e..d9e72d2373 100644 --- a/project/release/minor-release-lifecycle.md +++ b/project/release/minor-release-lifecycle.md @@ -56,7 +56,7 @@ For example, if you are a payment module developer, just installing your module If however you find a problem, you can - - [Report this as a bug on GitHub](https://github.com/PrestaShop/PrestaShop/issues) (read [how to report issues]({{< relref "/8/contribute/contribute-reporting-issues/" >}})) + - [Report this as a bug on GitHub](https://github.com/PrestaShop/PrestaShop/issues) (read [how to report issues]({{< relref "/8/contribute/contribute-reporting-issues" >}})) - Submit a bug fix by creating a [pull request](https://github.com/PrestaShop/PrestaShop/compare) (read the [contribution guidelines]({{< relref "/8/contribute/contribution-guidelines/" >}})) ## Release Candidate diff --git a/scale/benchmark/front-office.md b/scale/benchmark/front-office.md old mode 100755 new mode 100644 index 414d05171f..5bbe87a8b7 --- a/scale/benchmark/front-office.md +++ b/scale/benchmark/front-office.md @@ -8,7 +8,7 @@ How to benchmark your PrestaShop Shop (Front-office) ## Automatically benchmark with `Gatling` (recommended) -Follow instruction on **[Back-Office benchmark page]({{< relref "/8/scale/benchmark/back-office/" >}})** to get a pre-populated shop and to run Gatling scenarios on it. +Follow instruction on **[Back-Office benchmark page]({{< relref "/8/scale/benchmark/back-office" >}})** to get a pre-populated shop and to run Gatling scenarios on it. **[PrestaShop performance project](https://github.com/PrestaShop/performance-project)** on Github includes Front-Office scenarios you can edit to get your own scenarios running. @@ -118,5 +118,3 @@ concurrent user setting. ##### Failed transactions Closely related to Availability, the number of pages which have failed to load (404, 503, ...) - - diff --git a/themes/getting-started/guidelines.md b/themes/getting-started/guidelines.md index 3b6b05cd92..037271d7bc 100644 --- a/themes/getting-started/guidelines.md +++ b/themes/getting-started/guidelines.md @@ -10,7 +10,7 @@ weight: 1 ##### PHP Code -Your PHP code should be compatible with [PHP compatibility chart]({{< relref "8/basics/installation/system-requirements/#php-compatibility-chart" >}}) +Your PHP code should be compatible with [PHP compatibility chart]({{< relref "8/basics/installation/system-requirements#php-compatibility-chart" >}}) ##### HTML / CSS / Javascript From eb00bc6a60dfe31bcaf2caf3d55fc7d72d78a4d4 Mon Sep 17 00:00:00 2001 From: PululuK Date: Tue, 30 Aug 2022 01:34:38 +0200 Subject: [PATCH 022/310] Fix KpiRowHook location --- modules/concepts/hooks/list-of-hooks.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/concepts/hooks/list-of-hooks.md b/modules/concepts/hooks/list-of-hooks.md index 1d441ef8a1..4e432b7e52 100644 --- a/modules/concepts/hooks/list-of-hooks.md +++ b/modules/concepts/hooks/list-of-hooks.md @@ -2620,14 +2620,14 @@ validateCustomerFormFields : Located in: /classes/form/CustomerForm.php -actionKpiRowModifier +action<KpiIdentifier>KpiRowModifier : Available since: {{< minver v="1.7.6" >}} This hook allow to alter the list of Kpis used in a Kpi row. This hook is called just before the validation and the building of the KpiRow. - Located in: /controllers/front/listing/CategoryController.php + Located in: /src/Core/Kpi/Row/HookableKpiRowFactory.php Parameters: ```php From 26850027a97d7d6e9d6341a793125de3c6d2f1dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Fran=C3=A7ois=20Viguier?= <16720275+jf-viguier@users.noreply.github.com> Date: Wed, 31 Aug 2022 15:58:04 +0200 Subject: [PATCH 023/310] Add sendemail=1 to order_carriers endpoint --- webservice/getting-started.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/webservice/getting-started.md b/webservice/getting-started.md index c5f0937522..d479ac1f6d 100644 --- a/webservice/getting-started.md +++ b/webservice/getting-started.md @@ -234,6 +234,8 @@ The `language=1` or `language=[1|2]` parameter can be used to return only these The `sendemail=1` parameter can be used if you need to change the state of an order AND you want the emails to be sent to the customer: you will have to do a **POST** on `http://example.com/api/order_histories?sendemail=1` +The `sendemail=1` parameter can be used on order_carriers endpoint to send the in transit email with the tracking number. Example : `http://example.com/api/order_carriers/12345?sendemail=1` + ### Create a resource To create a resource, you simply need to **GET** the XML blank data for the resource (example `/api/addresses?schema=blank`), fill it with your changes, and send **POST HTTP request** with the whole XML as body content to the `/api/addresses/` URL. From 722f0f06dacdbd12494eca6bce49bf0d322329a3 Mon Sep 17 00:00:00 2001 From: PululuK Date: Thu, 1 Sep 2022 00:47:21 +0200 Subject: [PATCH 024/310] Update modules/concepts/hooks/list-of-hooks.md Co-authored-by: Jonathan Danse --- modules/concepts/hooks/list-of-hooks.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/concepts/hooks/list-of-hooks.md b/modules/concepts/hooks/list-of-hooks.md index 4e432b7e52..8f3bc2285a 100644 --- a/modules/concepts/hooks/list-of-hooks.md +++ b/modules/concepts/hooks/list-of-hooks.md @@ -2625,7 +2625,7 @@ action<KpiIdentifier>KpiRowModifier Available since: {{< minver v="1.7.6" >}} This hook allow to alter the list of Kpis used in a Kpi row. - This hook is called just before the validation and the building of the KpiRow. + This hook is called just before the validation and the building of the KpiRow. Located in: /src/Core/Kpi/Row/HookableKpiRowFactory.php From 1b7f704deb0a5b21544e7f84f8537ea4de394d47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Fran=C3=A7ois=20Viguier?= <16720275+jf-viguier@users.noreply.github.com> Date: Mon, 5 Sep 2022 10:01:54 +0200 Subject: [PATCH 025/310] update Co-authored-by: Krystian Podemski --- webservice/getting-started.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webservice/getting-started.md b/webservice/getting-started.md index d479ac1f6d..832f6de5a1 100644 --- a/webservice/getting-started.md +++ b/webservice/getting-started.md @@ -234,7 +234,7 @@ The `language=1` or `language=[1|2]` parameter can be used to return only these The `sendemail=1` parameter can be used if you need to change the state of an order AND you want the emails to be sent to the customer: you will have to do a **POST** on `http://example.com/api/order_histories?sendemail=1` -The `sendemail=1` parameter can be used on order_carriers endpoint to send the in transit email with the tracking number. Example : `http://example.com/api/order_carriers/12345?sendemail=1` +The `sendemail=1` parameter can be used on the `order_carriers` endpoint to send the _in-transit_ email with the tracking number. Example: `http://example.com/api/order_carriers/12345?sendemail=1` ### Create a resource From 49fa0b8d13b6dab0f868459d63484a4a3ed56d6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Fran=C3=A7ois=20Viguier?= <16720275+jf-viguier@users.noreply.github.com> Date: Mon, 5 Sep 2022 10:02:56 +0200 Subject: [PATCH 026/310] add id explanation --- webservice/getting-started.md | 1 + 1 file changed, 1 insertion(+) diff --git a/webservice/getting-started.md b/webservice/getting-started.md index 832f6de5a1..0a8c1a6f56 100644 --- a/webservice/getting-started.md +++ b/webservice/getting-started.md @@ -235,6 +235,7 @@ The `language=1` or `language=[1|2]` parameter can be used to return only these The `sendemail=1` parameter can be used if you need to change the state of an order AND you want the emails to be sent to the customer: you will have to do a **POST** on `http://example.com/api/order_histories?sendemail=1` The `sendemail=1` parameter can be used on the `order_carriers` endpoint to send the _in-transit_ email with the tracking number. Example: `http://example.com/api/order_carriers/12345?sendemail=1` +12345 is the order carrier id. ### Create a resource From d9b9e0bd6c2ef7e6c10b898d0d11d2a2e23c5776 Mon Sep 17 00:00:00 2001 From: "Carlos (carcam)" Date: Wed, 27 Apr 2022 06:15:25 +0200 Subject: [PATCH 027/310] Fix wrong url for composer.md --- modules/concepts/commands.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/concepts/commands.md b/modules/concepts/commands.md index 8bd02bffd3..34a03f7b5d 100644 --- a/modules/concepts/commands.md +++ b/modules/concepts/commands.md @@ -31,7 +31,7 @@ You need to create the file and register it as a "command". First you need to setup your composer file, you will find more info about it in [Setup composer][setup-composer] -[setup-composer]: {{< ref "/8/modules/concepts/services/_index.md#setup-composer" >}} +[setup-composer]: {{< ref "/8/modules/concepts/composer.md" >}} ### Creation of the command From 4030b6bd4f8e30122614a09a866335e13d72a7e9 Mon Sep 17 00:00:00 2001 From: Thomas Nares Date: Tue, 20 Sep 2022 16:45:54 +0200 Subject: [PATCH 028/310] Fix PSR issues Fix PSR issues --- .../mail-templates/add-a-layout-from-module.md | 15 ++++++++++----- .../mail-templates/add-a-theme-from-module.md | 15 ++++++++++----- .../add-layout-variables-from-module.md | 15 ++++++++++----- .../apply-transformation-from-module.md | 15 ++++++++++----- .../mail-templates/extend-a-layout-from-module.md | 15 ++++++++++----- 5 files changed, 50 insertions(+), 25 deletions(-) diff --git a/modules/concepts/mail-templates/add-a-layout-from-module.md b/modules/concepts/mail-templates/add-a-layout-from-module.md index 0242e92df4..107d18229d 100644 --- a/modules/concepts/mail-templates/add-a-layout-from-module.md +++ b/modules/concepts/mail-templates/add-a-layout-from-module.md @@ -68,27 +68,32 @@ use PrestaShop\PrestaShop\Core\MailTemplate\ThemeCatalogInterface; use PrestaShop\PrestaShop\Core\MailTemplate\ThemeCollectionInterface; use PrestaShop\PrestaShop\Core\MailTemplate\ThemeInterface; -class My_email_theme_module extends Module { - public function install() { +class MyEmailThemeModule extends Module +{ + public function install() + { return parent::install() // This class constant contains 'actionListMailThemes' && $this->registerHook(ThemeCatalogInterface::LIST_MAIL_THEMES_HOOK) ; } - public function uninstall() { + public function uninstall() + { return parent::uninstall() && $this->unregisterHook(ThemeCatalogInterface::LIST_MAIL_THEMES_HOOK) ; } - public function enable() { + public function enable() + { return parent::enable() && $this->registerHook(ThemeCatalogInterface::LIST_MAIL_THEMES_HOOK) ; } - public function disable() { + public function disable() + { return parent::disable() && $this->unregisterHook(ThemeCatalogInterface::LIST_MAIL_THEMES_HOOK) ; diff --git a/modules/concepts/mail-templates/add-a-theme-from-module.md b/modules/concepts/mail-templates/add-a-theme-from-module.md index 1d0200e882..cf71a83ed6 100644 --- a/modules/concepts/mail-templates/add-a-theme-from-module.md +++ b/modules/concepts/mail-templates/add-a-theme-from-module.md @@ -20,27 +20,32 @@ use PrestaShop\PrestaShop\Core\MailTemplate\ThemeCollectionInterface; use PrestaShop\PrestaShop\Core\MailTemplate\ThemeInterface; use PrestaShop\PrestaShop\Core\MailTemplate\FolderThemeScanner; -class My_email_theme_module extends Module { - public function install() { +class MyEmailThemeModule extends Module +{ + public function install() + { return parent::install() // This class constant contains 'actionListMailThemes' && $this->registerHook(ThemeCatalogInterface::LIST_MAIL_THEMES_HOOK) ; } - public function uninstall() { + public function uninstall() + { return parent::uninstall() && $this->unregisterHook(ThemeCatalogInterface::LIST_MAIL_THEMES_HOOK) ; } - public function enable() { + public function enable() + { return parent::enable() && $this->registerHook(ThemeCatalogInterface::LIST_MAIL_THEMES_HOOK) ; } - public function disable() { + public function disable() + { return parent::disable() && $this->unregisterHook(ThemeCatalogInterface::LIST_MAIL_THEMES_HOOK) ; diff --git a/modules/concepts/mail-templates/add-layout-variables-from-module.md b/modules/concepts/mail-templates/add-layout-variables-from-module.md index e2c996be9b..de4e5923cb 100644 --- a/modules/concepts/mail-templates/add-layout-variables-from-module.md +++ b/modules/concepts/mail-templates/add-layout-variables-from-module.md @@ -48,27 +48,32 @@ the `actionBuildMailLayoutVariables` hook. use PrestaShop\PrestaShop\Core\MailTemplate\Layout\LayoutVariablesBuilderInterface; use PrestaShop\PrestaShop\Core\MailTemplate\Layout\LayoutInterface; -class My_email_theme_module extends Module { - public function install() { +class MyEmailThemeModule extends Module +{ + public function install() + { return parent::install() // This class constant contains 'actionBuildMailLayoutVariables' && $this->registerHook(LayoutVariablesBuilderInterface::BUILD_MAIL_LAYOUT_VARIABLES_HOOK) ; } - public function uninstall() { + public function uninstall() + { return parent::uninstall() && $this->unregisterHook(LayoutVariablesBuilderInterface::BUILD_MAIL_LAYOUT_VARIABLES_HOOK) ; } - public function enable() { + public function enable() + { return parent::enable() && $this->registerHook(LayoutVariablesBuilderInterface::BUILD_MAIL_LAYOUT_VARIABLES_HOOK) ; } - public function disable() { + public function disable() + { return parent::disable() && $this->unregisterHook(LayoutVariablesBuilderInterface::BUILD_MAIL_LAYOUT_VARIABLES_HOOK) ; diff --git a/modules/concepts/mail-templates/apply-transformation-from-module.md b/modules/concepts/mail-templates/apply-transformation-from-module.md index d9c416aa7e..e6a9c9ef73 100644 --- a/modules/concepts/mail-templates/apply-transformation-from-module.md +++ b/modules/concepts/mail-templates/apply-transformation-from-module.md @@ -146,27 +146,32 @@ use PrestaShop\PrestaShop\Core\MailTemplate\Layout\LayoutInterface; use PrestaShop\PrestaShop\Core\MailTemplate\Transformation\TransformationCollectionInterface; use PrestaShop\Module\MyEmailThemeModule\MailTemplate\Transformation\CustomMessageColorTransformation; -class My_email_theme_module extends Module { - public function install() { +class MyEmailThemeModule extends Module +{ + public function install() + { return parent::install() // This class constant contains 'actionGetMailLayoutTransformations' && $this->registerHook(MailTemplateRendererInterface::GET_MAIL_LAYOUT_TRANSFORMATIONS) ; } - public function uninstall() { + public function uninstall() + { return parent::uninstall() && $this->unregisterHook(MailTemplateRendererInterface::GET_MAIL_LAYOUT_TRANSFORMATIONS) ; } - public function enable() { + public function enable() + { return parent::enable() && $this->registerHook(MailTemplateRendererInterface::GET_MAIL_LAYOUT_TRANSFORMATIONS) ; } - public function disable() { + public function disable() + { return parent::disable() && $this->unregisterHook(MailTemplateRendererInterface::GET_MAIL_LAYOUT_TRANSFORMATIONS) ; diff --git a/modules/concepts/mail-templates/extend-a-layout-from-module.md b/modules/concepts/mail-templates/extend-a-layout-from-module.md index 9fb997c051..893da04abc 100644 --- a/modules/concepts/mail-templates/extend-a-layout-from-module.md +++ b/modules/concepts/mail-templates/extend-a-layout-from-module.md @@ -40,27 +40,32 @@ use PrestaShop\PrestaShop\Core\MailTemplate\ThemeCatalogInterface; use PrestaShop\PrestaShop\Core\MailTemplate\ThemeCollectionInterface; use PrestaShop\PrestaShop\Core\MailTemplate\ThemeInterface; -class My_email_theme_module extends Module { - public function install() { +class MyEmailThemeModule extends Module +{ + public function install() + { return parent::install() // This class constant contains 'actionListMailThemes' && $this->registerHook(ThemeCatalogInterface::LIST_MAIL_THEMES_HOOK) ; } - public function uninstall() { + public function uninstall() + { return parent::uninstall() && $this->unregisterHook(ThemeCatalogInterface::LIST_MAIL_THEMES_HOOK) ; } - public function enable() { + public function enable() + { return parent::enable() && $this->registerHook(ThemeCatalogInterface::LIST_MAIL_THEMES_HOOK) ; } - public function disable() { + public function disable() + { return parent::disable() && $this->unregisterHook(ThemeCatalogInterface::LIST_MAIL_THEMES_HOOK) ; From fe953b49a9819f2be7ce1ceea6bd0bab5c8ad49d Mon Sep 17 00:00:00 2001 From: Paolo Gabrielli Date: Mon, 28 Mar 2022 15:35:50 +0200 Subject: [PATCH 029/310] Update upgrade.md Just tried an upgrade, and got an error, resolved cleaning the cache dir. ``` devshop@hosting:~/httpdocs$ /opt/plesk/php/7.2/bin/php install/upgrade/upgrade.php PHP Fatal error: Uncaught Symfony\Component\Debug\Exception\FatalThrowableError: Type error: Argument 1 passed to PrestaShopBundle\Service\DataProvider\Admin\CategoriesProvider::__construct() must be of the type array, object given, called in /var/www/vhosts/shop.example.com/httpdocs/var/cache/prod/ContainerYovgajs/appProdProjectContainer.php on line 2181 in /var/www/vhosts/shop.example.com/httpdocs/src/PrestaShopBundle/Service/DataProvider/Admin/CategoriesProvider.php:59 Stack trace: #0 /var/www/vhosts/shop.example.com/httpdocs/var/cache/prod/ContainerYovgajs/appProdProjectContainer.php(2181): PrestaShopBundle\Service\DataProvider\Admin\CategoriesProvider->__construct(Object(PrestaShopBundle\Service\DataProvider\Marketplace\ApiClient), Object(Symfony\Bridge\Monolog\Logger), Array, Array) #1 /var/www/vhosts/shop.example.com/httpdocs/var/cache/prod/ContainerYovgajs/appProdProjectContainer.php(2191): ContainerYovgajs\appProdProjectContainer->getPrestashop_CategoriesProviderService() #2 /var/www/vhosts/shop in /var/www/vhosts/shop.example.com/httpdocs/src/PrestaShopBundle/Service/DataProvider/Admin/CategoriesProvider.php on line 59 ``` --- basics/keeping-up-to-date/upgrade.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/basics/keeping-up-to-date/upgrade.md b/basics/keeping-up-to-date/upgrade.md index 1ad1f6bfd3..98dc59b8af 100644 --- a/basics/keeping-up-to-date/upgrade.md +++ b/basics/keeping-up-to-date/upgrade.md @@ -92,7 +92,7 @@ release content in the existing shop. ### Disable cache -You may have activated a caching system (eg. memcache) on your shop. In that case, make sure to disable it in "Advanced Parameters" > "Performance". You can enable it again once the upgrade process is done. +You may have activated a caching system (eg. memcache) on your shop. In that case, make sure to disable it in "Advanced Parameters" > "Performance". You can enable it again once the upgrade process is done. Please don't forget to also delete the var/cache/prod and var/cache/dev folders. **Note about `vendor` folder**: Previous upgrades of PrestaShop 1.7 showed that conflicts may occur when merging the new vendor/ folder with From e5646e60322a916f97e231f1439634f7130d89c6 Mon Sep 17 00:00:00 2001 From: Paolo Gabrielli Date: Wed, 20 Apr 2022 11:09:29 +0200 Subject: [PATCH 030/310] Fix english language style of the suggestion --- basics/keeping-up-to-date/upgrade.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/basics/keeping-up-to-date/upgrade.md b/basics/keeping-up-to-date/upgrade.md index 98dc59b8af..5f0f1d164e 100644 --- a/basics/keeping-up-to-date/upgrade.md +++ b/basics/keeping-up-to-date/upgrade.md @@ -92,7 +92,7 @@ release content in the existing shop. ### Disable cache -You may have activated a caching system (eg. memcache) on your shop. In that case, make sure to disable it in "Advanced Parameters" > "Performance". You can enable it again once the upgrade process is done. Please don't forget to also delete the var/cache/prod and var/cache/dev folders. +You may have activated a caching system (eg. memcache) on your shop. In that case, make sure to disable it in "Advanced Parameters" > "Performance". You can enable it again once the upgrade process is done. You might want to also delete the var/cache/prod and var/cache/dev folders. **Note about `vendor` folder**: Previous upgrades of PrestaShop 1.7 showed that conflicts may occur when merging the new vendor/ folder with From e5b0fdcfb7fac6221117755667a92696371fc026 Mon Sep 17 00:00:00 2001 From: Mathieu Ferment Date: Wed, 31 Aug 2022 22:09:00 +0200 Subject: [PATCH 031/310] Apply suggestions from code review Co-authored-by: Progi1984 --- basics/keeping-up-to-date/upgrade.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/basics/keeping-up-to-date/upgrade.md b/basics/keeping-up-to-date/upgrade.md index 5f0f1d164e..8fa6e236d6 100644 --- a/basics/keeping-up-to-date/upgrade.md +++ b/basics/keeping-up-to-date/upgrade.md @@ -92,7 +92,7 @@ release content in the existing shop. ### Disable cache -You may have activated a caching system (eg. memcache) on your shop. In that case, make sure to disable it in "Advanced Parameters" > "Performance". You can enable it again once the upgrade process is done. You might want to also delete the var/cache/prod and var/cache/dev folders. +You may have activated a caching system (eg. memcache) on your shop. In that case, make sure to disable it in "Advanced Parameters" > "Performance". You can enable it again once the upgrade process is done. You might want to also delete the `var/cache/prod` and `var/cache/dev` folders. **Note about `vendor` folder**: Previous upgrades of PrestaShop 1.7 showed that conflicts may occur when merging the new vendor/ folder with From ba09d7340068c9a9fb55584d91da4deef2940231 Mon Sep 17 00:00:00 2001 From: leemyongpakvn Date: Tue, 19 Apr 2022 11:23:02 +0700 Subject: [PATCH 032/310] Module error with namespace Foo\Repository Solution for the warning: Attempted to load class "ProductRepository" from namespace "Foo\Repository". Did you forget a "use" statement for another namespace? following https://stackoverflow.com/questions/52933943/prestashop-1-7-4-module-error-with-namespace --- .../hooks/use-hooks-on-modern-pages.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/modules/concepts/hooks/use-hooks-on-modern-pages.md b/modules/concepts/hooks/use-hooks-on-modern-pages.md index 6cbd7314fe..6059981d4f 100644 --- a/modules/concepts/hooks/use-hooks-on-modern-pages.md +++ b/modules/concepts/hooks/use-hooks-on-modern-pages.md @@ -153,6 +153,25 @@ Prestashop automatically checks if modules have a `config/services.yml` file and ``` ./bin/console cache:clear --no-warmup ``` +In case Prestashop failed to autoload automatically, make autoload with composer manually: + +- Install composer if you don't have https://getcomposer.org/ + +- Create inside the module's folder the file named composer.json and insert the below code +``` +{ + "autoload": { + "psr-4": { + "Foo\\": "classes/" + } + } +} +``` +- Open your terminal then go to your module folder and launch this command: +``` +php composer.phar dump-autoload -a +``` +This will generate a vendor folder, with inside composer folder and autoload.php file. You can now use it in your module (and everywhere in PrestaShop modern pages!): From 7eb98733787f1053b0f25533e1b68785fb5663d7 Mon Sep 17 00:00:00 2001 From: Mathieu Ferment Date: Mon, 9 May 2022 15:59:00 +0200 Subject: [PATCH 033/310] Update use-hooks-on-modern-pages.md --- .../hooks/use-hooks-on-modern-pages.md | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-) diff --git a/modules/concepts/hooks/use-hooks-on-modern-pages.md b/modules/concepts/hooks/use-hooks-on-modern-pages.md index 6059981d4f..6e0ea48a6e 100644 --- a/modules/concepts/hooks/use-hooks-on-modern-pages.md +++ b/modules/concepts/hooks/use-hooks-on-modern-pages.md @@ -153,24 +153,9 @@ Prestashop automatically checks if modules have a `config/services.yml` file and ``` ./bin/console cache:clear --no-warmup ``` -In case Prestashop failed to autoload automatically, make autoload with composer manually: -- Install composer if you don't have https://getcomposer.org/ +In case Prestashop failed to autoload automatically, [you can generate the autoload files][setup-composer] with composer manually. -- Create inside the module's folder the file named composer.json and insert the below code -``` -{ - "autoload": { - "psr-4": { - "Foo\\": "classes/" - } - } -} -``` -- Open your terminal then go to your module folder and launch this command: -``` -php composer.phar dump-autoload -a -``` This will generate a vendor folder, with inside composer folder and autoload.php file. You can now use it in your module (and everywhere in PrestaShop modern pages!): @@ -295,3 +280,5 @@ We have used a key for translation, making our own translations available in bac ![Export XML action button](https://i.imgur.com/5HExjcC.png) And "voila!", the module could be of course improved with so many features, adding filters on export for instance, using the `request` hook parameter and updating the Product repository. + +[setup-composer]: {{< ref "/1.7/modules/concepts/composer/#setup-composer-in-a-module" >}} From 6a18705103c00db0da289c848d100adbb52b4c2f Mon Sep 17 00:00:00 2001 From: Mathieu Ferment Date: Mon, 9 May 2022 16:03:37 +0200 Subject: [PATCH 034/310] Update use-hooks-on-modern-pages.md --- modules/concepts/hooks/use-hooks-on-modern-pages.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/concepts/hooks/use-hooks-on-modern-pages.md b/modules/concepts/hooks/use-hooks-on-modern-pages.md index 6e0ea48a6e..564bd29fa3 100644 --- a/modules/concepts/hooks/use-hooks-on-modern-pages.md +++ b/modules/concepts/hooks/use-hooks-on-modern-pages.md @@ -281,4 +281,5 @@ We have used a key for translation, making our own translations available in bac And "voila!", the module could be of course improved with so many features, adding filters on export for instance, using the `request` hook parameter and updating the Product repository. -[setup-composer]: {{< ref "/1.7/modules/concepts/composer/#setup-composer-in-a-module" >}} +[setup-composer]: {{< ref "/1.7/modules/concepts/composer/_index.md" >}} + From 49f2897b759667419396cd8498a9676d68eebc56 Mon Sep 17 00:00:00 2001 From: Thomas Nares Date: Wed, 21 Sep 2022 08:10:42 +0200 Subject: [PATCH 035/310] Fix typo on composer md page url --- modules/concepts/hooks/use-hooks-on-modern-pages.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/concepts/hooks/use-hooks-on-modern-pages.md b/modules/concepts/hooks/use-hooks-on-modern-pages.md index 564bd29fa3..604e8d27af 100644 --- a/modules/concepts/hooks/use-hooks-on-modern-pages.md +++ b/modules/concepts/hooks/use-hooks-on-modern-pages.md @@ -281,5 +281,5 @@ We have used a key for translation, making our own translations available in bac And "voila!", the module could be of course improved with so many features, adding filters on export for instance, using the `request` hook parameter and updating the Product repository. -[setup-composer]: {{< ref "/1.7/modules/concepts/composer/_index.md" >}} +[setup-composer]: {{< ref "/1.7/modules/concepts/composer.md" >}} From 1cc90ae675df31639812e9ed8e8641b2241a8609 Mon Sep 17 00:00:00 2001 From: Thomas Nares Date: Wed, 21 Sep 2022 08:19:46 +0200 Subject: [PATCH 036/310] Fix documentation version --- modules/concepts/hooks/use-hooks-on-modern-pages.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/concepts/hooks/use-hooks-on-modern-pages.md b/modules/concepts/hooks/use-hooks-on-modern-pages.md index 604e8d27af..669ffc3d2e 100644 --- a/modules/concepts/hooks/use-hooks-on-modern-pages.md +++ b/modules/concepts/hooks/use-hooks-on-modern-pages.md @@ -281,5 +281,5 @@ We have used a key for translation, making our own translations available in bac And "voila!", the module could be of course improved with so many features, adding filters on export for instance, using the `request` hook parameter and updating the Product repository. -[setup-composer]: {{< ref "/1.7/modules/concepts/composer.md" >}} +[setup-composer]: {{< ref "/8/modules/concepts/composer.md" >}} From 758ca0f3983e727a9f42aeb699f8591535fa81b5 Mon Sep 17 00:00:00 2001 From: Thomas Nares Date: Wed, 21 Sep 2022 08:50:27 +0200 Subject: [PATCH 037/310] fix minor typo MySQL --- .../components/faceted-search/inside-faceted-search-module.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/development/components/faceted-search/inside-faceted-search-module.md b/development/components/faceted-search/inside-faceted-search-module.md index 4be871b2ef..1df9231e18 100644 --- a/development/components/faceted-search/inside-faceted-search-module.md +++ b/development/components/faceted-search/inside-faceted-search-module.md @@ -94,7 +94,7 @@ Filter results are cached inside SQL in order to improve performance. Same query There were so many hooks used in the module that the hook actions have been moved outside of the main file, unlike many other modules. A hook dispatcher is in charge of linking the main module file and calling the right hooks. Hook actions will be found in `src/Hook` -### MysQL adapter +### MySQL adapter Inside `src/Adapter` is the code responsible for mapping faceted search queries to MySQL queries From b6da48e6bb6fe79602ca80677ac490639da746ba Mon Sep 17 00:00:00 2001 From: leemyongpakvn Date: Thu, 12 May 2022 10:50:28 +0700 Subject: [PATCH 038/310] spelling fix missing a 'd' character make wrong link --- webservice/tutorials/testing-access.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/webservice/tutorials/testing-access.md b/webservice/tutorials/testing-access.md index b3f7069b75..ee59e19afc 100644 --- a/webservice/tutorials/testing-access.md +++ b/webservice/tutorials/testing-access.md @@ -91,7 +91,7 @@ Let's see what they look like for the `address` resource. ### Blank schema -`/api/adresses?schema=blank` +`/api/addresses?schema=blank` ```xml @@ -126,7 +126,7 @@ Let's see what they look like for the `address` resource. ### Synopsis schema -`/api/adresses?schema=synopsis` +`/api/addresses?schema=synopsis` ```xml From 428e5d1f2549905532439a17c491b8c32a333532 Mon Sep 17 00:00:00 2001 From: Alexander Mandrov <45426001+Unsleeping@users.noreply.github.com> Date: Sun, 15 May 2022 00:05:51 +0200 Subject: [PATCH 039/310] Update _index.md --- development/architecture/file-structure/_index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/development/architecture/file-structure/_index.md b/development/architecture/file-structure/_index.md index 223430ba1c..577bf5f2d1 100644 --- a/development/architecture/file-structure/_index.md +++ b/development/architecture/file-structure/_index.md @@ -223,7 +223,7 @@ It contains the following subdirectories: - `/assets`: Script that allow building all static assets from sources. - `/build`: Used to create release packages. -- `/foreignkeyGenerator`: Creates forign keys for all tables (for educational purposes only) +- `/foreignkeyGenerator`: Creates foreign keys for all tables (for educational purposes only) - `/profiling`: Profiling tools for legacy classes ### /translations From 3cdfd21922e3a2304c072013756a33b55047c93a Mon Sep 17 00:00:00 2001 From: Alexander Mandrov <45426001+Unsleeping@users.noreply.github.com> Date: Sun, 15 May 2022 00:10:26 +0200 Subject: [PATCH 040/310] Update _index.md --- development/naming-conventions/_index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/development/naming-conventions/_index.md b/development/naming-conventions/_index.md index 7ecbced3d8..9a4838a79e 100644 --- a/development/naming-conventions/_index.md +++ b/development/naming-conventions/_index.md @@ -20,7 +20,7 @@ PrestaShop controllers follow these naming conventions: Actions follow these conventions: -- Action names names start with a lower case letter and end in _"Action"_ (e.g. `deleteAction`). +- Action names start with a lower case letter and end in _"Action"_ (e.g. `deleteAction`). - Action names should be clear and concise: `editAction()`, `savePrivateNoteAction()` are good examples, but `formAction()` or `processAction()` are not clear enough. - The main controller action should be named `indexAction`. - Some actions names are standardized: From bd5e6ad663c6eb7f45f4f0973b26033f4974bfce Mon Sep 17 00:00:00 2001 From: Alexander Mandrov <45426001+Unsleeping@users.noreply.github.com> Date: Sun, 15 May 2022 15:34:25 +0200 Subject: [PATCH 041/310] Update _index.md --- .../page-reference/back-office/order/add-new-order/_index.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/development/page-reference/back-office/order/add-new-order/_index.md b/development/page-reference/back-office/order/add-new-order/_index.md index b25b721e88..d5b95a6194 100644 --- a/development/page-reference/back-office/order/add-new-order/_index.md +++ b/development/page-reference/back-office/order/add-new-order/_index.md @@ -45,8 +45,8 @@ more information. When you enter the page, first thing you will notice is the `Customer` block: {{< figure src="./img/customer-search-block.png" title="Customer search block" >}} -Use the search to find desired customer by `email` or `name` or `create a new one` by pressing `Add new customer`. Customer search is performed using `ajax` by calling [CustomerController::searchAction](https://github.com/PrestaShop/PrestaShop/blob/develop/src/PrestaShopBundle/Controller/Admin/Sell/Customer/CustomerController.php). Javascript code can be found in [customer-manager.ts](https://github.com/PrestaShop/PrestaShop/blob/develop/admin-dev/themes/new-theme/js/pages/order/create/customer-manager.ts) - +Use the search to find desired customer by `email` or `name` or `create a new one` by pressing `Add new customer`. Customer search is performed using `ajax` by calling [CustomerController::searchAction](https://github.com/PrestaShop/PrestaShop/blob/develop/src/PrestaShopBundle/Controller/Admin/Sell/Customer/CustomerController.php). Javascript code can be found in [customer-manager.js](https://github.com/PrestaShop/PrestaShop/blob/develop/admin-dev/themes/new-theme/js/pages/order/create/customer-manager.js) + {{% notice %}} `Add new customer` button opens the same form from `Customers -> Customers -> Add new customer` loaded in an iframe. The `iframe` content is rendered using the `Lite Display` mode of the Back Office. {{% /notice %}} From b4abf6c7f9e6e380da07e761a2ad8e6cc62172bf Mon Sep 17 00:00:00 2001 From: Mathieu Ferment Date: Thu, 16 Jun 2022 17:41:17 +0200 Subject: [PATCH 042/310] Use 1.7.8.0 instead of develop for github links --- .../page-reference/back-office/order/add-new-order/_index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/development/page-reference/back-office/order/add-new-order/_index.md b/development/page-reference/back-office/order/add-new-order/_index.md index d5b95a6194..853a720fc4 100644 --- a/development/page-reference/back-office/order/add-new-order/_index.md +++ b/development/page-reference/back-office/order/add-new-order/_index.md @@ -45,7 +45,7 @@ more information. When you enter the page, first thing you will notice is the `Customer` block: {{< figure src="./img/customer-search-block.png" title="Customer search block" >}} -Use the search to find desired customer by `email` or `name` or `create a new one` by pressing `Add new customer`. Customer search is performed using `ajax` by calling [CustomerController::searchAction](https://github.com/PrestaShop/PrestaShop/blob/develop/src/PrestaShopBundle/Controller/Admin/Sell/Customer/CustomerController.php). Javascript code can be found in [customer-manager.js](https://github.com/PrestaShop/PrestaShop/blob/develop/admin-dev/themes/new-theme/js/pages/order/create/customer-manager.js) +Use the search to find desired customer by `email` or `name` or `create a new one` by pressing `Add new customer`. Customer search is performed using `ajax` by calling [CustomerController::searchAction](https://github.com/PrestaShop/PrestaShop/blob/1.7.8.0/src/PrestaShopBundle/Controller/Admin/Sell/Customer/CustomerController.php). Javascript code can be found in [customer-manager.js](https://github.com/PrestaShop/PrestaShop/blob/1.7.8.0/admin-dev/themes/new-theme/js/pages/order/create/customer-manager.js) {{% notice %}} `Add new customer` button opens the same form from `Customers -> Customers -> Add new customer` loaded in an iframe. The `iframe` content is rendered using the `Lite Display` mode of the Back Office. From 0368003327273f5b612cb4836b01f0d9a61a6c28 Mon Sep 17 00:00:00 2001 From: matks Date: Thu, 16 Jun 2022 17:47:36 +0200 Subject: [PATCH 043/310] Remove un-needed warning --- .../page-reference/back-office/order/add-new-order/_index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/development/page-reference/back-office/order/add-new-order/_index.md b/development/page-reference/back-office/order/add-new-order/_index.md index 853a720fc4..1abeaac9a0 100644 --- a/development/page-reference/back-office/order/add-new-order/_index.md +++ b/development/page-reference/back-office/order/add-new-order/_index.md @@ -46,7 +46,7 @@ When you enter the page, first thing you will notice is the `Customer` block: {{< figure src="./img/customer-search-block.png" title="Customer search block" >}} Use the search to find desired customer by `email` or `name` or `create a new one` by pressing `Add new customer`. Customer search is performed using `ajax` by calling [CustomerController::searchAction](https://github.com/PrestaShop/PrestaShop/blob/1.7.8.0/src/PrestaShopBundle/Controller/Admin/Sell/Customer/CustomerController.php). Javascript code can be found in [customer-manager.js](https://github.com/PrestaShop/PrestaShop/blob/1.7.8.0/admin-dev/themes/new-theme/js/pages/order/create/customer-manager.js) - + {{% notice %}} `Add new customer` button opens the same form from `Customers -> Customers -> Add new customer` loaded in an iframe. The `iframe` content is rendered using the `Lite Display` mode of the Back Office. {{% /notice %}} From fd4d72c7f9b6e5b81468b1cbf92fc40614985d17 Mon Sep 17 00:00:00 2001 From: Thomas Nares Date: Wed, 21 Sep 2022 10:39:07 +0200 Subject: [PATCH 044/310] fix references from develop to 8.0.x --- .../back-office/order/add-new-order/_index.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/development/page-reference/back-office/order/add-new-order/_index.md b/development/page-reference/back-office/order/add-new-order/_index.md index 1abeaac9a0..51e8ffb2a3 100644 --- a/development/page-reference/back-office/order/add-new-order/_index.md +++ b/development/page-reference/back-office/order/add-new-order/_index.md @@ -45,7 +45,7 @@ more information. When you enter the page, first thing you will notice is the `Customer` block: {{< figure src="./img/customer-search-block.png" title="Customer search block" >}} -Use the search to find desired customer by `email` or `name` or `create a new one` by pressing `Add new customer`. Customer search is performed using `ajax` by calling [CustomerController::searchAction](https://github.com/PrestaShop/PrestaShop/blob/1.7.8.0/src/PrestaShopBundle/Controller/Admin/Sell/Customer/CustomerController.php). Javascript code can be found in [customer-manager.js](https://github.com/PrestaShop/PrestaShop/blob/1.7.8.0/admin-dev/themes/new-theme/js/pages/order/create/customer-manager.js) +Use the search to find desired customer by `email` or `name` or `create a new one` by pressing `Add new customer`. Customer search is performed using `ajax` by calling [CustomerController::searchAction](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/Sell/Customer/CustomerController.php). Javascript code can be found in [customer-manager.js](https://github.com/PrestaShop/PrestaShop/blob/1.7.8.0/admin-dev/themes/new-theme/js/pages/order/create/customer-manager.js) {{% notice %}} `Add new customer` button opens the same form from `Customers -> Customers -> Add new customer` loaded in an iframe. The `iframe` content is rendered using the `Lite Display` mode of the Back Office. @@ -63,29 +63,29 @@ Once the customer is loaded, a new cart is created behind the scenes and the fol Details of each cart that was used by the customer can be checked by clicking on `Details` button - The `Sell -> Orders -> Shopping Carts -> View cart` page will be opened in a modal window. Existing `Cart` can be also used to create a new one - press `Use` and the selected `Cart` will be loaded and available for modifications. -This block is loaded using `ajax` by calling [CustomerController::getCartsAction](https://github.com/PrestaShop/PrestaShop/blob/develop/src/PrestaShopBundle/Controller/Admin/Sell/Customer/CustomerController.php). Related `javascript` code can be found in [customer-manager.ts](https://github.com/PrestaShop/PrestaShop/blob/develop/admin-dev/themes/new-theme/js/pages/order/create/customer-manager.ts) +This block is loaded using `ajax` by calling [CustomerController::getCartsAction](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/Sell/Customer/CustomerController.php). Related `javascript` code can be found in [customer-manager.ts](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/admin-dev/themes/new-theme/js/pages/order/create/customer-manager.ts) #### Customer orders list {{< figure src="./img/customer-orders-block.png" title="Customer orders" >}} Details of each order used by the customer can be checked by clicking on `Details` button - The `Sell -> Orders -> Carts -> View order` page will be opened in a modal window. Existing `Order` can be also used to create a new one - press `Use` and a new `Cart` will be created with all the information duplicated from the selected `Order`. -This block is loaded using `ajax` by calling [CustomerController::getOrdersAction](https://github.com/PrestaShop/PrestaShop/blob/develop/src/PrestaShopBundle/Controller/Admin/Sell/Customer/CustomerController.php). Related `javascript` code can be found in [customer-manager.ts](https://github.com/PrestaShop/PrestaShop/blob/develop/admin-dev/themes/new-theme/js/pages/order/create/customer-manager.ts) +This block is loaded using `ajax` by calling [CustomerController::getOrdersAction](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/Sell/Customer/CustomerController.php). Related `javascript` code can be found in [customer-manager.ts](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/admin-dev/themes/new-theme/js/pages/order/create/customer-manager.ts) #### Cart block {{< figure src="./img/cart-block.png" title="Cart" >}} -Cart block contains cart `products`, `currency` and `language` selection. Products can be searched and added to a cart. A list of products and a new block of [Cart rules]({{< relref "#cart-rules-block" >}}) will appear after a product is added. Listed products quantity and price can be modified. Related actions `addProductAction`, `editProductPriceAction` and `editProductQuantityAction` can be found in [CartController](https://github.com/PrestaShop/PrestaShop/blob/develop/src/PrestaShopBundle/Controller/Admin/Sell/Order/CartController.php) +Cart block contains cart `products`, `currency` and `language` selection. Products can be searched and added to a cart. A list of products and a new block of [Cart rules]({{< relref "#cart-rules-block" >}}) will appear after a product is added. Listed products quantity and price can be modified. Related actions `addProductAction`, `editProductPriceAction` and `editProductQuantityAction` can be found in [CartController](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/Sell/Order/CartController.php) {{< figure src="./img/products-list.png" title="Products list" >}} {{% notice %}} -Product price can be modified. This is similar behavior to the one in the `Order view page`, however behind the scenes it is different. Unlike in the `Order view page`, we don't have any `OrderDetail` yet, because at this point we are still modifying the `Cart`, so it is achieved by creating a new temporary [SpecificPrice](https://github.com/PrestaShop/PrestaShop/blob/1.7.8.x/classes/SpecificPrice.php) and assigning specifically to that certain `Cart`, `Product`, `Customer` and `Shop`. See [CartController::editProductPriceAction](https://github.com/PrestaShop/PrestaShop/blob/1.7.8.x/src/PrestaShopBundle/Controller/Admin/Sell/Order/CartController.php). +Product price can be modified. This is similar behavior to the one in the `Order view page`, however behind the scenes it is different. Unlike in the `Order view page`, we don't have any `OrderDetail` yet, because at this point we are still modifying the `Cart`, so it is achieved by creating a new temporary [SpecificPrice](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/SpecificPrice.php) and assigning specifically to that certain `Cart`, `Product`, `Customer` and `Shop`. See [CartController::editProductPriceAction](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/Sell/Order/CartController.php). {{% /notice %}} #### Cart rules block {{< figure src="./img/cart-rule-block.png" title="Vouchers" >}} -This block allows searching cart rules by name or code and adding them to the cart. Related actions can be found in [CartRuleController::searchAction](https://github.com/PrestaShop/PrestaShop/blob/develop/src/PrestaShopBundle/Controller/Admin/Sell/Catalog/CartRuleController.php) and [CartController::addCartRuleAction](https://github.com/PrestaShop/PrestaShop/blob/develop/src/PrestaShopBundle/Controller/Admin/Sell/Order/CartController.php) It is also possible to create a new `Cart rule` by clicking the `Add new voucher` button. +This block allows searching cart rules by name or code and adding them to the cart. Related actions can be found in [CartRuleController::searchAction](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/Sell/Catalog/CartRuleController.php) and [CartController::addCartRuleAction](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/Sell/Order/CartController.php) It is also possible to create a new `Cart rule` by clicking the `Add new voucher` button. {{% notice %}} `Add new voucher` button opens the same form from `Sell -> Catalog -> Discounts -> Add new cart rule` loaded in an `iframe`. @@ -105,13 +105,13 @@ The form in the modal is actually the same form from `Customers -> Addresses` pa Shipping block will appear only if at least one carrier is available for selected delivery address. This block allows selecting a carrier for the order, shows the shipping price and allows to mark the order as `Free shipping`. {{% notice %}} -When `Free shipping` is checked, behind the scenes, it is achieved by creating a new temporary [CartRule](https://github.com/PrestaShop/PrestaShop/blob/1.7.8.x/classes/CartRule.php) with `$free_shipping = true` and assigned to customer. See [UpdateCartDeliverySettingsHandler::handleFreeShippingOption](https://github.com/PrestaShop/PrestaShop/blob/1.7.8.x/src/Adapter/Cart/CommandHandler/UpdateCartDeliverySettingsHandler.php). +When `Free shipping` is checked, behind the scenes, it is achieved by creating a new temporary [CartRule](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/CartRule.php) with `$free_shipping = true` and assigned to customer. See [UpdateCartDeliverySettingsHandler::handleFreeShippingOption](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Cart/CommandHandler/UpdateCartDeliverySettingsHandler.php). {{% /notice %}} #### Summary block {{< figure src="./img/summary-block.png" title="Order summary block" >}} -This is the final block that requires selecting `payment method`, `order status` and allows submitting the whole form. Prior to that it also allows adding `a message for the customer` or `sending the email with the pre-filled order to the customer`. Once `Create the order` is clicked it uses the [OrderController::placeAction](https://github.com/PrestaShop/PrestaShop/blob/1.7.8.x/src/PrestaShopBundle/Controller/Admin/Sell/Order/OrderController.php) to create the order. +This is the final block that requires selecting `payment method`, `order status` and allows submitting the whole form. Prior to that it also allows adding `a message for the customer` or `sending the email with the pre-filled order to the customer`. Once `Create the order` is clicked it uses the [OrderController::placeAction](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/Sell/Order/OrderController.php) to create the order. {{% notice %}} You can also click `More actions -> Proceed to checkout in the front office` to finish up the order in the Front office of your shop. From 09486f4b2e16383db2d5953b5cae76f8095e9cf6 Mon Sep 17 00:00:00 2001 From: Thomas Nares Date: Wed, 21 Sep 2022 10:44:39 +0200 Subject: [PATCH 045/310] fix references from develop to 8.0.x --- .../page-reference/back-office/order/add-new-order/_index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/development/page-reference/back-office/order/add-new-order/_index.md b/development/page-reference/back-office/order/add-new-order/_index.md index 51e8ffb2a3..04b6f28ece 100644 --- a/development/page-reference/back-office/order/add-new-order/_index.md +++ b/development/page-reference/back-office/order/add-new-order/_index.md @@ -45,7 +45,7 @@ more information. When you enter the page, first thing you will notice is the `Customer` block: {{< figure src="./img/customer-search-block.png" title="Customer search block" >}} -Use the search to find desired customer by `email` or `name` or `create a new one` by pressing `Add new customer`. Customer search is performed using `ajax` by calling [CustomerController::searchAction](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/Sell/Customer/CustomerController.php). Javascript code can be found in [customer-manager.js](https://github.com/PrestaShop/PrestaShop/blob/1.7.8.0/admin-dev/themes/new-theme/js/pages/order/create/customer-manager.js) +Use the search to find desired customer by `email` or `name` or `create a new one` by pressing `Add new customer`. Customer search is performed using `ajax` by calling [CustomerController::searchAction](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/Sell/Customer/CustomerController.php). Javascript code can be found in [customer-manager.ts](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/admin-dev/themes/new-theme/js/pages/order/create/customer-manager.ts) {{% notice %}} `Add new customer` button opens the same form from `Customers -> Customers -> Add new customer` loaded in an iframe. The `iframe` content is rendered using the `Lite Display` mode of the Back Office. From e89711bcc0eff8e60c9f2a385bb73392f9810767 Mon Sep 17 00:00:00 2001 From: Thomas Nares Date: Wed, 21 Sep 2022 11:11:07 +0200 Subject: [PATCH 046/310] change referenced module name --- .../components/faceted-search/inside-faceted-search-module.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/development/components/faceted-search/inside-faceted-search-module.md b/development/components/faceted-search/inside-faceted-search-module.md index 1df9231e18..e3a5b113ba 100644 --- a/development/components/faceted-search/inside-faceted-search-module.md +++ b/development/components/faceted-search/inside-faceted-search-module.md @@ -53,7 +53,7 @@ Indexation results are stored in specific SQL tables. This allows to query flat ## Flow of the rendering process for displaying products on a category page 1. The core `CategoryController` executes a hook, searching for modules able to answer to a search request like "I need to fetch the products for the category with `id_category` === 4". See "How it's plugged on the Core" below. -2. A module (e.g. `blocklayered`) responds by returning an instance of a `ProductSearchProviderInterface` of its choosing +2. A module (e.g. `ps_facetedsearch`) responds by returning an instance of a `ProductSearchProviderInterface` of its choosing 3. The `CategoryController` retrieves the `ProductSearchProviderInterface` returned by the module and uses it to get the products. 4. The search provider returns a `ProductSearchResult`, it contains: - the products (which may just be an array like `[['id_product' => 2], ['id_product' => 3]]` - the core will add the missing data) From 9475f9921e0be8a46c43bb8c462f13c6c067fec0 Mon Sep 17 00:00:00 2001 From: Progi1984 Date: Wed, 21 Sep 2022 15:57:58 +0200 Subject: [PATCH 047/310] Testing : Reworking the menu (and redirect pages) --- .../how-to-create-your-own-behat-tests.md | 4 +++- .../how-to-create-your-own-symfony-controller-tests.md | 4 +++- ...ate-ui-tests.md => how-to-create-your-own-ui-tests.md} | 8 +++++--- .../{ => unit-tests}/how-to-create-your-own-unit-tests.md | 4 +++- 4 files changed, 14 insertions(+), 6 deletions(-) rename testing/{ => integration-tests}/how-to-create-your-own-behat-tests.md (99%) rename testing/{ => integration-tests}/how-to-create-your-own-symfony-controller-tests.md (92%) rename testing/ui-tests/{how-to-contribute-and-create-ui-tests.md => how-to-create-your-own-ui-tests.md} (98%) rename testing/{ => unit-tests}/how-to-create-your-own-unit-tests.md (92%) diff --git a/testing/how-to-create-your-own-behat-tests.md b/testing/integration-tests/how-to-create-your-own-behat-tests.md similarity index 99% rename from testing/how-to-create-your-own-behat-tests.md rename to testing/integration-tests/how-to-create-your-own-behat-tests.md index b493c421e3..a8d5704db0 100644 --- a/testing/how-to-create-your-own-behat-tests.md +++ b/testing/integration-tests/how-to-create-your-own-behat-tests.md @@ -1,7 +1,9 @@ --- title: How to create your own Behat tests menuTitle: Creating your own Behat tests -weight: 30 +weight: 20 +aliases: + - /8/testing/how-to-create-your-own-behat-tests/ --- # How to create your own Behat tests or add tests to PrestaShop diff --git a/testing/how-to-create-your-own-symfony-controller-tests.md b/testing/integration-tests/how-to-create-your-own-symfony-controller-tests.md similarity index 92% rename from testing/how-to-create-your-own-symfony-controller-tests.md rename to testing/integration-tests/how-to-create-your-own-symfony-controller-tests.md index 2c9c3956c8..88e0e98896 100644 --- a/testing/how-to-create-your-own-symfony-controller-tests.md +++ b/testing/integration-tests/how-to-create-your-own-symfony-controller-tests.md @@ -1,7 +1,9 @@ --- title: How to create your own symfony controller tests menuTitle: Creating your own symfony controller tests -weight: 20 +weight: 30 +aliases: + - /8/testing/how-to-create-your-own-symfony-controller-tests/ --- # How to create your own symfony controller tests or add tests to PrestaShop diff --git a/testing/ui-tests/how-to-contribute-and-create-ui-tests.md b/testing/ui-tests/how-to-create-your-own-ui-tests.md similarity index 98% rename from testing/ui-tests/how-to-contribute-and-create-ui-tests.md rename to testing/ui-tests/how-to-create-your-own-ui-tests.md index 7e70bf669e..4ab55dafeb 100644 --- a/testing/ui-tests/how-to-contribute-and-create-ui-tests.md +++ b/testing/ui-tests/how-to-create-your-own-ui-tests.md @@ -1,10 +1,12 @@ --- -title: How to contribute and create UI tests -menuTitle: Creation of UI tests +title: How to create your own UI tests +menuTitle: Creating your own UI tests weight: 2 +aliases: + - /8/testing/ui-tests/how-to-contribute-and-create-ui-tests/ --- -# How to contribute and create UI tests +# How to create your own UI tests ## Architecture [Page Object Model](https://martinfowler.com/bliki/PageObject.html) (also called Page Object Pattern) is a way to organize your code in a test framework. It encourages you to separate your test logic from your page manipulation logic. diff --git a/testing/how-to-create-your-own-unit-tests.md b/testing/unit-tests/how-to-create-your-own-unit-tests.md similarity index 92% rename from testing/how-to-create-your-own-unit-tests.md rename to testing/unit-tests/how-to-create-your-own-unit-tests.md index cb5f08a018..9f1e68e39f 100644 --- a/testing/how-to-create-your-own-unit-tests.md +++ b/testing/unit-tests/how-to-create-your-own-unit-tests.md @@ -1,7 +1,9 @@ --- title: How to create your own unit tests menuTitle: Creating your own unit tests -weight: 10 +weight: 20 +aliases: + - /8/testing/how-to-create-your-own-unit-tests/ --- # How to create your own unit tests or add tests to PrestaShop From 21a77996cd447735e7a48d6950ad6dfef61b2be1 Mon Sep 17 00:00:00 2001 From: Progi1984 Date: Wed, 21 Sep 2022 16:00:49 +0200 Subject: [PATCH 048/310] Testing : Execute tests --- .../integration-tests/how-to-execute-tests.md | 21 +++++++++++++++++++ testing/ui-tests/how-to-execute-tests.md | 9 ++++++++ .../how-to-execute-tests.md} | 21 ++++--------------- 3 files changed, 34 insertions(+), 17 deletions(-) create mode 100644 testing/integration-tests/how-to-execute-tests.md create mode 100644 testing/ui-tests/how-to-execute-tests.md rename testing/{how-to-launch-tests.md => unit-tests/how-to-execute-tests.md} (55%) diff --git a/testing/integration-tests/how-to-execute-tests.md b/testing/integration-tests/how-to-execute-tests.md new file mode 100644 index 0000000000..e78b626885 --- /dev/null +++ b/testing/integration-tests/how-to-execute-tests.md @@ -0,0 +1,21 @@ +--- +title: How to execute Integrations Tests +menuTitle: Executing integrations tests +weight: 10 +--- + +# How to execute Integrations Tests + +There are two integrations tests suite : + +* one for behat tests +* one for phpunit tests + +Each suite needs a specific PHPUnit configuration. This is why each test suite has a specific composer command: + +* `composer integration-tests` +* `composer integration-behaviour-tests` + +{{% notice tip %}} +You can execute the entire PHPUnit test suites using the `composer test-all` command. +{{% /notice %}} \ No newline at end of file diff --git a/testing/ui-tests/how-to-execute-tests.md b/testing/ui-tests/how-to-execute-tests.md new file mode 100644 index 0000000000..bfd6086e52 --- /dev/null +++ b/testing/ui-tests/how-to-execute-tests.md @@ -0,0 +1,9 @@ +--- +title: How to execute UI Tests +menuTitle: Executing UI tests +weight: 10 +--- + +# How to execute UI Tests + +This is thoroughly explained in the [Puppeteer tests Readme file](https://github.com/PrestaShop/PrestaShop/blob/develop/tests/UI/README.md). \ No newline at end of file diff --git a/testing/how-to-launch-tests.md b/testing/unit-tests/how-to-execute-tests.md similarity index 55% rename from testing/how-to-launch-tests.md rename to testing/unit-tests/how-to-execute-tests.md index f65a8b29cd..26fbb06763 100644 --- a/testing/how-to-launch-tests.md +++ b/testing/unit-tests/how-to-execute-tests.md @@ -1,32 +1,19 @@ --- -title: How to execute tests -menuTitle: Executing tests +title: How to execute Unit Tests +menuTitle: Executing unit tests weight: 10 --- -# How to execute the PrestaShop automatic test suite +# How to execute Unit Tests -## Executing Unit/integration test suites - -At least four test suites are available, testing different parts of PrestaShop: - -* Unit tests -* Integrations tests -* Functional tests - -Each suite needs a specific PHPUnit configuration. This is why each test suite has a specific composer command: +You can execute test suite with specific composer command: * `composer unit-tests` -* `composer integration-tests` -* `composer integration-behaviour-tests` {{% notice tip %}} You can execute the entire PHPUnit test suites using the `composer test-all` command. {{% /notice %}} -## Executing the Functional test suites - -This is thoroughly explained in the [Puppeteer tests Readme file](https://github.com/PrestaShop/PrestaShop/blob/develop/tests/UI/README.md). ## Executing only part of phpunit tests From 779d0a679d104163a2c33430e5bedb67512b868b Mon Sep 17 00:00:00 2001 From: Progi1984 Date: Wed, 21 Sep 2022 16:13:04 +0200 Subject: [PATCH 049/310] Testing : Improve index pages --- testing/_index.md | 14 +++++- testing/integration-tests/_index.md | 25 ++++++++++ testing/introduction.md | 62 ------------------------ testing/ui-tests/_index.md | 19 +++++--- testing/ui-tests/how-to-execute-tests.md | 3 +- testing/unit-tests/_index.md | 37 ++++++++++++++ 6 files changed, 89 insertions(+), 71 deletions(-) create mode 100644 testing/integration-tests/_index.md delete mode 100644 testing/introduction.md create mode 100644 testing/unit-tests/_index.md diff --git a/testing/_index.md b/testing/_index.md index b86e58e91f..1fc3dd33de 100644 --- a/testing/_index.md +++ b/testing/_index.md @@ -9,7 +9,17 @@ chapter: true # Testing -This section describes how PrestaShop Core is covered by automatic tests. +# How testing works in PrestaShop -{{% children %}} +PrestaShop is a complex software and uses automated testing to ensure that the new additions to the codebase do not break existing behaviors. + +Automated tests are located in `tests` folders + +## What kind of tests do PrestaShop use? + +In the `tests` folder, you will find: + +- [Integration tests](/8/testing/integration-tests/) +- [Unit tests](/8/testing/unit-tests/) +- [User interface tests](/8/testing/ui-tests/) diff --git a/testing/integration-tests/_index.md b/testing/integration-tests/_index.md new file mode 100644 index 0000000000..d5811770c0 --- /dev/null +++ b/testing/integration-tests/_index.md @@ -0,0 +1,25 @@ +--- +title: Integration tests +chapter: true +--- + +# Introduction + +Unit tests can validate the behavior of a php class when it can be isolated. +However, some classes cannot be validated this way. Moreover, a lot of logic from PrestaShop is written into complex SQL queries that cannot be validated by those kind of tests. This is why we also need integration tests. + +We use 2 technologies for the integration tests in the `Integration` folder: + +- [Behat](https://behat.org) for tests that are meaningful scenarios from a user point of view +- [PHPUnit](https://phpunit.de) for tests which rather answer the need to test the technical behavior of a class or a component + +## Stack + +We use the following stack: + +* [Behat](https://behat.org) +* [PHPUnit](https://phpunit.de) as test framework + +# Execute & Create tests + +{{% children %}} \ No newline at end of file diff --git a/testing/introduction.md b/testing/introduction.md deleted file mode 100644 index 26c1ed4103..0000000000 --- a/testing/introduction.md +++ /dev/null @@ -1,62 +0,0 @@ ---- -title: Introduction -weight: 1 ---- - -# How testing works in PrestaShop - -PrestaShop is a complex software and uses automated testing to ensure that the new additions to the codebase do not break existing behaviors. - -Automated tests are located in `tests` folders - -## What kind of tests do PrestaShop use? - -In the `tests` folder, you will find: - -- Unit tests -- Integration tests -- User interface tests - -### Unit tests - -Unit tests are powered by [PHPUnit][1]. They test one and only one php class, mocking/stubbing any dependencies that class has. - -This `Unit` folder meets some rules: - -- One php class = one test file. -- The test filepath must follow the class filepath/ -- Every dependency of the class must be replaced by [test doubles][2]. - -*If there is a hard-coded dependency such as a singleton pattern being used -or a static call, this class cannot be unit tested and should be tested using -integration tests.* - -#### Conventions - -- Use camelCase names for test function names. -- Try to make method names explain the *intent* of the test case as best as possible. Don't hesitate to write long method names if necessary. - - Bad example: `testGetPrice` (no idea what such a test is supposed to do) - - Good example: `testDiscountIsAppliedToFinalPrice` - -### Integration tests - -Unit tests can validate the behavior of a php class when it can be isolated. -However, some classes cannot be validated this way. Moreover, a lot of logic from PrestaShop is written into complex SQL queries that cannot be validated by those kind of tests. This is why we also need integration tests. - -We use 2 technologies for the integration tests in the `Integration` folder: - -- [Behat][3] for tests that are meaningful scenarios from a user point of view -- [PHPUnit][1] for tests which rather answer the need to test the technical behavior of a class or a component - -### User Interface tests - -Finally, we have some user interface tests (also sometimes referred to as web acceptance tests). These tests launch and control a browser that will then go on either the Front Office or the Back Office of a shop and perform several actions to check that the behavior, from the point of view of a browser, is as expected. So these tests send real HTTP requests and check the returned DOM. - -These tests can be found in `UI` folders. - -UI tests rely on [Playwright][4]. - -[1]: https://phpunit.de/ -[2]: https://martinfowler.com/articles/mocksArentStubs.html#TheDifferenceBetweenMocksAndStubs -[3]: https://behat.org/en/latest/ -[4]: https://github.com/microsoft/playwright/ diff --git a/testing/ui-tests/_index.md b/testing/ui-tests/_index.md index e38e77ced1..cc61ef6e0e 100644 --- a/testing/ui-tests/_index.md +++ b/testing/ui-tests/_index.md @@ -1,21 +1,28 @@ --- title: UI tests -weight: 30 chapter: true --- # Introduction +Finally, we have some user interface tests (also sometimes referred to as web acceptance tests). These tests launch and control a browser that will then go on either the Front Office or the Back Office of a shop and perform several actions to check that the behavior, from the point of view of a browser, is as expected. So these tests send real HTTP requests and check the returned DOM. + +These tests can be found in `UI` folders. + +UI tests rely on [Playwright](https://github.com/microsoft/playwright/). + +## Stack + UI tests work by controlling a browser and using the web interface like a real user. We use the following stack: * [Playwright](https://github.com/microsoft/playwright/) as automation tool -* [Mocha](https://mochajs.org/) as test framework -* [Chai](https://www.chaijs.com/) as assertion library +* [Mocha](https://mochajs.org) as test framework +* [Chai](https://www.chaijs.com) as assertion library * [Faker](https://github.com/marak/Faker.js/) as fake data generator -## Running web acceptance tests +# Execute & Create tests + +{{% children %}} -Everything is explained in [README](https://github.com/PrestaShop/PrestaShop/blob/develop/tests/UI/README.md) in the `tests/UI` folder. -You'll need a working installation of PrestaShop in order to run the tests. diff --git a/testing/ui-tests/how-to-execute-tests.md b/testing/ui-tests/how-to-execute-tests.md index bfd6086e52..3067698e45 100644 --- a/testing/ui-tests/how-to-execute-tests.md +++ b/testing/ui-tests/how-to-execute-tests.md @@ -6,4 +6,5 @@ weight: 10 # How to execute UI Tests -This is thoroughly explained in the [Puppeteer tests Readme file](https://github.com/PrestaShop/PrestaShop/blob/develop/tests/UI/README.md). \ No newline at end of file +This is thoroughly explained in [README](https://github.com/PrestaShop/PrestaShop/blob/develop/tests/UI/README.md) in the `tests/UI` folder. +You'll need a working installation of PrestaShop in order to run the tests. \ No newline at end of file diff --git a/testing/unit-tests/_index.md b/testing/unit-tests/_index.md new file mode 100644 index 0000000000..e9026624a6 --- /dev/null +++ b/testing/unit-tests/_index.md @@ -0,0 +1,37 @@ +--- +title: Integration tests +chapter: true +--- + +# Introduction + +Unit tests are powered by [PHPUnit](https://phpunit.de). They test one and only one php class, mocking/stubbing any dependencies that class has. + +This `Unit` folder meets some rules: + +- One php class = one test file. +- The test filepath must follow the class filepath/ +- Every dependency of the class must be replaced by [test doubles](https://martinfowler.com/articles/mocksArentStubs.html#TheDifferenceBetweenMocksAndStubs). + +*If there is a hard-coded dependency such as a singleton pattern being used +or a static call, this class cannot be unit tested and should be tested using +integration tests.* + +## Stack + +We use the following stack: + +* [PHPUnit](https://phpunit.de) as test framework + + +## Conventions + +- Use camelCase names for test function names. +- Try to make method names explain the *intent* of the test case as best as possible. Don't hesitate to write long method names if necessary. + - Bad example: `testGetPrice` (no idea what such a test is supposed to do) + - Good example: `testDiscountIsAppliedToFinalPrice` + + +# Execute & Create tests + +{{% children %}} \ No newline at end of file From b4d585dc27758a9833afc3c8a4e48b3169642086 Mon Sep 17 00:00:00 2001 From: Progi1984 Date: Wed, 21 Sep 2022 16:33:37 +0200 Subject: [PATCH 050/310] Testing : UI Tests (How to execute specific tests) --- testing/ui-tests/how-to-execute-tests.md | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/testing/ui-tests/how-to-execute-tests.md b/testing/ui-tests/how-to-execute-tests.md index 3067698e45..1ee92560ae 100644 --- a/testing/ui-tests/how-to-execute-tests.md +++ b/testing/ui-tests/how-to-execute-tests.md @@ -7,4 +7,17 @@ weight: 10 # How to execute UI Tests This is thoroughly explained in [README](https://github.com/PrestaShop/PrestaShop/blob/develop/tests/UI/README.md) in the `tests/UI` folder. -You'll need a working installation of PrestaShop in order to run the tests. \ No newline at end of file +You'll need a working installation of PrestaShop in order to run the tests. + +## How to execute specific tests + +If you want to run only one test from a campaign or a couple of tests in the same folder, you can use `test:specific` command. + +To specify which test to run, you can add the `TEST_PATH` parameter in the beginning of the command + +```bash +# To run the **Filter Products** test from sanity campaign +TEST_PATH="sanity/02_productsBO/01_filterProducts" URL_FO="https://domain.tld/" npm run test:specific +# To run all **Products BO** tests +TEST_PATH="sanity/02_productsBO/*" URL_FO="https://domain.tld/" npm run test:specific +``` \ No newline at end of file From 9095cddc384d6015ea59aacb95e45e95b59b9b40 Mon Sep 17 00:00:00 2001 From: Progi1984 Date: Wed, 21 Sep 2022 16:36:39 +0200 Subject: [PATCH 051/310] Testing : Remove last call of Puppeteer for Playwright --- modules/testing/resources.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/testing/resources.md b/modules/testing/resources.md index c39da4a9b7..0c07e84db9 100644 --- a/modules/testing/resources.md +++ b/modules/testing/resources.md @@ -140,7 +140,7 @@ php: ## Core Functional tests -PrestaShop provides its own test suite, running with puppeteer. It covers the features of PrestaShop and grows each time a bug is resolved or a feature is added. +PrestaShop provides its own test suite, running with Playwright. It covers the features of PrestaShop and grows each time a bug is resolved or a feature is added. These tests are launched every time a change is suggested to the core, but you can also run them with your module installed. This will ensure your module code does not break a critical feature of the core. From 40d0b1de378ac6932cf181da7d672c42a48e0e36 Mon Sep 17 00:00:00 2001 From: Progi1984 Date: Wed, 21 Sep 2022 16:39:13 +0200 Subject: [PATCH 052/310] Testing : Remove bad link --- contribute/contribute-pull-requests/contribute_using_docker.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contribute/contribute-pull-requests/contribute_using_docker.md b/contribute/contribute-pull-requests/contribute_using_docker.md index a32dfb8a84..5ad0ab2524 100644 --- a/contribute/contribute-pull-requests/contribute_using_docker.md +++ b/contribute/contribute-pull-requests/contribute_using_docker.md @@ -96,7 +96,7 @@ A good practice is to write meaningful commits messages: it's better to have "co ### Launch the test suite Your changes now sounds ok, and you're almost ready to share your changes with the community. -Before all, you may ensure your changes don't break everything: this is why we have multiple test suites you can use. Want to read more about tests in PrestaShop? Head to [this]({{< relref "/8/testing/introduction.md" >}}) page. +Before all, you may ensure your changes don't break everything: this is why we have multiple test suites you can use. Want to read more about tests in PrestaShop? Head to [this]({{< relref "/8/testing/" >}}) page. You can execute it in your dockerized PrestaShop application without altering your website (it uses a specific database). From 6fce1d917f7d4e7a9b40ce82ec463d3360b26ec0 Mon Sep 17 00:00:00 2001 From: Progi1984 Date: Wed, 21 Sep 2022 16:47:45 +0200 Subject: [PATCH 053/310] Apply suggestions from @boubkerbribri Co-authored-by: boubkerbribri <48441421+boubkerbribri@users.noreply.github.com> --- testing/ui-tests/_index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testing/ui-tests/_index.md b/testing/ui-tests/_index.md index cc61ef6e0e..6d12fd9b99 100644 --- a/testing/ui-tests/_index.md +++ b/testing/ui-tests/_index.md @@ -5,7 +5,7 @@ chapter: true # Introduction -Finally, we have some user interface tests (also sometimes referred to as web acceptance tests). These tests launch and control a browser that will then go on either the Front Office or the Back Office of a shop and perform several actions to check that the behavior, from the point of view of a browser, is as expected. So these tests send real HTTP requests and check the returned DOM. +Finally, we have some user interface tests (also sometimes referred to as web acceptance tests). These tests launch and control a browser, perform several actions to check that the behavior, from the point of view of a real user, is as expected. So these tests send real HTTP requests and check the returned DOM. These tests can be found in `UI` folders. From 84ac0b19403ec07225b04c8a7160a2fe492189d9 Mon Sep 17 00:00:00 2001 From: Thomas NARES Date: Wed, 21 Sep 2022 17:51:09 +0200 Subject: [PATCH 054/310] Update modules/concepts/hooks/use-hooks-on-modern-pages.md Co-authored-by: Krystian Podemski --- modules/concepts/hooks/use-hooks-on-modern-pages.md | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/concepts/hooks/use-hooks-on-modern-pages.md b/modules/concepts/hooks/use-hooks-on-modern-pages.md index 669ffc3d2e..82d19520ad 100644 --- a/modules/concepts/hooks/use-hooks-on-modern-pages.md +++ b/modules/concepts/hooks/use-hooks-on-modern-pages.md @@ -156,7 +156,6 @@ Prestashop automatically checks if modules have a `config/services.yml` file and In case Prestashop failed to autoload automatically, [you can generate the autoload files][setup-composer] with composer manually. -This will generate a vendor folder, with inside composer folder and autoload.php file. You can now use it in your module (and everywhere in PrestaShop modern pages!): From 8302e5576945cfbd01a0b5a259b17a3b543f3838 Mon Sep 17 00:00:00 2001 From: Thomas NARES Date: Wed, 21 Sep 2022 17:51:12 +0200 Subject: [PATCH 055/310] Update modules/concepts/hooks/use-hooks-on-modern-pages.md Co-authored-by: Krystian Podemski --- modules/concepts/hooks/use-hooks-on-modern-pages.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/concepts/hooks/use-hooks-on-modern-pages.md b/modules/concepts/hooks/use-hooks-on-modern-pages.md index 82d19520ad..7b51adc43d 100644 --- a/modules/concepts/hooks/use-hooks-on-modern-pages.md +++ b/modules/concepts/hooks/use-hooks-on-modern-pages.md @@ -154,7 +154,7 @@ Prestashop automatically checks if modules have a `config/services.yml` file and ./bin/console cache:clear --no-warmup ``` -In case Prestashop failed to autoload automatically, [you can generate the autoload files][setup-composer] with composer manually. +If PrestaShop fails to load files automatically, [you can generate the autoloader][setup-composer] with Composer. This will create a `vendor` directory with a Composer-based autoloader inside. You can now use it in your module (and everywhere in PrestaShop modern pages!): From 8e1e576487ec005663484b6620b1544f258d895a Mon Sep 17 00:00:00 2001 From: Thomas NARES Date: Wed, 21 Sep 2022 17:52:10 +0200 Subject: [PATCH 056/310] Update development/naming-conventions/_index.md Co-authored-by: Krystian Podemski --- development/naming-conventions/_index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/development/naming-conventions/_index.md b/development/naming-conventions/_index.md index 9a4838a79e..f52abac55f 100644 --- a/development/naming-conventions/_index.md +++ b/development/naming-conventions/_index.md @@ -20,7 +20,7 @@ PrestaShop controllers follow these naming conventions: Actions follow these conventions: -- Action names start with a lower case letter and end in _"Action"_ (e.g. `deleteAction`). +- Action names start with a lowercase letter and end in _"Action"_ (e.g. `deleteAction`). - Action names should be clear and concise: `editAction()`, `savePrivateNoteAction()` are good examples, but `formAction()` or `processAction()` are not clear enough. - The main controller action should be named `indexAction`. - Some actions names are standardized: From 51423d70efa02fbdf112a5eac1c25155dbd95700 Mon Sep 17 00:00:00 2001 From: Thomas NARES Date: Wed, 21 Sep 2022 17:53:03 +0200 Subject: [PATCH 057/310] Update basics/keeping-up-to-date/upgrade.md Co-authored-by: Krystian Podemski --- basics/keeping-up-to-date/upgrade.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/basics/keeping-up-to-date/upgrade.md b/basics/keeping-up-to-date/upgrade.md index 8fa6e236d6..52597f6b7b 100644 --- a/basics/keeping-up-to-date/upgrade.md +++ b/basics/keeping-up-to-date/upgrade.md @@ -92,7 +92,7 @@ release content in the existing shop. ### Disable cache -You may have activated a caching system (eg. memcache) on your shop. In that case, make sure to disable it in "Advanced Parameters" > "Performance". You can enable it again once the upgrade process is done. You might want to also delete the `var/cache/prod` and `var/cache/dev` folders. +You may have activated a caching system (e.g. Memcache) on your shop. In that case, make sure to disable it in "Advanced Parameters" > "Performance". You can enable it again once the upgrade process is done. You might want to also delete the `var/cache/prod` and `var/cache/dev` folders. **Note about `vendor` folder**: Previous upgrades of PrestaShop 1.7 showed that conflicts may occur when merging the new vendor/ folder with From 394017f2914ef1e10034cc46a71924bc1233ae3a Mon Sep 17 00:00:00 2001 From: leemyongpakvn Date: Thu, 22 Sep 2022 14:46:01 +0700 Subject: [PATCH 058/310] remove wrong link correct link was `noticed` 3 times above --- .../grid-and-identifiable-object-form-hooks-usage.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/modules/sample-modules/grid-and-identifiable-object-form-hooks-usage.md b/modules/sample-modules/grid-and-identifiable-object-form-hooks-usage.md index dac844b772..aad60241f0 100644 --- a/modules/sample-modules/grid-and-identifiable-object-form-hooks-usage.md +++ b/modules/sample-modules/grid-and-identifiable-object-form-hooks-usage.md @@ -341,6 +341,3 @@ private function updateCustomerReviewStatus(array $params) when we created the switch type form we named it `is_allowed_for_review`. By using the same name we can get the state (on or off). This hook receives from `$params` the form data, that you can retrieve like this: `$params['form_data']`. All the form data is available here, including `is_allowed_for_review` data which comes from the switch. - -You can find example module here: -https://github.com/PrestaShop/example-modules/tree/master/demoextendsymfonyform2 From bc79a1ac6a86a34dd15f4bc1f86c9b24189bce2f Mon Sep 17 00:00:00 2001 From: leemyongpakvn Date: Thu, 22 Sep 2022 15:07:29 +0700 Subject: [PATCH 059/310] PS 8.0.0 use doctrine-orm 2.7 https://github.com/PrestaShop/PrestaShop/blob/develop/composer.json#L38 --- .../grid-and-identifiable-object-form-hooks-usage.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/sample-modules/grid-and-identifiable-object-form-hooks-usage.md b/modules/sample-modules/grid-and-identifiable-object-form-hooks-usage.md index aad60241f0..737e711de1 100644 --- a/modules/sample-modules/grid-and-identifiable-object-form-hooks-usage.md +++ b/modules/sample-modules/grid-and-identifiable-object-form-hooks-usage.md @@ -175,7 +175,7 @@ Route name `ps_democqrshooksusage_toggle_is_allowed_for_review` matches the one ### Extending grid query builder By just extending grid definition we won't be able to display any data since we need to fetch it first. Luckily, we can add additional sql -conditions by extending [doctrine's query builder](https://www.doctrine-project.org/projects/doctrine-orm/en/2.6/reference/query-builder.html). +conditions by extending [doctrine's query builder](https://www.doctrine-project.org/projects/doctrine-orm/en/2.7/reference/query-builder.html). ```php Date: Thu, 22 Sep 2022 10:13:47 +0200 Subject: [PATCH 060/310] Testing : Fixes feedback from @kpodemski & @thomasnares --- modules/testing/resources.md | 2 +- testing/_index.md | 2 +- testing/integration-tests/_index.md | 20 +++++++---------- .../integration-tests/how-to-execute-tests.md | 14 ++++++------ testing/ui-tests/_index.md | 12 +++++----- testing/unit-tests/_index.md | 22 ++++++++++--------- testing/unit-tests/how-to-execute-tests.md | 2 +- 7 files changed, 36 insertions(+), 38 deletions(-) diff --git a/modules/testing/resources.md b/modules/testing/resources.md index 0c07e84db9..bf14f857dc 100644 --- a/modules/testing/resources.md +++ b/modules/testing/resources.md @@ -140,7 +140,7 @@ php: ## Core Functional tests -PrestaShop provides its own test suite, running with Playwright. It covers the features of PrestaShop and grows each time a bug is resolved or a feature is added. +PrestaShop provides its own test suite, running with [Playwright](https://playwright.dev). It covers the features of PrestaShop and grows each time a bug is resolved or a feature is added. These tests are launched every time a change is suggested to the core, but you can also run them with your module installed. This will ensure your module code does not break a critical feature of the core. diff --git a/testing/_index.md b/testing/_index.md index 1fc3dd33de..f66c0523f6 100644 --- a/testing/_index.md +++ b/testing/_index.md @@ -15,7 +15,7 @@ PrestaShop is a complex software and uses automated testing to ensure that the n Automated tests are located in `tests` folders -## What kind of tests do PrestaShop use? +## What kind of tests does PrestaShop use? In the `tests` folder, you will find: diff --git a/testing/integration-tests/_index.md b/testing/integration-tests/_index.md index d5811770c0..7ee3c6a94e 100644 --- a/testing/integration-tests/_index.md +++ b/testing/integration-tests/_index.md @@ -3,23 +3,19 @@ title: Integration tests chapter: true --- -# Introduction +# Integration tests +## Introduction -Unit tests can validate the behavior of a php class when it can be isolated. -However, some classes cannot be validated this way. Moreover, a lot of logic from PrestaShop is written into complex SQL queries that cannot be validated by those kind of tests. This is why we also need integration tests. +Unit tests can validate the behavior of a PHP class when it can be isolated. +However, some classes cannot be validated this way. Moreover, a lot of logic from PrestaShop is written into complex SQL queries that this kind of test cannot validate. This is why we also need integration tests. -We use 2 technologies for the integration tests in the `Integration` folder: - -- [Behat](https://behat.org) for tests that are meaningful scenarios from a user point of view -- [PHPUnit](https://phpunit.de) for tests which rather answer the need to test the technical behavior of a class or a component - -## Stack +### Stack We use the following stack: -* [Behat](https://behat.org) -* [PHPUnit](https://phpunit.de) as test framework +* [Behat](https://behat.org) for tests that are meaningful scenarios from a user point of view +* [PHPUnit](https://phpunit.de) for tests that instead answer the need to test the technical behavior of a class or a component -# Execute & Create tests +## Execute & Create tests {{% children %}} \ No newline at end of file diff --git a/testing/integration-tests/how-to-execute-tests.md b/testing/integration-tests/how-to-execute-tests.md index e78b626885..957d6e47e9 100644 --- a/testing/integration-tests/how-to-execute-tests.md +++ b/testing/integration-tests/how-to-execute-tests.md @@ -1,17 +1,17 @@ --- -title: How to execute Integrations Tests -menuTitle: Executing integrations tests +title: How to execute Integration Tests +menuTitle: Executing integration tests weight: 10 --- -# How to execute Integrations Tests +# How to execute Integration Tests -There are two integrations tests suite : +There are two integration tests suites : -* one for behat tests -* one for phpunit tests +* one using Behat +* one for PHPUnit tests -Each suite needs a specific PHPUnit configuration. This is why each test suite has a specific composer command: +Each suite needs a specific PHPUnit configuration. This is why each test suite has a specific Composer command: * `composer integration-tests` * `composer integration-behaviour-tests` diff --git a/testing/ui-tests/_index.md b/testing/ui-tests/_index.md index 6d12fd9b99..95bd44cc3c 100644 --- a/testing/ui-tests/_index.md +++ b/testing/ui-tests/_index.md @@ -3,15 +3,15 @@ title: UI tests chapter: true --- -# Introduction +# UI Tests -Finally, we have some user interface tests (also sometimes referred to as web acceptance tests). These tests launch and control a browser, perform several actions to check that the behavior, from the point of view of a real user, is as expected. So these tests send real HTTP requests and check the returned DOM. +## Introduction -These tests can be found in `UI` folders. +We have some user interface tests (sometimes called web acceptance tests). These tests launch and control a browser, and perform several actions to check that the behavior, from the point of view of a real user, is as expected. These tests send actual HTTP requests and check the returned [DOM](https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model/Introduction). -UI tests rely on [Playwright](https://github.com/microsoft/playwright/). +These tests can be found in `UI` folders. -## Stack +### Stack UI tests work by controlling a browser and using the web interface like a real user. @@ -22,7 +22,7 @@ We use the following stack: * [Chai](https://www.chaijs.com) as assertion library * [Faker](https://github.com/marak/Faker.js/) as fake data generator -# Execute & Create tests +## Execute & Create tests {{% children %}} diff --git a/testing/unit-tests/_index.md b/testing/unit-tests/_index.md index e9026624a6..dd99d54e3c 100644 --- a/testing/unit-tests/_index.md +++ b/testing/unit-tests/_index.md @@ -1,37 +1,39 @@ --- -title: Integration tests +title: Unit tests chapter: true --- -# Introduction +# Unit tests -Unit tests are powered by [PHPUnit](https://phpunit.de). They test one and only one php class, mocking/stubbing any dependencies that class has. +## Introduction + +Unit tests are powered by [PHPUnit](https://phpunit.de). They test one and only one PHP class, mocking/stubbing any dependencies that class might have. This `Unit` folder meets some rules: -- One php class = one test file. -- The test filepath must follow the class filepath/ -- Every dependency of the class must be replaced by [test doubles](https://martinfowler.com/articles/mocksArentStubs.html#TheDifferenceBetweenMocksAndStubs). +- One PHP class = one test file. +- The test file path must follow the class filepath/ +- Every class dependency must be replaced by [test doubles](https://martinfowler.com/articles/mocksArentStubs.html#TheDifferenceBetweenMocksAndStubs). *If there is a hard-coded dependency such as a singleton pattern being used or a static call, this class cannot be unit tested and should be tested using integration tests.* -## Stack +### Stack We use the following stack: * [PHPUnit](https://phpunit.de) as test framework -## Conventions +### Conventions -- Use camelCase names for test function names. +- Use `camelCase` names for test function names. - Try to make method names explain the *intent* of the test case as best as possible. Don't hesitate to write long method names if necessary. - Bad example: `testGetPrice` (no idea what such a test is supposed to do) - Good example: `testDiscountIsAppliedToFinalPrice` -# Execute & Create tests +## Execute & Create tests {{% children %}} \ No newline at end of file diff --git a/testing/unit-tests/how-to-execute-tests.md b/testing/unit-tests/how-to-execute-tests.md index 26fbb06763..0d5a6594ad 100644 --- a/testing/unit-tests/how-to-execute-tests.md +++ b/testing/unit-tests/how-to-execute-tests.md @@ -6,7 +6,7 @@ weight: 10 # How to execute Unit Tests -You can execute test suite with specific composer command: +You can execute the test suite with specific Composer command: * `composer unit-tests` From a59b265b58f88358c9fc4c40789b49cfe863ad6b Mon Sep 17 00:00:00 2001 From: leemyongpakvn Date: Fri, 23 Sep 2022 15:46:48 +0700 Subject: [PATCH 061/310] inconsistency between MarkDown and HugoServer ./ can not solve inconsistency. We still need 1 level jump up with ../ to make image links work in HugoServer :( --- modules/concepts/hooks/use-hooks-on-modern-pages.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/concepts/hooks/use-hooks-on-modern-pages.md b/modules/concepts/hooks/use-hooks-on-modern-pages.md index 7fce5ecdb7..5806d6185f 100644 --- a/modules/concepts/hooks/use-hooks-on-modern-pages.md +++ b/modules/concepts/hooks/use-hooks-on-modern-pages.md @@ -182,7 +182,7 @@ public function hookDisplayDashboardToolbarIcons($hookParams) In Product Catalog Page you should see the list of Products in debug toolbar in "Dump" section: -![Get products in Dump section](./Catalog_Products_dump.png) +![Get products in Dump section](../Catalog_Products_dump.png) #### Using the Symfony components to create an XML export file @@ -284,7 +284,7 @@ And now, the template: We have used a key for translation, making our own translations available in back office when using Twig. {{% /notice %}} -![Export XML action button](./Catalog_Products_2xml.png) +![Export XML action button](../Catalog_Products_2xml.png) And "voila!", the module could be of course improved with so many features, adding filters on export for instance, using the `request` hook parameter and updating the Product repository. From 6b285d6ac32d723e2bc135ad17eb509f5f285b70 Mon Sep 17 00:00:00 2001 From: Krystian Podemski Date: Wed, 28 Sep 2022 23:02:45 +0200 Subject: [PATCH 062/310] Update basics/keeping-up-to-date/migration.md --- basics/keeping-up-to-date/migration.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/basics/keeping-up-to-date/migration.md b/basics/keeping-up-to-date/migration.md index 7b270ed4c5..0b3646b3b7 100644 --- a/basics/keeping-up-to-date/migration.md +++ b/basics/keeping-up-to-date/migration.md @@ -635,4 +635,6 @@ automatic, because: Useful links: -- [Learning how-to use the webservice API](https://doc.prestashop.com/display/PS16/Using+the+PrestaShop+Web+Service) +- [Learning how to use the webservice API]([web-service]) + +[web-service]: {{< ref "1.7/webservice" >}} From ab99e58ef85889f3f542cccbf24e54861d1ec4bb Mon Sep 17 00:00:00 2001 From: Krystian Podemski Date: Wed, 28 Sep 2022 23:03:21 +0200 Subject: [PATCH 063/310] Update basics/keeping-up-to-date/migration.md --- basics/keeping-up-to-date/migration.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/basics/keeping-up-to-date/migration.md b/basics/keeping-up-to-date/migration.md index 0b3646b3b7..1b2c19c221 100644 --- a/basics/keeping-up-to-date/migration.md +++ b/basics/keeping-up-to-date/migration.md @@ -635,6 +635,6 @@ automatic, because: Useful links: -- [Learning how to use the webservice API]([web-service]) +- [Learning how to use the webservice API][web-service] [web-service]: {{< ref "1.7/webservice" >}} From d436697351ea14516addc4cb712eeeddbc5531f1 Mon Sep 17 00:00:00 2001 From: Krystian Podemski Date: Wed, 28 Sep 2022 23:03:59 +0200 Subject: [PATCH 064/310] Update basics/keeping-up-to-date/migration.md --- basics/keeping-up-to-date/migration.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/basics/keeping-up-to-date/migration.md b/basics/keeping-up-to-date/migration.md index 1b2c19c221..cfd887c74e 100644 --- a/basics/keeping-up-to-date/migration.md +++ b/basics/keeping-up-to-date/migration.md @@ -637,4 +637,4 @@ Useful links: - [Learning how to use the webservice API][web-service] -[web-service]: {{< ref "1.7/webservice" >}} +[web-service]: {{< ref "8/webservice" >}} From 1b6fbc40cb3f60bf8173714d5103e75a9f524ec5 Mon Sep 17 00:00:00 2001 From: Krystian Podemski Date: Wed, 28 Sep 2022 23:04:25 +0200 Subject: [PATCH 065/310] Update basics/keeping-up-to-date/migration.md --- basics/keeping-up-to-date/migration.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/basics/keeping-up-to-date/migration.md b/basics/keeping-up-to-date/migration.md index cfd887c74e..83f46d5017 100644 --- a/basics/keeping-up-to-date/migration.md +++ b/basics/keeping-up-to-date/migration.md @@ -635,6 +635,6 @@ automatic, because: Useful links: -- [Learning how to use the webservice API][web-service] +- [How to use the webservice API][web-service] [web-service]: {{< ref "8/webservice" >}} From 25ab02626b595494b5a029da8dd97a3a12c39ed8 Mon Sep 17 00:00:00 2001 From: Krystian Podemski Date: Wed, 28 Sep 2022 23:17:20 +0200 Subject: [PATCH 066/310] Apply suggestions from code review --- modules/sample-modules/order-pages-new-hooks/module-base.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/sample-modules/order-pages-new-hooks/module-base.md b/modules/sample-modules/order-pages-new-hooks/module-base.md index 24effc67db..5728bf7957 100644 --- a/modules/sample-modules/order-pages-new-hooks/module-base.md +++ b/modules/sample-modules/order-pages-new-hooks/module-base.md @@ -119,10 +119,10 @@ class FixturesInstaller } } ``` -Lets create `Installer` class inside `/demovieworderhooks/src/Install` folder structure. +Let's create `Installer` class inside `/demovieworderhooks/src/Install` folder structure. It is responsible only for module installation (hook registration, database creation, population database data). When it comes to database creation we use PrestaShop `DbCore` class -functions because doctrine is [not fully supported for modules installation]({{< relref "/8/modules/concepts/doctrine/#creating-the-database" >}}) at 1.7.7.0 release. +functions because [Doctrine](https://symfony.com/doc/4.4/doctrine) is [not fully supported for modules installation]({{< relref "/8/modules/concepts/doctrine/#creating-the-database" >}}) at 1.7.7.0 release. ```php Date: Wed, 21 Sep 2022 17:42:54 +0200 Subject: [PATCH 067/310] Fix references from develop to 8.0.x --- .../contribution-guidelines/pull-requests.md | 2 +- .../architecture/domain/domain-services.md | 28 +++++++++---------- .../migration-guide/controller-routing.md | 2 +- .../migration-guide/forms/CRUD-forms.md | 2 +- .../migration-guide/forms/settings-forms.md | 4 +-- .../architecture/migration-guide/hooks.md | 4 +-- .../migration-guide/testing/behat.md | 10 +++---- .../migration-guide/validation.md | 4 +-- .../architecture/modern/controller-routing.md | 6 ++-- development/coding-standards/_index.md | 2 +- .../components/console/context-helper.md | 2 +- development/multistore/shop-context/_index.md | 2 +- .../admin-controllers/route-generation.md | 2 +- modules/concepts/widgets.md | 2 +- modules/creation/good-practices.md | 2 +- modules/payment/_index.md | 4 +-- testing/ui-tests/_index.md | 2 ++ .../how-to-create-your-own-ui-tests.md | 2 +- testing/unit-tests/how-to-execute-tests.md | 3 ++ themes/getting-started/guidelines.md | 4 +-- themes/reference/templates/notifications.md | 4 +-- 21 files changed, 49 insertions(+), 44 deletions(-) diff --git a/contribute/contribution-guidelines/pull-requests.md b/contribute/contribution-guidelines/pull-requests.md index 3de6f9adec..621a7b01e5 100644 --- a/contribute/contribution-guidelines/pull-requests.md +++ b/contribute/contribution-guidelines/pull-requests.md @@ -95,7 +95,7 @@ Remember, this is only needed for the Pull Request form, not for your commit mes {{% notice note %}} **Why is this important?** -We use type & category to group changes in the [changelog](https://github.com/PrestaShop/PrestaShop/blob/develop/docs/CHANGELOG.txt). +We use type & category to group changes in the [changelog](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/docs/CHANGELOG.txt). {{% /notice %}} ### BC breaks diff --git a/development/architecture/domain/domain-services.md b/development/architecture/domain/domain-services.md index e3582ca075..405873920f 100644 --- a/development/architecture/domain/domain-services.md +++ b/development/architecture/domain/domain-services.md @@ -17,35 +17,35 @@ Here are some principles for implementing a Domain Service: 2. If it uses any legacy service or object model, then it MUST be placed in the `Adapter` namespace. 3. If it needs to perform a sql query and related `ObjectModel` exists, then this query MUST be delegated to the appropriate repository class which must ensure that no legacy exceptions are thrown. If the related `ObjectModel` already implements such method, then the repository must delegate its implementation to the `ObjectModel`. {{% notice %}} - Some reusable methods are present in [AbstractObjectModelRepository](https://github.com/PrestaShop/PrestaShop/blob/1.7.8.x/src/Adapter/AbstractObjectModelRepository.php). + Some reusable methods are present in [AbstractObjectModelRepository](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/AbstractObjectModelRepository.php). {{% /notice %}} -4. If `ObjectModel` contains fields validation, it MUST be validated by a dedicated validator class before persisting to database (e.g. when using `add`/`update`/`save` methods). It ensures that legacy [PrestashopException](https://github.com/PrestaShop/PrestaShop/blob/1.7.8.x/classes/exception/PrestaShopException.php) is not bubbling up and each validation error can be identified by a dedicated exception or exception code. +4. If `ObjectModel` contains fields validation, it MUST be validated by a dedicated validator class before persisting to database (e.g. when using `add`/`update`/`save` methods). It ensures that legacy [PrestashopException](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/exception/PrestaShopException.php) is not bubbling up and each validation error can be identified by a dedicated exception or exception code. {{% notice %}} - Some reusable methods are present in [AbstractObjectModelValidator](https://github.com/PrestaShop/PrestaShop/blob/1.7.8.x/src/Adapter/AbstractObjectModelValidator.php). + Some reusable methods are present in [AbstractObjectModelValidator](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/AbstractObjectModelValidator.php). {{% /notice %}} # Code examples ## `ObjectModel` repositories -1. [ProductRepository](https://github.com/PrestaShop/PrestaShop/blob/1.7.8.x/src/Adapter/Product/Repository/ProductRepository.php) -2. [ProductSupplierRepository](https://github.com/PrestaShop/PrestaShop/blob/1.7.8.x/src/Adapter/Product/Repository/ProductSupplierRepository.php) -3. [VirtualProductFileRepository](https://github.com/PrestaShop/PrestaShop/blob/1.7.8.x/src/Adapter/Product/VirtualProduct/Repository/VirtualProductFileRepository.php) -4. [SpecificPriceRepository](https://github.com/PrestaShop/PrestaShop/blob/1.7.8.x/src/Adapter/Product/SpecificPrice/Repository/SpecificPriceRepository.php) +1. [ProductRepository](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Product/Repository/ProductRepository.php) +2. [ProductSupplierRepository](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Product/Repository/ProductSupplierRepository.php) +3. [VirtualProductFileRepository](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Product/VirtualProduct/Repository/VirtualProductFileRepository.php) +4. [SpecificPriceRepository](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Product/SpecificPrice/Repository/SpecificPriceRepository.php) ## `ObjectModel` validators -1. [ProductValidator](https://github.com/PrestaShop/PrestaShop/blob/1.7.8.x/src/Adapter/Product/Validate/ProductValidator.php) -2. [ProductSupplierValidator](https://github.com/PrestaShop/PrestaShop/blob/1.7.8.x/src/Adapter/Product/Validate/ProductSupplierValidator.php) -2. [VirtualProductFileValidator](https://github.com/PrestaShop/PrestaShop/blob/1.7.8.x/src/Adapter/Product/VirtualProduct/Validate/VirtualProductFileValidator.php) -3. [SpecificPriceValidator](https://github.com/PrestaShop/PrestaShop/blob/1.7.8.x/src/Adapter/Product/SpecificPrice/Validate/SpecificPriceValidator.php) +1. [ProductValidator](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Product/Validate/ProductValidator.php) +2. [ProductSupplierValidator](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Product/Validate/ProductSupplierValidator.php) +2. [VirtualProductFileValidator](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Product/VirtualProduct/Validate/VirtualProductFileValidator.php) +3. [SpecificPriceValidator](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Product/SpecificPrice/Validate/SpecificPriceValidator.php) ## Product domain services 1. [Product update services](https://github.com/PrestaShop/PrestaShop/tree/1.7.8.x/src/Adapter/Product/Update) -2. [Virtual product update services](https://github.com/PrestaShop/PrestaShop/blob/1.7.8.x/src/Adapter/Product/VirtualProduct/Update) -2. [Combination update services](https://github.com/PrestaShop/PrestaShop/blob/1.7.8.x/src/Adapter/Product/Combination/Update) -2. [Combination create services](https://github.com/PrestaShop/PrestaShop/blob/1.7.8.x/src/Adapter/Product/Combination/Create) +2. [Virtual product update services](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Product/VirtualProduct/Update) +2. [Combination update services](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Product/Combination/Update) +2. [Combination create services](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Product/Combination/Create) ## Service usage in `CommandHandler` examples diff --git a/development/architecture/migration-guide/controller-routing.md b/development/architecture/migration-guide/controller-routing.md index 570ca314fe..fcf05acd58 100644 --- a/development/architecture/migration-guide/controller-routing.md +++ b/development/architecture/migration-guide/controller-routing.md @@ -21,5 +21,5 @@ Controllers are responsible for performing "Actions". Actions are methods of Con 5. **Try to avoid creating helper methods in your controller.** If you find yourself needing them, that might mean the Controller is becoming too complex. This can be solved by extracting the code into dedicated services. {{% notice %}} -You can take a look at [PerformanceController](https://github.com/PrestaShop/PrestaShop/blob/1.7.8.x/src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/PerformanceController.php) for an example of good implementation, and [ProductController](https://github.com/PrestaShop/PrestaShop/blob/1.7.8.x/src/PrestaShopBundle/Controller/Admin/ProductController.php) for something you should avoid at all costs. +You can take a look at [PerformanceController](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/PerformanceController.php) for an example of good implementation, and [ProductController](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/ProductController.php) for something you should avoid at all costs. {{% /notice %}} diff --git a/development/architecture/migration-guide/forms/CRUD-forms.md b/development/architecture/migration-guide/forms/CRUD-forms.md index ef1329655a..9676a68c78 100644 --- a/development/architecture/migration-guide/forms/CRUD-forms.md +++ b/development/architecture/migration-guide/forms/CRUD-forms.md @@ -460,7 +460,7 @@ and The core actually uses CQRS to handle data persistence, which raises a `DomainException` in case of a constraint error (for example, if the identifiable object you are trying to edit doesn't exist). This is handled in the controller by wrapping the code in a try-catch block, then flashing an error message accordingly. -For more details, check out the [ContactsController source code on GitHub](https://github.com/PrestaShop/PrestaShop/blob/develop/src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/ContactsController.php). +For more details, check out the [ContactsController source code on GitHub](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/ContactsController.php). {{% /notice %}} diff --git a/development/architecture/migration-guide/forms/settings-forms.md b/development/architecture/migration-guide/forms/settings-forms.md index 0e44515d24..29d0300b3c 100644 --- a/development/architecture/migration-guide/forms/settings-forms.md +++ b/development/architecture/migration-guide/forms/settings-forms.md @@ -92,7 +92,7 @@ Let's look at the arguments one by one: ## Form request handling in Controllers -In modern pages, Controllers have or should have only one responsibility: handle the User request and return a response. This is why in modern pages, controllers should be as thin as possible and rely on specific classes (services) to manage the data. As always, check out the existing implementations, like in the [PerformanceController](https://github.com/PrestaShop/PrestaShop/blob/develop/src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/PerformanceController.php). +In modern pages, Controllers have or should have only one responsibility: handle the User request and return a response. This is why in modern pages, controllers should be as thin as possible and rely on specific classes (services) to manage the data. As always, check out the existing implementations, like in the [PerformanceController](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/PerformanceController.php). This is how we manage a form submit inside a Controller: @@ -151,7 +151,7 @@ You can update this schema using the [source XML file](/8/schemas/form-submit.xm ## Render the form using Twig -The rendering of forms in Twig is already described by the [Symfony documentation](https://symfony.com/doc/4.4/form/rendering.html). PrestaShop uses its own [Form theme](https://github.com/PrestaShop/PrestaShop/blob/develop/src/PrestaShopBundle/Resources/views/Admin/TwigTemplateForm/prestashop_ui_kit.html.twig) that contains specific markup for the PrestaShop UI Kit. You can see it as a customized version of Symfony's Bootstrap 4 form theme, even though it's not directly based on it. +The rendering of forms in Twig is already described by the [Symfony documentation](https://symfony.com/doc/4.4/form/rendering.html). PrestaShop uses its own [Form theme](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Resources/views/Admin/TwigTemplateForm/prestashop_ui_kit.html.twig) that contains specific markup for the PrestaShop UI Kit. You can see it as a customized version of Symfony's Bootstrap 4 form theme, even though it's not directly based on it. To sum up how it works, the controller sends an instance of `FormView` to Twig and Twig uses form helpers to render the right markup for every field type (the Form theme defines a specific markup for each Form Type). diff --git a/development/architecture/migration-guide/hooks.md b/development/architecture/migration-guide/hooks.md index 6ef6c5c2af..60719a4cca 100644 --- a/development/architecture/migration-guide/hooks.md +++ b/development/architecture/migration-guide/hooks.md @@ -14,7 +14,7 @@ Getting the list of available Hooks in modern pages is really easy. Thanks to th Use this trick to find out which hooks are called on a legacy page. -In ``classes/Hook``, find the [exec() function](https://github.com/PrestaShop/PrestaShop/blob/develop/classes/Hook.php#L733) and add the following code: +In ``classes/Hook``, find the [exec() function](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Hook.php#L733) and add the following code: ```php dispatchHook('actionAdminPerformanceControllerPostProcessBefore', array(' ## Dispatching hooks using the Hook dispatcher -If you need to dispatch a hook from a non-controller class, you'll need to inject the [HookDispatcher](https://github.com/PrestaShop/PrestaShop/blob/develop/src/Core/Hook/HookDispatcher.php) class. +If you need to dispatch a hook from a non-controller class, you'll need to inject the [HookDispatcher](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Core/Hook/HookDispatcher.php) class. If your class is defined as a Symfony service, the HookDispatcher is available as a service called `prestashop.core.hook.dispatcher`. diff --git a/development/architecture/migration-guide/testing/behat.md b/development/architecture/migration-guide/testing/behat.md index a2665702d3..d891be9f20 100644 --- a/development/architecture/migration-guide/testing/behat.md +++ b/development/architecture/migration-guide/testing/behat.md @@ -18,7 +18,7 @@ A behaviour (`behat`) tests are a part of integration tests. They allow testing During behat tests the actual database queries are executed, therefore before testing you need to run a command `composer create-test-db` to create a test database. {{% notice %}} -The `create-test-db` script installs a fresh prestashop with fixtures in a new database called `test_{your database name}` and dumps the database in your machine `/tmp` directory named `ps_dump_database_name_8.0.0.sql`. That `ps_dump_database_name_8.0.0.sql` is later used to reset the database. You can check the actual script for more information - [/tests/bin/create-test-db.php](https://github.com/PrestaShop/PrestaShop/blob/develop/tests/bin/create-test-db.php). +The `create-test-db` script installs a fresh prestashop with fixtures in a new database called `test_{your database name}` and dumps the database in your machine `/tmp` directory named `ps_dump_database_name_8.0.0.sql`. That `ps_dump_database_name_8.0.0.sql` is later used to reset the database. You can check the actual script for more information - [/tests/bin/create-test-db.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/tests/bin/create-test-db.php). {{% /notice %}} ### Tables dump @@ -88,10 +88,10 @@ The behat `Context` files are classes that contains the implementations of the f The most recent `Context` files are located in [`Tests/Integration/Behaviour/Features/Context/Domain`](https://github.com/PrestaShop/PrestaShop/tree/develop/tests/Integration/Behaviour/Features/Context/Domain) namespace, so try to use these and avoid the ones from the `Tests/Integration/Behaviour/Features/Context/*` namespace (those are old and might not be implemented well). {{% /notice%}} -When creating a new Context class, it should extend the [`AbstractDomainFeatureContext`](https://github.com/PrestaShop/PrestaShop/blob/develop/tests/Integration/Behaviour/Features/Context/Domain/AbstractDomainFeatureContext.php). +When creating a new Context class, it should extend the [`AbstractDomainFeatureContext`](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/tests/Integration/Behaviour/Features/Context/Domain/AbstractDomainFeatureContext.php). {{% notice %}} -The [`AbstractDomainFeatureContext`](https://github.com/PrestaShop/PrestaShop/blob/develop/tests/Integration/Behaviour/Features/Context/Domain/AbstractDomainFeatureContext.php) contains some commonly used helper methods, and it implements the `Behat\Behat\Context` which is necessary for these tests to work. +The [`AbstractDomainFeatureContext`](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/tests/Integration/Behaviour/Features/Context/Domain/AbstractDomainFeatureContext.php) contains some commonly used helper methods, and it implements the `Behat\Behat\Context` which is necessary for these tests to work. {{% /notice %}} This is how the context looks like: @@ -133,7 +133,7 @@ As you can see in example, the string `@Given I add order :orderReference with t ## Shared storage -The [SharedStorage](https://github.com/PrestaShop/PrestaShop/blob/develop/tests/Integration/Behaviour/Features/Context/SharedStorage.php) is responsible for holding certain values in memory which are shared across the feature. The most common usage example is the `id` reference - we specify a certain keyword e.g. `product1` before creating it, and once the command returns the auto-incremented value, we set it in shared storage like this `SharedStorage::getStorage()->set($orderReference, $orderId->getValue());`. In upcoming scenarios we can reuse this reference to get the record, something like this: +The [SharedStorage](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/tests/Integration/Behaviour/Features/Context/SharedStorage.php) is responsible for holding certain values in memory which are shared across the feature. The most common usage example is the `id` reference - we specify a certain keyword e.g. `product1` before creating it, and once the command returns the auto-incremented value, we set it in shared storage like this `SharedStorage::getStorage()->set($orderReference, $orderId->getValue());`. In upcoming scenarios we can reuse this reference to get the record, something like this: ```php protected function getProductForEditing(string $reference): ProductForEditing { @@ -147,7 +147,7 @@ The [SharedStorage](https://github.com/PrestaShop/PrestaShop/blob/develop/tests/ ## Hooks -Behats allow you to use [hooks](https://docs.behat.org/en/v2.5/guides/3.hooks.html#hooks). You can find some usages in [CommonFeatureContext](https://github.com/PrestaShop/PrestaShop/blob/develop/tests/Integration/Behaviour/Features/Context/CommonFeatureContext.php). You can use these hooked methods by tagging them before the `Feature` (or before `Scenario` depending on the hook type), like this ([add_product.feature](https://github.com/PrestaShop/PrestaShop/blob/develop/tests/Integration/Behaviour/Features/Context/Domain/Product/AddProductFeatureContext.php) +Behats allow you to use [hooks](https://docs.behat.org/en/v2.5/guides/3.hooks.html#hooks). You can find some usages in [CommonFeatureContext](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/tests/Integration/Behaviour/Features/Context/CommonFeatureContext.php). You can use these hooked methods by tagging them before the `Feature` (or before `Scenario` depending on the hook type), like this ([add_product.feature](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/tests/Integration/Behaviour/Features/Context/Domain/Product/AddProductFeatureContext.php) ): ```feature diff --git a/development/architecture/migration-guide/validation.md b/development/architecture/migration-guide/validation.md index 43df7c52af..6e89ef82f2 100644 --- a/development/architecture/migration-guide/validation.md +++ b/development/architecture/migration-guide/validation.md @@ -7,12 +7,12 @@ weight: 70 The purpose of validation is to protect the application from failures, state inconsistency, security related issues etc. PrestaShop has few different levels of validation: * **Forms** (the [CRUD]({{}}) or [Settings]({{}})) - are using [Symfony validation constraints](https://symfony.com/doc/4.4/validation.html#constraints) to prevent the user from providing invalid information while also enriching the user experience. For example if a form input expects `Yes` or `No`, but user submitted value `XYZ` we want to reject the data and inform the user what was wrong. The best approach (if possible) is to prevent user providing the wrong value in the first place, so in this example we could simply use a checkbox or select input with only 2 possible selections. There are some custom constraints implemented in PrestaShop [here](https://github.com/PrestaShop/PrestaShop/tree/1.7.8.x/src/Core/ConstraintValidator). -* [Value objects]({{< relref "/8/development/architecture/domain/value_objects" >}}) - after the form is submitted and validated, controller is usually dispatching some `Command`. We must ensure that commands are valid too, because in theory, commands should not be aware whether they were dispatched from a controller or from a command line, therefore it is possible that inputs are not yet validated by the form. The `command` itself should not handle the validation (although there are some older commands that does that, but that might only be some early migration mistakes), but **use the value objects in the constructor instead**. Value objects have their own validation rules and can be reused in any other command. For example, take a look at [ProductCondition](https://github.com/PrestaShop/PrestaShop/blob/1.7.8.x/src/Core/Domain/Product/ValueObject/ProductCondition.php) - this is a value object of `Product` domain. It allows constructing specific values and throws `ProductConstraintException` if invalid one is provided. It is currently used in [UpdateProductOptionsCommand](https://github.com/PrestaShop/PrestaShop/1.7.8.x/develop/src/Core/Domain/Product/Command/UpdateProductOptionsCommand.php) and helps to maintain the command validity. +* [Value objects]({{< relref "/8/development/architecture/domain/value_objects" >}}) - after the form is submitted and validated, controller is usually dispatching some `Command`. We must ensure that commands are valid too, because in theory, commands should not be aware whether they were dispatched from a controller or from a command line, therefore it is possible that inputs are not yet validated by the form. The `command` itself should not handle the validation (although there are some older commands that does that, but that might only be some early migration mistakes), but **use the value objects in the constructor instead**. Value objects have their own validation rules and can be reused in any other command. For example, take a look at [ProductCondition](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Core/Domain/Product/ValueObject/ProductCondition.php) - this is a value object of `Product` domain. It allows constructing specific values and throws `ProductConstraintException` if invalid one is provided. It is currently used in [UpdateProductOptionsCommand](https://github.com/PrestaShop/PrestaShop/1.7.8.x/develop/src/Core/Domain/Product/Command/UpdateProductOptionsCommand.php) and helps to maintain the command validity. * [Domain services]({{< relref "/8/development/architecture/domain/domain-services" >}}) - after the command is constructed and dispatched, it reaches the `CommandHandler`, which calls all the needed `Domain services` (there are also lots of `CommandHandlers` that handles all the logic including the validation by themselves, but it is not recommended anymore and should be perceived as migration mistakes). Domain services can perform final checks (e.g. heavy sql queries to check certain records existence) before performing the `write` operations. * **Entities** (or the `ObjectModels` in Prestashop) - This is the last level. It is there to prevent data integrity issues (like attempting to store a string into an integer column). This is something that, if all data validations before were done correctly, should rarely happen. This is the last step before data is being persisted: if invalid data has slipped through validation levels and passes this step, then it is persisted in database and might introduce inconsistency in the application. If these errors still occur, you might get a legacy `PrestaShopException`, but in recent migration process we try to catch it early and replace it by related `CoreException` or `DomainException`. See more in [Domain services]({{< relref "/8/development/architecture/domain/domain-services" >}}). {{% notice tip %}} -Sometimes it is worth introducing `{SomeDomain}Settings` class, which holds some simple validation constants like `length` or `regex` pattern. This is advised when field has only one validation rule, and it is not worth adding a dedicated Value object just for that. For example, see [AddressSettings](https://github.com/PrestaShop/PrestaShop/blob/1.7.8.x/src/Core/Domain/Address/AddressSettings.php). +Sometimes it is worth introducing `{SomeDomain}Settings` class, which holds some simple validation constants like `length` or `regex` pattern. This is advised when field has only one validation rule, and it is not worth adding a dedicated Value object just for that. For example, see [AddressSettings](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Core/Domain/Address/AddressSettings.php). It is advised to replace the hardcoded values in related `ObjectModel` validation fields with such constants (same for `value object` constants - once we have a constant, we reuse it everywhere as a **single source of truth**). {{% /notice %}} diff --git a/development/architecture/modern/controller-routing.md b/development/architecture/modern/controller-routing.md index cbae328682..e3822a6d46 100644 --- a/development/architecture/modern/controller-routing.md +++ b/development/architecture/modern/controller-routing.md @@ -8,7 +8,7 @@ title: Symfony controllers & routing Read the Symfony documentation on [Controllers](https://symfony.com/doc/4.4/controller.html) and [Routing](https://symfony.com/doc/4.4/routing.html). {{% /notice %}} -Controllers are located in `src/PrestaShopBundle/Controller/Admin` folder. They are organized in sub-folders following the Back Office menu. For instance, the [TaxController](https://github.com/PrestaShop/PrestaShop/blob/1.7.8.x/src/PrestaShopBundle/Controller/Admin/Improve/International/TaxController.php) is located in `src/PrestaShop/Controller/Admin/Improve/International`. +Controllers are located in `src/PrestaShopBundle/Controller/Admin` folder. They are organized in sub-folders following the Back Office menu. For instance, the [TaxController](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/Improve/International/TaxController.php) is located in `src/PrestaShop/Controller/Admin/Improve/International`. Same applies to **Improve**, **Sell** sections etc. This is how the directory tree of controllers should look like: @@ -39,7 +39,7 @@ Symfony Controllers should be thin by default and have only one responsibility: * Validation * etc... -You can take a look at [PerformanceController](https://github.com/PrestaShop/PrestaShop/blob/develop/src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/PerformanceController.php) for an example of good implementation, and [ProductController](https://github.com/PrestaShop/PrestaShop/blob/develop/src/PrestaShopBundle/Controller/Admin/ProductController.php) for something you should avoid at all costs. +You can take a look at [PerformanceController](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/PerformanceController.php) for an example of good implementation, and [ProductController](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/ProductController.php) for something you should avoid at all costs. {{% notice warning %}} **Never, ever call the legacy controller inside the new controller**. It's a no go, no matter the reason! @@ -306,4 +306,4 @@ redirected to the new migrated url. ### Javascript generation -In order to avoid hardcoded links in JavaScript, Prestashop uses the [`Router` component](https://github.com/PrestaShop/PrestaShop/blob/1.7.8.x/admin-dev/themes/new-theme/js/components/router.js). +In order to avoid hardcoded links in JavaScript, Prestashop uses the [`Router` component](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/admin-dev/themes/new-theme/js/components/router.js). diff --git a/development/coding-standards/_index.md b/development/coding-standards/_index.md index ef5b16c054..7dcecf2444 100644 --- a/development/coding-standards/_index.md +++ b/development/coding-standards/_index.md @@ -47,7 +47,7 @@ You can run it using the following command: php ./vendor/bin/php-cs-fixer fix ``` -The prestashop specific configuration file [can be found here](https://github.com/PrestaShop/PrestaShop/blob/develop/.php-cs-fixer.dist.php). Also, you can also use the provided [git pre-commit](https://github.com/PrestaShop/PrestaShop/tree/develop/.github/contrib) sample in order to make sure you never forget to make your code compliant! +The prestashop specific configuration file [can be found here](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/.php-cs-fixer.dist.php). Also, you can also use the provided [git pre-commit](https://github.com/PrestaShop/PrestaShop/tree/develop/.github/contrib) sample in order to make sure you never forget to make your code compliant! ### Documenting types diff --git a/development/components/console/context-helper.md b/development/components/console/context-helper.md index 679e8425e9..03d8a527b5 100644 --- a/development/components/console/context-helper.md +++ b/development/components/console/context-helper.md @@ -33,4 +33,4 @@ MyCustomCommand extends ContainerAwareCommand }); ``` -You can load a generic context thanks to `loadGenericContext()` or choose which data you want to initialize using the method of [LegacyContextLoader](https://github.com/PrestaShop/PrestaShop/blob/1.7.8.x/src/Adapter/LegacyContextLoader.php). +You can load a generic context thanks to `loadGenericContext()` or choose which data you want to initialize using the method of [LegacyContextLoader](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/LegacyContextLoader.php). diff --git a/development/multistore/shop-context/_index.md b/development/multistore/shop-context/_index.md index efd6afe0e5..8ef9176da0 100644 --- a/development/multistore/shop-context/_index.md +++ b/development/multistore/shop-context/_index.md @@ -77,4 +77,4 @@ $shopList = $shopContext->getContextListShopID(); $currentIdShop = $shopContext->getContextShopID(); ``` -The shop context adapter class has many functions with self-explanatory naming and helpful comments, feel free to [explore it by yourself](https://github.com/PrestaShop/PrestaShop/blob/develop/src/Adapter/Shop/Context.php). +The shop context adapter class has many functions with self-explanatory naming and helpful comments, feel free to [explore it by yourself](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Shop/Context.php). diff --git a/modules/concepts/controllers/admin-controllers/route-generation.md b/modules/concepts/controllers/admin-controllers/route-generation.md index 62bca5fe55..7979d721e4 100644 --- a/modules/concepts/controllers/admin-controllers/route-generation.md +++ b/modules/concepts/controllers/admin-controllers/route-generation.md @@ -135,7 +135,7 @@ This will only work for **one route/one controller** the association by action d {{% /notice %}} #### Javascript routes -In order to generate a symfony route in javascript, you can use the [`Router` component](https://github.com/PrestaShop/PrestaShop/blob/1.7.8.x/admin-dev/themes/new-theme/js/components/router.js). +In order to generate a symfony route in javascript, you can use the [`Router` component](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/admin-dev/themes/new-theme/js/components/router.js). You can use it like this: ``` diff --git a/modules/concepts/widgets.md b/modules/concepts/widgets.md index 576b19d288..aa8881a633 100644 --- a/modules/concepts/widgets.md +++ b/modules/concepts/widgets.md @@ -35,7 +35,7 @@ In order to be widget-compliant, a module needs to follow two steps: Before calling a module for widgets, the core must be sure your module has this feature available. This can be done by implementing the interface `PrestaShop\PrestaShop\Core\Module\WidgetInterface` -([Source code](https://github.com/PrestaShop/PrestaShop/blob/develop/src/Core/Module/WidgetInterface.php)). +([Source code](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Core/Module/WidgetInterface.php)). ### Declare mandatory methods diff --git a/modules/creation/good-practices.md b/modules/creation/good-practices.md index 2168712a9a..9c1b97e6fb 100644 --- a/modules/creation/good-practices.md +++ b/modules/creation/good-practices.md @@ -52,7 +52,7 @@ menuTitle: Good practices - When your module has forms, you should: - show a confirmation message if everything went fine or an error message if it did not. - - make sure information entered by customers are correct. If you ask a sum, it has to be only numbers. More information about the Validate class of PrestaShop [here](https://github.com/PrestaShop/PrestaShop/blob/develop/classes/Validate.php). + - make sure information entered by customers are correct. If you ask a sum, it has to be only numbers. More information about the Validate class of PrestaShop [here](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Validate.php). - Consider carefully casting your variables and use pSQL/bqSQL in the SQL requests to avoid any injections (read [Best Practices of the Db Class](https://doc.prestashop.com/display/PS16/Best+Practices+of+the+Db+Class)). Make sure your files are properly protected (especially if your module uses a cron for example) to avoid anyone being able to execute them. As a result, you are required to use a token! diff --git a/modules/payment/_index.md b/modules/payment/_index.md index d5adb798d3..2702a54195 100644 --- a/modules/payment/_index.md +++ b/modules/payment/_index.md @@ -32,7 +32,7 @@ To make a payment module for PrestaShop 1.7, you'll have to respect some element - You'll have to register the two following methods: `hookPaymentOptions()` & `hookPaymentReturn()` and register these hooks. - You must not have a submit button into your module's HTML code. It will automatically be generated by PrestaShop. -In the `hookPaymentOptions()` method, you have to return an array of *[PaymentOption](https://github.com/PrestaShop/PrestaShop/blob/develop/src/Core/Payment/PaymentOption.php)*. +In the `hookPaymentOptions()` method, you have to return an array of *[PaymentOption](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Core/Payment/PaymentOption.php)*. How to generate your PaymentOption ---------------------------------- @@ -89,7 +89,7 @@ Migrating from 1.6 to 1.7 You need to change the *payment* hook where your module is hooked on by *paymentOption*. **It's not a display hook anymore**, so you must not use the `$this->display()` method to retrieve a template, but use the `$this->context->smarty->fetch()` method instead. -Then, implement the `hookPaymentOptions()` function to return an array of *[PaymentOption](https://github.com/PrestaShop/PrestaShop/blob/develop/src/Core/Payment/PaymentOption.php)*. +Then, implement the `hookPaymentOptions()` function to return an array of *[PaymentOption](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Core/Payment/PaymentOption.php)*. Next, you'll need to identify the type of your payment module to know which variables are mandatory. diff --git a/testing/ui-tests/_index.md b/testing/ui-tests/_index.md index 95bd44cc3c..a82e9b6e63 100644 --- a/testing/ui-tests/_index.md +++ b/testing/ui-tests/_index.md @@ -26,3 +26,5 @@ We use the following stack: {{% children %}} +Everything is explained in [README](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/tests/UI/README.md) in the `tests/UI` folder. +You'll need a working installation of PrestaShop in order to run the tests. diff --git a/testing/ui-tests/how-to-create-your-own-ui-tests.md b/testing/ui-tests/how-to-create-your-own-ui-tests.md index 4ab55dafeb..d1ce6d41cb 100644 --- a/testing/ui-tests/how-to-create-your-own-ui-tests.md +++ b/testing/ui-tests/how-to-create-your-own-ui-tests.md @@ -103,7 +103,7 @@ The utils directory contain files that are necessary to run tests. #### Globals This file contains all global variables that can be used in test files, pages and common tests. -The description of each variable in this file can be found in [README.md](https://github.com/PrestaShop/PrestaShop/blob/develop/tests/UI/README.md). +The description of each variable in this file can be found in [README.md](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/tests/UI/README.md). #### Setup [Mocha](https://mochajs.org/) gives us the possibility to load and run files before test files (with [\--file option](https://mochajs.org/#-file-filedirectoryglob)). diff --git a/testing/unit-tests/how-to-execute-tests.md b/testing/unit-tests/how-to-execute-tests.md index 0d5a6594ad..95adc34d89 100644 --- a/testing/unit-tests/how-to-execute-tests.md +++ b/testing/unit-tests/how-to-execute-tests.md @@ -14,6 +14,9 @@ You can execute the test suite with specific Composer command: You can execute the entire PHPUnit test suites using the `composer test-all` command. {{% /notice %}} +## Executing the Functional test suites + +This is thoroughly explained in the [Puppeteer tests Readme file](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/tests/UI/README.md). ## Executing only part of phpunit tests diff --git a/themes/getting-started/guidelines.md b/themes/getting-started/guidelines.md index 037271d7bc..b556c58de7 100644 --- a/themes/getting-started/guidelines.md +++ b/themes/getting-started/guidelines.md @@ -31,7 +31,7 @@ Mobile-wise: Use spaces for indentation in every language (PHP, HTML, CSS, etc.):
4 spaces for PHP files, 2 spaces for all other file types. -Use our [.editorconfig](https://editorconfig.org/) file in order to easily configure your editor: https://github.com/PrestaShop/PrestaShop/blob/develop/.editorconfig +Use our [.editorconfig](https://editorconfig.org/) file in order to easily configure your editor: https://github.com/PrestaShop/PrestaShop/blob/8.0.x/.editorconfig ##### PHP files @@ -58,7 +58,7 @@ We recommend that you follow the [RSCSS structure](https://github.com/rstacruz/r ##### Javascript -Make sure your linter tool follows our .eslint file: https://github.com/PrestaShop/PrestaShop/blob/develop/js/.eslintrc.js +Make sure your linter tool follows our .eslint file: https://github.com/PrestaShop/PrestaShop/blob/8.0.x/js/.eslintrc.js If you wish to write ECMAScript 2015 (ES6) code, we recommend using the [Babel compiler](https://babeljs.io/) to maximize compatibility. diff --git a/themes/reference/templates/notifications.md b/themes/reference/templates/notifications.md index 4abbe3c893..6b3900ecaa 100644 --- a/themes/reference/templates/notifications.md +++ b/themes/reference/templates/notifications.md @@ -99,7 +99,7 @@ In the "Classic" Theme, [notifications are implemented as a partial template fil ## Add your own message in your front controller -Your front controller holds [the 4 following variables](https://github.com/PrestaShop/PrestaShop/blob/develop/classes/controller/FrontController.php#L616-L621): +Your front controller holds [the 4 following variables](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/FrontController.php#L616-L621): * ``$this->errors`` * ``$this->success`` @@ -108,7 +108,7 @@ Your front controller holds [the 4 following variables](https://github.com/Prest They are PHP arrays, and they hold messages as a string. -Here is how you can [redirect the customer AND display a message after an action](https://github.com/PrestaShop/PrestaShop/blob/develop/classes/controller/FrontController.php#L614-L633): +Here is how you can [redirect the customer AND display a message after an action](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/FrontController.php#L614-L633): ```php $this->success[] = $this->l('Information successfully updated.'); From 2679d12ae07e19d64be3c44c44fa847fb57a3e7b Mon Sep 17 00:00:00 2001 From: Thomas Nares Date: Mon, 26 Sep 2022 09:34:13 +0200 Subject: [PATCH 068/310] Fix wrong lines, move some files, fix some links --- basics/installation/localhost.md | 2 +- development/architecture/domain/domain-services.md | 10 +++++----- development/architecture/migration-guide/hooks.md | 2 +- .../architecture/migration-guide/testing/behat.md | 10 +++++----- .../{validation.md => validation/_index.md} | 6 +++--- development/coding-standards/_index.md | 2 +- modules/testing/resources.md | 2 +- testing/ui-tests/how-to-create-your-own-ui-tests.md | 6 +++--- themes/reference/templates/notifications.md | 2 +- 9 files changed, 21 insertions(+), 21 deletions(-) rename development/architecture/migration-guide/{validation.md => validation/_index.md} (63%) diff --git a/basics/installation/localhost.md b/basics/installation/localhost.md index 7111319777..3f7568d88c 100644 --- a/basics/installation/localhost.md +++ b/basics/installation/localhost.md @@ -123,7 +123,7 @@ If you intend to work on PrestaShop itself, we suggest using Git to clone the so As stated above, if you decide to work on PrestaShop itself, it's best to clone the PrestaShop repository and work using git. Depending on the version of PrestaShop you want to work on, you will need to choose the right branch: -* The [develop branch](https://github.com/PrestaShop/PrestaShop/tree/develop) contains the current work in progress for the next minor or major version. +* The [develop branch](https://github.com/PrestaShop/PrestaShop/tree/8.0.x) contains the current work in progress for the next minor or major version. - **This is the right branch to contribute new features, refactors, small bug fixes, etc.** * The maintenance branches (_8.0.x, ..._) contains all patches made for each minor version. - For example, the _8.0.x_ branch contains all patches from 8.0.0 to 8.0.99. diff --git a/development/architecture/domain/domain-services.md b/development/architecture/domain/domain-services.md index 405873920f..a31dcd7c1f 100644 --- a/development/architecture/domain/domain-services.md +++ b/development/architecture/domain/domain-services.md @@ -17,7 +17,7 @@ Here are some principles for implementing a Domain Service: 2. If it uses any legacy service or object model, then it MUST be placed in the `Adapter` namespace. 3. If it needs to perform a sql query and related `ObjectModel` exists, then this query MUST be delegated to the appropriate repository class which must ensure that no legacy exceptions are thrown. If the related `ObjectModel` already implements such method, then the repository must delegate its implementation to the `ObjectModel`. {{% notice %}} - Some reusable methods are present in [AbstractObjectModelRepository](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/AbstractObjectModelRepository.php). + Some reusable methods are present in [AbstractObjectModelRepository](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Core/Repository/AbstractObjectModelRepository.php). {{% /notice %}} 4. If `ObjectModel` contains fields validation, it MUST be validated by a dedicated validator class before persisting to database (e.g. when using `add`/`update`/`save` methods). It ensures that legacy [PrestashopException](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/exception/PrestaShopException.php) is not bubbling up and each validation error can be identified by a dedicated exception or exception code. {{% notice %}} @@ -42,13 +42,13 @@ Here are some principles for implementing a Domain Service: ## Product domain services -1. [Product update services](https://github.com/PrestaShop/PrestaShop/tree/1.7.8.x/src/Adapter/Product/Update) +1. [Product update services](https://github.com/PrestaShop/PrestaShop/tree/8.0.x/src/Adapter/Product/Update) 2. [Virtual product update services](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Product/VirtualProduct/Update) 2. [Combination update services](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Product/Combination/Update) 2. [Combination create services](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Product/Combination/Create) ## Service usage in `CommandHandler` examples -1. [Combination command handlers](https://github.com/PrestaShop/PrestaShop/tree/1.7.8.x/src/Adapter/Product/Combination/CommandHandler) -2. [Virtual product command handlers](https://github.com/PrestaShop/PrestaShop/tree/1.7.8.x/src/Adapter/Product/VirtualProduct/CommandHandler) -2. [Product stock command handlers](https://github.com/PrestaShop/PrestaShop/tree/1.7.8.x/src/Adapter/Product/Stock/CommandHandler) +1. [Combination command handlers](https://github.com/PrestaShop/PrestaShop/tree/8.0.x/src/Adapter/Product/Combination/CommandHandler) +2. [Virtual product command handlers](https://github.com/PrestaShop/PrestaShop/tree/8.0.x/src/Adapter/Product/VirtualProduct/CommandHandler) +2. [Product stock command handlers](https://github.com/PrestaShop/PrestaShop/tree/8.0.x/src/Adapter/Product/Stock/CommandHandler) diff --git a/development/architecture/migration-guide/hooks.md b/development/architecture/migration-guide/hooks.md index 60719a4cca..16f69cb203 100644 --- a/development/architecture/migration-guide/hooks.md +++ b/development/architecture/migration-guide/hooks.md @@ -14,7 +14,7 @@ Getting the list of available Hooks in modern pages is really easy. Thanks to th Use this trick to find out which hooks are called on a legacy page. -In ``classes/Hook``, find the [exec() function](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Hook.php#L733) and add the following code: +In ``classes/Hook``, find the [exec() function](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Hook.php#L735) and add the following code: ```php }}) - this is the test suites configuration file which describes feature paths and contexts for every test suite. It can be passed as an argument when running the tests like this `./vendor/bin/behat -c tests/Integration/Behaviour/behat.yml`. - bootstrap.php - this file loads the `Kernel` for a behat tests environment. -- Features - this directory contains all the [Scenarios](https://github.com/PrestaShop/PrestaShop/tree/develop/tests/Integration/Behaviour/Features/Scenario) and [Contexts](https://github.com/PrestaShop/PrestaShop/tree/develop/tests/Integration/Behaviour/Features/Context). More about it [below]({{< relref "#features" >}}). +- Features - this directory contains all the [Scenarios](https://github.com/PrestaShop/PrestaShop/tree/8.0.x/tests/Integration/Behaviour/Features/Scenario) and [Contexts](https://github.com/PrestaShop/PrestaShop/tree/8.0.x/tests/Integration/Behaviour/Features/Context). More about it [below]({{< relref "#features" >}}). ## Features @@ -56,7 +56,7 @@ Behat related files are located in [tests/Integration/Behaviour/](https://github Before continuing, **please read the official `behat` documentation** about the [features and scenarios](https://docs.behat.org/en/latest/user_guide/features_scenarios.html). {{% /notice %}} -In PrestaShop all `*.feature` files are placed in [.tests/Integration/Behaviour/Features/Scenario](https://github.com/PrestaShop/PrestaShop/tree/develop/tests/Integration/Behaviour/Features/Scenario). Each feature is placed in a dedicated directory organized by `domain` (or even a `subdomain` if necessary). These feature files contains text that describes the testing scenarios in a user-friendly manner, each of them must start with a keyword `Feature` and have a one or multiple scenarios starting with a keyword `Scenario`. For example: +In PrestaShop all `*.feature` files are placed in [.tests/Integration/Behaviour/Features/Scenario](https://github.com/PrestaShop/PrestaShop/tree/8.0.x/tests/Integration/Behaviour/Features/Scenario). Each feature is placed in a dedicated directory organized by `domain` (or even a `subdomain` if necessary). These feature files contains text that describes the testing scenarios in a user-friendly manner, each of them must start with a keyword `Feature` and have a one or multiple scenarios starting with a keyword `Scenario`. For example: ```feature Feature: Update product status from BO (Back Office) As an employee I must be able to update product status (enable/disable) @@ -82,10 +82,10 @@ Every line in scenario has a related method defined in a [Context]({{< relref "# ## Context -The behat `Context` files are classes that contains the implementations of the features. In PrestaShop all `Context` files are placed in [tests/Integration/Behaviour/Features/Scenario](https://github.com/PrestaShop/PrestaShop/tree/develop/tests/Integration/Behaviour/Features/Context). +The behat `Context` files are classes that contains the implementations of the features. In PrestaShop all `Context` files are placed in [tests/Integration/Behaviour/Features/Scenario](https://github.com/PrestaShop/PrestaShop/tree/8.0.x/tests/Integration/Behaviour/Features/Context). {{% notice tip %}} -The most recent `Context` files are located in [`Tests/Integration/Behaviour/Features/Context/Domain`](https://github.com/PrestaShop/PrestaShop/tree/develop/tests/Integration/Behaviour/Features/Context/Domain) namespace, so try to use these and avoid the ones from the `Tests/Integration/Behaviour/Features/Context/*` namespace (those are old and might not be implemented well). +The most recent `Context` files are located in [`Tests/Integration/Behaviour/Features/Context/Domain`](https://github.com/PrestaShop/PrestaShop/tree/8.0.x/tests/Integration/Behaviour/Features/Context/Domain) namespace, so try to use these and avoid the ones from the `Tests/Integration/Behaviour/Features/Context/*` namespace (those are old and might not be implemented well). {{% /notice%}} When creating a new Context class, it should extend the [`AbstractDomainFeatureContext`](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/tests/Integration/Behaviour/Features/Context/Domain/AbstractDomainFeatureContext.php). diff --git a/development/architecture/migration-guide/validation.md b/development/architecture/migration-guide/validation/_index.md similarity index 63% rename from development/architecture/migration-guide/validation.md rename to development/architecture/migration-guide/validation/_index.md index 6e89ef82f2..e0419df42a 100644 --- a/development/architecture/migration-guide/validation.md +++ b/development/architecture/migration-guide/validation/_index.md @@ -6,9 +6,9 @@ weight: 70 # Validation The purpose of validation is to protect the application from failures, state inconsistency, security related issues etc. PrestaShop has few different levels of validation: -* **Forms** (the [CRUD]({{}}) or [Settings]({{}})) - are using [Symfony validation constraints](https://symfony.com/doc/4.4/validation.html#constraints) to prevent the user from providing invalid information while also enriching the user experience. For example if a form input expects `Yes` or `No`, but user submitted value `XYZ` we want to reject the data and inform the user what was wrong. The best approach (if possible) is to prevent user providing the wrong value in the first place, so in this example we could simply use a checkbox or select input with only 2 possible selections. There are some custom constraints implemented in PrestaShop [here](https://github.com/PrestaShop/PrestaShop/tree/1.7.8.x/src/Core/ConstraintValidator). -* [Value objects]({{< relref "/8/development/architecture/domain/value_objects" >}}) - after the form is submitted and validated, controller is usually dispatching some `Command`. We must ensure that commands are valid too, because in theory, commands should not be aware whether they were dispatched from a controller or from a command line, therefore it is possible that inputs are not yet validated by the form. The `command` itself should not handle the validation (although there are some older commands that does that, but that might only be some early migration mistakes), but **use the value objects in the constructor instead**. Value objects have their own validation rules and can be reused in any other command. For example, take a look at [ProductCondition](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Core/Domain/Product/ValueObject/ProductCondition.php) - this is a value object of `Product` domain. It allows constructing specific values and throws `ProductConstraintException` if invalid one is provided. It is currently used in [UpdateProductOptionsCommand](https://github.com/PrestaShop/PrestaShop/1.7.8.x/develop/src/Core/Domain/Product/Command/UpdateProductOptionsCommand.php) and helps to maintain the command validity. -* [Domain services]({{< relref "/8/development/architecture/domain/domain-services" >}}) - after the command is constructed and dispatched, it reaches the `CommandHandler`, which calls all the needed `Domain services` (there are also lots of `CommandHandlers` that handles all the logic including the validation by themselves, but it is not recommended anymore and should be perceived as migration mistakes). Domain services can perform final checks (e.g. heavy sql queries to check certain records existence) before performing the `write` operations. +* **Forms** (the [CRUD]({{}}) or [Settings]({{}})) - are using [Symfony validation constraints](https://symfony.com/doc/4.4/validation.html#constraints) to prevent the user from providing invalid information while also enriching the user experience. For example if a form input expects `Yes` or `No`, but user submitted value `XYZ` we want to reject the data and inform the user what was wrong. The best approach (if possible) is to prevent user providing the wrong value in the first place, so in this example we could simply use a checkbox or select input with only 2 possible selections. There are some custom constraints implemented in PrestaShop [here](https://github.com/PrestaShop/PrestaShop/tree/8.0.x/src/Core/ConstraintValidator). +* [Value objects]({{< relref "/8/development/architecture/domain/value_objects" >}}) - after the form is submitted and validated, controller is usually dispatching some `Command`. We must ensure that commands are valid too, because in theory, commands should not be aware whether they were dispatched from a controller or from a command line, therefore it is possible that inputs are not yet validated by the form. The `command` itself should not handle the validation (although there are some older commands that does that, but that might only be some early migration mistakes), but **use the value objects in the constructor instead**. Value objects have their own validation rules and can be reused in any other command. For example, take a look at [ProductCondition](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Core/Domain/Product/ValueObject/ProductCondition.php) - this is a value object of `Product` domain. It allows constructing specific values and throws `ProductConstraintException` if invalid one is provided. It is currently used in [UpdateProductOptionsCommand](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Core/Domain/Product/Command/UpdateProductOptionsCommand.php) and helps to maintain the command validity. +* [Domain services]({{}}) - after the command is constructed and dispatched, it reaches the `CommandHandler`, which calls all the needed `Domain services` (there are also lots of `CommandHandlers` that handles all the logic including the validation by themselves, but it is not recommended anymore and should be perceived as migration mistakes). Domain services can perform final checks (e.g. heavy sql queries to check certain records existence) before performing the `write` operations. * **Entities** (or the `ObjectModels` in Prestashop) - This is the last level. It is there to prevent data integrity issues (like attempting to store a string into an integer column). This is something that, if all data validations before were done correctly, should rarely happen. This is the last step before data is being persisted: if invalid data has slipped through validation levels and passes this step, then it is persisted in database and might introduce inconsistency in the application. If these errors still occur, you might get a legacy `PrestaShopException`, but in recent migration process we try to catch it early and replace it by related `CoreException` or `DomainException`. See more in [Domain services]({{< relref "/8/development/architecture/domain/domain-services" >}}). {{% notice tip %}} diff --git a/development/coding-standards/_index.md b/development/coding-standards/_index.md index 7dcecf2444..dfdc7106a8 100644 --- a/development/coding-standards/_index.md +++ b/development/coding-standards/_index.md @@ -47,7 +47,7 @@ You can run it using the following command: php ./vendor/bin/php-cs-fixer fix ``` -The prestashop specific configuration file [can be found here](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/.php-cs-fixer.dist.php). Also, you can also use the provided [git pre-commit](https://github.com/PrestaShop/PrestaShop/tree/develop/.github/contrib) sample in order to make sure you never forget to make your code compliant! +The prestashop specific configuration file [can be found here](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/.php-cs-fixer.dist.php). Also, you can also use the provided [git pre-commit](https://github.com/PrestaShop/PrestaShop/tree/8.0.x/.github/contrib) sample in order to make sure you never forget to make your code compliant! ### Documenting types diff --git a/modules/testing/resources.md b/modules/testing/resources.md index bf14f857dc..7c66ed7ad0 100644 --- a/modules/testing/resources.md +++ b/modules/testing/resources.md @@ -144,4 +144,4 @@ PrestaShop provides its own test suite, running with [Playwright](https://playwr These tests are launched every time a change is suggested to the core, but you can also run them with your module installed. This will ensure your module code does not break a critical feature of the core. -This section will be completed when these tests will be available on a dedicated repository. In the meantime you can already reach them on GitHub, in the [tests/UI](https://github.com/PrestaShop/PrestaShop/tree/develop/tests/UI) of PrestaShop files. +This section will be completed when these tests will be available on a dedicated repository. In the meantime you can already reach them on GitHub, in the [tests/UI](https://github.com/PrestaShop/PrestaShop/tree/8.0.x/tests/UI) of PrestaShop files. diff --git a/testing/ui-tests/how-to-create-your-own-ui-tests.md b/testing/ui-tests/how-to-create-your-own-ui-tests.md index d1ce6d41cb..0353a6780b 100644 --- a/testing/ui-tests/how-to-create-your-own-ui-tests.md +++ b/testing/ui-tests/how-to-create-your-own-ui-tests.md @@ -81,10 +81,10 @@ Each selector must belong to a certain type. Here is a non-exhaustive list: ## Tests ### Campaigns -We currently have 2 [campaigns](https://github.com/PrestaShop/PrestaShop/tree/develop/tests/UI/campaigns) implemented: +We currently have 2 [campaigns](https://github.com/PrestaShop/PrestaShop/tree/8.0.x/tests/UI/campaigns) implemented: -- **Sanity**: its purpose is to validate a Pull Request. Executed on [Travis CI](https://travis-ci.com/), [this campaign](https://github.com/PrestaShop/PrestaShop/tree/develop/tests/UI/campaigns/sanity) must fully pass before merging the PR (one failed test blocks the merge). It consists of a few tests of the core features of PrestaShop: shop installation, orders/products pages in BO, and catalog/cart/checkout process in FO. -- **Functional**: it is the biggest and most important [campaign](https://github.com/PrestaShop/PrestaShop/tree/develop/tests/UI/campaigns/functional). Its purpose is to validate that every feature of PrestaShop works, by testing them one by one. It goes on every page and tests whatever it can: table (filtering, ordering, quick edits, etc), [CRUD](https://en.wikipedia.org/wiki/Create,_read,_update_and_delete) items (orders, customers, products…), setting changes, etc. +- **Sanity**: its purpose is to validate a Pull Request. Executed on [Travis CI](https://travis-ci.com/), [this campaign](https://github.com/PrestaShop/PrestaShop/tree/8.0.x/tests/UI/campaigns/sanity) must fully pass before merging the PR (one failed test blocks the merge). It consists of a few tests of the core features of PrestaShop: shop installation, orders/products pages in BO, and catalog/cart/checkout process in FO. +- **Functional**: it is the biggest and most important [campaign](https://github.com/PrestaShop/PrestaShop/tree/8.0.x/tests/UI/campaigns/functional). Its purpose is to validate that every feature of PrestaShop works, by testing them one by one. It goes on every page and tests whatever it can: table (filtering, ordering, quick edits, etc), [CRUD](https://en.wikipedia.org/wiki/Create,_read,_update_and_delete) items (orders, customers, products…), setting changes, etc. We plan on implementing 2 more campaigns: diff --git a/themes/reference/templates/notifications.md b/themes/reference/templates/notifications.md index 6b3900ecaa..58e659d12c 100644 --- a/themes/reference/templates/notifications.md +++ b/themes/reference/templates/notifications.md @@ -108,7 +108,7 @@ Your front controller holds [the 4 following variables](https://github.com/Prest They are PHP arrays, and they hold messages as a string. -Here is how you can [redirect the customer AND display a message after an action](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/FrontController.php#L614-L633): +Here is how you can [redirect the customer AND display a message after an action](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/FrontController.php#L634-L653): ```php $this->success[] = $this->l('Information successfully updated.'); From d8fd35d093470a2538d143d47e3cd4255bd17baf Mon Sep 17 00:00:00 2001 From: Thomas Nares Date: Mon, 26 Sep 2022 10:10:45 +0200 Subject: [PATCH 069/310] Fix wrong lines and js to ts files --- development/architecture/modern/controller-routing.md | 2 +- .../concepts/controllers/admin-controllers/route-generation.md | 2 +- themes/reference/templates/notifications.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/development/architecture/modern/controller-routing.md b/development/architecture/modern/controller-routing.md index e3822a6d46..041e076224 100644 --- a/development/architecture/modern/controller-routing.md +++ b/development/architecture/modern/controller-routing.md @@ -306,4 +306,4 @@ redirected to the new migrated url. ### Javascript generation -In order to avoid hardcoded links in JavaScript, Prestashop uses the [`Router` component](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/admin-dev/themes/new-theme/js/components/router.js). +In order to avoid hardcoded links in JavaScript, Prestashop uses the [`Router` component](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/admin-dev/themes/new-theme/js/components/router.ts). diff --git a/modules/concepts/controllers/admin-controllers/route-generation.md b/modules/concepts/controllers/admin-controllers/route-generation.md index 7979d721e4..e41f785a9b 100644 --- a/modules/concepts/controllers/admin-controllers/route-generation.md +++ b/modules/concepts/controllers/admin-controllers/route-generation.md @@ -135,7 +135,7 @@ This will only work for **one route/one controller** the association by action d {{% /notice %}} #### Javascript routes -In order to generate a symfony route in javascript, you can use the [`Router` component](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/admin-dev/themes/new-theme/js/components/router.js). +In order to generate a symfony route in javascript, you can use the [`Router` component](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/admin-dev/themes/new-theme/js/components/router.ts). You can use it like this: ``` diff --git a/themes/reference/templates/notifications.md b/themes/reference/templates/notifications.md index 58e659d12c..6ff38bcdbe 100644 --- a/themes/reference/templates/notifications.md +++ b/themes/reference/templates/notifications.md @@ -99,7 +99,7 @@ In the "Classic" Theme, [notifications are implemented as a partial template fil ## Add your own message in your front controller -Your front controller holds [the 4 following variables](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/FrontController.php#L616-L621): +Your front controller holds [the 4 following variables](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/FrontController.php#L637-L640): * ``$this->errors`` * ``$this->success`` From 046ebad21a5b03b3c4d43723124746e09f316614 Mon Sep 17 00:00:00 2001 From: Thomas Nares Date: Mon, 26 Sep 2022 11:38:25 +0200 Subject: [PATCH 070/310] Fix broken links on 8.x --- .../how-pull-requests-are-processed.md | 2 +- development/architecture/domain/domain-services.md | 8 ++++---- development/database/structure.md | 4 ++-- .../page-reference/back-office/order/view-order/_index.md | 2 +- modules/creation/good-practices.md | 4 ++-- modules/creation/module-translation/classic-system.md | 2 +- testing/ui-tests/_index.md | 6 +++--- testing/ui-tests/how-to-create-your-own-ui-tests.md | 4 ++-- 8 files changed, 16 insertions(+), 16 deletions(-) diff --git a/contribute/contribution-process/how-pull-requests-are-processed.md b/contribute/contribution-process/how-pull-requests-are-processed.md index 89899d45cd..fe5027b7f0 100644 --- a/contribute/contribution-process/how-pull-requests-are-processed.md +++ b/contribute/contribution-process/how-pull-requests-are-processed.md @@ -26,7 +26,7 @@ The results of these checks is displayed at the bottom of the Pull Request. Some ### Prestonbot and Issuebot -[Prestonbot](https://github.com/PrestaShop/prestonbot) (based on [Carsonbot](https://github.com/carsonbot/carsonbot)) is a custom bot that looks at all Pull Requests and tries to help us manage the project. He has multiple capabilities. +[Prestonbot](https://github.com/PrestaShop/prestonbot) (based on [Carsonbot](https://github.com/symfony-tools/carsonbot)) is a custom bot that looks at all Pull Requests and tries to help us manage the project. He has multiple capabilities. For example he detects mistakes in the pull request description, he add some labels to classify the pull requests, he welcomes new contributors to the project ... diff --git a/development/architecture/domain/domain-services.md b/development/architecture/domain/domain-services.md index a31dcd7c1f..5d3aa68355 100644 --- a/development/architecture/domain/domain-services.md +++ b/development/architecture/domain/domain-services.md @@ -42,10 +42,10 @@ Here are some principles for implementing a Domain Service: ## Product domain services -1. [Product update services](https://github.com/PrestaShop/PrestaShop/tree/8.0.x/src/Adapter/Product/Update) -2. [Virtual product update services](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Product/VirtualProduct/Update) -2. [Combination update services](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Product/Combination/Update) -2. [Combination create services](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Product/Combination/Create) +1. [Product update services](https://github.com/PrestaShop/PrestaShop/tree/1.7.8.x/src/Adapter/Product/Update) +2. [Virtual product update services](https://github.com/PrestaShop/PrestaShop/tree/1.7.8.x/src/Adapter/Product/VirtualProduct/Update) +2. [Combination update services](https://github.com/PrestaShop/PrestaShop/tree/1.7.8.x/src/Adapter/Product/Combination/Update) +2. [Combination create services](https://github.com/PrestaShop/PrestaShop/tree/1.7.8.x/src/Adapter/Product/Combination/Create) ## Service usage in `CommandHandler` examples diff --git a/development/database/structure.md b/development/database/structure.md index 4c11919259..a6cb867608 100644 --- a/development/database/structure.md +++ b/development/database/structure.md @@ -46,8 +46,8 @@ This SQL file will be stored in the [auto upgrade](https://github.com/PrestaShop Its name is the PrestaShop version on which the change will be applied. -For instance, here is the file *[1.7.8.0.sql](https://github.com/PrestaShop/autoupgrade/tree/dev/upgrade/sql/1.7.8.0.sql)*, -used by shops upgrading to 1.7.8.0 or later: +For instance, here is the file *[8.0.0.sql](https://github.com/PrestaShop/autoupgrade/blob/dev/upgrade/sql/8.0.0.sql)*, +used by shops upgrading to 8.0.0 or later: ```sql [...] diff --git a/development/page-reference/back-office/order/view-order/_index.md b/development/page-reference/back-office/order/view-order/_index.md index de454798d3..f326c5dc01 100644 --- a/development/page-reference/back-office/order/view-order/_index.md +++ b/development/page-reference/back-office/order/view-order/_index.md @@ -9,7 +9,7 @@ title: Order view {{% /notice %}} This page can be reached by visiting `Sell -> Orders -> Orders -> View (grid row action)`. It allows the Back Office user to view the details of selected order and edit it. The **related code can be found in following locations**: -- Main **twig template** [src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/view.html.twig](https://github.com/PrestaShop/PrestaShop/tree/8.0.x/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/view.html.twig). +- Main **twig template** [src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/view.html.twig](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/view.html.twig). - **Javascript** ([pre-compiled]({{< relref "/8/development/compile-assets" >}})) [admin-dev/themes/new-theme/js/pages/order/view](https://github.com/PrestaShop/PrestaShop/tree/8.0.x/admin-dev/themes/new-theme/js/pages/order/view). - **OrderController** [src/PrestaShopBundle/Controller/Admin/Sell/Order/OrderController](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/Sell/Order/OrderController.php) (other domain controllers are used as well, those will be mentioned in related block references bellow) - **Commands** & **Queries** at [src/Core/Domain/Order](https://github.com/PrestaShop/PrestaShop/tree/8.0.x/src/Core/Domain/Order) in `Command`, `Query` directories. diff --git a/modules/creation/good-practices.md b/modules/creation/good-practices.md index 9c1b97e6fb..0319d05bc6 100644 --- a/modules/creation/good-practices.md +++ b/modules/creation/good-practices.md @@ -85,9 +85,9 @@ add a preliminary check before using them (I.e with `extension_loaded`). This pr **A few recommendations for your email templates** -- Use our [official SDK](https://github.com/PrestaShop/email-templates-sdk) to develop your emails: +- Use our [official SDK](https://github.com/PrestaShopCorp/email-templates-sdk) to develop your emails: - Make sure to submit on Addons a valid zip, built with the SDK. -- Test your emails with the [official module](https://github.com/PrestaShop/email-templates-sdk). +- Test your emails with the [official module](https://github.com/PrestaShopCorp/email-templates-sdk). [coding-standards]: {{< ref "8/development/coding-standards" >}} [display-content-front-office]: {{< ref "8/modules/creation/displaying-content-in-front-office" >}} diff --git a/modules/creation/module-translation/classic-system.md b/modules/creation/module-translation/classic-system.md index c000187382..069808566c 100644 --- a/modules/creation/module-translation/classic-system.md +++ b/modules/creation/module-translation/classic-system.md @@ -415,5 +415,5 @@ In the meantime, refer to this list for the equivalences between language codes [iso-619-1]: https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes [ietf-language-tags]: https://en.wikipedia.org/wiki/IETF_language_tag -[legacy-to-standard]: https://github.com/PrestaShop/PrestaShop/blob/1.7.6.x/app/Resources/legacy-to-standard-locales.json +[legacy-to-standard]: https://github.com/PrestaShop/PrestaShop/blob/8.0.x/app/Resources/legacy-to-standard-locales.json [new-translation-system]: {{< ref "new-system" >}} diff --git a/testing/ui-tests/_index.md b/testing/ui-tests/_index.md index a82e9b6e63..f5a91e1389 100644 --- a/testing/ui-tests/_index.md +++ b/testing/ui-tests/_index.md @@ -18,9 +18,9 @@ UI tests work by controlling a browser and using the web interface like a real u We use the following stack: * [Playwright](https://github.com/microsoft/playwright/) as automation tool -* [Mocha](https://mochajs.org) as test framework -* [Chai](https://www.chaijs.com) as assertion library -* [Faker](https://github.com/marak/Faker.js/) as fake data generator +* [Mocha](https://mochajs.org/) as test framework +* [Chai](https://www.chaijs.com/) as assertion library +* [Faker](https://github.com/faker-js/faker) as fake data generator ## Execute & Create tests diff --git a/testing/ui-tests/how-to-create-your-own-ui-tests.md b/testing/ui-tests/how-to-create-your-own-ui-tests.md index 0353a6780b..88bf013dad 100644 --- a/testing/ui-tests/how-to-create-your-own-ui-tests.md +++ b/testing/ui-tests/how-to-create-your-own-ui-tests.md @@ -107,7 +107,7 @@ The description of each variable in this file can be found in [README.md](https: #### Setup [Mocha](https://mochajs.org/) gives us the possibility to load and run files before test files (with [\--file option](https://mochajs.org/#-file-filedirectoryglob)). -We use that option to run our `setup.js` file. This file opens only one browser for the whole campaign (and not one browser per test), since we're then running each test file in its [own context](https://github.com/microsoft/playwright/blob/master/docs/api.md#class-browsercontext). +We use that option to run our `setup.js` file. This file opens only one browser for the whole campaign (and not one browser per test), since we're then running each test file in its [own context](https://github.com/microsoft/playwright/blob/main/docs/src/api/class-browsercontext.md). #### Browser helper This helper file is used to centralize the browser and tab functions called in all tests. @@ -192,5 +192,5 @@ The only assumption we have to make is the presence of certain items like Orders If you need to rely on the fixtures too, make sure to use the description of the objects you’re looking for in the `data` folder. If it’s not complete, you can expand it and make a Pull Request, we’ll be happy to improve our datasets ! ### Faker -When we need to create new items, we rely on [Faker](https://github.com/marak/Faker.js/) to create random data. +When we need to create new items, we rely on [Faker](https://github.com/faker-js/faker) to create random data. This helps us make sure we’re testing with randomized sets of data and covering a lot of cases. It’s very important to check the specifications before to make sure you’re properly setting up your faker : input length, authorized characters, range of dates/values, etc. From 8de7763b486c2922ab52dc0962d2f75645fef988 Mon Sep 17 00:00:00 2001 From: Thomas Nares Date: Mon, 26 Sep 2022 13:53:24 +0200 Subject: [PATCH 071/310] Fix upgrade example --- development/database/structure.md | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/development/database/structure.md b/development/database/structure.md index a6cb867608..e1c818fec3 100644 --- a/development/database/structure.md +++ b/development/database/structure.md @@ -37,11 +37,9 @@ Another file is being used to load data during the install process: `install/dat ### Defining changes -Once PrestaShop is installed, the default structure and content files we saw -are not used anymore. +Once PrestaShop is installed, the default structure and content files we saw are not used anymore. -If a new release of PrestaShop must bring changes to the existing database, an -upgrade file must be created along the `db_structure.sql` update. +If a new release of PrestaShop must bring changes to the existing database, an upgrade file must be created along the `db_structure.sql` update. This SQL file will be stored in the [auto upgrade](https://github.com/PrestaShop/autoupgrade/tree/dev/upgrade/sql) module in the folder `/upgrade/sql/`. Its name is the PrestaShop version on which the change will be applied. @@ -51,17 +49,16 @@ used by shops upgrading to 8.0.0 or later: ```sql [...] -/* First set all products to standard type, then update them based on cached columns that identify the type */ -UPDATE `PREFIX_product` SET `product_type` = "standard"; -UPDATE `PREFIX_product` SET `product_type` = "combinations" WHERE `cache_default_attribute` != 0; -UPDATE `PREFIX_product` SET `product_type` = "pack" WHERE `cache_is_pack` = 1; -UPDATE `PREFIX_product` SET `product_type` = "virtual" WHERE `is_virtual` = 1; +SET SESSION sql_mode=''; +SET NAMES 'utf8mb4'; -/* PHP:ps_1780_add_feature_flag_tab(); */; +DROP TABLE IF EXISTS `PREFIX_referrer`; +DROP TABLE IF EXISTS `PREFIX_referrer_cache`; +DROP TABLE IF EXISTS `PREFIX_referrer_shop`; [...] ``` -In there we can read the SQL queries to execute when upgrading to 1.7.8.0. +In there we can read the SQL queries to execute when upgrading to 8.0.0. Each of them alters the structure and/or modify the existing data. In case you have complex algorithms to run, you can call PHP code with the `PHP:` keyword. @@ -70,13 +67,13 @@ To make the code callable, a dedicated file has to be created in `/upgrade/php/` with a function in it. This file and function must have the same name as we saw in the SQL upgrade file. -If we reuse the previous example, we will find the corresponding file *[/upgrade/php/ps_1780_add_feature_flag_tab.php](https://github.com/PrestaShop/autoupgrade/blob/dev/upgrade/php/ps_1780_add_feature_flag_tab.php)*: +If we reuse the previous example, we will find the corresponding file *[/upgrade/php/ps_800_add_security_tab.php](https://github.com/PrestaShop/autoupgrade/blob/dev/upgrade/php/ps_800_add_security_tab.php)*: ```php Date: Mon, 26 Sep 2022 13:55:21 +0200 Subject: [PATCH 072/310] Fix upgrade example --- development/database/structure.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/development/database/structure.md b/development/database/structure.md index e1c818fec3..b978fad179 100644 --- a/development/database/structure.md +++ b/development/database/structure.md @@ -56,6 +56,8 @@ DROP TABLE IF EXISTS `PREFIX_referrer`; DROP TABLE IF EXISTS `PREFIX_referrer_cache`; DROP TABLE IF EXISTS `PREFIX_referrer_shop`; [...] +/* PHP:ps_800_add_security_tab(); */; +[...] ``` In there we can read the SQL queries to execute when upgrading to 8.0.0. From b7b65d183ad91d91549ede16426c2b51e559836a Mon Sep 17 00:00:00 2001 From: Thomas Nares Date: Wed, 28 Sep 2022 11:11:38 +0200 Subject: [PATCH 073/310] fix blob to tree and a reference to checkout --- development/architecture/domain/domain-services.md | 8 ++++---- .../controllers/admin-controllers/route-generation.md | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/development/architecture/domain/domain-services.md b/development/architecture/domain/domain-services.md index 5d3aa68355..4cb8245f46 100644 --- a/development/architecture/domain/domain-services.md +++ b/development/architecture/domain/domain-services.md @@ -42,10 +42,10 @@ Here are some principles for implementing a Domain Service: ## Product domain services -1. [Product update services](https://github.com/PrestaShop/PrestaShop/tree/1.7.8.x/src/Adapter/Product/Update) -2. [Virtual product update services](https://github.com/PrestaShop/PrestaShop/tree/1.7.8.x/src/Adapter/Product/VirtualProduct/Update) -2. [Combination update services](https://github.com/PrestaShop/PrestaShop/tree/1.7.8.x/src/Adapter/Product/Combination/Update) -2. [Combination create services](https://github.com/PrestaShop/PrestaShop/tree/1.7.8.x/src/Adapter/Product/Combination/Create) +1. [Product update services](https://github.com/PrestaShop/PrestaShop/tree/8.0.x/src/Adapter/Product/Update) +2. [Virtual product update services](https://github.com/PrestaShop/PrestaShop/tree/8.0.x/src/Adapter/Product/VirtualProduct/Update) +2. [Combination update services](https://github.com/PrestaShop/PrestaShop/tree/8.0.x/src/Adapter/Product/Combination/Update) +2. [Combination create services](https://github.com/PrestaShop/PrestaShop/tree/8.0.x/src/Adapter/Product/Combination/Create) ## Service usage in `CommandHandler` examples diff --git a/modules/concepts/controllers/admin-controllers/route-generation.md b/modules/concepts/controllers/admin-controllers/route-generation.md index e41f785a9b..b2128ee666 100644 --- a/modules/concepts/controllers/admin-controllers/route-generation.md +++ b/modules/concepts/controllers/admin-controllers/route-generation.md @@ -111,7 +111,7 @@ You should be **extra careful** about these misused code and replace it accordin - If the controller has already been migrated in your minimum supported version, use the `Router` service directly with the appropriate route name and parameters. - If the controller hasn't been migrated as of your minimum supported version: - **For >= 1.7.5**, use `getAdminLink` method with the parameters **fully injected** in the function. - - **For < 1.7.5**, consider creating your own Link class adapter to switch to the appropriate routing mode for each PrestaShop version ([see example](https://github.com/PrestaShopCorp/ps_checkout/blob/v1.x.x/classes/Adapter/LinkAdapter.php)). + - **For < 1.7.5**, consider creating your own Link class adapter to switch to the appropriate routing mode for each PrestaShop version ([see example](https://github.com/PrestaShopCorp/ps_checkout/blob/v1.5.2/classes/Adapter/LinkAdapter.php)). {{% /notice %}} From ac637a4335de3518916869e578d40b64d4bca344 Mon Sep 17 00:00:00 2001 From: Thomas Nares Date: Wed, 28 Sep 2022 11:15:50 +0200 Subject: [PATCH 074/310] Remove unnecessary files --- .../concepts/hooks/Catalog_Products_2xml.png | Bin 53171 -> 0 bytes .../concepts/hooks/Catalog_Products_dump.png | Bin 45922 -> 0 bytes 2 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 modules/concepts/hooks/Catalog_Products_2xml.png delete mode 100644 modules/concepts/hooks/Catalog_Products_dump.png diff --git a/modules/concepts/hooks/Catalog_Products_2xml.png b/modules/concepts/hooks/Catalog_Products_2xml.png deleted file mode 100644 index 60b1f12b24e377631b0e74eb292e00e1ecb22993..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 53171 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 XmIJThTl{&700000NkvXXu0mjf?%2f9 diff --git a/modules/concepts/hooks/Catalog_Products_dump.png b/modules/concepts/hooks/Catalog_Products_dump.png deleted file mode 100644 index 844adb7c1b0b5193c71f1fe642a215008b3620f5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 45922 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 xo0;3Rk3SDHR0645hN2?DqO5XZO Date: Wed, 28 Sep 2022 17:00:06 +0200 Subject: [PATCH 075/310] Apply suggestions from code review --- modules/testing/resources.md | 2 +- testing/ui-tests/how-to-create-your-own-ui-tests.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/testing/resources.md b/modules/testing/resources.md index 7c66ed7ad0..9c1ad47be7 100644 --- a/modules/testing/resources.md +++ b/modules/testing/resources.md @@ -144,4 +144,4 @@ PrestaShop provides its own test suite, running with [Playwright](https://playwr These tests are launched every time a change is suggested to the core, but you can also run them with your module installed. This will ensure your module code does not break a critical feature of the core. -This section will be completed when these tests will be available on a dedicated repository. In the meantime you can already reach them on GitHub, in the [tests/UI](https://github.com/PrestaShop/PrestaShop/tree/8.0.x/tests/UI) of PrestaShop files. +This section will be completed when these tests are available on a dedicated repository. In the meantime, you can already reach them on GitHub, in the [tests/UI](https://github.com/PrestaShop/PrestaShop/tree/8.0.x/tests/UI) of PrestaShop files. diff --git a/testing/ui-tests/how-to-create-your-own-ui-tests.md b/testing/ui-tests/how-to-create-your-own-ui-tests.md index 88bf013dad..230859e05b 100644 --- a/testing/ui-tests/how-to-create-your-own-ui-tests.md +++ b/testing/ui-tests/how-to-create-your-own-ui-tests.md @@ -107,7 +107,7 @@ The description of each variable in this file can be found in [README.md](https: #### Setup [Mocha](https://mochajs.org/) gives us the possibility to load and run files before test files (with [\--file option](https://mochajs.org/#-file-filedirectoryglob)). -We use that option to run our `setup.js` file. This file opens only one browser for the whole campaign (and not one browser per test), since we're then running each test file in its [own context](https://github.com/microsoft/playwright/blob/main/docs/src/api/class-browsercontext.md). +We use that option to run our `setup.js` file. This file opens only one browser for the whole campaign (and not one browser per test), since we're then running each test file in its [own context](https://playwright.dev/docs/api/class-browsercontext). #### Browser helper This helper file is used to centralize the browser and tab functions called in all tests. From cbad0f0914a40a1851191592b8e3e86c502f6ef7 Mon Sep 17 00:00:00 2001 From: Jordan Brito Date: Thu, 29 Sep 2022 15:02:31 +0200 Subject: [PATCH 076/310] Improve webservice create resource example --- .../create-resource.md | 39 +++++++++++++------ 1 file changed, 27 insertions(+), 12 deletions(-) diff --git a/webservice/tutorials/prestashop-webservice-lib/create-resource.md b/webservice/tutorials/prestashop-webservice-lib/create-resource.md index 72e76cbce9..4b5530b3d4 100644 --- a/webservice/tutorials/prestashop-webservice-lib/create-resource.md +++ b/webservice/tutorials/prestashop-webservice-lib/create-resource.md @@ -55,16 +55,31 @@ Remember that each resource has its own validation rules (required fields, field ```php customer->children(); -$customerFields->firstname = 'John'; -$customerFields->lastname = 'DOE'; -$customerFields->email = 'john.doe@unknown.com'; -$customerFields->passwd = 'password1234'; - -$createdXml = $webService->add([ - 'resource' => 'customers', - 'postXml' => $blankXml->asXML(), -]); -$newCustomerFields = $createdXml->customer->children(); -echo 'Customer created with ID ' . $newCustomerFields->id . PHP_EOL; +try { + // creating webservice access + $webService = new PrestaShopWebservice('http://example.com/', 'ZR92FNY5UFRERNI3O9Z5QDHWKTP3YIIT', false); + + // call to retrieve the blank schema + $blankXml = $webService->get(['url' => 'http://example.com/api/customers?schema=blank']); + + // get the entity + $customerFields = $blankXml->customer->children(); + + // edit entity fields + $customerFields->firstname = 'John'; + $customerFields->lastname = 'DOE'; + $customerFields->email = 'john.doe@unknown.com'; + $customerFields->passwd = 'password1234'; + + // send entity to webservice + $createdXml = $webService->add([ + 'resource' => 'customers', + 'postXml' => $blankXml->asXML(), + ]); + $newCustomerFields = $createdXml->customer->children(); + echo 'Customer created with ID ' . $newCustomerFields->id . PHP_EOL; +} catch (PrestaShopWebserviceException $ex) { + // Shows a message related to the error + echo 'Other error:
' . $ex->getMessage(); +} ``` From 3627e8652705c508a93fb9262c8714b88ccfd006 Mon Sep 17 00:00:00 2001 From: leemyongpakvn Date: Thu, 29 Sep 2022 21:36:19 +0700 Subject: [PATCH 077/310] Fix some typos and syntax --- .../order-pages-new-hooks/signature-widget.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/modules/sample-modules/order-pages-new-hooks/signature-widget.md b/modules/sample-modules/order-pages-new-hooks/signature-widget.md index cf2ad9704a..a19d769d39 100644 --- a/modules/sample-modules/order-pages-new-hooks/signature-widget.md +++ b/modules/sample-modules/order-pages-new-hooks/signature-widget.md @@ -7,10 +7,10 @@ weight: 2 ## displayAdminOrderSide hook -We use this hook to display scanned customer signature. +We use this hook to display a scanned customer signature. -Lets create custom repository `OrderSignatureRepository` class inside `demovieworderhooks/src/Repository` folder. -Symfony Repository classes (https://symfony.com/doc/3.3/doctrine/repository.html) help to interact with the database by providing frequently used functions +Let's create custom repository `OrderSignatureRepository` class inside `demovieworderhooks/src/Repository` folder. +Symfony Repository classes (https://symfony.com/doc/4.4/doctrine/repository.html) help to interact with the database by providing frequently used functions like `findOneBy` to get the data (for example filtered data by a certain criteria - `orderId` field from `OrderSignature` entity). @@ -443,7 +443,7 @@ class OrderSignaturePresenter } } ``` -Then lets use Symfony Dependency Injection +Then let's use Symfony Dependency Injection (https://www.freecodecamp.org/news/a-quick-intro-to-dependency-injection-what-it-is-and-when-to-use-it-7578c84fa88f/). and [create services configuration]({{< relref "/8/modules/concepts/services/#symfony-services" >}}) for the above classes in `demovieworderhooks/config/services.yml`. @@ -521,8 +521,8 @@ card.html.twig {% endblock %} ``` -Lets add several methods to `DemoViewOrderHooks` class. -`getModuleTemplatePath` - get's the path of the templates folder. +Let's add several methods to `DemoViewOrderHooks` class. +`getModuleTemplatePath` - get the path of the templates folder. ```php Date: Fri, 30 Sep 2022 09:31:44 +0200 Subject: [PATCH 078/310] Revert "Remove unnecessary files" This reverts commit ac637a4335de3518916869e578d40b64d4bca344. --- .../concepts/hooks/Catalog_Products_2xml.png | Bin 0 -> 53171 bytes .../concepts/hooks/Catalog_Products_dump.png | Bin 0 -> 45922 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 modules/concepts/hooks/Catalog_Products_2xml.png create mode 100644 modules/concepts/hooks/Catalog_Products_dump.png diff --git a/modules/concepts/hooks/Catalog_Products_2xml.png b/modules/concepts/hooks/Catalog_Products_2xml.png new file mode 100644 index 0000000000000000000000000000000000000000..60b1f12b24e377631b0e74eb292e00e1ecb22993 GIT binary patch literal 53171 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 XmIJThTl{&700000NkvXXu0mjf?%2f9 literal 0 HcmV?d00001 diff --git a/modules/concepts/hooks/Catalog_Products_dump.png b/modules/concepts/hooks/Catalog_Products_dump.png new file mode 100644 index 0000000000000000000000000000000000000000..844adb7c1b0b5193c71f1fe642a215008b3620f5 GIT binary patch literal 45922 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 xo0;3Rk3SDHR0645hN2?DqO5XZO Date: Fri, 30 Sep 2022 11:53:36 +0200 Subject: [PATCH 079/310] Fix typos --- .../architecture/migration-guide/forms/CRUD-forms.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/development/architecture/migration-guide/forms/CRUD-forms.md b/development/architecture/migration-guide/forms/CRUD-forms.md index 9676a68c78..1df296d020 100644 --- a/development/architecture/migration-guide/forms/CRUD-forms.md +++ b/development/architecture/migration-guide/forms/CRUD-forms.md @@ -106,7 +106,7 @@ Don't forget to register your class as a service, you will need it to use it wit class: 'PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataProvider\ContactFormDataProvider' ``` -Note: if you use the above snippet of code outside of the `PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataProvider`, like a module, you need to import the classes that come from this namespace. +Note: if you use the above snippet of code outside of the `PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataProvider` namespace, like in a module, you need to import the classes that come from this namespace. Example ```php @@ -218,7 +218,7 @@ When creating your Form Data Handler you must implement the following interface: \PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataHandler\FormDataHandlerInterface -In the example below, you can see a `ConctactFormDataHandler` that uses `ObjectModel` to create and update an instance of `Contact`: +In the example below, you can see a `ContactFormDataHandler` that uses `ObjectModel` to create and update an instance of `Contact`: ```php Date: Fri, 30 Sep 2022 12:02:37 +0200 Subject: [PATCH 080/310] Fix wrong file referenced --- development/architecture/migration-guide/forms/CRUD-forms.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/development/architecture/migration-guide/forms/CRUD-forms.md b/development/architecture/migration-guide/forms/CRUD-forms.md index 1df296d020..565833aed5 100644 --- a/development/architecture/migration-guide/forms/CRUD-forms.md +++ b/development/architecture/migration-guide/forms/CRUD-forms.md @@ -278,7 +278,7 @@ Note: if you use the above snippet of code outside of the `\PrestaShop\PrestaSho Example ```php -use PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataProvider\FormDataProviderInterface; +use PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataHandler\FormDataHandlerInterface; ``` ## Form Handler From 6cf904fcb6fd84cc0752d5beca45b64b07da352e Mon Sep 17 00:00:00 2001 From: Krystian Podemski Date: Fri, 30 Sep 2022 12:45:12 +0200 Subject: [PATCH 081/310] Update development/architecture/migration-guide/forms/CRUD-forms.md --- development/architecture/migration-guide/forms/CRUD-forms.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/development/architecture/migration-guide/forms/CRUD-forms.md b/development/architecture/migration-guide/forms/CRUD-forms.md index 565833aed5..b308238d01 100644 --- a/development/architecture/migration-guide/forms/CRUD-forms.md +++ b/development/architecture/migration-guide/forms/CRUD-forms.md @@ -274,7 +274,7 @@ prestashop.core.form.identifiable_object.data_handler.contact_form_data_handler: class: 'PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataHandler\ContactFormDataHandler' ``` -Note: if you use the above snippet of code outside of the `\PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataHandler` namespace, like in a module, you need to import the classes that come from this namespace. +Note: if you use the above snippet of code outside of the `PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataHandler` namespace, like in a module, you need to import the classes that come from this namespace. Example ```php From 30eaa446b6cd3a326fee183593a8446da5d057b7 Mon Sep 17 00:00:00 2001 From: Progi1984 Date: Fri, 30 Sep 2022 14:09:10 +0200 Subject: [PATCH 082/310] Fixed JS Doc on UI Tests --- testing/ui-tests/how-to-create-your-own-ui-tests.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testing/ui-tests/how-to-create-your-own-ui-tests.md b/testing/ui-tests/how-to-create-your-own-ui-tests.md index 230859e05b..d1a8809362 100644 --- a/testing/ui-tests/how-to-create-your-own-ui-tests.md +++ b/testing/ui-tests/how-to-create-your-own-ui-tests.md @@ -56,7 +56,7 @@ Example: ```js /** * Get order status - * @param page + * @param page {Page} Browser tab * @return {Promise} */ async getOrderStatus(page) { From 6d2ca1390756a58b8523f214eb4c1d4039bad7bf Mon Sep 17 00:00:00 2001 From: Yannick Armand Date: Sat, 1 Oct 2022 22:15:53 +0200 Subject: [PATCH 083/310] Fix style around example codes --- basics/installation/httpd.md | 1 + basics/installation/localhost.md | 3 + basics/keeping-up-to-date/backup.md | 3 + basics/keeping-up-to-date/migration.md | 4 + .../contribute_using_docker.md | 1 - .../project-modules.md | 4 +- contribute/documentation/shortcodes/_index.md | 8 +- contribute/documentation/shortcodes/minver.md | 4 +- .../architecture/domain/domain-exceptions.md | 1 + .../forms/CQRS-usage-in-forms.md | 2 +- .../migration-guide/forms/CRUD-forms.md | 8 +- .../migration-guide/forms/settings-forms.md | 1 + .../migration-guide/templating-with-twig.md | 3 + .../migration-guide/testing/behat.md | 9 +- .../architecture/modern/controller-routing.md | 1 + development/coding-standards/_index.md | 1 + .../configuration/backward-compatibility.md | 1 + .../components/console/context-helper.md | 3 +- development/components/database/db.md | 6 +- .../components/form/form-theme/_index.md | 1 + .../form/types-reference/change-password.md | 3 +- .../form/types-reference/generatable-text.md | 3 +- .../form/types-reference/ip-address.md | 3 +- .../types-reference/material-choice-table.md | 3 +- .../types-reference/material-choice-tree.md | 3 +- .../material-multiple-choice-table.md | 3 +- .../text-with-length-counter.md | 2 +- .../form/types-reference/translatable.md | 2 +- development/components/grid/_index.md | 4 +- .../tutorials/extend-grid-with-javascript.md | 1 + .../grid/tutorials/work-with-bulk-actions.md | 1 + .../grid/tutorials/work-with-grid-actions.md | 1 + .../grid/tutorials/work-with-row-actions.md | 1 + development/components/helpers/helperform.md | 2 +- .../components/position-updater/_index.md | 1 + .../components/smarty-extensions/_index.md | 2 +- .../translation/translation-tips.md | 3 +- .../translation/using-the-translator.md | 2 +- .../multistore/configuration-forms/_index.md | 4 +- development/upgrade-module/upgrade-cli.md | 6 +- faq/pricing.md | 3 +- faq/tips-and-tricks/hook-tips.md | 2 + .../controllers/admin-controllers/_index.md | 1 + .../admin-controllers/route-generation.md | 3 + .../concepts/controllers/front-controllers.md | 1 + modules/concepts/hooks/list-of-hooks.md | 96 +++++++++---------- modules/concepts/overrides.md | 4 +- modules/concepts/pdf.md | 3 +- modules/concepts/templating/import-js.md | 6 +- .../module-translation/classic-system.md | 3 +- .../creation/module-translation/new-system.md | 2 +- ...nd-identifiable-object-form-hooks-usage.md | 2 +- .../order-pages-new-hooks/module-base.md | 2 + .../order-pages-new-hooks/signature-widget.md | 1 + scale/benchmark/_index.md | 12 ++- scale/benchmark/back-office.md | 5 +- scale/benchmark/front-office.md | 2 +- scale/optimizations.md | 1 + .../how-to-create-your-own-behat-tests.md | 3 +- .../how-to-create-your-own-ui-tests.md | 5 +- .../asset-management/_index.md | 2 + .../setting-up-your-local-environment.md | 4 +- themes/getting-started/theme-yml.md | 1 + themes/reference/overriding-modules.md | 1 + .../parent-child-feature.md | 1 + webservice/getting-started.md | 10 +- webservice/tutorials/testing-access.md | 2 +- 67 files changed, 179 insertions(+), 114 deletions(-) diff --git a/basics/installation/httpd.md b/basics/installation/httpd.md index b6e41f6481..904a06cd92 100644 --- a/basics/installation/httpd.md +++ b/basics/installation/httpd.md @@ -50,6 +50,7 @@ After installing these packages, fpm service will automatically be started. PHP-FPM uses so-called pools to handle incoming FastCGI requests. Here's an example: + ```ini ; a pool called www [www] diff --git a/basics/installation/localhost.md b/basics/installation/localhost.md index 3f7568d88c..2926ff62c7 100644 --- a/basics/installation/localhost.md +++ b/basics/installation/localhost.md @@ -155,6 +155,7 @@ composer install # or alternatively: make composer ``` + ### JavaScript and CSS dependencies PrestaShop uses NPM to manage dependencies and [Webpack][webpack] to compile them into static assets. @@ -190,11 +191,13 @@ PrestaShop needs recursive write permissions on several directories: - ./var You can set up the appropriate permissions using this command: + ```bash $ chmod -R +w admin-dev/autoupgrade app/config app/logs app/Resources/translations cache config download img log mails modules override themes translations upload var ``` If you do not have some of the folders above, please create them before changing permissions. For example: + ```bash $ mkdir log app/logs ``` diff --git a/basics/keeping-up-to-date/backup.md b/basics/keeping-up-to-date/backup.md index 0a4f15b717..7437b71094 100644 --- a/basics/keeping-up-to-date/backup.md +++ b/basics/keeping-up-to-date/backup.md @@ -41,6 +41,7 @@ tar -czf .tar ``` For instance: + ``` tar -czf backup.tar /var/www/html ``` @@ -60,9 +61,11 @@ In a Windows or Linux terminal, run the following command to create a file `dump ``` mysqldump yourdbname > dump.sql ``` + With `yourdbname` an example name for the PrestaShop database. Your server is likely to require credentials. These details can also be provided as parameters: + ``` mysqldump -h -u --single-transaction --create-options -ecqQ -p db1 > dump.sql ``` diff --git a/basics/keeping-up-to-date/migration.md b/basics/keeping-up-to-date/migration.md index 83f46d5017..98e7835972 100644 --- a/basics/keeping-up-to-date/migration.md +++ b/basics/keeping-up-to-date/migration.md @@ -110,6 +110,7 @@ We explained how to export all your tables to make sure you keep as much data as If you get your data from another CMS or prefer to proceed with your own method, you can run a custom SQL query to get all the information you need. This option is useful if you plan to import your data with the import feature of PrestaShop. As an example here is a SQL request to get the main product details, along with the texts corresponding to the first language of the first shop: + ```sql SELECT p.*, pl.* FROM `ps_product` p JOIN `ps_product_lang` pl ON p.id_product = pl.id_product AND pl.id_lang = 1 AND pl.id_shop = 1 GROUP BY pl.id_product ``` @@ -122,6 +123,7 @@ If the result fits your needs, you can export it with the “export” button av If you used `mysqldump` for your backups, there is also an option for extracting your data in CSV files, as described in the [documentation](https://dev.mysql.com/doc/refman/8.0/en/mysqldump-delimited-text.html). However, our tests have shown that method is far from being easy. Example for exporting the table ps_product: + ```bash mysqldump -h127.0.0.1 -P3307 -uroot -p -T/var/lib/mysql-files --fields-enclosed-by=\" --fields-terminated-by=\; prestashop16 ps_product ``` @@ -180,6 +182,7 @@ mysqldiff --server1=user:pass@host:port:socket --server2=user:pass@host:port:soc You need to provide the credentials to your MySQL servers. If the source and the destination databases are on the same server, the `--server2` parameter can be omitted. `db3` and `db4` are respectively the source and the destination databases of your data. Getting the structure diff will require additional options, as provided in this example: + ```bash mysqldiff --server1=root:xxxx@127.0.0.1:3307 --changes-for=server1 --skip-table-options --force prestashop16:prestashop ``` @@ -246,6 +249,7 @@ You will probably notice the same change on your table keys: - `id_attribute_group` int(10) unsigned NOT NULL, + `id_attribute_group` int(11) NOT NULL, ``` + This change does not imply anything on your side. This is a preliminary work for building relations between our tables. ##### Column removed diff --git a/contribute/contribute-pull-requests/contribute_using_docker.md b/contribute/contribute-pull-requests/contribute_using_docker.md index 5ad0ab2524..1ca44edbb4 100644 --- a/contribute/contribute-pull-requests/contribute_using_docker.md +++ b/contribute/contribute-pull-requests/contribute_using_docker.md @@ -31,7 +31,6 @@ Once you have forked the project, you need to download it to your computer. For instance, if your GitHub nickname is `preston`, this is what you should do in your terminal: - ``` git clone https://github.com/preston/PrestaShop.git ``` diff --git a/contribute/contribution-guidelines/project-modules.md b/contribute/contribution-guidelines/project-modules.md index 2af29b97fb..ff4b5c517c 100644 --- a/contribute/contribution-guidelines/project-modules.md +++ b/contribute/contribution-guidelines/project-modules.md @@ -14,7 +14,7 @@ Contributors wishing to edit a module's files should follow the following proces 1. Create your GitHub account, if you do not have one already. 2. Fork the project to your GitHub account. -3. Clone your fork to your local machine in the ```/modules``` directory of your PrestaShop installation. +3. Clone your fork to your local machine in the `/modules` directory of your PrestaShop installation. 4. Create a branch in your local clone of the module for your changes. 5. Change the files in your branch. @@ -68,12 +68,14 @@ Submitted Pull Requests must comply with the full defined scope. For example if the module compatibility scope includes PS 1.7 and PS 8, it is not possible to merge a Pull Request that can only be used with PS 1.7. If the module uses an extended scope such as: + ``` $this->ps_versions_compliancy = array( 'min' => '1.7.0.0', 'max' => _PS_VERSION_, ); ``` + Because the `max` value will always use the latest PrestaShop version, it means the module must remain compatible with upcoming (not released) PrestaShop versions too. [report-issue]: https://github.com/PrestaShop/PrestaShop/issues/new/choose diff --git a/contribute/documentation/shortcodes/_index.md b/contribute/documentation/shortcodes/_index.md index b938b59588..63bb13d104 100644 --- a/contribute/documentation/shortcodes/_index.md +++ b/contribute/documentation/shortcodes/_index.md @@ -14,10 +14,10 @@ Shortcodes are a special tags that you can use when writing your content that ar There are two kinds of shortcodes: 1. **Tag style** (surrounds your content) - ```go - {{%/* ExampleShortcode */%}} My custom content goes here {{%/* /ExampleShortcode */%}} - ``` - + ```go + {{%/* ExampleShortcode */%}} My custom content goes here {{%/* /ExampleShortcode */%}} + ``` + 2. **Placeholder style** (self-closing, adds some content) ```go {{%/* ExampleShortcode */%}} diff --git a/contribute/documentation/shortcodes/minver.md b/contribute/documentation/shortcodes/minver.md index 5e01cc8ceb..49487c655a 100644 --- a/contribute/documentation/shortcodes/minver.md +++ b/contribute/documentation/shortcodes/minver.md @@ -8,7 +8,7 @@ When highlighting a new feature, you may want to highlight the version on which ```markdown Everything's better on {{}} -``` +``` Which renders to: @@ -21,7 +21,7 @@ To align a pill with a title, use the parameter `title="true"`: ```markdown #### Example title {{}} -``` +``` Which is rendered like this: diff --git a/development/architecture/domain/domain-exceptions.md b/development/architecture/domain/domain-exceptions.md index 083edc4fba..c26c019777 100644 --- a/development/architecture/domain/domain-exceptions.md +++ b/development/architecture/domain/domain-exceptions.md @@ -18,6 +18,7 @@ Let's see how domain exceptions look like in the code. For this example, let's look at `Category` domain: ##### src/Core/Domain/Category/ + ``` . ├── Command diff --git a/development/architecture/migration-guide/forms/CQRS-usage-in-forms.md b/development/architecture/migration-guide/forms/CQRS-usage-in-forms.md index 5a8a71d224..a15980d30a 100644 --- a/development/architecture/migration-guide/forms/CQRS-usage-in-forms.md +++ b/development/architecture/migration-guide/forms/CQRS-usage-in-forms.md @@ -129,7 +129,7 @@ public function create(array $data) return $contactId->getValue(); } ``` - + In this example, the Command Handler for `AddContactCommand` returns a `ContactId` value object that contains the contact ID. ### Using Queries diff --git a/development/architecture/migration-guide/forms/CRUD-forms.md b/development/architecture/migration-guide/forms/CRUD-forms.md index b308238d01..2b5356541f 100644 --- a/development/architecture/migration-guide/forms/CRUD-forms.md +++ b/development/architecture/migration-guide/forms/CRUD-forms.md @@ -108,7 +108,8 @@ Don't forget to register your class as a service, you will need it to use it wit Note: if you use the above snippet of code outside of the `PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataProvider` namespace, like in a module, you need to import the classes that come from this namespace. -Example +Example: + ```php use PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataProvider\FormDataProviderInterface; ``` @@ -161,7 +162,7 @@ In the example above, we are declaring a specific service for this form based on ```text prestashop.core.form.builder.form_builder_factory:create ``` - + ...using two specific arguments: - The **Form Type**'s class name @@ -276,7 +277,8 @@ prestashop.core.form.identifiable_object.data_handler.contact_form_data_handler: Note: if you use the above snippet of code outside of the `PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataHandler` namespace, like in a module, you need to import the classes that come from this namespace. -Example +Example: + ```php use PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataHandler\FormDataHandlerInterface; ``` diff --git a/development/architecture/migration-guide/forms/settings-forms.md b/development/architecture/migration-guide/forms/settings-forms.md index 29d0300b3c..754d6bc4da 100644 --- a/development/architecture/migration-guide/forms/settings-forms.md +++ b/development/architecture/migration-guide/forms/settings-forms.md @@ -182,6 +182,7 @@ To sum up how it works, the controller sends an instance of `FormView` to Twig a {{ form_end(logsByEmailForm) }} ``` + All these helpers are documented and help you generate an HTML form from your `FormView` object, using the right markup to be rendered by the PrestaShop UI Kit. Currently, several forms have already been migrated, so you can use them as base for your own work. All the templates for modern pages can be found in the `src/PrestaShopBundle/Resources/views/Admin` folder. Twig templates for a page are split in subfolders: Forms, Blocks, Lists, Panels. This helps to keep track the role of each template. diff --git a/development/architecture/migration-guide/templating-with-twig.md b/development/architecture/migration-guide/templating-with-twig.md index e954166b4a..79011a751b 100644 --- a/development/architecture/migration-guide/templating-with-twig.md +++ b/development/architecture/migration-guide/templating-with-twig.md @@ -86,12 +86,15 @@ Be careful when copying translatable wordings, you must use the exact same strin {{% /notice %}} Example: + ```php trans('Before activating the webservice, you must be sure to: ', array(), 'Admin.Advparameters.Help'); ``` + ... must become: + ```twig {{ 'Before activating the webservice, you must be sure to: '|trans({}, 'Admin.Advparameters.Help') }} ``` diff --git a/development/architecture/migration-guide/testing/behat.md b/development/architecture/migration-guide/testing/behat.md index 6c3bdd0026..3e1803f0fe 100644 --- a/development/architecture/migration-guide/testing/behat.md +++ b/development/architecture/migration-guide/testing/behat.md @@ -57,6 +57,7 @@ Before continuing, **please read the official `behat` documentation** about the {{% /notice %}} In PrestaShop all `*.feature` files are placed in [.tests/Integration/Behaviour/Features/Scenario](https://github.com/PrestaShop/PrestaShop/tree/8.0.x/tests/Integration/Behaviour/Features/Scenario). Each feature is placed in a dedicated directory organized by `domain` (or even a `subdomain` if necessary). These feature files contains text that describes the testing scenarios in a user-friendly manner, each of them must start with a keyword `Feature` and have a one or multiple scenarios starting with a keyword `Scenario`. For example: + ```feature Feature: Update product status from BO (Back Office) As an employee I must be able to update product status (enable/disable) @@ -72,6 +73,7 @@ Feature: Update product status from BO (Back Office) When I disable product "product1" Then product "product1" should be disabled ``` + As you can see, we state the `given` information, then we describe the action and finally the assertion. These scenarios should be easy to understand even for non-technical people. So when writing one, try to avoid the technical keywords and make it as user-friendly as possible. {{% notice tip %}} @@ -95,6 +97,7 @@ The [`AbstractDomainFeatureContext`](https://github.com/PrestaShop/PrestaShop/bl {{% /notice %}} This is how the context looks like: + ```php class OrderFeatureContext extends AbstractDomainFeatureContext { @@ -126,7 +129,6 @@ class OrderFeatureContext extends AbstractDomainFeatureContext } // ... - ``` As you can see in example, the string `@Given I add order :orderReference with the following details:` maps this method to related line in `*.feature` file. The `:orderReference` acts as a variable which actually is the `id` of the order, that is saved into the [`SharedStorage`]({{< relref "#shared-storage" >}}). The `TableNode $table` is a specific argument, you can read about it [here](https://behat.org/en/latest/user_guide/writing_scenarios.html#tables). @@ -134,6 +136,7 @@ As you can see in example, the string `@Given I add order :orderReference with t ## Shared storage The [SharedStorage](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/tests/Integration/Behaviour/Features/Context/SharedStorage.php) is responsible for holding certain values in memory which are shared across the feature. The most common usage example is the `id` reference - we specify a certain keyword e.g. `product1` before creating it, and once the command returns the auto-incremented value, we set it in shared storage like this `SharedStorage::getStorage()->set($orderReference, $orderId->getValue());`. In upcoming scenarios we can reuse this reference to get the record, something like this: + ```php protected function getProductForEditing(string $reference): ProductForEditing { @@ -161,6 +164,7 @@ Feature: Add basic product from Back Office (BO) {{% notice tip %}} You can also tag specific `features` if you want to run only them with a `--tags` filter. For example, if you add following tag in your Feature: + ```feature @add Feature: Add basic product from Back Office (BO) @@ -168,6 +172,7 @@ Feature: Add basic product from Back Office (BO) I need to be able to add new product with basic information from the BO ... ``` + Then you can run only this feature by following command `./vendor/bin/behat -c tests/Integration/Behaviour/behat.yml -s product --tags add` {{% /notice %}} @@ -389,6 +394,7 @@ class CommonFeatureContext extends AbstractPrestaShopFeatureContext { ## behat.yml When you have already created features and contexts it is time to map them with the test suite. The mapping is done in the behat.yml configuration file. It looks like this: + ```yml default: suites: @@ -410,4 +416,5 @@ default: - Tests\Integration\Behaviour\Features\Context\CategoryFeatureContext - Tests\Integration\Behaviour\Features\Context\Domain\CategoryFeatureContext ``` + As you can see, you have to define the `suite`, the `path` to features, and all the necessary `contexts`. According to the example, when you run the following: `./vendor/bin/behat -c tests/Integration/Behaviour/behat.yml -s customer` - all the `*.feature` files from `tests/Integration/Behaviour/Features/Scenario/Customer` directory will be used to execute the related methods in all the provided contexts. diff --git a/development/architecture/modern/controller-routing.md b/development/architecture/modern/controller-routing.md index 041e076224..18d532cb39 100644 --- a/development/architecture/modern/controller-routing.md +++ b/development/architecture/modern/controller-routing.md @@ -32,6 +32,7 @@ Controller/ ├── Orders └── Stats ``` + Symfony Controllers should be thin by default and have only one responsibility: getting the HTTP Request from the client and returning an HTTP Response. This means that every business logic should be placed in dedicated classes outside the Controller: * Form management diff --git a/development/coding-standards/_index.md b/development/coding-standards/_index.md index dfdc7106a8..002e8e7dff 100644 --- a/development/coding-standards/_index.md +++ b/development/coding-standards/_index.md @@ -156,6 +156,7 @@ You are able to get global types in the `admin-dev/themes/new-theme/js/types` fo ```bash npm run lint-fix ``` + ## HTML, CSS (Sass), Twig & Smarty code conventions HTML, CSS (Sass), Twig and Smarty files MUST follow the [Mark Otto's coding standards](https://codeguide.co/). diff --git a/development/components/configuration/backward-compatibility.md b/development/components/configuration/backward-compatibility.md index dd8058d350..899463b0c0 100644 --- a/development/components/configuration/backward-compatibility.md +++ b/development/components/configuration/backward-compatibility.md @@ -76,6 +76,7 @@ This method returns the data for `$key` if it data exists, or `NULL` otherwise. ```php Configuration::deleteByName(string $key) ``` + This method returns `true` if the key is removed, `false` otherwise. **Parameters:** diff --git a/development/components/console/context-helper.md b/development/components/console/context-helper.md index 03d8a527b5..6cee00f2ff 100644 --- a/development/components/console/context-helper.md +++ b/development/components/console/context-helper.md @@ -14,7 +14,8 @@ It loads the needed property in `Context` using, when needed, a fake Employee or It is available as a Symfony service `prestashop.adapter.legacy_context_loader`. -Example +Example: + ``` MyCustomCommand extends ContainerAwareCommand { diff --git a/development/components/database/db.md b/development/components/database/db.md index 5e2d43e68a..e36b2be8b1 100644 --- a/development/components/database/db.md +++ b/development/components/database/db.md @@ -19,7 +19,7 @@ In some cases, you might encounter this alternative: ```php $db = Db::getInstance(_PS_USE_SQL_SLAVE_); -```` +``` If PrestaShop's database user allows the use of MySQL slave servers in its architecture, then this last instance's connection can be done on the slave servers. You should only use the `PS_USE_SQL_SLAVE` argument when making read-only queries (`SELECT`, `SHOW`, etc.), and only if these do not need a result to be immediately updated with a result. If you make a query on a table right after inserting data in that same table, you should make that query on the master server. @@ -95,6 +95,7 @@ Be careful, if your request has a limit, the method `numRows()` is limited too. ```php $db->Affected_Rows(); ``` + Returns the number of rows impacted by the latest `INSERT`, `UPDATE`, `REPLACE` or `DELETE` query. ### Execute a raw SQL request (UPDATE, INSERT...) @@ -164,6 +165,7 @@ $result = $db->insert( ] ); ``` + This will execute the `INSERT` SQL command only once. `_DB_PREFIX_` will be automatically prefixed to the table name. @@ -180,6 +182,7 @@ $result = $db->update('db_table', array( 'date_upd' => date('Y-m-d H:i:s'), ), 'id_table = 10', 1, true); ``` + Method signature: `update($table, $data, $where = '', $limit = 0, $null_values = false, $use_cache = true, $add_prefix = true)` `_DB_PREFIX_` will be automatically prefixed to the table name if `$add_prefix` is `true` (by default). @@ -192,6 +195,7 @@ The result is boolean saying if the request was properly executed or not. /** @var bool $result */ $result = $db->delete('db_table', 'id_table = 10'); ``` + Method signature: `delete($table, $where = '', $limit = 0, $use_cache = true, $add_prefix = true)` `_DB_PREFIX_` will be automatically prefixed to the table name if `$add_prefix` is `true` (by default). diff --git a/development/components/form/form-theme/_index.md b/development/components/form/form-theme/_index.md index 79d782bd06..200b1cc113 100644 --- a/development/components/form/form-theme/_index.md +++ b/development/components/form/form-theme/_index.md @@ -14,6 +14,7 @@ The code below renders a whole form using Twig: {{ form_widget(form) }} {{ form_end(form) }} ``` + [sf-form-component]: https://symfony.com/doc/4.4/forms.html ## Read more diff --git a/development/components/form/types-reference/change-password.md b/development/components/form/types-reference/change-password.md index 4bdf0d4d8c..ffeefc04c2 100644 --- a/development/components/form/types-reference/change-password.md +++ b/development/components/form/types-reference/change-password.md @@ -30,9 +30,10 @@ class CustomType extends AbstractType } } ``` + Then in Javascript you have to enable `ChangePasswordControl` component. -```javascript +```js import ChangePasswordControl from 'admin-dev/themes/new-theme/js/components/form/change-password-control'; // This component requires many css selectors for targeting. diff --git a/development/components/form/types-reference/generatable-text.md b/development/components/form/types-reference/generatable-text.md index 1185d31caa..dccccf111b 100644 --- a/development/components/form/types-reference/generatable-text.md +++ b/development/components/form/types-reference/generatable-text.md @@ -42,8 +42,7 @@ class CustomType Then in Javascript you have to enable `GeneratableInput` component. -```javascript - +```js import GeneratableInput from "admin-dev/themes/new-theme/js/components/generatable-input"; // initiate the component diff --git a/development/components/form/types-reference/ip-address.md b/development/components/form/types-reference/ip-address.md index f38bdcfd5e..e6e22cd21a 100644 --- a/development/components/form/types-reference/ip-address.md +++ b/development/components/form/types-reference/ip-address.md @@ -41,8 +41,7 @@ class CustomType Then in Javascript you have to enable `IpInput` component. -```javascript - +```js import IpInput from 'admin-dev/themes/new-theme/js/maintenance-page/ip-input'; // initialize the component diff --git a/development/components/form/types-reference/material-choice-table.md b/development/components/form/types-reference/material-choice-table.md index 9f939f6d31..f5dcc1a561 100644 --- a/development/components/form/types-reference/material-choice-table.md +++ b/development/components/form/types-reference/material-choice-table.md @@ -38,9 +38,10 @@ class CustomType extends AbstractType } } ``` + Then in Javascript you have to enable `ChoiceTable` component. -```javascript +```js import ChoiceTable from 'admin-dev/themes/new-theme/js/components/choice-table'; // initiate the component. diff --git a/development/components/form/types-reference/material-choice-tree.md b/development/components/form/types-reference/material-choice-tree.md index d57460595f..1d18337d5c 100644 --- a/development/components/form/types-reference/material-choice-tree.md +++ b/development/components/form/types-reference/material-choice-tree.md @@ -54,9 +54,10 @@ class CustomType extends AbstractType } } ``` + Then in Javascript you have to enable `ChoiceTree` component. -```javascript +```js import ChoiceTree from 'admin-dev/themes/new-theme/js/components/form/choice-tree'; // initiate the component by providing your tree selector diff --git a/development/components/form/types-reference/material-multiple-choice-table.md b/development/components/form/types-reference/material-multiple-choice-table.md index abfb276e8e..631e7e7628 100644 --- a/development/components/form/types-reference/material-multiple-choice-table.md +++ b/development/components/form/types-reference/material-multiple-choice-table.md @@ -74,9 +74,10 @@ class CustomType extends AbstractType } } ``` + Then in Javascript you have to enable `MultipleChoiceTable` component. -```javascript +```js import MultipleChoiceTable from 'admin-dev/themes/new-theme/js/components/multiple-choice-table'; // enable the component diff --git a/development/components/form/types-reference/text-with-length-counter.md b/development/components/form/types-reference/text-with-length-counter.md index 88a7b9c02e..1ad8ba3f72 100644 --- a/development/components/form/types-reference/text-with-length-counter.md +++ b/development/components/form/types-reference/text-with-length-counter.md @@ -43,7 +43,7 @@ class SomeType extends AbstractType Then in Javascript you have to enable `TextWithLengthCounter` component. -```javascript +```js import TextWithLengthCounter from "admin-dev/themes/new-theme/js/components/form/text-with-length-counter"; // enables length counter for all TextWithLengthCounterType inputs on the page diff --git a/development/components/form/types-reference/translatable.md b/development/components/form/types-reference/translatable.md index 660ead4a56..95a2a30a66 100644 --- a/development/components/form/types-reference/translatable.md +++ b/development/components/form/types-reference/translatable.md @@ -51,7 +51,7 @@ class SomeType extends AbstractType Then in Javascript you have to enable `TranslatableInput` component. -```javascript +```js import TranslatableInput from "admin-dev/themes/new-theme/js/components/translatable-input"; // enable togging of different locales diff --git a/development/components/grid/_index.md b/development/components/grid/_index.md index 3fafda0340..b532e98d66 100644 --- a/development/components/grid/_index.md +++ b/development/components/grid/_index.md @@ -100,7 +100,7 @@ prestashop.core.grid.definition.factory.product_grid_definition_factory: class: 'PrestaShop\PrestaShop\Core\Grid\Definition\Factory\ProductGridDefinitionFactory' parent: 'prestashop.core.grid.definition.factory.abstract_grid_definition' public: true -``` +``` Most of the time you won't be creating Grid Definitions by yourself but delegating this task to other services, but in case you need to create a Grid Definition by hand, here's how you can do that. @@ -114,7 +114,7 @@ $productsGridDefinition = $productsGridDefinitionFactory->getDefinition(); $productsGridDefinition->getColumns(); // collection of defined columns $productsGridDefinition->getName(); // "Products" $productsGridDefinition->getId(); // "products" -``` +``` ## Search Criteria diff --git a/development/components/grid/tutorials/extend-grid-with-javascript.md b/development/components/grid/tutorials/extend-grid-with-javascript.md index 4c3b3cabd9..f3e6ce97b8 100644 --- a/development/components/grid/tutorials/extend-grid-with-javascript.md +++ b/development/components/grid/tutorials/extend-grid-with-javascript.md @@ -155,6 +155,7 @@ $(() => { taxGrid.addExtension(new BulkActionCheckboxExtension()); }); ``` + The last thing to do is to run the compiler. [More about compiler and npm commands here]({{< relref "/8/development/compile-assets" >}}). In our example we open command line, cd to `{{Our prestashop root directory}}/admin-dev/themes/new-theme` and type the following command: diff --git a/development/components/grid/tutorials/work-with-bulk-actions.md b/development/components/grid/tutorials/work-with-bulk-actions.md index a7a768ec05..5076f4ab3c 100644 --- a/development/components/grid/tutorials/work-with-bulk-actions.md +++ b/development/components/grid/tutorials/work-with-bulk-actions.md @@ -139,4 +139,5 @@ Then you need to create template so it can render nicely in your grid. {{ action.name }} ``` + Last thing is to add your newly created Bulk action to Grid's `BulkActionCollection` and then it should be available in your Grid! diff --git a/development/components/grid/tutorials/work-with-grid-actions.md b/development/components/grid/tutorials/work-with-grid-actions.md index f06161e5da..65bf1d8bd2 100644 --- a/development/components/grid/tutorials/work-with-grid-actions.md +++ b/development/components/grid/tutorials/work-with-grid-actions.md @@ -182,4 +182,5 @@ Then you need to create template so it can render nicely in your grid. {{ action.name }} ``` + Last thing is to add your newly created Grid action to Grid's `GridActionCollection` and then it should be available in your Grid! diff --git a/development/components/grid/tutorials/work-with-row-actions.md b/development/components/grid/tutorials/work-with-row-actions.md index 799a9c945c..539e183b47 100644 --- a/development/components/grid/tutorials/work-with-row-actions.md +++ b/development/components/grid/tutorials/work-with-row-actions.md @@ -194,4 +194,5 @@ Then you need to create template so it can render nicely in your grid. {{ action.name }} ``` + Last thing is to add your newly created Row action to Grid's `RowActionCollection` and then it should be available in your Grid! diff --git a/development/components/helpers/helperform.md b/development/components/helpers/helperform.md index 9ebd24ac65..71fdb5e7cf 100644 --- a/development/components/helpers/helperform.md +++ b/development/components/helpers/helperform.md @@ -200,7 +200,7 @@ $formDeclaration = [ 'succcess' => $this->l('Form saved!'), 'error' => $this->l('Oops, something went wrong.'), ]; -``` +``` ### Buttons diff --git a/development/components/position-updater/_index.md b/development/components/position-updater/_index.md index bf0e02f240..069ca51ac7 100644 --- a/development/components/position-updater/_index.md +++ b/development/components/position-updater/_index.md @@ -121,6 +121,7 @@ The format of the input data is not random nor fixed, it actually matches the de - 'newPosition' - 'parentId' ``` + If you need this component to match another input format you can instanciate your own factory with the appropriate settings. {{% /notice %}} diff --git a/development/components/smarty-extensions/_index.md b/development/components/smarty-extensions/_index.md index 12413aecb3..1e78996a44 100644 --- a/development/components/smarty-extensions/_index.md +++ b/development/components/smarty-extensions/_index.md @@ -81,7 +81,7 @@ If you need to escape quotes in the _translated_ text, do it like this: -``` +``` ### {render} diff --git a/development/internationalization/translation/translation-tips.md b/development/internationalization/translation/translation-tips.md index 4c2ddd585e..b57414e238 100644 --- a/development/internationalization/translation/translation-tips.md +++ b/development/internationalization/translation/translation-tips.md @@ -61,7 +61,7 @@ In Twig files, you can use `trans_default_domain` to set up your default domain. {% trans_default_domain 'Admin.Catalog.Feature' %} {{ 'Hello world'|trans }} {{ 'Something else'|trans }} -``` +``` #### Form ChoiceTypes @@ -115,6 +115,7 @@ You can declare wordings as arrays as well. This obviously won't translate the w 'parameters' => [], ]; ``` + ## Translate core wordings You can translate core wordings (mainly present in PHP files) via Classic theme translation interface. diff --git a/development/internationalization/translation/using-the-translator.md b/development/internationalization/translation/using-the-translator.md index 0f80aaf98b..1068b79e50 100644 --- a/development/internationalization/translation/using-the-translator.md +++ b/development/internationalization/translation/using-the-translator.md @@ -17,7 +17,7 @@ To translate wordings in PHP files, you first need an instance of the `Translato ```php trans('This product is no longer available.', [], 'Shop.Notifications.Error'); -``` +``` The `trans()` method takes three arguments: diff --git a/development/multistore/configuration-forms/_index.md b/development/multistore/configuration-forms/_index.md index ddb5c061ba..5994fc9535 100644 --- a/development/multistore/configuration-forms/_index.md +++ b/development/multistore/configuration-forms/_index.md @@ -73,9 +73,7 @@ window.prestashop.component.initComponents( 'MultistoreConfigField', ], ); -```` - - +``` Doing this will have several effects: diff --git a/development/upgrade-module/upgrade-cli.md b/development/upgrade-module/upgrade-cli.md index f35f0da89e..0f4aeffa40 100644 --- a/development/upgrade-module/upgrade-cli.md +++ b/development/upgrade-module/upgrade-cli.md @@ -20,7 +20,8 @@ The following parameters are mandatory: If you use default `action` parameter, it will run the full upgrade process. -Exemple +Example: + ``` $ php cli-upgrade.php --dir=admin-dev --channel=major ``` @@ -38,7 +39,8 @@ The following parameters are mandatory: * **--dir**: Tells where the admin directory is. * **--backup**: Select the backup to restore (this can be found in your folder `/autoupgrade/backup/`) -Exemple +Example: + ``` $ php cli-rollback.php --dir=admin-dev --backup=V1.7.5.1_20190502-191341-22e883bd ``` diff --git a/faq/pricing.md b/faq/pricing.md index ff0c0c6b24..f1f6ab139c 100644 --- a/faq/pricing.md +++ b/faq/pricing.md @@ -31,7 +31,8 @@ In order to obtain this secure key, you need 2 items: - your shop name The secure key is computed like this: -``` + +```php $secureKey = md5(_COOKIE_KEY_ . Configuration::get('PS_SHOP_NAME')); ``` diff --git a/faq/tips-and-tricks/hook-tips.md b/faq/tips-and-tricks/hook-tips.md index a2c6405ba0..412bc20373 100644 --- a/faq/tips-and-tricks/hook-tips.md +++ b/faq/tips-and-tricks/hook-tips.md @@ -40,7 +40,9 @@ if ('admin_orders_create' === $currentRoute) { ``` Other methods are available. For example, thanks to `LegacyParametersConverter` which was introduced in 1.7.7.0, you can get controller action parameter using following approach: + ```php $action = Tools::getValue('action'); ``` + The configuration `legacy_params` for migrated page allows to link legacy parameters with new Symfony routes. If they are configured correctly, above mentioned code snippet should return 'addorder'. So you can use the legacy parameters to check a Symfony page identity. diff --git a/modules/concepts/controllers/admin-controllers/_index.md b/modules/concepts/controllers/admin-controllers/_index.md index 060f841b5a..ab64575b30 100644 --- a/modules/concepts/controllers/admin-controllers/_index.md +++ b/modules/concepts/controllers/admin-controllers/_index.md @@ -107,6 +107,7 @@ You must enable the autoloading for this Controller. For example using a `compos "type": "prestashop-module" } ``` + You should run `composer dumpautoload` console command from where your module's composer.json file is located. If you do not have "composer" you can search for it. Composer is available on [any operating system](https://getcomposer.org/doc/00-intro.md). diff --git a/modules/concepts/controllers/admin-controllers/route-generation.md b/modules/concepts/controllers/admin-controllers/route-generation.md index b2128ee666..01820f4ac7 100644 --- a/modules/concepts/controllers/admin-controllers/route-generation.md +++ b/modules/concepts/controllers/admin-controllers/route-generation.md @@ -138,6 +138,7 @@ This will only work for **one route/one controller** the association by action d In order to generate a symfony route in javascript, you can use the [`Router` component](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/admin-dev/themes/new-theme/js/components/router.ts). You can use it like this: + ``` import Router from '@components/router'; @@ -148,9 +149,11 @@ const route = this.router.generate('my_route', {parameters}); It however uses a computed file that you might need to recompute if you modified some route settings. You can recompute it using this: + ``` php bin/console fos:js-routing:dump --format=json ``` + And put it in `admin-dev/themes/new-theme/js/fos_js_routes.json` {{% notice %}} diff --git a/modules/concepts/controllers/front-controllers.md b/modules/concepts/controllers/front-controllers.md index ee83660229..5576990d12 100644 --- a/modules/concepts/controllers/front-controllers.md +++ b/modules/concepts/controllers/front-controllers.md @@ -149,6 +149,7 @@ without URL rewriting. link->getModuleLink('cheque', 'validation', array('idPayment' => 1337)); ``` + * Without URL rewriting: `http:///index.php?idPayment=1337&fc=module&module=cheque&controller=validation&id_lang=1` * With URL rewriting: `http:///en/module/cheque/validation?idPayment=1337` diff --git a/modules/concepts/hooks/list-of-hooks.md b/modules/concepts/hooks/list-of-hooks.md index 7cf5d5a578..47abc8ce0a 100644 --- a/modules/concepts/hooks/list-of-hooks.md +++ b/modules/concepts/hooks/list-of-hooks.md @@ -47,7 +47,7 @@ action<AdminControllerClassName><Action>After 'return' => (mixed) ); ``` - + action<AdminControllerClassName><Action>Before : Called before performing <Action> in any <AdminController> @@ -61,7 +61,7 @@ action<AdminControllerClassName><Action>Before 'controller' => (AdminController) ); ``` - + action<AdminControllerClassName>FormModifier : Called when rendering a form in any <AdminController> @@ -78,7 +78,7 @@ action<AdminControllerClassName>FormModifier 'form_vars' => &(array), ); ``` - + action<AdminControllerClassName>ListingFieldsModifier : Located in: /classes/controller/AdminController.php @@ -95,7 +95,7 @@ action<AdminControllerClassName>ListingFieldsModifier 'fields' => &(array) ); ``` - + action<AdminControllerClassName>OptionsModifier : Located in: /classes/controller/AdminController.php @@ -108,7 +108,7 @@ action<AdminControllerClassName>OptionsModifier 'option_vars' => &(array), ); ``` - + actionAdmin<Action>After : Called after performing <Action> in any admin controller @@ -123,7 +123,7 @@ actionAdmin<Action>After 'return' => (mixed) ); ``` - + actionAdmin<Action>Before : Called before performing <Action> in any admin controller @@ -137,7 +137,7 @@ actionAdmin<Action>Before 'controller' => (AdminController) ); ``` - + actionAdminControllerSetMedia : Located in: /classes/controller/AdminController.php @@ -166,7 +166,7 @@ actionAdminMetaAfterWriteRobotsFile 'write_fd' => &(resource) File handle ); ``` - + actionAdminMetaBeforeWriteRobotsFile : Called before generating the robots.txt file @@ -180,7 +180,7 @@ actionAdminMetaBeforeWriteRobotsFile 'rb_data' => &(array) File data ); ``` - + actionAdminMetaSave : Called after saving the configuration in AdminMeta @@ -230,7 +230,7 @@ actionAdminProductsListingFieldsModifier 'sql_limit' => &(string), ); ``` - + actionAdminProductsListingResultsModifier : Located in: /src/Adapter/Product/AdminProductDataProvider.php @@ -244,7 +244,7 @@ actionAdminProductsListingResultsModifier 'total' => (int), ); ``` - + actionAdminThemesControllerUpdate_optionsAfter : Located in: /controllers/admin/AdminThemesController.php for PrestaShop < 1.7.6 @@ -264,7 +264,7 @@ actionAjaxDie<ControllerName><Method>Before 'value' => (string) ); ``` - + actionAjaxDieBefore : **(deprecated since 1.6.1.1)** @@ -438,7 +438,7 @@ actionCustomerAccountAdd 'newCustomer' => (object) Customer object ); ``` - + actionCustomerAccountUpdate : Invoked when a customer updates its account successfully @@ -593,7 +593,7 @@ actionFrontControllerSetVariables 'templateVars' => &(array) ); ``` - + Example usage: Your hook implementation should return array of values that will be added to `prestashop` object in `javascript` and `$modules` object in `smarty`. @@ -607,19 +607,19 @@ actionFrontControllerSetVariables ]; } ``` - + In Front Office you can access it globally using: - ```javascript + ```js console.log(prestashop.modules.your_module_name.your_variable_name); "Hello world" ``` - + with smarty ```smarty {$modules.your_module_name.your_variable_name} - ``` + ``` actionGetAlternativeSearchPanels : @@ -811,7 +811,7 @@ actionOrderEdited array( 'order' => (object) Order ); ``` - + actionOrderHistoryAddAfter : This hook is displayed when a customer returns a product @@ -832,7 +832,7 @@ actionOrderReturn 'orderReturn' => (object) OrderReturn ); ``` - + actionOrderSlipAdd : Called when the quantity of a product changes in an order. @@ -860,7 +860,7 @@ WARNING: only invoked when a product is actually removed from an order. ); The order of IDs and quantities is important! ``` - + actionOrderStatusPostUpdate : Called after the status of an order changes. @@ -879,7 +879,7 @@ actionOrderStatusPostUpdate 'id_order' => (int) Order ID ); ``` - + actionOrderStatusUpdate : Called before the status of an order changes. @@ -895,7 +895,7 @@ actionOrderStatusUpdate 'id_order' => (int) Order ID ); ``` - + actionOutputHTMLBefore : Available since: {{< minver v="1.7.1" >}} @@ -924,7 +924,7 @@ actionPaymentCCAdd 'paymentCC' => (object) OrderPayment object ); ``` - + actionPaymentConfirmation : Called after a payment has been validated @@ -938,7 +938,7 @@ actionPaymentConfirmation 'id_order' => (int) Order ID ); ``` - + actionPDFInvoiceRender : Located in: @@ -1041,7 +1041,7 @@ actionProductFlagsModifier 'product' => (Product) $product, ), ``` - + actionSearch : @@ -1059,7 +1059,7 @@ actionSearch 'total' => (int) Amount of search results ); ``` - + actionSetInvoice : Located in: /classes/order/Order.php @@ -1088,7 +1088,7 @@ actionShopDataDuplication 'new_id_shop' => (int) New shop ID ); ``` - + actionSubmitAccountBefore : Available since: {{< minver v="1.7.1" >}} @@ -1121,7 +1121,7 @@ Quantity is updated only when a customer effectively places their order 'quantity' => (int) New product quantity ); ``` - + actionValidateCustomerAddressForm : This hook is called when a customer submit its address form @@ -1135,7 +1135,7 @@ actionValidateCustomerAddressForm 'form' => (object) CustomerAddressForm ); ``` - + actionValidateOrder : After an order has been validated. @@ -1193,7 +1193,7 @@ actionValidateStepComplete 'completed' => &$isComplete, ); ``` - + Usage: ```php (int) Product ID ); ``` - + actionGetAdminOrderButtons : Available since: {{< minver v="1.7.7" >}} @@ -1319,7 +1319,7 @@ Located in: /controllers/admin/AdminDashboardController.php 'date_to' => (string|null) $statsDateTo, ] ``` - + displayAdminAfterHeader : Located in: @@ -1342,7 +1342,6 @@ This hook launches modules when the AdminCustomers tab is displayed in the Back 'id_customer' = (int) Customer ID ); ``` - displayAdminCustomersAddressesItemAction : @@ -1469,7 +1468,7 @@ This hook launches modules when the AdminOrder tab is displayed in the Back Offi 'id_order' = (int) Order ID ); ``` - + displayAdminOrderContentOrder : **(removed in 1.7.7 in favor of)** @@ -1924,6 +1923,7 @@ displayBeforeCarrier ) ); ``` + NOTE: intified means an array of integers 'intified' by Cart::intifier displayCarrierExtraContent @@ -1948,7 +1948,7 @@ displayCarrierList 'address' => (object) Address object ); ``` - + displayCartExtraProductActions : Extra buttons in shopping cart @@ -2276,7 +2276,7 @@ displayOrderConfirmation 'order' => (object) Order ); ``` - + displayOrderConfirmation1 : Located in: /themes/classic/templates/checkout/order-confirmation.tpl @@ -2303,7 +2303,7 @@ displayOrderDetail 'order' => (object) Order object ); ``` - + displayOrderPreview : Available since: {{< minver v="1.7.7" >}} @@ -2319,7 +2319,6 @@ displayOrderPreview 'order_id' => (integer) Order Id ); ``` - displayPaymentByBinaries : @@ -2455,6 +2454,7 @@ displayRightColumn 'cart' => (object) Cart object ); ``` + Note that the Cart object can also be retrieved from the current Context. displayRightColumnProduct @@ -2663,7 +2663,7 @@ action<KpiIdentifier>KpiRowModifier 'kpis' => KpiInterface[] $kpis ), ``` - + action<HookName>Form : Available since: {{< minver v="1.7.4" >}} @@ -2678,7 +2678,7 @@ action<HookName>Form [ 'form_builder' => (FormBuilderInterface) $this->formBuilder, ] - ``` + ``` action<HookName>Save : @@ -2710,7 +2710,7 @@ action<GridDefinitionId>GridDefinitionModifier 'definition' => (GridDefinition) $definition, ] ``` - + action<GridDefinitionId>GridQueryBuilderModifier : Available since: {{< minver v="1.7.5" >}} @@ -2725,7 +2725,7 @@ action<GridDefinitionId>GridQueryBuilderModifier 'search_criteria' => (SearchCriteriaInterface) $searchCriteria, ] ``` - + action<GridDefinitionId>GridDataModifier : Available since: {{< minver v="1.7.5" >}} @@ -2738,7 +2738,7 @@ action<GridDefinitionId>GridDataModifier 'data' => (GridData) $data, ] ``` - + action<GridDefinitionId>GridFilterFormModifier : Available since: {{< minver v="1.7.5" >}} @@ -2751,7 +2751,7 @@ action<GridDefinitionId>GridFilterFormModifier 'filter_form_builder' => (FormBuilderInterface) $formBuilder, ] ``` - + action<GridDefinitionId>GridPresenterModifier : Available since: {{< minver v="1.7.5" >}} @@ -2822,7 +2822,7 @@ actionBeforeUpdate<FormName>FormHandler 'id' => (int) $id, ] ``` - + actionAfterUpdate<FormName>FormHandler : Available since: {{< minver v="1.7.6" >}} @@ -2835,7 +2835,7 @@ actionAfterUpdate<FormName>FormHandler 'id' => (int) $id, ] ``` - + actionBeforeCreate<FormName>FormHandler : Available since: {{< minver v="1.7.6" >}} diff --git a/modules/concepts/overrides.md b/modules/concepts/overrides.md index 02fa1c1ea0..1372f043a7 100644 --- a/modules/concepts/overrides.md +++ b/modules/concepts/overrides.md @@ -154,7 +154,6 @@ Despite a module having different files, the main one, additional classes, etc., To override a module's instance class, you have to extend it, giving the extended class the same name and adding the `Override` suffix: ```php - class BlockUserInfoOverride extends BlockUserInfo { public function hookDisplayNav($params) @@ -164,6 +163,7 @@ class BlockUserInfoOverride extends BlockUserInfo } } ``` + You must put the file in `/override/modules/blockuserinfo/blockuserinfo.php` After adding an override, don't forget to clean the cache. You can do it from the back office or by CLI using the Symfony console. @@ -176,7 +176,6 @@ You may even create a module that overrides other modules! For instance: To override a module's front/admin controller class, you have to extend it, giving the extended class the same name and adding the `Override` suffix: ```php - class AdminBlockListingControllerOverride extends AdminBlockListingController { public function displayAjaxSaveColor() @@ -196,6 +195,7 @@ class AdminBlockListingControllerOverride extends AdminBlockListingController } } ``` + You must put the file in `/override/modules/blockreassurance/controllers/admin/AdminBlockListingController.php` After adding an override, don't forget to clean the cache. You can do it from the back office or by CLI using the Symfony console. diff --git a/modules/concepts/pdf.md b/modules/concepts/pdf.md index 889cb98588..31222faf6d 100644 --- a/modules/concepts/pdf.md +++ b/modules/concepts/pdf.md @@ -293,7 +293,7 @@ public function hookActionGetExtraMailTemplateVars($hookArgs) ``` -### Code exemple : +### Code example: {{% notice tip %}} You can override the core PDF templates in your module. @@ -318,6 +318,7 @@ mycustompdfgenerator ├── logo.png ``` + * PHP Code ```php diff --git a/modules/concepts/templating/import-js.md b/modules/concepts/templating/import-js.md index e9cde1a04e..6343f5b24f 100644 --- a/modules/concepts/templating/import-js.md +++ b/modules/concepts/templating/import-js.md @@ -11,7 +11,7 @@ Most of the time, you will use the [global JavaScript components][global JavaScr **We don't recommend doing this.** If you absolutely need it, make sure to remove the file extension from the import path: -```javascript +```js // Incorrect import AutoCompletSearch from '../../../../admin-dev/themes/new-theme/js/components/auto-complete-search.js' import AutoCompletSearch from '../../../../admin-dev/themes/new-theme/js/components/auto-complete-search.ts' @@ -23,7 +23,7 @@ import AutoCompletSearch from '../../../../admin-dev/themes/new-theme/js/compone If you need to carry out the above import, it is likely you will be using a bundler such as Webpack or Parcel. If the file you are trying to import is a TypeScript file, you need to add the TypeScript loader to your project and a `tsconfig` file. Example of a TypeScript loader: -```javascript +```js { test: /\.ts?$/, use: 'ts-loader', @@ -32,7 +32,7 @@ Example of a TypeScript loader: ``` Example of a TypeScript configuration file: -```javascript +```js { "compilerOptions": { "outDir": "./public/", diff --git a/modules/creation/module-translation/classic-system.md b/modules/creation/module-translation/classic-system.md index 069808566c..9cbf2bbbe9 100644 --- a/modules/creation/module-translation/classic-system.md +++ b/modules/creation/module-translation/classic-system.md @@ -243,7 +243,6 @@ sprintf=['[foo]' => 'some replacement, '%bar%' => 'something else'] {{% /notice %}} - #### Interpolating HTML You may need to add HTML content in your translated string. Writing it directly in the string (original or translated) won't work, as the special characters would be escaped to avoid XSS security issues. @@ -401,7 +400,7 @@ $this->l('Some '. $var . ' wording'); public function translate($wording) { $this->l($wording); } -``` +``` ### Language codes diff --git a/modules/creation/module-translation/new-system.md b/modules/creation/module-translation/new-system.md index e6d5128606..38304948fe 100644 --- a/modules/creation/module-translation/new-system.md +++ b/modules/creation/module-translation/new-system.md @@ -298,7 +298,7 @@ In Twig files, you can use `trans_default_domain` to set up your default domain. {% trans_default_domain 'Modules.Mymodule.Foo' %} {{ 'Hello world'|trans }} {{ 'Something else'|trans }} -``` +``` ## Distributing your translations diff --git a/modules/sample-modules/grid-and-identifiable-object-form-hooks-usage.md b/modules/sample-modules/grid-and-identifiable-object-form-hooks-usage.md index 737e711de1..b55b51ca37 100644 --- a/modules/sample-modules/grid-and-identifiable-object-form-hooks-usage.md +++ b/modules/sample-modules/grid-and-identifiable-object-form-hooks-usage.md @@ -110,6 +110,7 @@ class Ps_DemoCQRSHooksUsage extends Module // ... } ``` + This hook, through `$params` array, received `GridDefinition` that defines how the grid is rendered. See [Grid definition]({{< relref "/8/development/components/grid/#grid-definition" >}}) for more information. In this sample a new toggable column which determines if the customer is eligible to review products is added just after another column which has id `optin`. The sample code also demonstrates how add new filter. @@ -159,7 +160,6 @@ class CustomerReviewController extends FrameworkBundleAdminController - As this is a Symfony controller, we must configure the related routing (read more about [symfony routing](https://symfony.com/doc/current/routing.html)), which means create a route in `ps_democqrshooksusage/config/routes.yml` file: ```yml - ps_democqrshooksusage_toggle_is_allowed_for_review: path: demo-cqrs-hook-usage/{customerId}/toggle-is-allowed-for-review methods: [POST] diff --git a/modules/sample-modules/order-pages-new-hooks/module-base.md b/modules/sample-modules/order-pages-new-hooks/module-base.md index 5728bf7957..9b976ec983 100644 --- a/modules/sample-modules/order-pages-new-hooks/module-base.md +++ b/modules/sample-modules/order-pages-new-hooks/module-base.md @@ -119,10 +119,12 @@ class FixturesInstaller } } ``` + Let's create `Installer` class inside `/demovieworderhooks/src/Install` folder structure. It is responsible only for module installation (hook registration, database creation, population database data). When it comes to database creation we use PrestaShop `DbCore` class functions because [Doctrine](https://symfony.com/doc/4.4/doctrine) is [not fully supported for modules installation]({{< relref "/8/modules/concepts/doctrine/#creating-the-database" >}}) at 1.7.7.0 release. + ```php }}) for the above diff --git a/scale/benchmark/_index.md b/scale/benchmark/_index.md index 0394e5664d..cd8523269a 100755 --- a/scale/benchmark/_index.md +++ b/scale/benchmark/_index.md @@ -80,9 +80,9 @@ stock_availables (1): langs ([fr_FR, en_US]): ``` -If you want to customize later the number of entities, just modify the file ```app/config/config.yml``` +If you want to customize later the number of entities, just modify the file `app/config/config.yml` -Then run the following command to generate your initial dataset, which will be stored in the ```generated_data``` +Then run the following command to generate your initial dataset, which will be stored in the `generated_data`` directory ``` @@ -91,18 +91,20 @@ php app/console.php #### How to use this dataset during PrestaShop install? -Actually it's quite simple. Just copy the content of the ```generated_data``` folders (three folders should be -there: data, img and langs) in the PrestaShop ```install/fixtures/fashion``` folders (overwrite the folders already +Actually it's quite simple. Just copy the content of the `generated_data` folders (three folders should be +there: data, img and langs) in the PrestaShop `install/fixtures/fashion` folders (overwrite the folders already there). Then launch a standard PrestaShop install. ### Prepare your shop -Make sure you're not in debug mode! In ```config/defines.inc.php``` you should have: +Make sure you're not in debug mode! In `config/defines.inc.php` you should have: + ```text define('_PS_MODE_DEV_', false); ``` + The smarty cache should be enabled, but the multi-front synchronisation should be disabled for best performances. (those are the default settings). diff --git a/scale/benchmark/back-office.md b/scale/benchmark/back-office.md index a68165df99..7852fc420e 100755 --- a/scale/benchmark/back-office.md +++ b/scale/benchmark/back-office.md @@ -191,7 +191,7 @@ And choose the simulation you want to run ![Gatling](https://i.imgur.com/HQ5eCfZ.png) -In my example I run "[1] basic.BasicExempleSimulation" +In my example I run "[1] basic.BasicExampleSimulation" ![Gatling](https://i.imgur.com/nJdOPsB.png) ##### Well done! Our Gatling installation is ready! @@ -223,10 +223,13 @@ For example if you site is setup in /etc/apache2/sites-enabled/000-default.conf add the value + ```bash SetEnv _TOKEN_ disabled ``` + before + ``` < /VirtualHost > ``` diff --git a/scale/benchmark/front-office.md b/scale/benchmark/front-office.md index 5bbe87a8b7..9abee03cc1 100644 --- a/scale/benchmark/front-office.md +++ b/scale/benchmark/front-office.md @@ -20,7 +20,7 @@ Try to always use the latest available version Date: Mon, 3 Oct 2022 12:32:01 +0700 Subject: [PATCH 084/310] Update module names, template code for PS 1.7 switch language to en, use more neutral path --- themes/reference/overriding-modules.md | 28 ++++++++++++++++---------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/themes/reference/overriding-modules.md b/themes/reference/overriding-modules.md index 19c3f2333a..ee2f637a0d 100644 --- a/themes/reference/overriding-modules.md +++ b/themes/reference/overriding-modules.md @@ -111,20 +111,26 @@ Here an example of generated markup with SmartyDev activated: - + - + - - - - + + + + +
- + shopping_cart [...] ``` From d2e5993dcdfe22acf982e7d9090cfe307104c119 Mon Sep 17 00:00:00 2001 From: Thomas Nares Date: Mon, 3 Oct 2022 13:04:55 +0200 Subject: [PATCH 085/310] Begin refacto doc ObjectManager --- .../components/database/objectmodel.md | 209 +++++++++++++----- 1 file changed, 158 insertions(+), 51 deletions(-) diff --git a/development/components/database/objectmodel.md b/development/components/database/objectmodel.md index ddb308d4d0..b97e91e53a 100644 --- a/development/components/database/objectmodel.md +++ b/development/components/database/objectmodel.md @@ -4,13 +4,48 @@ title: ObjectModel class # The ObjectModel class -When needing to dive deep, you have to use the ObjectModel class. This is the main object of PrestaShop’s object model. It can be overridden… with precaution. +## Introduction -It is an Active Record kind of class (see: [Active record pattern](https://en.wikipedia.org/wiki/Active_record_pattern)). The table attributes or view attributes of PrestaShop’s database are encapsulated in this class. Therefore, the class is tied to a database record. After the object has been instantiated, a new record is added to the database. Each object retrieves its data from the database; when an object is updated, the record to which it is tied is updated as well. The class implements accessors for each attribute. +ObjectModel class is one of the main pillar of Prestashop's core. ObjectModel is the Data Access Layer for PrestaShop, implemented following the Active Record pattern. The Data Access Layer (DAL) is a part (with the Database Abstraction Layer - DBAL) of the Object Relational Mapping (ORM) system for PrestaShop. + +Read more about Object relation mapping (ORM), Database abstraction layer (DBAL), Data access layer (DAL), and Active Record : + +- [Object relational mapping (ORM)](https://en.wikipedia.org/wiki/Object%E2%80%93relational_mapping) +- [Database abstraction layer (DBAL)](https://en.wikipedia.org/wiki/Database_abstraction_layer) +- [Data access layer (DAL)](https://en.wikipedia.org/wiki/Data_access_layer) +- [Active record pattern](https://en.wikipedia.org/wiki/Active_record_pattern) + +A class extending ObjectModel class is tied to a database table. A static attribute (`$definition`) is representing the model. + +Its instances are tied to database records. The ObjectModel class provides accessors for each attribute. + +When instancied with an id passed to the class constructor, the attributes are set with the related database record content (using the id as a primary key). + +When the `save()` method is called, ObjectModel will ask the DBAL to insert or update the object to database, depending if the id (reflection of the primary key in database), is known or not in the ObjectModel. + +ObjectModel is also in charge of deleting an object in database (with its `delete()` method). + +An ObjectModel extended class can be overriden, but with extreme precaution : defining a wrong `$definition` model for example, can break the entire system, or can lead to data loss. + +## Create a new entity managed by ObjectModel + +You can create a new entity (in a module for example), with its own database table, managed by ObjectModel. + +To do this, extend you class with "ObjectModel" : + +```php +use PrestaShop\PrestaShop\Adapter\Entity\ObjectModel; // not sure if i should namespace/use the adapter in this example or just use ObjectModel; ? + +class Cms extends ObjectModel { + +} +``` + +Next step is to define your model. ## Defining the model -You must use the `$definition` static variable in order to define the model. +To define your model (reflection of the database table structure, fields, type, ...), you must use the `$definition` static variable. For instance: @@ -64,82 +99,154 @@ public static $definition = [ ]; ``` -## Multiple stores and/or languages - -In order to retrieve an object in many languages: +Let's analyse this definition : ```php -'multilang' => true +public static $definition = [ + 'table' => 'cms', + 'primary' => 'id_cms', + 'multilang' => true, + 'fields' => array( ``` -In order to retrieve an object depending on the current store: +- `table` is the related database table name (without the database table `PREFIX`, usually `ps_`), +- `primary` is the name of the `PRIMARY KEY` field in the database table, which will be used as `$id` in the ObjectModel +- `multilang` is a boolean value indicating that the entity is available in multiple langages, see [Multiple stores and/or languages]({{< ref "#multiple-stores-languages" >}}) +- `fields` is an array containing all other of the fields from the database table. + +### Fields description + +A field is defined by a key (its name in the database table) and an array of description of its settings. ```php -'multishop' => true +'meta_description' => [ + 'type' => self::TYPE_STRING, + 'lang' => true, + 'validate' => 'isGenericName', + 'size' => 255 +], ``` -In order to retrieve an object which depends on the current store, and in many languages: +In this example : + +- `meta_description` is the field's name +- `self::TYPE_STRING` is its type +- `lang` is a boolean related to multilang features ([Multiple stores and/or languages]({{< ref "#multiple-stores-languages" >}})) +- `validate` is a validation rule (optional) +- `size` is the max size of the field. It should match the database definition to avoid data cropping or overflow when inserting/updating objects. + +#### Field types reference + +Field type is an important setting, it determines how ObjectModel will format your data. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Type in ObjectModelRelated type in MySQL
TYPE_INTINTEGER, INT, SMALLINT, TINYINT, MEDIUMINT, BIGINT, ...
TYPE_BOOLSMALLINT
TYPE_STRINGVARCHAR
TYPE_FLOATFLOAT, DOUBLE
TYPE_DATEDATE
TYPE_HTMLBLOB, TEXT
TYPE_NOTHINGShould not be used (avoids ObjectModel formating)
TYPE_SQLShould not be used
+ +#### Validation rules reference + +Several validation rules are available for your ObjectModel fields. +Please refer to the Validate class of PrestaShop [here](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Validate.php) for a complete list. + +## Basic usage of an ObjectModel managed entity + +### Create a new object ```php -'multilang_shop' => true +$cms = new Cms(); +$cms->position = 2; +$cms->meta_title = "My awesome CMS title"; +[...] +$cms->save(); ``` -## Main methods +In this example, we create an entity from scratch. Then, we set its `position` and `meta_title` attribute, and we call the `save()` method. The `save()` method will trigger the `add()` method since its `id` attribute is not yet known (because the entity is not created in database). +If the insert was successful, the ObjectModel class will set the id of the entity (retrieved from database). [Complete reference here](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/ObjectModel.php#L572-L658). -{{% funcdef %}} -__construct($id = NULL, $id_lang = NULL) -: - Build object. +### Load an object -add($autodate = true, $nullValues = false) -: - Adds current object to the database. +```php +$id = 2; // id of the entity in database +$cms = new Cms($id); +$cms->meta_title = "My awesome CMS title with an update"; +[...] +$cms->save(); +``` -associateTo(integer|array $id_shops) -: - Associate an item to its context. +In this example, we retrieve an entity from the database, with its id. Then, we change its `meta_title` attribute, and we call the same `save()` method. The `save()` method will trigger the `update()` method and not the `add()` method since its `id` attribute is known. -delete() -: - Delete current object from database. +### Delete an object -deleteImage(mixed $force_delete = false) -: - Delete images associated with the object. +```php +$id = 2; // id of the entity in database +$cms = new Cms($id); +$cms->delete(); +``` -deleteSelection($selection) -: - Delete several objects from database. +In this example, we retrieve an entity from the database, with its id. Then, we trigger the `delete()` method. -getFields() -: - Prepare fields for ObjectModel class (add, update). +## Multiple stores and/or languages {#multiple-stores-languages} -getValidationRules($className = \_CLASS\_) -: - Return object validation rules (field validity). +In order to retrieve an object in many languages: -save($nullValues = false, $autodate = true) -: - Save current object to database (add or update). +```php +'multilang' => true +``` -toggleStatus() -: - Toggle object's status in database. +In order to retrieve an object depending on the current store: -update($nullValues = false) -: - Update current object to database. +```php +'multishop' => true +``` -validateFields($die = true, $errorReturn = false) -: - Check for field validity before database interaction. +In order to retrieve an object which depends on the current store, and in many languages: -{{% /funcdef %}} +```php +'multilang_shop' => true +``` -## ObjectModel lifecycle +## ObjectModel lifecycle and hooks Thanks to the hooks, you can alter the Object Model or execute functions during the lifecycle of your models. Every hook receive an instance of the manipulated object model: From 6a6179806d4a9947e14e0d035a8f514e30d5b835 Mon Sep 17 00:00:00 2001 From: Thomas Nares Date: Mon, 3 Oct 2022 13:13:17 +0200 Subject: [PATCH 086/310] Begin refacto doc ObjectManager --- .../components/database/objectmodel.md | 22 +++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/development/components/database/objectmodel.md b/development/components/database/objectmodel.md index b97e91e53a..45ce30b47d 100644 --- a/development/components/database/objectmodel.md +++ b/development/components/database/objectmodel.md @@ -214,7 +214,7 @@ $cms->meta_title = "My awesome CMS title with an update"; $cms->save(); ``` -In this example, we retrieve an entity from the database, with its id. Then, we change its `meta_title` attribute, and we call the same `save()` method. The `save()` method will trigger the `update()` method and not the `add()` method since its `id` attribute is known. +In this example, we retrieve an entity from the database, with its id. Then, we change its `meta_title` attribute, and we call the same `save()` method. The `save()` method will trigger the `update()` method and not the `add()` method since its `id` attribute is known. [Complete reference here](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/ObjectModel.php#L750-L868). ### Delete an object @@ -224,7 +224,25 @@ $cms = new Cms($id); $cms->delete(); ``` -In this example, we retrieve an entity from the database, with its id. Then, we trigger the `delete()` method. +In this example, we retrieve an entity from the database, with its id. Then, we trigger the `delete()` method, and the object will be removed from the database. [Complete reference here](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/ObjectModel.php#L877-L919). + +## Advanced usage + +### Partial update of an entity + +todo + +### Toggle status + +todo + +### Delete multiple entities + +todo + +### Associate an entity to a context + +todo ## Multiple stores and/or languages {#multiple-stores-languages} From b9fdf30edbf096e5dedc59cb5199e7b243a89472 Mon Sep 17 00:00:00 2001 From: MeKeyCool Date: Mon, 3 Oct 2022 15:11:46 +0200 Subject: [PATCH 087/310] Update project hostname --- .github/PULL_REQUEST_TEMPLATE.md | 2 +- README.md | 4 ++-- development/coding-standards/_index.md | 2 +- modules/concepts/hooks/use-hooks-on-modern-pages.md | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index e1a050c43f..1280f6b775 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -4,7 +4,7 @@ Thank you for contributing to the PrestaShop developer documentation! Please take the time to edit the "Answers" rows below with the necessary information. Check out our contribution guidelines on how to contribute: -https://devdocs.prestashop.com/8/contribute/documentation/how/ +https://devdocs.prestashop-project.org/8/contribute/documentation/how/ ------------------------------------------------------------------------------> | Questions | Answers diff --git a/README.md b/README.md index 8988633359..a31b83a39f 100644 --- a/README.md +++ b/README.md @@ -3,11 +3,11 @@ [![Build](https://github.com/PrestaShop/docs/actions/workflows/build.yml/badge.svg)](https://github.com/PrestaShop/docs/actions/workflows/build.yml) [![DevDocs Site update](https://github.com/PrestaShop/docs/actions/workflows/update-site.yml/badge.svg)](https://github.com/PrestaShop/docs/actions/workflows/update-site.yml) -This documentation is available at https://devdocs.prestashop.com/ +This documentation is available at [https://devdocs.prestashop-project.org/](https://devdocs.prestashop-project.org/) ## Contributing -Contributions are more than welcome! [Find out how](https://devdocs.prestashop.com/8/contribute/documentation/how/). +Contributions are more than welcome! [Find out how](https://devdocs.prestashop-project.org/8/contribute/documentation/how/). ## Rendering the site locally diff --git a/development/coding-standards/_index.md b/development/coding-standards/_index.md index dfdc7106a8..27a8853b9c 100644 --- a/development/coding-standards/_index.md +++ b/development/coding-standards/_index.md @@ -202,7 +202,7 @@ All PrestaShop files MUST start with the PrestaShop license block: * * 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 https://devdocs.prestashop.com/ for more information. + * needs please refer to https://devdocs.prestashop-project.org/ for more information. * * @author PrestaShop SA and Contributors * @copyright Since 2007 PrestaShop SA and Contributors diff --git a/modules/concepts/hooks/use-hooks-on-modern-pages.md b/modules/concepts/hooks/use-hooks-on-modern-pages.md index 5806d6185f..95ed27bf83 100644 --- a/modules/concepts/hooks/use-hooks-on-modern-pages.md +++ b/modules/concepts/hooks/use-hooks-on-modern-pages.md @@ -49,7 +49,7 @@ As we need to act on Dashboard but after the header, in the icons toolbar (with ### Second step: create and register the Hook -Create a [new module](https://devdocs.prestashop.com/8/modules/creation/tutorial) called `foo` and register the hook. You should end up with this kind of code in your module: +Create a [new module](https://devdocs.prestashop-project.org/8/modules/creation/tutorial) called `foo` and register the hook. You should end up with this kind of code in your module: ```php Date: Mon, 3 Oct 2022 17:21:29 +0200 Subject: [PATCH 088/310] Refacto doc ObjectManager --- .../components/database/objectmodel.md | 120 ++++++++++++++---- 1 file changed, 93 insertions(+), 27 deletions(-) diff --git a/development/components/database/objectmodel.md b/development/components/database/objectmodel.md index 45ce30b47d..1bf563a5af 100644 --- a/development/components/database/objectmodel.md +++ b/development/components/database/objectmodel.md @@ -15,17 +15,19 @@ Read more about Object relation mapping (ORM), Database abstraction layer (DBAL) - [Data access layer (DAL)](https://en.wikipedia.org/wiki/Data_access_layer) - [Active record pattern](https://en.wikipedia.org/wiki/Active_record_pattern) -A class extending ObjectModel class is tied to a database table. A static attribute (`$definition`) is representing the model. +A class extending ObjectModel class is tied to a database table. Its static attribute (`$definition`) is representing the model. Its instances are tied to database records. The ObjectModel class provides accessors for each attribute. -When instancied with an id passed to the class constructor, the attributes are set with the related database record content (using the id as a primary key). +When instancied with an `$id` passed to the class constructor, the attributes are set with the related database record content (using the `$id` as a primary key). -When the `save()` method is called, ObjectModel will ask the DBAL to insert or update the object to database, depending if the id (reflection of the primary key in database), is known or not in the ObjectModel. +When the `save()` method is called, ObjectModel will ask the DBAL to **insert** or **update** the object to database, depending if the `$id` is known or not in the ObjectModel. ObjectModel is also in charge of deleting an object in database (with its `delete()` method). +{{% notice info %}} An ObjectModel extended class can be overriden, but with extreme precaution : defining a wrong `$definition` model for example, can break the entire system, or can lead to data loss. +{{% /notice %}} ## Create a new entity managed by ObjectModel @@ -34,7 +36,7 @@ You can create a new entity (in a module for example), with its own database tab To do this, extend you class with "ObjectModel" : ```php -use PrestaShop\PrestaShop\Adapter\Entity\ObjectModel; // not sure if i should namespace/use the adapter in this example or just use ObjectModel; ? +use PrestaShop\PrestaShop\Adapter\Entity\ObjectModel; class Cms extends ObjectModel { @@ -111,7 +113,7 @@ public static $definition = [ - `table` is the related database table name (without the database table `PREFIX`, usually `ps_`), - `primary` is the name of the `PRIMARY KEY` field in the database table, which will be used as `$id` in the ObjectModel -- `multilang` is a boolean value indicating that the entity is available in multiple langages, see [Multiple stores and/or languages]({{< ref "#multiple-stores-languages" >}}) +- `multilang` is a boolean value indicating that the entity is available in multiple langages, see [Multiple languages]({{< ref "#multiple-languages" >}}) - `fields` is an array containing all other of the fields from the database table. ### Fields description @@ -131,7 +133,7 @@ In this example : - `meta_description` is the field's name - `self::TYPE_STRING` is its type -- `lang` is a boolean related to multilang features ([Multiple stores and/or languages]({{< ref "#multiple-stores-languages" >}})) +- `lang` is a boolean related to multilang features ([Multiple languages]({{< ref "#multiple-languages" >}})) - `validate` is a validation rule (optional) - `size` is the max size of the field. It should match the database definition to avoid data cropping or overflow when inserting/updating objects. @@ -185,7 +187,7 @@ Field type is an important setting, it determines how ObjectModel will format yo #### Validation rules reference Several validation rules are available for your ObjectModel fields. -Please refer to the Validate class of PrestaShop [here](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Validate.php) for a complete list. +[Please refer to the Validate class of PrestaShop](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Validate.php) for a complete list. ## Basic usage of an ObjectModel managed entity @@ -207,7 +209,7 @@ If the insert was successful, the ObjectModel class will set the id of the entit ### Load an object ```php -$id = 2; // id of the entity in database +$id = 2; // id of the object in database $cms = new Cms($id); $cms->meta_title = "My awesome CMS title with an update"; [...] @@ -216,59 +218,123 @@ $cms->save(); In this example, we retrieve an entity from the database, with its id. Then, we change its `meta_title` attribute, and we call the same `save()` method. The `save()` method will trigger the `update()` method and not the `add()` method since its `id` attribute is known. [Complete reference here](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/ObjectModel.php#L750-L868). -### Delete an object +### Hard or soft delete an object + +Two delete mecanisms are available with ObjectModel : hard delete and soft delete. +Hard-delete deletes the record from the database, while soft-delete sets a flag to database indicating that this record is deleted. + +{{% notice info %}} +**Soft delete is not always available.** + +If the model object has no `deleted` property or no `deleted` definition field, a `PrestaShopException` will be thrown +{{% /notice %}} + +{{% notice info %}} +**Soft delete does not trigger DeleteHooks.** + +Soft deleting an object does not trigger **Delete** related hooks, but will trigger **Update** related hooks. [ObjectModel lifecycle hooks]({{< ref "#lifecycle-hooks" >}}) +{{% /notice %}} ```php -$id = 2; // id of the entity in database +$id = 2; // id of the object in database $cms = new Cms($id); -$cms->delete(); +$cms->softDelete(); // sets the deleted property to true, and triggers an update() call +[...] +$cms->delete(); // triggers a DELETE statement to the DBAL ``` -In this example, we retrieve an entity from the database, with its id. Then, we trigger the `delete()` method, and the object will be removed from the database. [Complete reference here](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/ObjectModel.php#L877-L919). - ## Advanced usage -### Partial update of an entity +### Multiple languages objects{#multiple-languages} +{{% notice %}} todo +{{% /notice %}} -### Toggle status +### Multiple stores objects{#multiple-stores} +{{% notice %}} todo +{{% /notice %}} -### Delete multiple entities +### Duplicate an object +{{% notice %}} todo +{{% /notice %}} -### Associate an entity to a context +### Partial update of an object -todo +Since {{< minver v="8.x" >}}, a partial update mecanism is available in ObjectModel. This mecanism allows you to choose which attributes you want to update during the `update()` method call. + +On previous versions ({{< minver v="1.7.x" >}}, {{< minver v="1.6.x" >}}, ...), this method was already available but was not properly working. + +Example : + +```php +$cms = new Cms(2); +$cms->meta_title = "My awesome CMS title with an update"; +$cms->meta_description = "My updated description"; +$cms->setFieldsToUpdate(["meta_title" => true]); +$cms->save(); +``` + +In this example, only the `meta_title` will be updated. `meta_description` (and all other fields) will not be updated in database. + +### Toggle status + +A mecanism of state is available with ObjectModel : active / inactive state. +When triggered, this mecanism allows your entities to be enabled / disabled. -## Multiple stores and/or languages {#multiple-stores-languages} +{{% notice info %}} +**Status is not always available.** -In order to retrieve an object in many languages: +If the model object has no `active` property or no `active` definition field, a `PrestaShopException` will be thrown +{{% /notice %}} ```php -'multilang' => true +$id = 2; // id of the entity in database +$cms = new Cms($id); +$cms->toggleStatus(); // sets the active property to true or false (depending on its current value), and triggers an update() call ``` -In order to retrieve an object depending on the current store: +### Delete multiple entities + +You can delete multiple object at once with the `deleteSelection` method. Pass an array of IDs to delete to this method, and they will be deleted. + +Usage : ```php -'multishop' => true +$cmsIdsToDelete = [1, 2, 3, 8, 10]; +(new Cms())->deleteSelection($cmsIdsToDelete); ``` -In order to retrieve an object which depends on the current store, and in many languages: +### Associate an object to a store (context) + +When working with multi-store ObjectModels, you can associate an object to one or several stores with the `associateTo` method : ```php -'multilang_shop' => true +$cms->associateTo(1); // associates the object to the store #1 +[...] +$cms->associateTo([1, 2, 4]); // associates the object to the stores #1, #2 and #4 ``` -## ObjectModel lifecycle and hooks +## ObjectModel lifecycle and hooks{#lifecycle-hooks} Thanks to the hooks, you can alter the Object Model or execute functions during the lifecycle of your models. Every hook receive an instance of the manipulated object model: -{{< figure src="../../../img/object-model-lifecycle.png" title="ObjectModel lifecycle" >}} +{{% mermaid %}} +graph TD + subgraph "DELETE" + deleteA(actionObjectDeleteBefore) --> deleteB(actionObjectClassnameDeleteBefore) --> deleteC(actionObjectDeleteAfter) --> deleteD(actionObjectClassnameDeleteAfter) + end + subgraph "UPDATE" + updateA(actionObjectUpdateBefore) --> updateB(actionObjectClassnameUpdateBefore) --> updateC(actionObjectUpdateAfter) --> updateD(actionObjectClassnameUpdateAfter) + end + subgraph "CREATE" + createA(actionObjectAddBefore) --> createB(actionObjectClassnameAddBefore) --> createC(actionObjectAddAfter) --> createD(actionObjectClassnameAddAfter) + end +{{% /mermaid %}} As an example, this is how you can retrieve information about a product when we delete it from the database: From 3ae4743ca072d39c2170c335d7a24a82d2429820 Mon Sep 17 00:00:00 2001 From: Thomas Nares Date: Mon, 3 Oct 2022 18:08:47 +0200 Subject: [PATCH 089/310] Change mermaid mode --- development/components/database/objectmodel.md | 1 + development/img/object-model-lifecycle.png | Bin 61563 -> 0 bytes 2 files changed, 1 insertion(+) delete mode 100644 development/img/object-model-lifecycle.png diff --git a/development/components/database/objectmodel.md b/development/components/database/objectmodel.md index 1bf563a5af..e1706a1bf6 100644 --- a/development/components/database/objectmodel.md +++ b/development/components/database/objectmodel.md @@ -1,5 +1,6 @@ --- title: ObjectModel class +useMermaid: true --- # The ObjectModel class diff --git a/development/img/object-model-lifecycle.png b/development/img/object-model-lifecycle.png deleted file mode 100644 index 1efded1a88e99dd9c3f4549006a57a7a7c047ea0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 61563 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 Rfd#%4W!0XQJu!XrzW@Ru5_kXr From 677f1fc94ebcfede8599f7c4db09ab2e2fe86a46 Mon Sep 17 00:00:00 2001 From: Thomas Nares Date: Tue, 4 Oct 2022 16:57:01 +0200 Subject: [PATCH 090/310] Update Objectmodel doc --- .../components/database/objectmodel.md | 283 +++++++++++++++--- 1 file changed, 244 insertions(+), 39 deletions(-) diff --git a/development/components/database/objectmodel.md b/development/components/database/objectmodel.md index e1706a1bf6..5d6b581584 100644 --- a/development/components/database/objectmodel.md +++ b/development/components/database/objectmodel.md @@ -7,7 +7,9 @@ useMermaid: true ## Introduction -ObjectModel class is one of the main pillar of Prestashop's core. ObjectModel is the Data Access Layer for PrestaShop, implemented following the Active Record pattern. The Data Access Layer (DAL) is a part (with the Database Abstraction Layer - DBAL) of the Object Relational Mapping (ORM) system for PrestaShop. +ObjectModel class is one of the main pillar of PrestaShop's legacy core. While a complete migration to Symfony/Doctrine entities is planned in the roadmap, ObjectModel will still remain present and available in our software for a while. + +ObjectModel is the Data Access Layer for PrestaShop, implemented following the Active Record pattern. The Data Access Layer (DAL) is a part (with the Database Abstraction Layer - DBAL) of the Object Relational Mapping (ORM) legacy system for PrestaShop. Read more about Object relation mapping (ORM), Database abstraction layer (DBAL), Data access layer (DAL), and Active Record : @@ -18,9 +20,9 @@ Read more about Object relation mapping (ORM), Database abstraction layer (DBAL) A class extending ObjectModel class is tied to a database table. Its static attribute (`$definition`) is representing the model. -Its instances are tied to database records. The ObjectModel class provides accessors for each attribute. +Its instances are tied to database records. The ObjectModel class provides accessors for each attribute defined in `$definition`. -When instancied with an `$id` passed to the class constructor, the attributes are set with the related database record content (using the `$id` as a primary key). +When instancied with an `$id` passed to the class constructor, the attributes are retrieved in the related database (using the `$id` as the primary key to find the table record). When the `save()` method is called, ObjectModel will ask the DBAL to **insert** or **update** the object to database, depending if the `$id` is known or not in the ObjectModel. @@ -44,9 +46,9 @@ class Cms extends ObjectModel { } ``` -Next step is to define your model. +Next step is to define your model. [Defining the model]({{< ref "#defining-model" >}}). -## Defining the model +## Defining the model{#defining-model} To define your model (reflection of the database table structure, fields, type, ...), you must use the `$definition` static variable. @@ -192,32 +194,31 @@ Several validation rules are available for your ObjectModel fields. ## Basic usage of an ObjectModel managed entity -### Create a new object +### Create and save a new object ```php $cms = new Cms(); $cms->position = 2; -$cms->meta_title = "My awesome CMS title"; -[...] +... $cms->save(); ``` -In this example, we create an entity from scratch. Then, we set its `position` and `meta_title` attribute, and we call the `save()` method. The `save()` method will trigger the `add()` method since its `id` attribute is not yet known (because the entity is not created in database). +In this example, we create an entity from scratch. Then, we set its `position` attribute, and we call the `save()` method. The `save()` method will trigger the `add()` method since its `id` attribute is not yet known (because the entity is not created in database). If the insert was successful, the ObjectModel class will set the id of the entity (retrieved from database). [Complete reference here](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/ObjectModel.php#L572-L658). -### Load an object +### Load and save an object ```php $id = 2; // id of the object in database $cms = new Cms($id); -$cms->meta_title = "My awesome CMS title with an update"; -[...] +$cms->position = 3; +... $cms->save(); ``` -In this example, we retrieve an entity from the database, with its id. Then, we change its `meta_title` attribute, and we call the same `save()` method. The `save()` method will trigger the `update()` method and not the `add()` method since its `id` attribute is known. [Complete reference here](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/ObjectModel.php#L750-L868). +In this example, we retrieve an entity from the database, with its id. Then, we change its `position` attribute, and we call the same `save()` method. The `save()` method will trigger the `update()` method and not the `add()` method since its `id` attribute is known. [Complete reference here](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/ObjectModel.php#L750-L868). ### Hard or soft delete an object @@ -240,7 +241,7 @@ Soft deleting an object does not trigger **Delete** related hooks, but will trig $id = 2; // id of the object in database $cms = new Cms($id); $cms->softDelete(); // sets the deleted property to true, and triggers an update() call -[...] +... $cms->delete(); // triggers a DELETE statement to the DBAL ``` @@ -248,20 +249,211 @@ $cms->delete(); // triggers a DELETE statement to the DBAL ### Multiple languages objects{#multiple-languages} -{{% notice %}} -todo -{{% /notice %}} +PrestaShop's ObjectModel can handle translations (also called internationalization, or i18n) of your objects. -### Multiple stores objects{#multiple-stores} +#### Under the hood : how does it work ? -{{% notice %}} -todo -{{% /notice %}} +When declaring a multi-language ObjectModel, PrestaShop will fetch another database table named like your base database table, with a suffix `_lang` +This table references the id of the base Object (`id_cms`), the id of the language (`id_lang`), and each translatable field. + +In our previous example, for `Cms` ObjectModel : + +
+classDiagram + ps_cms <|-- ps_cms_lang + ps_cms : id_cms + ps_cms : id_cms_category + ps_cms : position + ps_cms : active + ps_cms : ... + class ps_cms_lang { + id_cms + id_lang + meta_title + meta_description + meta_keywords + link_rewrite + content + ... + } +
+ +#### Translate your ObjectModel entity + +To do so, you must declare the `multilang` setting of your model definition to `true` : + +```php +public static $definition = [ + ... + 'multilang' => true, + ... +``` + +And then, you must declare which ones of your fields are translated : + +```php +'fields' => array( + ... + 'meta_description' => [ + ... + 'lang' => true, + ... + ], + ... +) +``` + +#### Accessors for Translatable ObjectModels{#multiple-language-accessors} + +Translatable fields are available in your ObjectModel as `array`. +In our example, to update the attributes `meta_title` for languages EN (`$lang_id=1`) and FR (`$lang_id=2`), use the following method : + +```php +$cms->meta_title[1] = "My awesome title"; +$cms->meta_title[2] = "Mon fabuleux titre"; +$cms->save(); +``` + +### Multiple stores/shops objects{#multiple-stores} + +PrestaShop's ObjectModel can handle multiple stores (or multi shop) ObjectModels. + +#### Under the hood : how does it work ? + +When declaring a multi-store ObjectModel, PrestaShop will fetch another database table named like your base database table, with a suffix `_shop` +This table is a pivot table referencing at least the id of the base Object (`id_cms`) and the id of the shop (`id_shop`). + +In our previous example, for `Cms` ObjectModel : + +
+classDiagram + ps_cms <|-- ps_cms_shop + ps_cms : id_cms + ps_cms : id_cms_category + ps_cms : position + ps_cms : active + ps_cms : ... + class ps_cms_shop { + id_cms + id_shop + } +
+ +#### Enable multi-shop for your entity + +To do so, you must declare the `multishop` setting of your model definition to `true` : + +```php +public static $definition = [ + ... + 'multishop' => true, + ... +``` + +#### Associate an object to a store + +You can associate an object to one or several stores with the `associateTo` method : + +```php +$cms->associateTo(1); // associates the object to the store #1 +... +$cms->associateTo([1, 2, 4]); // associates the object to the stores #1, #2 and #4 +``` + +### Multiple stores/shops and languages objects{#multiple-stores-languages} + +PrestaShop's ObjectModel can handle both multiple languages and multiple shops entities. The entity `Category` is a good example of this case : + +- we need to translate a Category name for each language +- we may need to change the name of a Category for different shops + +#### Under the hood : how does it work ? + +When declaring a multi-store ObjectModel, PrestaShop will fetch another database table named like your base database table, with a suffix `_shop` +This table is a pivot table referencing at least the id of the base Object (`id_cms`) and the id of the shop (`id_shop`). + +In our previous example, for `Category` ObjectModel : + +
+classDiagram + ps_category <|-- ps_category_lang + ps_category <|-- ps_category_shop + ps_category : id_category + ps_category : position + ps_category : active + ps_category : ... + class ps_category_lang { + id_category + id_shop + id_lang + additional_description + ... + } + class ps_category_shop { + id_category + id_shop + } +
+ +#### Enable multi language + multi shop for your entity + +To do so, you must declare the `multishop_lang` setting of your model definition to `true` : + +```php +public static $definition = [ + ... + 'multishop_lang' => true, + ... +``` + +And then, you must declare which ones of your fields are translated : + +```php +'fields' => array( + ... + 'additional_description' => [ + ... + 'lang' => true, + ... + ], + ... +) +``` + +#### Loading or save a multishop_lang object + +While languages are [accessible with accessors]({{< ref "#multiple-language-accessors" >}}), if you need to programatically retrieve an ObjectModel related to a particular shop (not the selected / current shop from Context), you need to change the method used to load an object : + +```php +$targetShopId = 2; +$category = new Category(1, null, $targetShopId); // 1 is the id of the object +``` + +If you need to update a translatable field on your entity, you need to add a `Shop::setContext()` call before you save your object : + +```php +$targetShopId = 2; +Shop::setContext(Shop::CONTEXT_SHOP, $targetShopId); + +$category = new Category(1, null, $targetShopId); +$category->additional_description[1] = "Additional description for shop #2"; // language id #1, english +$category->additional_description[2] = "Description additionelle pour le shop #2"; // language id #2, french +$category->save(); +``` ### Duplicate an object -{{% notice %}} -todo +To duplicate an object, use the following method : `duplicateObject()` + +```php +$cms = new Cms(2); +$duplicatedCms = $cms->duplicateObject(); +``` + +{{% notice info %}} +**duplicateObject will save the object to database.** + +Please note that `duplicateObject()` will instantly save the duplicated object to database {{% /notice %}} ### Partial update of an object @@ -274,13 +466,32 @@ Example : ```php $cms = new Cms(2); -$cms->meta_title = "My awesome CMS title with an update"; -$cms->meta_description = "My updated description"; -$cms->setFieldsToUpdate(["meta_title" => true]); +$cms->position = 4; +$cms->active = 0; +$cms->setFieldsToUpdate(["position" => true]); $cms->save(); ``` -In this example, only the `meta_title` will be updated. `meta_description` (and all other fields) will not be updated in database. +In this example, only the `position` will be updated. `active` (and all other fields) will not be updated in database. + +#### Partial update of a multi language field + +You need to specify the language Ids you want to update, as an array : + +```php +$cms = new Cms(2); +$cms->meta_title[1] = "My awesome title"; // language id #1 +$cms->meta_title[2] = "Mon fabuleux titre"; // language id #2 +$cms->setFieldsToUpdate( + [ + "meta_title" => [ + 1 => true, + 2 => false + ] + ] +); +$cms->save(); // only meta_title for language id #1 will be updated +``` ### Toggle status @@ -310,21 +521,15 @@ $cmsIdsToDelete = [1, 2, 3, 8, 10]; (new Cms())->deleteSelection($cmsIdsToDelete); ``` -### Associate an object to a store (context) - -When working with multi-store ObjectModels, you can associate an object to one or several stores with the `associateTo` method : - -```php -$cms->associateTo(1); // associates the object to the store #1 -[...] -$cms->associateTo([1, 2, 4]); // associates the object to the stores #1, #2 and #4 -``` +{{% notice info %}} +**This method only does Hard deletes** +{{% /notice %}} ## ObjectModel lifecycle and hooks{#lifecycle-hooks} Thanks to the hooks, you can alter the Object Model or execute functions during the lifecycle of your models. Every hook receive an instance of the manipulated object model: -{{% mermaid %}} +
graph TD subgraph "DELETE" deleteA(actionObjectDeleteBefore) --> deleteB(actionObjectClassnameDeleteBefore) --> deleteC(actionObjectDeleteAfter) --> deleteD(actionObjectClassnameDeleteAfter) @@ -332,10 +537,10 @@ graph TD subgraph "UPDATE" updateA(actionObjectUpdateBefore) --> updateB(actionObjectClassnameUpdateBefore) --> updateC(actionObjectUpdateAfter) --> updateD(actionObjectClassnameUpdateAfter) end - subgraph "CREATE" + subgraph "CREATE" createA(actionObjectAddBefore) --> createB(actionObjectClassnameAddBefore) --> createC(actionObjectAddAfter) --> createD(actionObjectClassnameAddAfter) end -{{% /mermaid %}} +
As an example, this is how you can retrieve information about a product when we delete it from the database: From 107244ade7375a60132a4523360268c09712ac21 Mon Sep 17 00:00:00 2001 From: leemyongpakvn Date: Thu, 6 Oct 2022 09:19:17 +0700 Subject: [PATCH 091/310] In PrestaShop 8 classic theme is moved out of core and checkout.tpl does not include notifications.tpl --- themes/reference/templates/notifications.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/themes/reference/templates/notifications.md b/themes/reference/templates/notifications.md index 6ff38bcdbe..49d7bdbc3e 100644 --- a/themes/reference/templates/notifications.md +++ b/themes/reference/templates/notifications.md @@ -33,7 +33,7 @@ An array of notification is passed to the templates, containing at least one of ## How to display notifications -In the "Classic" Theme, [notifications are implemented as a partial template file](https://github.com/PrestaShop/PrestaShop/blob/1.7.6.0/themes/classic/templates/_partials/notifications.tpl): +In the "Classic" Theme, [notifications are implemented as a partial template file](https://github.com/PrestaShop/classic-theme/blob/develop/templates/_partials/notifications.tpl): ```smarty ``` -...and are then [included in the template file](https://github.com/PrestaShop/PrestaShop/blob/1.7.6.0/themes/classic/templates/checkout/checkout.tpl#L46-L48): +...and are then [included in the template file](https://github.com/PrestaShop/classic-theme/blob/develop/templates/customer/page.tpl#L32-L34): ```smarty {block name='notifications'} From 86937bd638dd9f7b985c99df7f4491937f9e68c4 Mon Sep 17 00:00:00 2001 From: Thomas Nares Date: Thu, 6 Oct 2022 10:56:30 +0200 Subject: [PATCH 092/310] Fix sentences, remove duplicate doc from Configuration for maintanibility, add installation method --- modules/creation/tutorial.md | 79 +++++++++++++++--------------------- 1 file changed, 32 insertions(+), 47 deletions(-) diff --git a/modules/creation/tutorial.md b/modules/creation/tutorial.md index 9953490226..e9fb7a3cdd 100644 --- a/modules/creation/tutorial.md +++ b/modules/creation/tutorial.md @@ -2,6 +2,8 @@ title: "Tutorial: Creating your first module" menuTitle: "Tutorial" weight: 1 +useMermaid: true + --- # Tutorial: Creating your first module @@ -10,7 +12,7 @@ weight: 1 Before you start writing code for your PrestaShop module, we recommend reading PrestaShop's [Coding standards]({{< ref "/8/development/coding-standards" >}}). Configuring your IDE hints or using [automated tools](https://github.com/PrestaShop/php-dev-tools) can help you make sure you follow the project's standards properly. {{% /notice %}} -Let's create a simple first module; this will enable us to better describe its structure. We will name it **"My module"**. +Let's create a first simple module, this will allow us to better describe its structure. We will name it **"My module"**. First, create the module's folder, in PrestaShop's `/modules` folder. Let's call it `mymodule`. This will be the module's "technical" name. @@ -64,7 +66,7 @@ At this stage, if you place the module's folder on the `/modules` folder, the mo ## The constructor method -Now, let's fill the class' code block with the essential constructor lines. Since the constructor is the first method to be called when the module is loaded by PrestaShop, this is the best place to set its details. +Now, let's create the constructor method of the module. Since the constructor is the first method to be called when the module is loaded by PrestaShop, this is the best place to set its details. ```php name = 'mymodule'; @@ -245,49 +247,12 @@ As you can see, our three blocks of code (`__construct()`, `install()` and `unin This is a PrestaShop-specific object that allows to easily manage all the shop's settings. It stores its data on the `ps_configuration` database table. -### The main methods - -This component has three main methods, allowing you to perform basic CRUD operations: - -`Configuration::get('myVariable')` -: Retrieves a specific value from the database. - -`Configuration::updateValue('myVariable', $value)` -: Updates an existing setting with a new value. If the setting does not yet exist, it creates it with that value. - -`Configuration::deleteByName('myVariable')` -: Deletes the setting. - - -Note that when using `updateValue()`, the content of `$value` can be anything, be it a string, a number, a serialized PHP array or a JSON object. As long as you properly code the data handling function, anything goes. For instance, here is how to handle a PHP array using the `Configuration` object: - -```php -}}). +You can read more about this component in [Legacy Configuration object]({{< ref "/8/development/components/configuration/backward-compatibility" >}}) and [Configuration storage]({{< ref "/8/development/components/configuration" >}}). {{% /notice %}} -### Retrieving external values from the ps_configuration data table - -You are not limited to your own variables: PrestaShop stores all its own configuration settings in the `ps_configuration` database table. There are literally hundreds of settings, and you can access them just as easily as you would access your own. For instance: - -- `Configuration::get('PS_LANG_DEFAULT')`: retrieves the ID for the default language. -- `Configuration::get('PS_TIMEZONE')`: retrieves the name of the current timezone, in standard TZ format (see: [List of tz database time zones](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones)). -- `Configuration::get('PS_DISTANCE_UNIT')`: retrieves the default distance unit ("km" for kilometers, etc.). -- `Configuration::get('PS_SHOP_EMAIL')`: retrieves the main contact e-mail address. -- `Configuration::get('PS_NB_DAYS_NEW_PRODUCT')`: retrieves the number of days during which a newly-added product is considered "New" by PrestaShop. - -Dive into the `ps_configuration` table to discover many other settings! - ## The Shop object The `install()` method also references this: @@ -326,8 +291,32 @@ There are many free icon libraries available on the web. Here are a few: ## Installing the module +You have two options to install a module : via back office interface, or via Symfony Console + +### Install module via back office interface + Now that all basics are in place, reload the back office's "Module Catalog" page, in the "Front office features" section, you should find your module. Install it (or reset it if it is already installed). +### Install module via Symfony Console + +Access your project's directory with a CLI, and run : + +```shell +php bin/console prestashop:module install mymodule +``` + +Where `mymodule` is your module's name. + +To uninstall module, run : + +```shell +php bin/console prestashop:module uninstall mymodule +``` + +For more informations, please read [the reference of the ModuleCommand]({{< ref "/8/development/components/console/prestashop-module" >}}) + +### The config.xml file + During the module's installation, PrestaShop automatically creates a small `config.xml` file in the module's folder, which stores the module's information. You should be very careful when editing this file by hand. ## Keeping things secure @@ -347,9 +336,5 @@ header('Location: ../'); exit; ``` -## Further reading - -{{< children />}} - [existing-tab-sections]: {{< ref "/8/modules/concepts/module-class/#tab" >}} -[multistore]: {{< ref "/8/development/multistore/" >}} +[multistore]: {{< ref "/8/development/multistore/" >}} \ No newline at end of file From 379506295efbfff4c58ce0e6b45d8494fe81a59d Mon Sep 17 00:00:00 2001 From: Thomas Nares Date: Thu, 6 Oct 2022 10:57:18 +0200 Subject: [PATCH 093/310] Remove unused mermaid --- modules/creation/tutorial.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/modules/creation/tutorial.md b/modules/creation/tutorial.md index e9fb7a3cdd..cd112fbc0a 100644 --- a/modules/creation/tutorial.md +++ b/modules/creation/tutorial.md @@ -2,8 +2,6 @@ title: "Tutorial: Creating your first module" menuTitle: "Tutorial" weight: 1 -useMermaid: true - --- # Tutorial: Creating your first module From a67a64a58fd32f4abe59b2b4562adf7eb0897905 Mon Sep 17 00:00:00 2001 From: leemyongpakvn Date: Thu, 6 Oct 2022 20:30:51 +0700 Subject: [PATCH 094/310] fixed version tag Co-authored-by: Thomas NARES --- themes/reference/templates/notifications.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/themes/reference/templates/notifications.md b/themes/reference/templates/notifications.md index 49d7bdbc3e..9d65a81db9 100644 --- a/themes/reference/templates/notifications.md +++ b/themes/reference/templates/notifications.md @@ -89,7 +89,7 @@ In the "Classic" Theme, [notifications are implemented as a partial template fil ``` -...and are then [included in the template file](https://github.com/PrestaShop/classic-theme/blob/develop/templates/customer/page.tpl#L32-L34): +...and are then [included in the template file](https://github.com/PrestaShop/classic-theme/blob/2.0.1/templates/customer/page.tpl#L32-L34): ```smarty {block name='notifications'} From 009a99eab173816b6d245192f92446ca060702f9 Mon Sep 17 00:00:00 2001 From: leemyongpakvn Date: Thu, 6 Oct 2022 20:31:05 +0700 Subject: [PATCH 095/310] fixed version tag Co-authored-by: Thomas NARES --- themes/reference/templates/notifications.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/themes/reference/templates/notifications.md b/themes/reference/templates/notifications.md index 9d65a81db9..4cc120d72f 100644 --- a/themes/reference/templates/notifications.md +++ b/themes/reference/templates/notifications.md @@ -33,7 +33,7 @@ An array of notification is passed to the templates, containing at least one of ## How to display notifications -In the "Classic" Theme, [notifications are implemented as a partial template file](https://github.com/PrestaShop/classic-theme/blob/develop/templates/_partials/notifications.tpl): +In the "Classic" Theme, [notifications are implemented as a partial template file](https://github.com/PrestaShop/classic-theme/blob/2.0.1/templates/_partials/notifications.tpl): ```smarty
-## Filling the cart and creating the order +## Convert a Cart to an Order -To create the order, the cart has to be filled with the following information: +For a Cart to be able to convert to an Order, we need the following steps : -1. Personal information - details like name, email, birthday etc. In FO you can either fill this information manually as - guest (and optionally create new customer account) or login with existing customer. In BO - order creation you will be asked to select an existing customer before you can modify the existing cart or create a - new one. -2. Addresses - provide the shipping and invoice addresses information. Shipping (a.k.a. delivery) address is where the +
+flowchart TB + A(Cart)-->|Associate to customer|B(Cart associated) + B-->|Select shipping and invoice addresses|C(Cart addressed) + C-->|Select shipping method and carrier|D(Cart shipping configured) + D-->|Select payment method|E(Cart payment configured) + E-->|Submit order|F(Order) +
+ + +1. **Associate to customer** : details like name, email, birthday etc. In FO you can either fill this information manually as + guest (and optionally create new customer account) or login with existing customer. + In BO order creation you will be asked to select an existing customer before you can modify the existing cart or create a new one. +2. **Select shipping and invoice addresses** : provide the shipping and invoice addresses information. Shipping (a.k.a. delivery) address is where the ordered products should be sent while the invoice address is where the invoice is sent. In FO, you can provide one address to be used as both - shipping and invoice. In BO, you must select shipping and invoice addresses (the same - address can also be selected for both - shipping and invoices). After this step is complete you will need to select - available carriers (carriers are searched by delivery address and can be modified by shop admin in Improve -> - Shipping -> Carriers page). Note - carrier will not be available if selected country or zone is disabled (in BO - International -> Locations) or carrier shipping and locations settings are not configured. -3. Payment - choose how to pay for the order. Shop admin can configure payment methods in BO Payment -> Payment methods. + address can also be selected for both - shipping and invoices). +3. **Select shipping method and carrier** : after this step is complete you will need to select available carriers + (carriers are searched by delivery address and can be modified by shop admin in Improve -> Shipping -> Carriers page). Note - carrier will not be available if selected country or zone is disabled (in BO International -> Locations) or carrier shipping and locations settings are not configured. +3. **Select payment method** : choose how to pay for the order. Shop admin can configure payment methods in BO Payment -> Payment methods. All payments are handled by payment modules. Prestashop comes with 2 payment modules by default: * ps_checkpayment - allows check payments. * ps_wirepayment - allows wire payments (bank transfers). {{% notice note %}} - - Payment restrictions for currency, country, group and carrier can be configured in - BO `Improve -> Payment -> Preferences`. - + Payment restrictions for currency, country, group and carrier can be configured in BO `Improve -> Payment -> Preferences`. {{% /notice %}} -4. Once the order is submitted, a unique order reference is generated and certain records from a cart and related +4. **Submit Order** : Once the order is submitted, a unique order reference is generated and certain records from a cart and related entities are added into following database tables: * orders * order_history From 552b6347b8ee664f75cc7e452198d71de962d830 Mon Sep 17 00:00:00 2001 From: Thomas NARES Date: Fri, 7 Oct 2022 11:06:07 +0200 Subject: [PATCH 098/310] Update modules/creation/tutorial.md Co-authored-by: Krystian Podemski --- modules/creation/tutorial.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/creation/tutorial.md b/modules/creation/tutorial.md index cd112fbc0a..59c242d25b 100644 --- a/modules/creation/tutorial.md +++ b/modules/creation/tutorial.md @@ -243,7 +243,7 @@ public function uninstall() As you can see, our three blocks of code (`__construct()`, `install()` and `uninstall()`) all make use of a new object, `Configuration`. -This is a PrestaShop-specific object that allows to easily manage all the shop's settings. It stores its data on the `ps_configuration` database table. +This PrestaShop-specific object allows you to easily manage all the shop's settings. It stores its data on the `PREFIX_configuration` database table. This is a very useful and easy-to-use object, and you will certainly use it in many situations. Most native modules use it too for their own settings. From b3c530e5943f29486f6e0eb7ecba2384ed4fe1bf Mon Sep 17 00:00:00 2001 From: Thomas NARES Date: Fri, 7 Oct 2022 11:06:12 +0200 Subject: [PATCH 099/310] Update modules/creation/tutorial.md Co-authored-by: Krystian Podemski --- modules/creation/tutorial.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/creation/tutorial.md b/modules/creation/tutorial.md index 59c242d25b..f687237d9b 100644 --- a/modules/creation/tutorial.md +++ b/modules/creation/tutorial.md @@ -101,7 +101,7 @@ class MyModule extends Module } ``` -Let's examine each line : +Let's examine each line: ```php $this->name = 'mymodule'; From 104283eea8b498d66e9c7a8ca803f1af2bcd27f2 Mon Sep 17 00:00:00 2001 From: Thomas Nares Date: Mon, 10 Oct 2022 08:37:34 +0200 Subject: [PATCH 100/310] imrpove lifecycle doc --- development/orders-lifecycle/_index.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/development/orders-lifecycle/_index.md b/development/orders-lifecycle/_index.md index fcdfa25fea..d527097c5a 100644 --- a/development/orders-lifecycle/_index.md +++ b/development/orders-lifecycle/_index.md @@ -14,8 +14,8 @@ Orders can be created from a cart either in Front Office (FO) by the customer or ### Cart in Front Office (FO) -In FO by default, a new empty cart is created everytime a customer signs in - this behavior can be adjusted in BO -`Configure -> Shop parameters -> Customer settings`. If customer is not signed in (guest) - the cart is created once +In FO by default, a new empty cart is created in database everytime a customer signs in - this behavior can be adjusted in BO +`Configure -> Shop parameters -> Customer settings`. If customer is not signed in (guest) - the cart is created in database once first product is being added into it. If guest already has a cart and signs in, the cart is assigned to him instead of creating a new one. From 90b4bd6c7ca0dc675f4747cdb1b71ea380a7bd84 Mon Sep 17 00:00:00 2001 From: Thomas Nares Date: Mon, 10 Oct 2022 10:19:52 +0200 Subject: [PATCH 101/310] Add install method from cli --- basics/installation/install-from-cli.md | 91 +++++++++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 basics/installation/install-from-cli.md diff --git a/basics/installation/install-from-cli.md b/basics/installation/install-from-cli.md new file mode 100644 index 0000000000..5e26182b08 --- /dev/null +++ b/basics/installation/install-from-cli.md @@ -0,0 +1,91 @@ +--- +title: Installing PrestaShop from CLI +menuTitle: Installation from CLI +weight: 15 +--- + +# Installing PrestaShop from CLI + +Since version 1.5.4, PrestaShop has had a command-line installer. + +This special installer makes it possible to install PrestaShop without the need to use a web browser: simply put the content of the zip archive on your web server or pull code from an official PrestaShop repository, and you can install PrestaShop through your command-line interface (CLI). + +{{% notice info %}} +If deploying from sources (PrestaShop repository), you must first install Composer dependencies. +Install them with `composer install` from project's root directory. +{{% /notice %}} + +The point of having a CLI installer in addition to the regular in-browser installer is to give this option to cater for some advanced users, who often prefer command-line interfaces as they tend to provide a more concise and powerful means to control a program or operating system. + +## How to use it + +The CLI installer is easy to use: from your terminal, go to the /install (or /install-dev) folder, and start the script with this command: + +```shell +php index_cli.php +``` + +This will display the various available options: + +``` +Arguments available: +--step all / database,fixtures,theme,modules,postInstall (Default: all) +--language language iso code (Default: en) +--all_languages install all available languages (Default: 0) +--timezone (Default: Europe/Paris) +--base_uri (Default: /) +--domain (Default: localhost) +--db_server (Default: localhost) +--db_user (Default: root) +--db_password (Default: ) +--db_name (Default: prestashop) +--db_clear Drop existing tables (Default: 1) +--db_create Create the database if not exist (Default: 0) +--prefix (Default: ps_) +--engine InnoDB/MyISAM (Default: InnoDB) +--name (Default: PrestaShop) +--activity (Default: 0) +--country (Default: fr) +--firstname (Default: John) +--lastname (Default: Doe) +--password (Default: Correct Horse Battery Staple) +--email (Default: pub@prestashop.com) +--license show PrestaShop license (Default: 0) +--theme (Default: ) +--ssl enable SSL for PrestaShop (Default: 0) +--rewrite enable rewrite engine for PrestaShop (Default: 1) +--fixtures enable fixtures installation (Default: 1) +--modules Modules to install, separated by comma (Default: []) +``` + +- All the options from the regular in-browser installer are available, with their default value listed. +- Almost all default values value can be left as is, because you can edit them all from the PrestaShop back-office once the installation is done. + +{{% notice info %}} +Note that the e-mail and password are the ones used to create the administrator's back-office account. +{{% /notice %}} + +To start the installation, you only need to provide one argument. In reality, you need to provide more: + +- `domain`. The location where you want your store to appear. +- `db_server`. The database server address. +- `db_name`. The name of the database you want to use. +- `db_user`. The username for the database you want to use. +- `db_password`. The password for the database username above. + +For instance: + +```shell +php install_cli.php --domain=example.com --db_server=sql.example.com --db_name=prestashop --db_user=root --db_password=123456789 +``` + +And if your database credentials were good, you should see : + +```shell +-- Installation successful! -- +``` + +{{% notice info %}} +Please note that your database must be created with a `CREATE DATABASE xxx;` statement before running this command. +The Web GUI has an option to **Attempt to create the database automatically** but not the CLI. +{{% /notice %}} \ No newline at end of file From de220810bd483b795e5b587fb6d9b7c6b09fa93c Mon Sep 17 00:00:00 2001 From: Thomas Nares Date: Mon, 10 Oct 2022 14:36:24 +0200 Subject: [PATCH 102/310] Fix references to build.prestashop.com --- basics/keeping-up-to-date/_index.md | 2 +- contribute/contribute-pull-requests/_index.md | 2 +- .../contribute_using_localhost.md | 2 +- .../how-issues-are-sorted.md | 4 ++-- .../how-pull-requests-are-processed.md | 4 ++-- development/architecture/introduction.md | 16 ++++++++-------- .../architecture/migration-guide/strategy.md | 2 +- .../migration-guide/templating-with-twig.md | 2 +- .../order/view-order/refunds/_index.md | 2 +- development/uikit.md | 2 +- modules/introduction.md | 2 +- project/release/minor-release-lifecycle.md | 2 +- project/release/patch-release-lifecycle.md | 2 +- .../setting-up-your-local-environment.md | 4 ++-- 14 files changed, 24 insertions(+), 24 deletions(-) diff --git a/basics/keeping-up-to-date/_index.md b/basics/keeping-up-to-date/_index.md index eaaac6fd04..40288e332a 100644 --- a/basics/keeping-up-to-date/_index.md +++ b/basics/keeping-up-to-date/_index.md @@ -13,7 +13,7 @@ The purpose of this chapter is to provide the best practices and tips for keepin Keeping a shop updated to the latest available version ensures you have the latest changes brought by the core team and the developer community. Depending on the version you upgrade to, you can get new features, security or performance improvements, or simply bug fixes. -Furthermore, the support of PrestaShop 1.6 [is now ended](https://build.prestashop.com/news/1.6.1.x-what-s-next/). We recommend using recent PrestaShop versions to get support, along with core and modules upgrades. +Furthermore, the support of PrestaShop 1.6 [is now ended](https://build.prestashop-project.org/news/1.6.1.x-what-s-next/). We recommend using recent PrestaShop versions to get support, along with core and modules upgrades. ## Upgrade and migration, two different processes diff --git a/contribute/contribute-pull-requests/_index.md b/contribute/contribute-pull-requests/_index.md index 2ffbe35e6f..7e58acbcb1 100644 --- a/contribute/contribute-pull-requests/_index.md +++ b/contribute/contribute-pull-requests/_index.md @@ -29,7 +29,7 @@ If you have trouble using this flow, you can find out more at [GitHub help](http While it may seem complex, this flow is the standard way most open source projects use to handle contributions. [This article](https://dev.to/mathieuks/introduction-to-github-fork-workflow-why-is-it-so-complex-3ac8) about the flow can help you understand the reasons for each part of the process. {{% notice tip %}} -If you wish to start contributing smoothly, have a look at [issues labelled "good first issue"](https://github.com/PrestaShop/PrestaShop/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) and pick one to work with. This label lists all beginner-friendly bugs and improvements. Read more about this label on [Build](https://build.prestashop.com/news/a-definition-of-the-good-first-issue-label). +If you wish to start contributing smoothly, have a look at [issues labelled "good first issue"](https://github.com/PrestaShop/PrestaShop/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) and pick one to work with. This label lists all beginner-friendly bugs and improvements. Read more about this label on [Build](https://build.prestashop-project.org/news/a-definition-of-the-good-first-issue-label). {{% /notice %}} ## In this section diff --git a/contribute/contribute-pull-requests/contribute_using_localhost.md b/contribute/contribute-pull-requests/contribute_using_localhost.md index 941062afce..924648a5ba 100644 --- a/contribute/contribute-pull-requests/contribute_using_localhost.md +++ b/contribute/contribute-pull-requests/contribute_using_localhost.md @@ -82,7 +82,7 @@ composer install ### Compile assets -Static assets are not present in the repository and need to be compiled (we explained why in [this article](https://build.prestashop.com/news/open-question-not-commiting-assets-anymore/)). +Static assets are not present in the repository and need to be compiled (we explained why in [this article](https://build.prestashop-project.org/news/open-question-not-commiting-assets-anymore/)). You will need `npm` installed on your environment (here is the documentation about [how to compile assets][compile-assets]), then you can simply run: ```bash diff --git a/contribute/contribution-process/how-issues-are-sorted.md b/contribute/contribution-process/how-issues-are-sorted.md index 00d7850656..f328a3ebe1 100644 --- a/contribute/contribution-process/how-issues-are-sorted.md +++ b/contribute/contribution-process/how-issues-are-sorted.md @@ -32,7 +32,7 @@ Examples: - Difficulty to globally manage categories, products or customers - Difficulty to globally place and manage orders -A critical issue should result in a patch version that should be released as soon as possible. [PrestaShop 1.7.2.5](https://build.prestashop.com/news/prestashop-1-7-2-5-maintenance-release/) is a good example: this patch release fixes two vulnerabilities affecting the Back Office. +A critical issue should result in a patch version that should be released as soon as possible. [PrestaShop 1.7.2.5](https://build.prestashop-project.org/news/prestashop-1-7-2-5-maintenance-release/) is a good example: this patch release fixes two vulnerabilities affecting the Back Office. ### Major @@ -98,4 +98,4 @@ In the end, handling bugs requires two points of view: micro and macro. Severity --- -_(This article was originally published on our blog: [Introducing A New Bug Severity Classification](https://build.prestashop.com/news/severity-classification/))_ +_(This article was originally published on our blog: [Introducing A New Bug Severity Classification](https://build.prestashop-project.org/news/severity-classification/))_ diff --git a/contribute/contribution-process/how-pull-requests-are-processed.md b/contribute/contribution-process/how-pull-requests-are-processed.md index fe5027b7f0..3623d86b3c 100644 --- a/contribute/contribution-process/how-pull-requests-are-processed.md +++ b/contribute/contribution-process/how-pull-requests-are-processed.md @@ -30,7 +30,7 @@ The results of these checks is displayed at the bottom of the Pull Request. Some For example he detects mistakes in the pull request description, he add some labels to classify the pull requests, he welcomes new contributors to the project ... -[Read his article for the full details.](https://build.prestashop.com/news/prestonbot-reaches-stable-version/) +[Read his article for the full details.](https://build.prestashop-project.org/news/prestonbot-reaches-stable-version/) If something is wrong, Prestonbot will write a comment in the pull request to tell you what to fix. @@ -83,4 +83,4 @@ After the Pull Request has finally passed the QA validation, it is merged in the --- -_(This article was originally published on our blog: [What Happens To Pull Requests After They Are Submitted](https://build.prestashop.com/news/the-review-process/))_ +_(This article was originally published on our blog: [What Happens To Pull Requests After They Are Submitted](https://build.prestashop-project.org/news/the-review-process/))_ diff --git a/development/architecture/introduction.md b/development/architecture/introduction.md index 19a9d04e1d..149111955a 100644 --- a/development/architecture/introduction.md +++ b/development/architecture/introduction.md @@ -10,7 +10,7 @@ summary: "Learn how PrestaShop is structured: back-end, front-end, business stac PrestaShop is a big project, with several moving parts. In this article you will learn how they are structured and how they work together. {{% notice note %}} -Part of this article was originally published in 2019 as a [blog post](https://build.prestashop.com/news/prestashop-in-2019-and-beyond-part-1-current-architecture/). It has been updated and adapted for documentation purposes here. +Part of this article was originally published in 2019 as a [blog post](https://build.prestashop-project.org/news/prestashop-in-2019-and-beyond-part-1-current-architecture/). It has been updated and adapted for documentation purposes here. {{% /notice %}} ## Overview @@ -231,7 +231,7 @@ This means that the global interface is handled by the **default** theme, _even Rest assured, this is a _temporary issue_ which will be solved when everything has been migrated to Twig and Symfony. -[introducing-symfony]: http://build.prestashop.com/news/prestashop-1-7-and-symfony/ +[introducing-symfony]: http://build.prestashop-project.org/news/prestashop-1-7-and-symfony/ {{% /callout %}} Finally, there's [Vue pages][introducing-vue]. Vue pages are hybrid: half-Symfony, half-API based BO pages. In those pages, the page's skeleton is first rendered by a Symfony controller (therefore, based on the **new theme**), and then a VueJS application takes over in the browser and draws its content based on data sent by the BO API. @@ -281,12 +281,12 @@ Remember the overview at the top of the article? Have a look at this more detail [SSOT]: https://en.wikipedia.org/wiki/Single_source_of_truth [vuejs]: https://vuejs.org/ -[introduction]: https://build.prestashop.com/news/prestashop-in-2019-and-beyond-introduction/ -[architecture-1610]: https://build.prestashop.com/news/new-architecture-1-6-1-0/ -[child-themes]: https://build.prestashop.com/news/Child-Themes-Feature/ -[uikit]: https://build.prestashop.com/news/PrestaShop-UI-Kit/ -[introducing-vue]: https://build.prestashop.com/news/introducing-vuejs-symfony-api/ -[future-architecture]: https://build.prestashop.com/news/prestashop-in-2019-and-beyond-part-3-the-future-architecture/ +[introduction]: https://build.prestashop-project.org/news/prestashop-in-2019-and-beyond-introduction/ +[architecture-1610]: https://build.prestashop-project.org/news/new-architecture-1-6-1-0/ +[child-themes]: https://build.prestashop-project.org/news/Child-Themes-Feature/ +[uikit]: https://build.prestashop-project.org/news/PrestaShop-UI-Kit/ +[introducing-vue]: https://build.prestashop-project.org/news/introducing-vuejs-symfony-api/ +[future-architecture]: https://build.prestashop-project.org/news/prestashop-in-2019-and-beyond-part-3-the-future-architecture/ [SOLID]: https://en.wikipedia.org/wiki/SOLID [adapter-pattern]: https://sourcemaking.com/design_patterns/adapter [dependency-inversion]: https://en.wikipedia.org/wiki/Dependency_inversion_principle diff --git a/development/architecture/migration-guide/strategy.md b/development/architecture/migration-guide/strategy.md index 870ade39e9..ddfec77b05 100644 --- a/development/architecture/migration-guide/strategy.md +++ b/development/architecture/migration-guide/strategy.md @@ -165,7 +165,7 @@ Our Handlers started as "place where we put the legacy code we dont have the tim [adapter-namespace]: {{< ref "/8/development/architecture/file-structure/understanding-src-folder.md" >}} [cqrs]: {{< ref "/8/development/architecture/domain/cqrs.md" >}} [domain]: https://en.wikipedia.org/wiki/Domain-driven_design -[future-architecture]: https://build.prestashop.com/news/prestashop-in-2019-and-beyond-part-3-the-future-architecture/#our-proposal-for-a-future-architecture +[future-architecture]: https://build.prestashop-project.org/news/prestashop-in-2019-and-beyond-part-3-the-future-architecture/#our-proposal-for-a-future-architecture [ubiquitous-langage]: https://enterprisecraftsmanship.com/posts/ubiquitous-language-naming/ [vue-js]: https://vuejs.org/ [twig-form-theme]: {{< ref "/8/development/components/form/form-theme/" >}} diff --git a/development/architecture/migration-guide/templating-with-twig.md b/development/architecture/migration-guide/templating-with-twig.md index 79011a751b..f6ed35bf78 100644 --- a/development/architecture/migration-guide/templating-with-twig.md +++ b/development/architecture/migration-guide/templating-with-twig.md @@ -67,7 +67,7 @@ label_with_help(label, help) ## Bootstrap -Legacy templates use [Bootstrap 3](https://getbootstrap.com/docs/3.3/) while modern pages use the [PrestaShop UI Kit](https://build.prestashop.com/prestashop-ui-kit/) that is based on [Bootstrap 4](https://getbootstrap.com/docs/4.0/getting-started/introduction/). This means that you'll need to update some markup (especially CSS classes). +Legacy templates use [Bootstrap 3](https://getbootstrap.com/docs/3.3/) while modern pages use the [PrestaShop UI Kit](https://build.prestashop-project.org/prestashop-ui-kit/) that is based on [Bootstrap 4](https://getbootstrap.com/docs/4.0/getting-started/introduction/). This means that you'll need to update some markup (especially CSS classes). {{% notice tip %}} If you aren't familiar with Bootstrap 4, check out their [article on migrating to v4](https://getbootstrap.com/docs/4.0/migration/), which explains the major changes from v3 to v4. diff --git a/development/page-reference/back-office/order/view-order/refunds/_index.md b/development/page-reference/back-office/order/view-order/refunds/_index.md index f11d7468a2..c4f6bb0060 100644 --- a/development/page-reference/back-office/order/view-order/refunds/_index.md +++ b/development/page-reference/back-office/order/view-order/refunds/_index.md @@ -6,7 +6,7 @@ menuTitle: Refunds # Cancellations and refunds {{% notice info %}} -For a full specification of how these features work, you can read [the functional specifications](https://build.prestashop.com/prestashop-specs/1.7/back-office/orders/orders/view-page.html#merchandise-return-has-to-be-enabled-if-the-merchant-wants-to-use-the-standard-refund-partial-refund-and-return-product-feature) +For a full specification of how these features work, you can read [the functional specifications](https://build.prestashop-project.org/prestashop-specs/1.7/back-office/orders/orders/view-page.html#merchandise-return-has-to-be-enabled-if-the-merchant-wants-to-use-the-standard-refund-partial-refund-and-return-product-feature) {{% /notice %}} ## Order history and corresponding cancellation types diff --git a/development/uikit.md b/development/uikit.md index c480749ae1..0c59b244f4 100644 --- a/development/uikit.md +++ b/development/uikit.md @@ -5,7 +5,7 @@ weight: 70 # What's the PrestaShop UIKit? -The UIKit is a project extending Bootstrap 4 in order to provide some components with PrestaShop's colors. You can see every component on [this page](https://build.prestashop.com/prestashop-ui-kit/). +The UIKit is a project extending Bootstrap 4 in order to provide some components with PrestaShop's colors. You can see every component on [this page](https://build.prestashop-project.org/prestashop-ui-kit/). ## How do we use the UIKit? diff --git a/modules/introduction.md b/modules/introduction.md index 0756e235ff..112ff40531 100644 --- a/modules/introduction.md +++ b/modules/introduction.md @@ -39,7 +39,7 @@ Modules can: PrestaShop 1.7 was built so that modules that were written for PS 1.6 can work almost as-is — save for minor changes and a cosmetic update, the template files being in need of adapting to the 1.7 default theme. -The major module development changes in PrestaShop 1.7 are explained in details [in this Build article](https://build.prestashop.com/news/module-development-changes-in-17/), and are integrated into this updated documentation. If you already know how to create a module that works with PS 1.6, we strongly advise you to read that article from top to bottom in order to get up to speed with 1.7 development. +The major module development changes in PrestaShop 1.7 are explained in details [in this Build article](https://build.prestashop-project.org/news/module-development-changes-in-17/), and are integrated into this updated documentation. If you already know how to create a module that works with PS 1.6, we strongly advise you to read that article from top to bottom in order to get up to speed with 1.7 development. Some native modules have had their names changed in PrestaShop 1.7. [See the full list here]({{< ref "/8/development/native-modules/_index.md#module-name-changes-since-16" >}}). diff --git a/project/release/minor-release-lifecycle.md b/project/release/minor-release-lifecycle.md index d9e72d2373..18e44e9f1d 100644 --- a/project/release/minor-release-lifecycle.md +++ b/project/release/minor-release-lifecycle.md @@ -98,4 +98,4 @@ The global duration for all the process is about 6 months. This is why we expect _(This article was originally published on our blog: [PrestaShop 1.7 Minor Release Lifecycle -](https://build.prestashop.com/news/ps17-patch-release-lifecycle/))_ +](https://build.prestashop-project.org/news/ps17-patch-release-lifecycle/))_ diff --git a/project/release/patch-release-lifecycle.md b/project/release/patch-release-lifecycle.md index 9444695e42..2bdb027bf0 100644 --- a/project/release/patch-release-lifecycle.md +++ b/project/release/patch-release-lifecycle.md @@ -50,4 +50,4 @@ If the campaign reports that no bugs are found, the new patch release is validat _(This article was originally published on our blog: [PrestaShop 1.7 Patch Release Lifecycle -](https://build.prestashop.com/news/ps17-minor-release-lifecycle/))_ +](https://build.prestashop-project.org/news/ps17-minor-release-lifecycle/))_ diff --git a/themes/getting-started/setting-up-your-local-environment.md b/themes/getting-started/setting-up-your-local-environment.md index ee1da49a2c..bf69de10d4 100644 --- a/themes/getting-started/setting-up-your-local-environment.md +++ b/themes/getting-started/setting-up-your-local-environment.md @@ -36,7 +36,7 @@ git checkout 8.0 Also we would warn you to test your final result with a zip release, just for safety (since vendor version might be slightly different). {{% notice note %}} -If you haven’t done it yet, we strongly recommend you to read our article [Set Up Your Git For Contributing](https://build.prestashop.com/howtos/misc/set-up-your-git-for-contributing/) +If you haven’t done it yet, we strongly recommend you to read our article [Set Up Your Git For Contributing](https://build.prestashop-project.org/howtos/misc/set-up-your-git-for-contributing/) {{% /notice %}} ## Building your .gitignore file @@ -58,7 +58,7 @@ Generally, you shouldn’t version the following types of files: We suggest that you build your own using https://gitignore.io. {{% notice note %}} -If you are building a full project for a client, you can read our article on [building a gitignore for PrestaShop](https://build.prestashop.com/howtos/misc/prestashop-perfect-gitignore/). +If you are building a full project for a client, you can read our article on [building a gitignore for PrestaShop](https://build.prestashop-project.org/howtos/misc/prestashop-perfect-gitignore/). {{% /notice %}} ## Create your theme from the Classic Theme From 5c033616ddfaa8b332d937bd6c79178c203b29c7 Mon Sep 17 00:00:00 2001 From: Thomas Nares Date: Mon, 10 Oct 2022 14:41:38 +0200 Subject: [PATCH 103/310] Fix unmerged url change --- project/release/minor-release-lifecycle.md | 2 +- project/release/patch-release-lifecycle.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/project/release/minor-release-lifecycle.md b/project/release/minor-release-lifecycle.md index 18e44e9f1d..279b1d469c 100644 --- a/project/release/minor-release-lifecycle.md +++ b/project/release/minor-release-lifecycle.md @@ -98,4 +98,4 @@ The global duration for all the process is about 6 months. This is why we expect _(This article was originally published on our blog: [PrestaShop 1.7 Minor Release Lifecycle -](https://build.prestashop-project.org/news/ps17-patch-release-lifecycle/))_ +](https://build.prestashop-project.org/news/ps17-minor-release-lifecycle/))_ diff --git a/project/release/patch-release-lifecycle.md b/project/release/patch-release-lifecycle.md index 2bdb027bf0..feab7185ac 100644 --- a/project/release/patch-release-lifecycle.md +++ b/project/release/patch-release-lifecycle.md @@ -50,4 +50,4 @@ If the campaign reports that no bugs are found, the new patch release is validat _(This article was originally published on our blog: [PrestaShop 1.7 Patch Release Lifecycle -](https://build.prestashop-project.org/news/ps17-minor-release-lifecycle/))_ +](https://build.prestashop-project.org/news/ps17-patch-release-lifecycle/))_ From 50a266e92d917dbedfdc87e75dd3ed94f1341688 Mon Sep 17 00:00:00 2001 From: Thomas NARES Date: Mon, 10 Oct 2022 15:57:43 +0200 Subject: [PATCH 104/310] Update basics/installation/install-from-cli.md --- basics/installation/install-from-cli.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/basics/installation/install-from-cli.md b/basics/installation/install-from-cli.md index 5e26182b08..2a6bb8d7d0 100644 --- a/basics/installation/install-from-cli.md +++ b/basics/installation/install-from-cli.md @@ -6,7 +6,7 @@ weight: 15 # Installing PrestaShop from CLI -Since version 1.5.4, PrestaShop has had a command-line installer. +Since version 1.5.4, PrestaShop has a command-line installer. This special installer makes it possible to install PrestaShop without the need to use a web browser: simply put the content of the zip archive on your web server or pull code from an official PrestaShop repository, and you can install PrestaShop through your command-line interface (CLI). From 23b6d183c8ef5c9cd8887e03029b2468c2448d91 Mon Sep 17 00:00:00 2001 From: Thomas NARES Date: Tue, 11 Oct 2022 11:45:13 +0200 Subject: [PATCH 105/310] Apply suggestions from code review Co-authored-by: Krystian Podemski --- modules/creation/tutorial.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/modules/creation/tutorial.md b/modules/creation/tutorial.md index f687237d9b..498881cf47 100644 --- a/modules/creation/tutorial.md +++ b/modules/creation/tutorial.md @@ -289,15 +289,15 @@ There are many free icon libraries available on the web. Here are a few: ## Installing the module -You have two options to install a module : via back office interface, or via Symfony Console +You have two options to install a module: from the back office interface or using the Symfony Console component (CLI-base installation) -### Install module via back office interface +### Install module from the back office interface Now that all basics are in place, reload the back office's "Module Catalog" page, in the "Front office features" section, you should find your module. Install it (or reset it if it is already installed). -### Install module via Symfony Console +### Install module from CLI using the Symfony Console component -Access your project's directory with a CLI, and run : +Access your project's directory with a CLI, and run: ```shell php bin/console prestashop:module install mymodule @@ -305,7 +305,7 @@ php bin/console prestashop:module install mymodule Where `mymodule` is your module's name. -To uninstall module, run : +To uninstall the module, run the following: ```shell php bin/console prestashop:module uninstall mymodule From 6a734ef1e9da8022138f7e8c10a56da606ec2297 Mon Sep 17 00:00:00 2001 From: Thomas NARES Date: Tue, 11 Oct 2022 11:47:10 +0200 Subject: [PATCH 106/310] Apply suggestions from code review Co-authored-by: Krystian Podemski --- basics/installation/install-from-cli.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/basics/installation/install-from-cli.md b/basics/installation/install-from-cli.md index 2a6bb8d7d0..5bb1c31638 100644 --- a/basics/installation/install-from-cli.md +++ b/basics/installation/install-from-cli.md @@ -15,17 +15,17 @@ If deploying from sources (PrestaShop repository), you must first install Compos Install them with `composer install` from project's root directory. {{% /notice %}} -The point of having a CLI installer in addition to the regular in-browser installer is to give this option to cater for some advanced users, who often prefer command-line interfaces as they tend to provide a more concise and powerful means to control a program or operating system. +The point of having a CLI installer in addition to the regular in-browser installer is to provide a solution to some advanced users, who often prefer command-line interfaces as they tend to give a more concise and powerful means to control a program or operating system. We can see the advantage of CLI installer in Continuous Integration processes. ## How to use it -The CLI installer is easy to use: from your terminal, go to the /install (or /install-dev) folder, and start the script with this command: +To use the CLI installer, use your terminal, go to the `/install` (or `/install-dev`) folder, and start the script with this command: ```shell php index_cli.php ``` -This will display the various available options: +This command, by default, will display the various available options: ``` Arguments available: @@ -58,11 +58,11 @@ Arguments available: --modules Modules to install, separated by comma (Default: []) ``` -- All the options from the regular in-browser installer are available, with their default value listed. -- Almost all default values value can be left as is, because you can edit them all from the PrestaShop back-office once the installation is done. +- All the options from the regular in-browser installer are available, with their default values listed above. +- Almost all default option values can be left as is because you can edit them all from the PrestaShop back office once the installation is complete. {{% notice info %}} -Note that the e-mail and password are the ones used to create the administrator's back-office account. +Note that the e-mail and password are used to create the administrator's back office account. {{% /notice %}} To start the installation, you only need to provide one argument. In reality, you need to provide more: @@ -73,19 +73,19 @@ To start the installation, you only need to provide one argument. In reality, yo - `db_user`. The username for the database you want to use. - `db_password`. The password for the database username above. -For instance: +Example: ```shell php install_cli.php --domain=example.com --db_server=sql.example.com --db_name=prestashop --db_user=root --db_password=123456789 ``` -And if your database credentials were good, you should see : +If the installation completes without any errors, you should see the following confirmation: ```shell -- Installation successful! -- ``` {{% notice info %}} -Please note that your database must be created with a `CREATE DATABASE xxx;` statement before running this command. -The Web GUI has an option to **Attempt to create the database automatically** but not the CLI. +Before running this command, please note that your database must be created with a `CREATE DATABASE xxx;` statement. +The in-browser installer has an option to attempt to create the database automatically **but not the CLI**. {{% /notice %}} \ No newline at end of file From d2f065933b7d42ba404576944cf8e80855315a13 Mon Sep 17 00:00:00 2001 From: Thomas Nares Date: Tue, 11 Oct 2022 14:16:20 +0200 Subject: [PATCH 107/310] Add table to describe arguments, apply Krystian suggestions --- basics/installation/install-from-cli.md | 91 ++++++++++++++----------- 1 file changed, 53 insertions(+), 38 deletions(-) diff --git a/basics/installation/install-from-cli.md b/basics/installation/install-from-cli.md index 5bb1c31638..20d70bc910 100644 --- a/basics/installation/install-from-cli.md +++ b/basics/installation/install-from-cli.md @@ -27,56 +27,66 @@ php index_cli.php This command, by default, will display the various available options: -``` -Arguments available: ---step all / database,fixtures,theme,modules,postInstall (Default: all) ---language language iso code (Default: en) ---all_languages install all available languages (Default: 0) ---timezone (Default: Europe/Paris) ---base_uri (Default: /) ---domain (Default: localhost) ---db_server (Default: localhost) ---db_user (Default: root) ---db_password (Default: ) ---db_name (Default: prestashop) ---db_clear Drop existing tables (Default: 1) ---db_create Create the database if not exist (Default: 0) ---prefix (Default: ps_) ---engine InnoDB/MyISAM (Default: InnoDB) ---name (Default: PrestaShop) ---activity (Default: 0) ---country (Default: fr) ---firstname (Default: John) ---lastname (Default: Doe) ---password (Default: Correct Horse Battery Staple) ---email (Default: pub@prestashop.com) ---license show PrestaShop license (Default: 0) ---theme (Default: ) ---ssl enable SSL for PrestaShop (Default: 0) ---rewrite enable rewrite engine for PrestaShop (Default: 1) ---fixtures enable fixtures installation (Default: 1) ---modules Modules to install, separated by comma (Default: []) -``` +|Argument|Description|Default value|Allowed values| +|:----|:----|:----|:----| +|`step`|Installation steps to execute|all|all, database, fixtures, theme, modules, postInstall| +|`language`|Language ISO code to install|en|2 letters ISO 639-1 code ([ISO 639-1](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes)) with available translation files in `/translations`| +|`all_languages`|Installs all available languages|0|0, 1| +|`timezone`|Set timezone of instance|Europe/Paris|Valid timezone ([TZ Database](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones))| +|`base_uri`|Base URI (appended after domain name)|/|Any URI| +|`domain`|Domain name for the shop (without http/s)|localhost|Any domain name or IP address| +|`db_server`|Database server hostname|localhost|Any valid MySQL valid server name or IP address| +|`db_user`|Database server user|root|Any valid MySQL user name| +|`db_password`|Database server password|""|The valid password for `db_user`| +|`db_name`|Database name|prestashop|_string_| +|`db_clear`|Drop existing tables|1|0, 1| +|`db_create`|Create the database if not exists|0|0, 1| +|`prefix`|Prefix of table names|ps_|_string_| +|`engine`|Engine for MySQL|InnoDB|InnoDB, MyISAM| +|`name`|Name of the shop|PrestaShop|_string_| +|`activity`|Default activity of the shop|0|Id of an activity ([Complete list of activities](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Form/Admin/Configure/ShopParameters/General/PreferencesType.php#L211-L230))| +|`country`|Country of the shop|fr|2 letters Alpha-2 code of ISO-3166 list([ISO-3166](https://en.wikipedia.org/wiki/List_of_ISO_3166_country_codes))| +|`firstname`|Admin user firstname|John|_string_| +|`lastname`|Admin user lastname|Doe|_string_| +|`password`|Admin user password|Correct Horse Battery Staple|_string_| +|`email`|Admin user email|pub@prestashop.com|_string_| +|`license`|Show PrestaShop license after installation|0|0, 1| +|`theme`|Theme name to install|"" (classic)|Theme name (located in `/themes`)| +|`ssl`|Enable SSL (from PS 1.7.4)|0|0, 1| +|`rewrite`|Enable rewrite engine|1|0, 1| +|`fixtures`|Install fixtures|1|0, 1| +|`modules`|Modules to install, separated by comma|[]|_array_ of module names (located in `/modules`)| - All the options from the regular in-browser installer are available, with their default values listed above. -- Almost all default option values can be left as is because you can edit them all from the PrestaShop back office once the installation is complete. +- Almost all default option values can be left as is because you can edit them all from the PrestaShop Back Office once the installation is complete. {{% notice info %}} -Note that the e-mail and password are used to create the administrator's back office account. +Note that the e-mail and password are used to create the administrator's Back Office account. {{% /notice %}} -To start the installation, you only need to provide one argument. In reality, you need to provide more: +To start the installation, we recommend that you provide at least these arguments : -- `domain`. The location where you want your store to appear. +- `domain`. The domain name where your shop will be available. - `db_server`. The database server address. -- `db_name`. The name of the database you want to use. +- `db_name`. The name of the database you want to use. **We strongly recommend that you change the default `prestashop` value** - `db_user`. The username for the database you want to use. - `db_password`. The password for the database username above. +- `prefix`. **We strongly recommend that you change the default `ps_` value.** +- `email`. Your email to connect to the Back Office. +- `password`. The password to connect to the Back Office. Example: ```shell -php install_cli.php --domain=example.com --db_server=sql.example.com --db_name=prestashop --db_user=root --db_password=123456789 +php install_cli.php + --domain=example.com + --db_server=sql.example.com + --db_name=myshop + --db_user=root + --db_password=123456789 + --prefix=myshop_ + --email=me@example.com + --password=mystrongpassword ``` If the installation completes without any errors, you should see the following confirmation: @@ -87,5 +97,10 @@ If the installation completes without any errors, you should see the following c {{% notice info %}} Before running this command, please note that your database must be created with a `CREATE DATABASE xxx;` statement. -The in-browser installer has an option to attempt to create the database automatically **but not the CLI**. -{{% /notice %}} \ No newline at end of file +If the database is not created, please use argument `--db_create=1` to create the database. +{{% /notice %}} + +{{% notice info %}} +If your MySQL server is configured on a different port than `3306`, please specify it in the `db_server` argument like this : +`--db_server=sql.example.com:3307` +{{% /notice %}} From ba5e461d6f3cd29bc8373f21f21987fd47614e34 Mon Sep 17 00:00:00 2001 From: Thomas NARES Date: Tue, 11 Oct 2022 15:00:25 +0200 Subject: [PATCH 108/310] Apply suggestions from code review Co-authored-by: Krystian Podemski --- .../components/database/objectmodel.md | 78 +++++++++---------- 1 file changed, 39 insertions(+), 39 deletions(-) diff --git a/development/components/database/objectmodel.md b/development/components/database/objectmodel.md index 5d6b581584..a3b35cfcd7 100644 --- a/development/components/database/objectmodel.md +++ b/development/components/database/objectmodel.md @@ -7,46 +7,46 @@ useMermaid: true ## Introduction -ObjectModel class is one of the main pillar of PrestaShop's legacy core. While a complete migration to Symfony/Doctrine entities is planned in the roadmap, ObjectModel will still remain present and available in our software for a while. +ObjectModel class is one of the main pillars of PrestaShop's legacy core. While a complete migration to Symfony/Doctrine entities is planned in the roadmap, ObjectModel will remain present and available in our software for a while. ObjectModel is the Data Access Layer for PrestaShop, implemented following the Active Record pattern. The Data Access Layer (DAL) is a part (with the Database Abstraction Layer - DBAL) of the Object Relational Mapping (ORM) legacy system for PrestaShop. -Read more about Object relation mapping (ORM), Database abstraction layer (DBAL), Data access layer (DAL), and Active Record : +Read more about Object relation mapping (ORM), Database abstraction layer (DBAL), Data access layer (DAL), and Active Record: - [Object relational mapping (ORM)](https://en.wikipedia.org/wiki/Object%E2%80%93relational_mapping) - [Database abstraction layer (DBAL)](https://en.wikipedia.org/wiki/Database_abstraction_layer) - [Data access layer (DAL)](https://en.wikipedia.org/wiki/Data_access_layer) - [Active record pattern](https://en.wikipedia.org/wiki/Active_record_pattern) -A class extending ObjectModel class is tied to a database table. Its static attribute (`$definition`) is representing the model. +A class extending the ObjectModel class is tied to a database table. Its static attribute (`$definition`) represents the model. Its instances are tied to database records. The ObjectModel class provides accessors for each attribute defined in `$definition`. -When instancied with an `$id` passed to the class constructor, the attributes are retrieved in the related database (using the `$id` as the primary key to find the table record). +When instantiated with an `$id` in the class constructor, the attributes are retrieved from the related database record (using the `$id` as the primary key to find the table record). When the `save()` method is called, ObjectModel will ask the DBAL to **insert** or **update** the object to database, depending if the `$id` is known or not in the ObjectModel. ObjectModel is also in charge of deleting an object in database (with its `delete()` method). {{% notice info %}} -An ObjectModel extended class can be overriden, but with extreme precaution : defining a wrong `$definition` model for example, can break the entire system, or can lead to data loss. +You can override classes that extend ObjectModel, but with extreme precaution, e.g., defining a wrong `$definition` model can break the entire system or lead to data loss. {{% /notice %}} ## Create a new entity managed by ObjectModel You can create a new entity (in a module for example), with its own database table, managed by ObjectModel. -To do this, extend you class with "ObjectModel" : +To do this, create class extending the ObjectModel: ```php -use PrestaShop\PrestaShop\Adapter\Entity\ObjectModel; -class Cms extends ObjectModel { +class Cms extends ObjectModel +{ } ``` -Next step is to define your model. [Defining the model]({{< ref "#defining-model" >}}). +The next step is [defining the model]({{< ref "#defining-model" >}}). ## Defining the model{#defining-model} @@ -104,7 +104,7 @@ public static $definition = [ ]; ``` -Let's analyse this definition : +Let's analyse this definition: ```php public static $definition = [ @@ -114,14 +114,14 @@ public static $definition = [ 'fields' => array( ``` -- `table` is the related database table name (without the database table `PREFIX`, usually `ps_`), +- `table` is the related database table name (without the database table `PREFIX`), - `primary` is the name of the `PRIMARY KEY` field in the database table, which will be used as `$id` in the ObjectModel - `multilang` is a boolean value indicating that the entity is available in multiple langages, see [Multiple languages]({{< ref "#multiple-languages" >}}) - `fields` is an array containing all other of the fields from the database table. ### Fields description -A field is defined by a key (its name in the database table) and an array of description of its settings. +A field is defined by a key (its name in the database table) and an array of its settings. ```php 'meta_description' => [ @@ -132,7 +132,7 @@ A field is defined by a key (its name in the database table) and an array of des ], ``` -In this example : +In this example: - `meta_description` is the field's name - `self::TYPE_STRING` is its type @@ -205,7 +205,7 @@ $cms->save(); In this example, we create an entity from scratch. Then, we set its `position` attribute, and we call the `save()` method. The `save()` method will trigger the `add()` method since its `id` attribute is not yet known (because the entity is not created in database). -If the insert was successful, the ObjectModel class will set the id of the entity (retrieved from database). [Complete reference here](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/ObjectModel.php#L572-L658). +If the insert is successful, the ObjectModel class will set the entity's id (retrieved from the database). [Complete reference here](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/ObjectModel.php#L572-L658). ### Load and save an object @@ -218,17 +218,17 @@ $cms->position = 3; $cms->save(); ``` -In this example, we retrieve an entity from the database, with its id. Then, we change its `position` attribute, and we call the same `save()` method. The `save()` method will trigger the `update()` method and not the `add()` method since its `id` attribute is known. [Complete reference here](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/ObjectModel.php#L750-L868). +In this example, we retrieve an entity from the database with its id. Then, we change its `position` attribute and call the same `save()` method. The `save()` method will trigger the `update()` method and not the `add()` method since its `id` attribute is known. [Complete reference here](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/ObjectModel.php#L750-L868). ### Hard or soft delete an object -Two delete mecanisms are available with ObjectModel : hard delete and soft delete. -Hard-delete deletes the record from the database, while soft-delete sets a flag to database indicating that this record is deleted. +Two delete mechanisms are available with ObjectModel: hard delete and soft delete. +Hard-delete deletes the record from the database, while soft-delete sets a flag in the table's field indicating that this record is deleted. {{% notice info %}} **Soft delete is not always available.** -If the model object has no `deleted` property or no `deleted` definition field, a `PrestaShopException` will be thrown +If the model object doesn't have a `deleted` property or there is no `deleted` field available in the class definition, a `PrestaShopException` will be thrown {{% /notice %}} {{% notice info %}} @@ -251,12 +251,12 @@ $cms->delete(); // triggers a DELETE statement to the DBAL PrestaShop's ObjectModel can handle translations (also called internationalization, or i18n) of your objects. -#### Under the hood : how does it work ? +#### Under the hood: how does it work? -When declaring a multi-language ObjectModel, PrestaShop will fetch another database table named like your base database table, with a suffix `_lang` +When declaring a multi-language ObjectModel, PrestaShop will fetch another database table named like your base database table, but with a suffix `_lang` This table references the id of the base Object (`id_cms`), the id of the language (`id_lang`), and each translatable field. -In our previous example, for `Cms` ObjectModel : +In our previous example, for `Cms` ObjectModel:
classDiagram @@ -280,7 +280,7 @@ classDiagram #### Translate your ObjectModel entity -To do so, you must declare the `multilang` setting of your model definition to `true` : +To do so, you must declare the `multilang` setting of your model definition to `true`: ```php public static $definition = [ @@ -289,7 +289,7 @@ public static $definition = [ ... ``` -And then, you must declare which ones of your fields are translated : +And then, you must declare which fields are available for translations: ```php 'fields' => array( @@ -303,7 +303,7 @@ And then, you must declare which ones of your fields are translated : ) ``` -#### Accessors for Translatable ObjectModels{#multiple-language-accessors} +#### Accessors for translatable ObjectModels{#multiple-language-accessors} Translatable fields are available in your ObjectModel as `array`. In our example, to update the attributes `meta_title` for languages EN (`$lang_id=1`) and FR (`$lang_id=2`), use the following method : @@ -318,12 +318,12 @@ $cms->save(); PrestaShop's ObjectModel can handle multiple stores (or multi shop) ObjectModels. -#### Under the hood : how does it work ? +#### Under the hood: how does it work? When declaring a multi-store ObjectModel, PrestaShop will fetch another database table named like your base database table, with a suffix `_shop` This table is a pivot table referencing at least the id of the base Object (`id_cms`) and the id of the shop (`id_shop`). -In our previous example, for `Cms` ObjectModel : +In our previous example, for `Cms` ObjectModel:
classDiagram @@ -341,7 +341,7 @@ classDiagram #### Enable multi-shop for your entity -To do so, you must declare the `multishop` setting of your model definition to `true` : +To do so, you must declare the `multishop` setting of your model definition to `true`: ```php public static $definition = [ @@ -352,7 +352,7 @@ public static $definition = [ #### Associate an object to a store -You can associate an object to one or several stores with the `associateTo` method : +You can associate an object to one or several stores with the `associateTo` method: ```php $cms->associateTo(1); // associates the object to the store #1 @@ -362,12 +362,12 @@ $cms->associateTo([1, 2, 4]); // associates the object to the stores #1, #2 and ### Multiple stores/shops and languages objects{#multiple-stores-languages} -PrestaShop's ObjectModel can handle both multiple languages and multiple shops entities. The entity `Category` is a good example of this case : +PrestaShop's ObjectModel can handle both multiple languages and multiple shop entities. The entity `Category` is a good example of this case: - we need to translate a Category name for each language - we may need to change the name of a Category for different shops -#### Under the hood : how does it work ? +#### Under the hood: how does it work? When declaring a multi-store ObjectModel, PrestaShop will fetch another database table named like your base database table, with a suffix `_shop` This table is a pivot table referencing at least the id of the base Object (`id_cms`) and the id of the shop (`id_shop`). @@ -397,7 +397,7 @@ classDiagram #### Enable multi language + multi shop for your entity -To do so, you must declare the `multishop_lang` setting of your model definition to `true` : +To do so, you must declare the `multishop_lang` setting of your model definition to `true`: ```php public static $definition = [ @@ -406,7 +406,7 @@ public static $definition = [ ... ``` -And then, you must declare which ones of your fields are translated : +And then, you must declare which fields are available for translations: ```php 'fields' => array( @@ -420,9 +420,9 @@ And then, you must declare which ones of your fields are translated : ) ``` -#### Loading or save a multishop_lang object +#### Loading or saving a multishop_lang object -While languages are [accessible with accessors]({{< ref "#multiple-language-accessors" >}}), if you need to programatically retrieve an ObjectModel related to a particular shop (not the selected / current shop from Context), you need to change the method used to load an object : +While languages are [accessible with accessors]({{< ref "#multiple-language-accessors" >}}), if you need to programmatically retrieve an ObjectModel related to a particular shop (not the selected / current shop from Context), you need to change the method used to load an object: ```php $targetShopId = 2; @@ -453,16 +453,16 @@ $duplicatedCms = $cms->duplicateObject(); {{% notice info %}} **duplicateObject will save the object to database.** -Please note that `duplicateObject()` will instantly save the duplicated object to database +Please note that the `duplicateObject()` method will instantly save the duplicated object to the database. {{% /notice %}} ### Partial update of an object -Since {{< minver v="8.x" >}}, a partial update mecanism is available in ObjectModel. This mecanism allows you to choose which attributes you want to update during the `update()` method call. +Since {{< minver v="8.x" >}}, a partial update mechanism is available in ObjectModel. This mechanism allows you to choose which attributes you want to update during the `update()` method call. -On previous versions ({{< minver v="1.7.x" >}}, {{< minver v="1.6.x" >}}, ...), this method was already available but was not properly working. +On previous versions ({{< minver v="1.7.x" >}}, {{< minver v="1.6.x" >}}, ...), this method was already available but was not working properly. -Example : +Example: ```php $cms = new Cms(2); @@ -472,7 +472,7 @@ $cms->setFieldsToUpdate(["position" => true]); $cms->save(); ``` -In this example, only the `position` will be updated. `active` (and all other fields) will not be updated in database. +In this example, only the `position` is updated, `active` (and all other fields) will not be updated in the database. #### Partial update of a multi language field From e2acfcc8eb25f8c2e7d88406af4c09a7e5da1a82 Mon Sep 17 00:00:00 2001 From: Thomas Nares Date: Tue, 11 Oct 2022 15:16:10 +0200 Subject: [PATCH 109/310] Fix table style --- basics/installation/install-from-cli.md | 63 +++++++++++++------------ 1 file changed, 34 insertions(+), 29 deletions(-) diff --git a/basics/installation/install-from-cli.md b/basics/installation/install-from-cli.md index 20d70bc910..2693463443 100644 --- a/basics/installation/install-from-cli.md +++ b/basics/installation/install-from-cli.md @@ -27,35 +27,35 @@ php index_cli.php This command, by default, will display the various available options: -|Argument|Description|Default value|Allowed values| -|:----|:----|:----|:----| -|`step`|Installation steps to execute|all|all, database, fixtures, theme, modules, postInstall| -|`language`|Language ISO code to install|en|2 letters ISO 639-1 code ([ISO 639-1](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes)) with available translation files in `/translations`| -|`all_languages`|Installs all available languages|0|0, 1| -|`timezone`|Set timezone of instance|Europe/Paris|Valid timezone ([TZ Database](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones))| -|`base_uri`|Base URI (appended after domain name)|/|Any URI| -|`domain`|Domain name for the shop (without http/s)|localhost|Any domain name or IP address| -|`db_server`|Database server hostname|localhost|Any valid MySQL valid server name or IP address| -|`db_user`|Database server user|root|Any valid MySQL user name| -|`db_password`|Database server password|""|The valid password for `db_user`| -|`db_name`|Database name|prestashop|_string_| -|`db_clear`|Drop existing tables|1|0, 1| -|`db_create`|Create the database if not exists|0|0, 1| -|`prefix`|Prefix of table names|ps_|_string_| -|`engine`|Engine for MySQL|InnoDB|InnoDB, MyISAM| -|`name`|Name of the shop|PrestaShop|_string_| -|`activity`|Default activity of the shop|0|Id of an activity ([Complete list of activities](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Form/Admin/Configure/ShopParameters/General/PreferencesType.php#L211-L230))| -|`country`|Country of the shop|fr|2 letters Alpha-2 code of ISO-3166 list([ISO-3166](https://en.wikipedia.org/wiki/List_of_ISO_3166_country_codes))| -|`firstname`|Admin user firstname|John|_string_| -|`lastname`|Admin user lastname|Doe|_string_| -|`password`|Admin user password|Correct Horse Battery Staple|_string_| -|`email`|Admin user email|pub@prestashop.com|_string_| -|`license`|Show PrestaShop license after installation|0|0, 1| -|`theme`|Theme name to install|"" (classic)|Theme name (located in `/themes`)| -|`ssl`|Enable SSL (from PS 1.7.4)|0|0, 1| -|`rewrite`|Enable rewrite engine|1|0, 1| -|`fixtures`|Install fixtures|1|0, 1| -|`modules`|Modules to install, separated by comma|[]|_array_ of module names (located in `/modules`)| +| Argument | Description | Default value | Allowed values | +| :-------------- | :----------------------------------------- | :--------------------------- | :---------------------------------------------------------------------------------------------------- | +| `step` | Installation steps to execute | all | all, database, fixtures, theme, modules, postInstall | +| `language` | Language ISO code to install | en | 2 letters ISO 639-1 code ([ISO 639-1][iso-639-1]) with available translation files in `/translations` | +| `all_languages` | Installs all available languages | 0 | 0, 1 | +| `timezone` | Set timezone of instance | Europe/Paris | Valid timezone ([TZ Database][tz-database]) | +| `base_uri` | Base URI (appended after domain name) | / | Any URI | +| `domain` | Domain name for the shop (without http/s) | localhost | Any domain name or IP address | +| `db_server` | Database server hostname | localhost | Any valid MySQL valid server name or IP address | +| `db_user` | Database server user | root | Any valid MySQL user name | +| `db_password` | Database server password | "" | The valid password for `db_user` | +| `db_name` | Database name | prestashop | _string_ | +| `db_clear` | Drop existing tables | 1 | 0, 1 | +| `db_create` | Create the database if not exists | 0 | 0, 1 | +| `prefix` | Prefix of table names | ps\_ | _string_ | +| `engine` | Engine for MySQL | InnoDB | InnoDB, MyISAM | +| `name` | Name of the shop | PrestaShop | _string_ | +| `activity` | Default activity of the shop | 0 | Id of an activity ([Complete list of activities][activities]) | +| `country` | Country of the shop | fr | 2 letters Alpha-2 code of ISO-3166 list([ISO-3166][iso-3166]) | +| `firstname` | Admin user firstname | John | _string_ | +| `lastname` | Admin user lastname | Doe | _string_ | +| `password` | Admin user password | Correct Horse Battery Staple | _string_ | +| `email` | Admin user email | pub@prestashop.com | _string_ | +| `license` | Show PrestaShop license after installation | 0 | 0, 1 | +| `theme` | Theme name to install | "" (classic) | Theme name (located in `/themes`) | +| `ssl` | Enable SSL (from PS 1.7.4) | 0 | 0, 1 | +| `rewrite` | Enable rewrite engine | 1 | 0, 1 | +| `fixtures` | Install fixtures | 1 | 0, 1 | +| `modules` | Modules to install, separated by comma | [] | _array_ of module names (located in `/modules`) | - All the options from the regular in-browser installer are available, with their default values listed above. - Almost all default option values can be left as is because you can edit them all from the PrestaShop Back Office once the installation is complete. @@ -104,3 +104,8 @@ If the database is not created, please use argument `--db_create=1` to create th If your MySQL server is configured on a different port than `3306`, please specify it in the `db_server` argument like this : `--db_server=sql.example.com:3307` {{% /notice %}} + +[iso-639-1]: https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes +[tz-database]: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones +[activities]: https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Form/Admin/Configure/ShopParameters/General/PreferencesType.php#L211-L230 +[iso-3166]: https://en.wikipedia.org/wiki/List_of_ISO_3166_country_codes \ No newline at end of file From 7d0eda25fa8db57366bb71a1259ca91e4113af05 Mon Sep 17 00:00:00 2001 From: Thomas Nares Date: Tue, 11 Oct 2022 15:31:11 +0200 Subject: [PATCH 110/310] Precision about modules --- basics/installation/install-from-cli.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/basics/installation/install-from-cli.md b/basics/installation/install-from-cli.md index 2693463443..48b237182d 100644 --- a/basics/installation/install-from-cli.md +++ b/basics/installation/install-from-cli.md @@ -55,7 +55,7 @@ This command, by default, will display the various available options: | `ssl` | Enable SSL (from PS 1.7.4) | 0 | 0, 1 | | `rewrite` | Enable rewrite engine | 1 | 0, 1 | | `fixtures` | Install fixtures | 1 | 0, 1 | -| `modules` | Modules to install, separated by comma | [] | _array_ of module names (located in `/modules`) | +| `modules` | Modules to install, separated by comma | [] (all) | _array_ of module names (located in `/modules`) | - All the options from the regular in-browser installer are available, with their default values listed above. - Almost all default option values can be left as is because you can edit them all from the PrestaShop Back Office once the installation is complete. From 4fd7993a9bdb947e93a41651d922ccff6d622cbc Mon Sep 17 00:00:00 2001 From: Thomas Nares Date: Wed, 12 Oct 2022 10:07:59 +0200 Subject: [PATCH 111/310] Add a method reference, fix types, add multilang constructor description --- .../components/database/objectmodel.md | 187 +++++++++++++----- 1 file changed, 139 insertions(+), 48 deletions(-) diff --git a/development/components/database/objectmodel.md b/development/components/database/objectmodel.md index a3b35cfcd7..465d69bce5 100644 --- a/development/components/database/objectmodel.md +++ b/development/components/database/objectmodel.md @@ -20,14 +20,10 @@ Read more about Object relation mapping (ORM), Database abstraction layer (DBAL) A class extending the ObjectModel class is tied to a database table. Its static attribute (`$definition`) represents the model. -Its instances are tied to database records. The ObjectModel class provides accessors for each attribute defined in `$definition`. +Its instances are tied to database records. When instantiated with an `$id` in the class constructor, the attributes are retrieved from the related database record (using the `$id` as the primary key to find the table record). -When the `save()` method is called, ObjectModel will ask the DBAL to **insert** or **update** the object to database, depending if the `$id` is known or not in the ObjectModel. - -ObjectModel is also in charge of deleting an object in database (with its `delete()` method). - {{% notice info %}} You can override classes that extend ObjectModel, but with extreme precaution, e.g., defining a wrong `$definition` model can break the entire system or lead to data loss. {{% /notice %}} @@ -39,13 +35,25 @@ You can create a new entity (in a module for example), with its own database tab To do this, create class extending the ObjectModel: ```php - class Cms extends ObjectModel { } ``` +Next, define the properties of your entity : + +```php +class Cms extends ObjectModel +{ + public $id_cms; + public $id_cms_category; + public $position; + public $active; + [...] +} +``` + The next step is [defining the model]({{< ref "#defining-model" >}}). ## Defining the model{#defining-model} @@ -144,48 +152,16 @@ In this example: Field type is an important setting, it determines how ObjectModel will format your data. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Type in ObjectModelRelated type in MySQL
TYPE_INTINTEGER, INT, SMALLINT, TINYINT, MEDIUMINT, BIGINT, ...
TYPE_BOOLSMALLINT
TYPE_STRINGVARCHAR
TYPE_FLOATFLOAT, DOUBLE
TYPE_DATEDATE
TYPE_HTMLBLOB, TEXT
TYPE_NOTHINGShould not be used (avoids ObjectModel formating)
TYPE_SQLShould not be used
+| Type in ObjectModel | Related type in MySQL | Formating | +|---------------------|---------------------------------------------------------|-------------------------------------------------------| +| TYPE_INT | INTEGER, INT, SMALLINT, TINYINT, MEDIUMINT, BIGINT, ... | Cast to int | +| TYPE_BOOL | SMALLINT | Cast to int | +| TYPE_STRING | VARCHAR | Return string, escape value, remove php and html tags | +| TYPE_FLOAT | FLOAT, DOUBLE | Cast to float | +| TYPE_DATE | DATE | Return string, escape value, remove php and html tags | +| TYPE_HTML | BLOB, TEXT | Return string, escape value, keep safe html tags | +| TYPE_NOTHING | | Use with caution, not secure, does no formating | +| TYPE_SQL | BLOB, TEXT | Return string, escape value, keep safe html tag | #### Validation rules reference @@ -314,6 +290,15 @@ $cms->meta_title[2] = "Mon fabuleux titre"; $cms->save(); ``` +But... what if i want to retrieve my object only for a specific language, and update its `meta_title` ? +In this case, you can load your object with the `$id_lang` parameter in constructor, and you will have a non-array accessor : + +```php +$cms = new Cms($cms_id, $lang_id); +$cms->meta_title = "Mon fabuleux titre"; +$cms->save(); +``` + ### Multiple stores/shops objects{#multiple-stores} PrestaShop's ObjectModel can handle multiple stores (or multi shop) ObjectModels. @@ -555,3 +540,109 @@ public function hookActionObjectProductDeleteAfter(Product $product) ); } ``` + +## Class reference + +Here is the reference of the methods described on this page. Many other methods that we don't described here are available. + +See complete implementation here : [ObjectModel.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/ObjectModel.php) + +```php +/** + * Builds the object. + * + * @param int|null $id if specified, loads and existing object from DB (optional) + * @param int|null $id_lang required if object is multilingual (optional) + * @param int|null $id_shop ID shop for objects with multishop tables + * @param TranslatorComponent|null $translator + * + * @throws PrestaShopDatabaseException + * @throws PrestaShopException + */ +public function __construct($id = null, $id_lang = null, $id_shop = null, $translator = null) + +/** + * Saves current object to database (add or update). + * + * @param bool $null_values + * @param bool $auto_date + * + * @return bool Insertion result + * + * @throws PrestaShopException + */ +public function save($null_values = false, $auto_date = true) + +/** + * Takes current object ID, gets its values from database, + * saves them in a new row and loads newly saved values as a new object. + * + * @return ObjectModel|false + * + * @throws PrestaShopDatabaseException + */ +public function duplicateObject() + +/** + * Deletes current object from database. + * + * @return bool True if delete was successful + * + * @throws PrestaShopException + */ +public function delete() + +/** + * Deletes multiple objects from the database at once. + * + * @param array $ids array of objects IDs + * + * @return bool + */ +public function deleteSelection($ids) + +/** + * Does a soft delete on current object, using the "deleted" field in DB + * If the model object has no "deleted" property or no "deleted" definition field it will throw an exception + * + * @return bool + * + * @throws PrestaShopDatabaseException + * @throws PrestaShopException + */ +public function softDelete() + +/** + * Toggles object status in database. + * + * @return bool Update result + * + * @throws PrestaShopException + */ +public function toggleStatus() + +/** + * This function associate an item to its context. + * + * @param int|array $id_shops + * + * @return bool|void + * + * @throws PrestaShopDatabaseException + */ +public function associateTo($id_shops) + +/** + * Set a list of specific fields to update + * array(field1 => true, field2 => false, + * langfield1 => array(1 => true, 2 => false)). + * + * @since 1.5.0.1 + * + * @param array>|null $fields + */ +public function setFieldsToUpdate(?array $fields) +{ + $this->update_fields = $fields; +} +``` \ No newline at end of file From 1104799f0e2a82e74491e5eb4fd92e6959044639 Mon Sep 17 00:00:00 2001 From: Daniel Hlavacek Date: Mon, 3 Oct 2022 14:03:07 +0200 Subject: [PATCH 112/310] Update instructions on how to fill PR. --- contribute/contribution-guidelines/pull-requests.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/contribute/contribution-guidelines/pull-requests.md b/contribute/contribution-guidelines/pull-requests.md index 621a7b01e5..11ae4dc8ba 100644 --- a/contribute/contribution-guidelines/pull-requests.md +++ b/contribute/contribution-guidelines/pull-requests.md @@ -120,7 +120,7 @@ If your code introduces deprecations, please note them here. ### Fixed ticket -If your Pull Request resolves an existing issue, please note it using the _magic word_ "Fixes", followed by the issue number, like this: `Fixes #12314`. +If your Pull Request resolves an existing issue, please note it using the _magic word_ "Fixes", followed by the issue number, like this: `Fixes #12314`. If your Pull Request fixes multiple issues, use following syntax: `Resolves #12314, Resolves #56789`. {{% notice tip %}} Using the appropriate syntax will link your Pull Request to that issue, and will automatically close it once your Pull Request is merged. @@ -130,10 +130,11 @@ If no issue is linked to your Pull Request, maintainers might ask you to create ### Related PRs -If your Pull Request is linked to another contribution and they should be reviewed or tested together, please provide the other Pull Request links into this field. Examples: +This field should contain links to related PRs in other repositories. -* Please provide the URL of Pull Request that submit theme changes, if your PR requires modifications both in the core and a supported theme. -* Please provide the URL of Pull Request that submit changes to the Upgrade process (such as database or configuration changes), if your PR requires modifications both in the core and the upgrade process +If your Pull Request modifies database structure or adds new configuration fields, you should also provide a PR for [autoupgrade module](https://github.com/PrestaShop/autoupgrade). + +If your Pull Request needs a theme change to work, you should provide [hummingbird](https://github.com/PrestaShop/hummingbird) and [classic-theme](https://github.com/PrestaShop/classic-theme) PR. ### How to test From c93a473e0d1a7d8f40943c50b019f93413d0a571 Mon Sep 17 00:00:00 2001 From: "J. Cernek" Date: Wed, 7 Sep 2022 17:37:10 +0200 Subject: [PATCH 113/310] Update reference.md For Prestashop 1.7.8.6 classes/webservice/WebserviceRequest.php:329: 'stock_availables' => ['description' => 'Available quantities', 'class' => 'StockAvailable', 'forbidden_method' => ['POST', 'DELETE']], --- webservice/reference.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webservice/reference.md b/webservice/reference.md index 2b7ca4610d..2e7e93d271 100644 --- a/webservice/reference.md +++ b/webservice/reference.md @@ -14,7 +14,7 @@ Most resources can be accessed in a REST manner, with the 5 main HTTP request me | Key | GET | POST | PUT | DELETE | HEAD | |--------------------------------|:---:|:----:|:---:|:------:|:----:| | search | ✅ | | | | ✅ | -| stock_availables | ✅ | ✅ | | | ✅ | +| stock_availables | ✅ | | ✅ | | ✅ | | stock_movements | ✅ | | | | ✅ | | stocks | ✅ | | | | ✅ | | supply_order_details | ✅ | | | | ✅ | From 3aeb340b88ca5379bc752f7bee4f0ba5045099ad Mon Sep 17 00:00:00 2001 From: marsaldev Date: Wed, 13 Jul 2022 12:26:42 +0200 Subject: [PATCH 114/310] Add Webservice tutorial in (Module) extension concept section Add new page about how to extend the Webservice resources through custom entity and module --- modules/concepts/webservice/_index.md | 123 ++++++++++++++++++++++++++ 1 file changed, 123 insertions(+) create mode 100644 modules/concepts/webservice/_index.md diff --git a/modules/concepts/webservice/_index.md b/modules/concepts/webservice/_index.md new file mode 100644 index 0000000000..cd2f3c252b --- /dev/null +++ b/modules/concepts/webservice/_index.md @@ -0,0 +1,123 @@ +--- +title: Webservice +--- + +# Webservice +{{< minver v="1.7" title="true" >}} + +## PrestaShop Webservice +PrestaShop enables merchants to give third-party tools access to their shop's database through a CRUD API, otherwise called a web service. + +Since 1.7 version, developers can extend the resources available through the PrestaShop Webservice with a module. + +### Create and declare your new entity + +The following example is about an entity that can manage blog articles, the folder where you create your Entity is not relevant. + +PS: Remember to create the respective table(s) in the database, usually created during the module installation. Don't forget to set your [composer.json](#composer-configuration-to-use-namespaces-in-your-objectmodel-entity) correctly to use namespaces and autoload of your classes in the PrestaShop environment. +```php + 'article', + 'primary' => 'id_article', + 'multilang' => true, + 'fields' => array( + 'title' => array('type' => self::TYPE_STRING, 'validate' => 'isCleanHtml', 'required' => true, 'size' => 255), + 'type' => array('type' => self::TYPE_STRING, 'validate' => 'isCleanHtml', 'required' => true, 'size' => 255), + + // Lang fields + 'content' => array('type' => self::TYPE_HTML, 'lang' => true, 'validate' => 'isCleanHtml', 'size' => 4000), + 'meta_title' => array('type' => self::TYPE_STRING, 'lang' => true, 'validate' => 'isCleanHtml', 'size' => 255) + ) + ); + + protected $webserviceParameters = array( + 'objectNodeName' => 'article', + 'objectsNodeName' => 'articles', + 'fields' => array( + 'title' => array('required' => true), + 'type' => array('required' => true), + 'content' => array(), + 'meta_title' => array(), + ) + ); +} +``` + +The `$webserviceParameters` is mandatory to define how and which fields to expose. + +The name to access to all the elements: +```php +'objectsNodeName' => 'articles' +``` + +The name to access to the single element: +```php +'objectNodeName' => 'articles' +``` + +The parameter to set which fields to expose through the webservice and settings for each of them: +```php +'fields' => array() +``` + +### Register it through the addWebserviceResources hook +The hook `addWebserviceResources` must be registered by your module, usually done during the module installation. +```php +public function hookAddWebserviceResources($params) +{ + return [ + 'articles' => array( + 'description' => 'Blog articles', + 'class' => 'Acme\MyModule\Models\Article', + 'forbidden_method' => array('DELETE') // optional + ) + ]; +} +``` + +### Composer configuration to use namespaces in your ObjectModel entity + +To correctly load your class (Entity) you need to configure correctly your composer.json +The follow is an example of correct configuration to load your entities in whatever folder you want. + +```php +// modules/yourmodule/composer.json +``` +```json +{ + "name": "yourname/yourmodule", + "autoload" : { + "psr-4" : { + "Acme\\MyModule\\" : "src/" + } + }, + "type" : "prestashop-module" +} +``` + +Don't forget to load the `autoload.php` in your module +```php +// modules/yourmodule/mymodule.php + Date: Thu, 14 Jul 2022 09:34:30 +0200 Subject: [PATCH 115/310] Apply suggestions from code review by @matthieu-rolland Co-authored-by: Matthieu Rolland --- modules/concepts/webservice/_index.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/concepts/webservice/_index.md b/modules/concepts/webservice/_index.md index cd2f3c252b..0d1680a680 100644 --- a/modules/concepts/webservice/_index.md +++ b/modules/concepts/webservice/_index.md @@ -59,14 +59,14 @@ class Article extends ObjectModel } ``` -The `$webserviceParameters` is mandatory to define how and which fields to expose. +The `$webserviceParameters` array is mandatory to define how and which fields to expose. -The name to access to all the elements: +The key to access all the elements: ```php 'objectsNodeName' => 'articles' ``` -The name to access to the single element: +The key to access a single element: ```php 'objectNodeName' => 'articles' ``` @@ -94,7 +94,7 @@ public function hookAddWebserviceResources($params) ### Composer configuration to use namespaces in your ObjectModel entity To correctly load your class (Entity) you need to configure correctly your composer.json -The follow is an example of correct configuration to load your entities in whatever folder you want. +The following is an example of a correct configuration to load your entities in whatever folder you want. ```php // modules/yourmodule/composer.json From 0244998cf7c8d7ca77ccb2223cbbfdac6e63c87e Mon Sep 17 00:00:00 2001 From: marsaldev Date: Fri, 23 Sep 2022 17:06:51 +0200 Subject: [PATCH 116/310] Applied suggestions + more info + screenshots --- modules/concepts/img/articles-list.png | Bin 0 -> 73134 bytes modules/concepts/img/empty-articles.png | Bin 0 -> 56238 bytes modules/concepts/img/new-ws-resource.png | Bin 0 -> 46787 bytes modules/concepts/webservice/_index.md | 124 ++++++++++++++++++----- 4 files changed, 96 insertions(+), 28 deletions(-) create mode 100644 modules/concepts/img/articles-list.png create mode 100644 modules/concepts/img/empty-articles.png create mode 100644 modules/concepts/img/new-ws-resource.png diff --git a/modules/concepts/img/articles-list.png b/modules/concepts/img/articles-list.png new file mode 100644 index 0000000000000000000000000000000000000000..5bb58fa81c6b72577ba2c2a37b108b9068679f7a GIT binary patch literal 73134 zcmeEuhdW$d_b8DfYKRhDB6{!LBoRdKT?nE@ndnB1AQGZQ@4bfThG0Y&ZK8J*ZALFM z7{lOB-mm<==l-7O{q7%d=Q-QiXP@29T5GSp+V)9DONEq(o(K;Qk5u)=b3Ht~TW~x) z{CkAAaV1lsMXI<5Qzu159aTj|RvizZy_1U_9v)YMYy4C78@f~x&?IYdBATa}?@c3! z6NM7ZGD4LEN`A5yMyxr~e?IjWrFgb8uXN!!6G!;ak@k6O9-)~^ro=7EBn`B5vYC8y zR$MnIbqN2vzjvPo`8$tZxS5BM=}0B_vdXdb1CbkPW2Di&hT=*TfzF7puxFJ1q5?j* zprV4cyH^vP?_2;@81ieltYrw~6f_K4cDxOOtE2&jzt`Ef{r?6^&ObcgGA6+Y>{)B$JgL>^hI6QcK&^L)s< zP8W~)0tf3TI}=rVO-(!=T%Hi`CO$phEnE&CmlW_B{+(CG=fWfStNaEYUZfM=&41R> z!rlM;;&JIun}6I1zI?#DgL|UHCBM8I|Ehfpo=5PnJpMi0JG`g*imEtFf+`p<0t>=*Ie|Uuzqnx0n2*M}G$T_wOI`wDWWNpOM@= z|M^+C4;1|KMo?HlNbui%eeUFngBflN1rbRRxxecFuQ&fQ;(xR> z`Ja};;=)4z+4MhN{ohRuJ?%Ucfv&hQy%hcjU;k|UpD+K}P)_jAr~d~i{sHH|N^yWz zAd(aOH_{Y{G*AQMI6N{sJ=ZqC-Ema**Y6|lFBdNTx#Lo1;Nj<+`FMCw@Km2aHSojV z&A!zpp>)z8xxY{5RMaY~6tBna^z`0ydiKdxxhS#!?ZjAd zwRp)tz9am*>j{7|-Uh;A&CBy&2939|1pPh8p4>c7ct?f0BsACk^!J0}Y7G+n9ZYf1 z{1tbzDD6OHHcIVp@$>{&%b5A^;dL)G_%Um5AfU_0;J*yY+S`WwFHV&)Gu-YP1EtFyJYxK59E!j642 zouar)2#E#T-uhkafxE-V6=tiU=Y~-(@N@^QIMiyiU~n?C^DJP<7}Fjre>!WOphUBU z7WtN}(KxB6?#=$v6DsffI}^KE7-#mWiC^-*hS1Y(7QpGOtt*CMHIYEso^$ z^{E={)hM)`@++;}nl#AbQESo5tLQ!amEruV$}l;ls(axuCer)k$?o zL~*L+_q{`4+fiT5@At$X1Us-IF1Ux4rUf@=+0RDu@%tkZ3zg-lA;Av0EdT9tabMZp z8pXk+M&h}j=?*#RIYAH%d}u%X*kZw@Uej-<3hck+>}6f>iGv7{6X5p1_Or0RG=s3s z^JZN4UBMT7GdnpQKl)pzjLaj@%K=cU{Xq;49?Y@Q@U)sfdgq%-$iQYoDCU%Z3cNu#L+NLc$M}(HVCL+F8Lu4+QYi@Ge zP}~cZxv^B?yM1GdoWe2Thu>NZE#zY9;De^b++*&qo9k8~mnU0h(N7J0rgL3OlxSay zWqD7VT7RIkFDuS$n#Updp3zJ1sl%&_gPCtTMZ%%Em%9$uGcSELW3^K$7%ROj*N`5V@$r40>J1VGi0z zzHcj1Lz}eOx?30BF?pONM0Yk2fq!q@ZzY2ELl~J1m(cmgI@Z*X>kHUQd1(%j>_MBS zA0pcqxsV(@@ucHyHM%=VUn`xyF63eX_Qe~caIt&84+mc=pM)+ZCHX-=L8X1{<&{ha zj>abN65|fW)dfixfF11}MV>hNz<*S8vES-jyiAw3&O855>s5-W{arLHB;+N-JC$wi z-oTKi^i90Qx80=WTGu1M;6$odT!~er$LNmhc6Pgl6|aFuK*uV>3YL-E4*2H5O&vb(gc!bD1^@<2fqL z$&KYNn6uBUg54I~VkvmB^h$PR;AkL zsR`cdHp;X<-?Np-nPq&pt&jPBy?Rj;(n+HwZ|xu3)%Ma5muCBz)$#S&az=r$nA?=3 zpY*k)BZh)_OhT=D<9Ro?ylj3NaL~T=(lv4KrJislVo1`(VPe!4}zBWv}E@T5Z^KZelvWi_g`%G8fU)U(#-iWxQP5o z#9OHYZli!IT6h15)VyTkivnd5`D`Q`bMP`UN8#VOE%8T2BhbbxehuEv4h^9%e#J$Z zN5)1z9$a(Y0-#0-6+$G7^{krG_aPViMRLK|qkjF1xMp&x-|uQ>ECbx>o1vdoRh@4> z*tBwM+4y2xa#K{?MCABx;M6kj313hf;Bre_oELP?_5h!h#u~oZO%AY7C!<+Bwlk;B zA>V*V3hfa0V#$LK!(I<4e@}ZEZUgBEzgmrz-A^m9y(@Aa@xZzLcwD_4rWP`N{^qzF zhr?De&vy#DGaXkaH7g$&rq7cfe3Hkl{4LX(9+eMK?_Igp5jPF4pXU+$L2APni{t1A zD6&S6!eoaXXUQ5x)lr`N9GCfNrIxQ6$@t(QCts~hC+pH!lnR`qKvX{snoVTP?OYq2 z-dfYyJu6L&TOw97!am~KrAWfSuCLG&pwcMNG_s^ng){EMvyi({*3%Ki;}W3NPn_ed z;g_c>^ajnG-EbnOgIG_Pds9F^OGsc2-e1ZI)2TXzuX7A}I72Yy$zzYmgil{&__rp1FM|6cSv0tgG{^P-+j_&ezr} zzEf@cODrw?>fTUzPSEL`x0-)$pZ)G;hY3rKAQh^}t}sS|NL`@iwMd2k<;hGC@(m)X zG-fb1qgz62Gjfb}oi5sb=)$4Y>aMonu$z4xKN3wIa@PI!3WMO3ob(;g(H&k8B|XKu zY)#fmhIU{#1i1yzLmQUA4OWZs-Wd!ci;=BL5+=YrPU2T=Tzv4tttV!TOL_7S_Q1_j zBEL16-VN9&SQEa~AFe+lVUppyg^VFE(;ZG^OwqAs@}73KrK7Db+A|OaAcgP10n?UZ z+iiJX3TvN5vBi^bZ4)zb>`x|$Rh_T)xtT0vG~uH2`2M25HPiEYO7u+hC>`tXmm4+& zk1*bR57VYzz4vIVme{c7X0oTRQ60yLIIne^ypJbd-_EpQjt*HC?4rM3${?Dj$+KQf z8y(;WFMgqVVv?`+;dW?fFi^35nT{R^+AOI9AQ9BY7P{u&t2?Msmq+$Srgq6fHH1) z2N6a(B(i%&vVJ<`DB3CBE@CUK}19;lg+1U`^?rBC!Lko z-*f;a7N?l;RMie9{j_&(%CyPR9CxW;T`^zlTjh}vz->@JJ#KVpu$&AYi1f;-f2(9n zr5D*!@0FursRSum+GJ>QiWpF#La=KrtxX_3&Me4au*vN%D!R|N)rA3K%crmWfL0Oy z4vuYm`Kg0fgSl4Ty>d~0`hDucFsy71_DQQ|6b9b5ULbxW*eW^HV7MMzPFLBGf(-SY zB5Li-OFQ^lN6`J~{QZM9YE|ASkh#b}3W#ZtNTNE8B?{BB$rLo#_y%8vZi%gQuKL#~P>F$%-G>p5cx58W5{1vQ z`^_uu=;fh8-pi3m>FE{T`!Y+OBjUzpI|5bhmHy2>xrA=YJR1eKt31KP;}e5w&=TbhPlwjJ*R zYd+C2Wba~^h=>Oha8qUbwFyR)RitrN*M{RAAaN{zrxC44my4a_zH>I3*0m62Z~{|f zv~%Og@mu}z=>4Gp*TSxEp-=?`Y=l%UJlnGb?=acF6COCj30uMJ zDe%q5RyyEE5X)i(`@HYTZPo`Rf^j2*?G>2%?1oH{TYxIFVSVMJDsTOa#`FPV2x*_> zK%>3-uU~g9aRAfTTQD5fN7q}Z%RUuRj69rl(4I(S~HlchNHH?!J1^D~*&VLj5b(hSE zMlTc@`ovJ7)?4j2ih5@TYq@}4dOi)5v~G?QdG~A+_a8Ya3C97DOqY5lVtO?RAsm@5 zb>BpI)qKCsd{4-gEguRz_d_&P4WC?h1PFjn%Pu1P~yni|8tY)mr*D8+Rmjv#8ikY21 zDRVsd#D*?j=^eGw<_iocc$SC2ZMVE$v@;aDpTdY5g`^+G&YJAD?0jn_x@_on!HE(3 zpQtrnp8XL$wJp>eefVR)H!*4(IC6xzzwFFucG2M{(fXqvqv<$@wl(gGM{0* zrSmq!aZfvi|A1moKMUsfq`o%)$;2Q^X~R`}5t=8UeU!6W`9%iqo?bZar=@^dKi*{t z!Mgj?VEa3xn3t6-_RA+(w$>E(ZEUMfEriz07KieF9aPqj&J$?o=1RpeMdviv>T5HK z@f;iXvGGv)uWG~}e>*#U3;xNGdE6teF##S>?A=JE4{kks*zPV=$SHvgunFU+Wo?uC zHFn>Du}Gw|^dVX0Nsk&wOMOV&%q&JTMEBwHv}ZiLS)t^Xp=?)TAbhO})okq!H8g&i zoD zih*~h-KX`*H`Et-3sbHOkX65OiyITs({9T(%^6Isx(7Wc9s#R(TK>W0U*vxHCX|K- zKFb-nE}$$N<@Yw({{S3`ocW19xTMYY{UXSvze=@|(_C)8dT*v^?^9G6Gx7#Z^jR<+ zPNl3yMj(o?Jm==VOWw{MW3(f(Yy&k55J>}5akM`90hzh--E zEx@jP`~}99A&;u{RP^t7#7H?6o}I0VkZrY8wH5JGBx|&9v#aa3Zaiar)#RchOaE1B zc1aP^P~!wUa_x)=@R0}jn7R3U)q+l}g@A|pv3==z^6o7|^lVywoDJ?jqv4}0aX1Tu znfXn0o7H@Dl4b+6-8{sy*i~8TtW>iT{N|ZiVZP?lMT3+%sCq923W=>3)A?Ysyc$q{ zCT&!%zv{tWuJK;b21c=wp(hCb*GVT*&0p;I8R7quZq1T|vb$!)?4dQ`s=C)_BODV-(wlZl+by z7AsI4dw$E1Kg(w@)@b$3Oic2p$Dc(SsIT26K>lP`M{b9TL0Yi>@Kb>6kkngadi!MT zJYTjU%Cpovy*TtU>a2yN*RLSM=we^0M9Bjaw<-QgnM}@||aDDi-o_nYqeD-aq%LRSW z_?AmnW3__2cm-_kc4{o!nNygl!q=ky)N995k_yG;=&4lKt`X~X9^|ikbwL};;M@%I z^}0bJ!WyN(^N`+py6kr$YF}0!VT*nin6mW=oc&fabmUI>_&71OkEuzjrN5KM8?|>? z4(T14=O)4|k|U}y`T(gL46}vritj6Sf9{KjH85 z+nxt`j3}!ANv1YKELT|NgaK+@OGnJq&UmV$ILww4lX?3AhIys+qq^pC4=Go`Dy3;7 zFb@4Y8MVHH4Px4-eV(vDl*qxvi zcQ;Ct{Hm>TZ@N+V| zqzLWhqLI$r#_GfVfW{rhHTxxT09XIk@62Bx*s{5hfkA5WpH@EfPHDCDT>Ko`D-anT z$0LBKZy$(oi)=cAEq=GIWyAMOz791<79@zUhM>6~e2xJ4=(+jSYoVQfLKik{uQ1E} zfCRvRCrRaxyAN~I%w@k=-J>d4IvkUofzsGA~g9ekNZH*M_$2S8kit36lI|vdAS5DA?nY=6i>xgB@yg3DDo|8p@5}Ve9PF`%Fn{+y@tXO?Rwi*{}u~jm}<+I)1_8x?>5Cy z^`z(96=~h?2=o~7Mv$zR07uC}#eCeGzPWw#Hpc4KeVOa}{Vb6sFmxoO6;_Q|+nl4~ zhRgCxUesm(o`BIJ6qSX6En&*{Z`}?tiua6*8YEcl#!lp385keZaKp>F?kWFn52^Ry zBnxRDl#c1J7^J6-S*^V-&O$IP2Jv`^wYdAlml&2%fyfe;$F*%?ZWbL&)svD-DC=f#nCh$J<^Pj6gnp`I z{V`L^`%j~hsqLrpUj+h}qc?6PwWTN%anZ|iP=&j1`|K&GJxr7v;krjbrB7p7$QC0& zuM-^K+a;kc26KX2UhPpT(2#O)MOS@UV zrBiVCvnT-`4Ks`>O4@47?BBZnvI8 zkf1`Bdv}SY9~(PqNYajjnx?Z}x6bnM1M)MmBnp?q3fY z6OnT{BdJglnt5+ooXD^VeApA(HQKfQQSVpk-X0hHD6aFJwk#}QL zLLx6hZ>X#IvxCk=wDEAJ6-x+(>>>vE+!FLH#_u+qeX}|xKG-lYp0{a4IhWNPG0?rSjne_g|G?? zDres92Rj^j4&Py_99gVtA_NT;WgkFGYjvf6X~~8Q$&PenpQE4&xnQ$CukqN?wZV`~ z=3>M4EaTyY3zyQxGP4fEcc$^R+`Ecwf?TM}pivCjfcm8Q=1%i;Ot1m7_82f%VpNr2 z&-AlR;9QsdJS0Uy-50lnwZq6eUI-rymHM3H^^6(s-ORm$NU`WeVFLZxsT*nQ#g6iH z{L|NQD*B>ER8o!Cv<}|+VMSJ<+%T_n>FU3m3WAxk?)AVBEJgXJy}mf=_QZM5~TYMXUQ z&hR-F&o`ti&Z@t3@L$L0SkS$27{AG$B_GXnNpfqE?tTt&uX(!1ICh~n8EqsEG_kPj zw`iGjYhRQDIT?({T zpZ=YC`z7RY3VCbUau?6=O=ghvQ-96QP;XV;^Pz9vdi#xE08Ykd{>*mIbm@P0iel)v z;NKE#nAs`y;4_k5mp}3&mUd^$M#5n@Th*+ksv3bPO<>xjGe=V5RZcdzAT7>W$6QGD zDKPkQjF;VAw&khyUI}T9CP|gT%$EW^pVE-Z}8@+WHltVz| zIA7rDV2TWKivwyGHx<2AbwBtn$b<>5(cmp@qw7!TvbVS_3d=(d&B`gf-N1s5-*yTTzfh~YO^h4a_bLXSQS zaQt-_dh3KK3n2N%r@H0nJD3M1xOM0XZ|ksVTzrg$xN)xYwH~!PXLd-KJphz8k_v4#3uW(MCs%$8RzIoOVx z2$jNwyCY^_kdM_B_yCMPJmdi?GG>2!`PHA2xb~ik`}TV$-wE~wtT)aitj*x4Z1?6P z^&5VToLlf(VY5~mhKSIZ#aHxzA}{&aALJDyRv^jJ++cq-bH0x^pvlBgry1Lod#8(@ z&_&gcq^bA#bH`5{<>Mue#Z|`Y`2P4>w-7kz?3lA>x|AAY!K2x%NUJMk>O-F3H@J^@ z#XxOuJuKW$Qfr+g!5l;FBZwIL{xv1ec7@4?Q@F+2c5K$Kyd{ptkUMKWLYFg#BGsn* z@$+KPN1|VN zW;G0lk)`#LoPB_^NQhdo>7KZCOF-m_s(9z~&ziG^~0K!L&7 z_Jbh7=fn}~>%JWqFXs)SSjKE1g+M8@z(`e&^v6B1A@gVAx8%01TnKMT{7@XwzB1*G z9FTmmn^sI(HBOEOMo=5QI2aXB`a1HXkMjlfwINaxrnmd9MC`ep`N!$nt*nr-F6rk= z`sYlk@VglM@3oy-64%}M7U z=_4scYjSK7+q&%63BO#N!|c@vDNL6!iv$#8vT;#;%hE%S-RcY(`(2PnYsW@#?5syQi&lV~DY~k#MVR zqivJNJT*J>_bk@re@ususG+{cBfoe()OAXqH-#_9PAWBw#n)-(&&ErR(wA+-wJrV9 zYI)vbxA@0Jey^&WpL^@Uoh?PiG*yI)86$tz_CBf`V0;ziYbKzR(zoHGXQ2zqmLS=q zc5nMVv^hI>*IlO?UdgawpDfd!5`UXB8=1epY}+47+ib^e>CQa-xim8=K9g zAGRZMLxM-RGZXqcOXm;T7|ra{?erLy7<-;(K4E!xilk6sv`%$af%O%Vl?a@Uf6Q({ z*`)#3<}V%PajeFr{y6b)wz-+f+SUvP4FfTfRNWeTGpCFC)q8)?Mne1fDrLGg&Xw#& zF9TCEAema!l-@{c^pssu*uMwyoxgmMjLo>=cv$@=_!N_u_=ZMS?kEDtg~R6Ac$jxWo!RkyAeutzJzbojbodV1;kGst&U!9tad~cNRi1O|GMW8 z#{q;~|FAERW7vDSZ8a~@@~gTrFbQ3X(-pW5R#~4#iSWRkFLUKcV}dUnphG&S88z9W z3G6~SK;69FwqB$p(Z{P$N_K3>kXy21`rwprlWa{vY0DvD^at8|^@--2?o6v#qdq?H zqQ^tB*>m%)g;;{0TV`XD+uZ`&DpR+N4%x_}roJf?tllGi;@lyfpFQIH24*exp3ohS z-QY6#ZszGl_izaPm;?DJ)OXEUuDm>Bgv zrg>Ey+~)n>>O1}rf8yfm!?>ZiVKa-OdZr^-q9#n@`tyEjm33}u@vh{=S-X%Xudj28 zTQiE`mj6!FqW^GYLVxE#)e^9`Zfa3N=F80Ge6LB?^9}X7z61KOBVIXEd!8?Lf)699kj)8yQE4^DBJl*l6!|H%&z3f^we8rfMWK${tr zGUVF#Yn{zflArD--DAvWx3P|~si zw}HY|24pJiuKY2e>)|d(uXToFN@@ddMst2y`rffE`9Yqs+U@r`uF0xl4aKx-dWyvKdvuqKG-2h@liCP z=)9=)gjw!4u-I8sGwH7vUQsV0=!5X@Bjsi)f;+->?S-ux7muN1se3nBw85j1ZM|~S zUJ@0Sua_80St4i4)d}d8rmci+r}&<_PO{lU-eNXVBb%KZ@~7%roDmq&mRLh5|*I%`lZKQKB5&7eq{5cqzF3n*G z2_Y^_wr$09nct%|^>=CAYiexMdmW^iQP$d)Y;5s?S9l}Gl+i}`{VjXh@xPYa`B^PI zdg9##`!cmr>**CPc5LI_l(zv9NU#wl5)A@e!~;9+;gfPSS+7+4(F+w~&Z3|laDnd! zLsGkNRo%G*lu|;koKdeyP5Pf$!B5$^z=`X2k8C<`nh@EIFTUolg|#mSc6p12Z4|!g zGf3dVh1NL)s;E}QuDx=uol7kaU0cgG`5M#EFg-V6Sd2%#T6PW~q#m|+m>>9Y=-s3} zo$0KcDAsdFaKGQ~;|+Je6^7m~Ilc$QZx)83Ir(l-hm-T>s8NRYnZ=;ije78D_?>!U z4Vfzaw0sw68bXmc(>ANbGLy8g@($np0ySTl>uFM+cZ?WWF!R;$)ipkIvkIZ>fPz$yev-z z$?zsew7$*L9MPaKyOVWd>oW|=`S58l|KPbwHXNpPX*!?5l$k7?-B6g>JNM1<8+A0M z&ZF?n<$i9&d5^t3NM6Ta{?0kT5)1Cx9c-L7;~kkj+_UsNSQyGaE##{#Co!L^+R@+XWzb6Tv}Z|Yz%Y)sdddNiogRzs#XjdQ6|AE6@8 zFQ>d$px5#C=GQS49BraMuAJm5N-S|}m>tF?MBX2qY3Kr3{`M05))X-~P1x_j4kn>< zqd}R}WV{-&mTPriZ_nt7suObo3LnfgpswhaoRdldU&=3@Q*>$}`3e(t)2-uleEI5k zU6cBFroER333rZ_kIuvb)ZKt{^s<|z-HucWJJL2mAK$)al3EOKuF&F#ue|A^cT0&i z;)i=)FAczIZDIGRK`E8Ym5DV%$3_7;^~KUg-^2k+b!meBe+1qXc%AJ()(_;Vd1_o; zYD{sBJ!*O&2EzLwb2cN(9gpiJPhDEs`DJQt%}zEv+CGI@!HU|{${f4QGjC3V)YS7; z*|6BV5C&8+F7Tu0xs7cimo2SjY^2pQT;N%`Qz@lW=28LCAoIvCc+rqJxh$>V3%RId z4Q6Fg-p0kQih;U$MD(L*&^0NtvW2}&J28m1SrMzefiqDpyW&=ilMr|P%~LxMM!&t@ zZ;2lHhF^`Z`8Q}#OI(s)C%3MG#AOb`$ycni;SOwb0bOQP0!r?12GtCfL07;+Iga#! z?{lg@y-fOsH7i8Fag*iG4eHo#*_A#qz2bz14gB-6wk+1y{L1 zHnD9LjL>CE5CP+*cSz2G_>Y4MnBdBUve1$9ura@6(EJ~h@Y>ciCVmb(r5%DKhiN<= zuS|5Z9@{#MD7B-a+HSeAh;8tAO-G_%S7R~HOv%}ARZL(me_uqO%5qQV^HRj#=hZLxO9uj zGdsppLj&ZpzaU-5T?rg8O;gHD7b60zaV`VY>$ykWmBZL;-7<=+@!Ti4s_f7@B^kd= z(LCQryM;)NL%oE4*_js5yaK&LIuKpt4pU8XvbYr}6BaxywmpzAC-psoWf zXY4ciXX1(XdpW>~WbcpBi>DDbkO_}Y-kHrdQ-4&UV4-Jkn;;901>-0gWELIlJJ{b< zAWvKMlaFCCHYwMgCHk40SCQ^V`07q`g{$br@~1*a5Sx0)Twq*9M*Ky|3S?Cb%8$y5;LPAoLgTn zbUV=oqC023wFj@og=J;KXY8RC|FGF$N02UK^(N*?a#jX$=L+23AT_NdX=poM zHHh54eMf6~S}Ex)AEe+SW>Ciy_MajWE~<#QaLT8l1?b~qC}^xCe1Lkz`8^d&7Z~tp zlu=u~8@Z=To98Ea$u#r37w@KCQDJ>e>r`CbA<|auM_C9){$hkR>@Fy0C+8(6Owc-Q zG_0ZIUt-5+D4gp@Tc*!wRpF02P{KrXbg~t* zvBjhO(HLJK;?x=u1=>eAdmfPlKCcY1yV{#&i2~6N+U?kz%It2cFa-4v?0brBP(i6n zSx@{q7RAhLmr-sdE`4?QJD(qoDrjc)kHo0zQPLL$zw|hmmVA%R@Uf(O!D=A3oC`pc zvfJ*o{GvGCj~=b<`p6*6;VU*B*#Dl6St3sq`APW-=)hX2#;Krn@l{FP&L}Ck70w{% z9@dtz;6v?5lf$(3VYpE&-T|550(06i5I(p=-S()=us1N_ng^5Fc_&e-xTBAf!%|x3 z*!3L!O9S8jb9C&;vbiKuS-0&fg7ej5|)`XTfKQ?`sScj~JAr(c_Sb=1(r&4si@1bk9f&{r6g_y-n2S6K*&v)(BGizBrlfB<+*;gIx$zbYzhI zU^=y*#t66d@@zcAd7=NonEPsWO(Mwm`kF({`QuP8`#0|Js~52a6qzhGM6?&=G|>+V zB4bl=haRLbM<@8`1=q}8_Lw)FdL;pCjOvL1k@~*YBX6L>@An-%8}%XZz`U9XnFxiX z)JJx#Tl*-W<$!m>Ooc;sYx}2}V|?l*gX@kj*a9ePOIlv;l-Mwb zNfLvzZ3{&vyN+C=>wI36V!-+#DNXkM_E8wE`LU5z7h}QH5L=~{)RBgAoH5@$KUE|@ z*KyDp$>UZI({xNtQ;5S~ljFNs8VOE{*osSGj=lO0aFF-i<6GH#k7rP-(W zyL9Ij*{@c7QL} ztXRbLh7%<^_&!9KmS~hAFH_xr`%nEL+zp=vSBD30R3M?sTR^YsL=W86D+so`Tl#c? z%N0km*fWv2+xF32&+zZE$V4cihrVIt%nVKq_ekznLur-N=YD_qK2tR2d5-*YniulT zNTvtAj1&2B!DB7IsZm^leC@b12xFkRiGN7drQ+8wBgmm91iv-bBn9yYH?w6|1uG6s4W&8;;?VH zgO(F8YCiQ%$wwG4*?r}s*h#&d)vLA)Ngnlx7G{U1Y z)v{%Geb#s6-sG{LJWQ1pgY|RfSS@-q!q49x;=D_3h>O{Pcs}*Bi&3ub>CX1H2(-uw zV8`E&O3@p*{FNr$o1dHWr4`k2Il9Lsij|jjn7ff!M;0siWPk;p$~I^(Xkytnvbw$a zdvuz`^>m-lrRy+4cp|+<4t(L$@RWM|EiQ_0dI_C<2a7P8r}^N{4r!))MbvG6i$Vf~ z=d6jcRnfOO+~1>zeXN$+l~Dmo$FYCunAw!Gvi!lre$ZdSkZ8$6)7oFh1kq)Y^s87B zm1Jx`;hMl;+i^$8!d@jNB{MDKj0wq37(SY$X-MtPotuRH5AK5!Zm{|)TB44Ok8qe6 zooO2GaHqP>p(Gd7eP1a&B*$ko^UtD)vEM4!J2<;!IlGNY7fq7nkSH@sVIHIsj7hp{ z2)V91Yq1o!Ix}TbB30|K_va;51Gv&k#FT_c_zUdg+*9I1xi|q>UxXXnzFIX9SM7Nz zV%&UUCqj~zoSIr~l5>>($em!g3DU3Z%CU-8FQ;x7T|NC$8Y6_I1lW1+N+Yt?!piG! z91qWibv_07zpzGikK9M3$e`vX$FOR%-cjRd#@# zZ9={#n-9&0#wpdrDj*OorDvI*)JWZafn7YWq4}`k?m6>jE;Qi0?YMj(5+p@qDXRiw z;SsGI>K;n|jR^`y?Q3kxW@hqWrngF}uBAAG5io1EQa%Tecyfx}V#1H#k;SS!k#1 g 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%0A-&&}DYlS>ap-K>tEYsc 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 literal 0 HcmV?d00001 diff --git a/modules/concepts/img/empty-articles.png b/modules/concepts/img/empty-articles.png new file mode 100644 index 0000000000000000000000000000000000000000..be6585bf4dbc2d8a683fc30e6f629a5daf516ffb GIT binary patch literal 56238 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

1?K z)I_a|E)WNMiIro61QBo#vZB1bfCc`{ z%SV4j1j2Z%w?6IIj3v>>QrBmM<78^4WAB6xFL|1!D;BM10ZVg|>35Az0@tvU4{ zx$BX@ta1A~B|tG{R@Q>TcnJfHw;$$J3;e#@+Cje}W{S)=J#vlWIZ*kml5ShWpSX(S zBImu3L}XCma0N~RETMAe%k_#dsEO@1TG`O>hK!trcgP1jdQB8P>Aj<;baGu?!pI2c2DIw=GP&WUWBW%6E8T(4&AQo2)c=)lmj&Er*%JyXXUt z^Xy#xsfKeexzO7LadAVMD&T6vKZt$y$_K&Awus6kCf@Z?MH!gv z0J?sT_1*4DYZbNT_bXVdWw=WAI`_B*J%f3^fR;LPqnxnSIdqAen;MpV@YyN^82Icl zmUpxme}^{K$#1gT@epIkoN`VBUUGMcBlxAIU<8CbF`D z+vZ^0QL2R_`_kmOf3xI2sJ&v_nX*y|QK80yuM&jK>_z>ziWT;yOUB|~-(Z$|UrFuL@Z85&WM2tLu=lrlDfp>U1u=8#YOPuk;FhX+Eif)NyO>!eQ-o%@y;)-+NS7`gQ(sNQMx zTS4bkQETFH>AHE*dSs5M6R}en_fu1THJfzY9N<`JEFk?xaw?F4-hdEvlPL{M(Cx?` zji!hu8c*2E2976tWk$`Dgx>nwJGqxP*Npv-^Z4^T@FDz+EfsoL8_LflDhTV#>B^O% zsu<^?6^>2Ham$H$T#z11GG(&Rg>IA-g z!-X2mSZ(dCyH#TY2^&-1FjFzPsft0+<=&C=Xq^!tN!mg`?n0K+E0{qkna#7sUFV9e^^@n z8o>0t7l`BL8~(G_+Y0vJ#&O4&MIASE`x3~CP9g+vyy>v%ti;>3UhO>e-Y0pf5IkFy z#P`Qhh)BJh3mI}(lZp_eA6QS-hBKr=nan$Q*Il1@<_V-c-rZowG0 zD%9+lIIn5cqT8h?Qj`c5>t?g1MAI*X?r%cQdzE#dK9ibT=^KPttU)!e?c%$h@v;4} zd_Z3HngeT51UM9N2=yxd%b?&e4;~JVvZXJq4Y3*Ugu5w*EOnm^j2dE7momT{Y(Tx( zI^ZW#*vJm(hEi#!Mia7W+dYnWAwG>`Xi8WSuQGEyed;>U?u{PrYRuzTK5ul6Z|AW{ zhYI3DDv}-Hj`I(}>ves^zcDN9HoOZ)ncgRUp8A{z$0WuO#OH!!*3+~IFP>cpOlWU_ z4LOdeSt0}arEKo9h8(yMo&Q!O{Z>Q04sx9qMV>!U+bY4P*&hGRC2v8cmpI~Gbb4) zo0Q5@z`V7ej2pZfBj)IRYyYWD7_*b|G3>HXRm33<{SgC}_;a*u9 zE%{_v?3pFg?`$Aiyr}Cwwy!xkA-0qrC}o3p6pTZHPezr+7-GEZ#J<&@U|0j#Yc^WU zb_#GAyTysXi8f_|f4dG{qH4Y0fYD$;a7v?hpEu#9>+I;>%C0_tYOsysa_aDW2>^<4 z`!!4_l|hb+dp51xq7UWjw=^j zv~YH3mzv;Tl>L$GVD;kT+2VMD=7;3)Q$|DMaIkuU^)kRF=IilDu~+{Qfkf7wBz^W2 zW8R@sWyuhBTh%X3y-gC1bO2lZ6?U07I(cM006ujxF4bds?t{G<_kBgjYqcQmE$JBl`B?Pmc#1GdRQ*_FI~B)16fGFz%}A};@(^f=C~BZ z4_dg8iHkB224yqBbSX^&yO-MdNt<9yAcokRy}3a}crlPw8|Vi$7`au)0)S6xQC8}1 zSPxJ{88$^z239gB`!P5>#Nqk*f${_zOT;=9{w0zzf4LO{eU&fIc~l9A#iA3O#%kZ_tX#pD-Zp~%oj=EkdI+?Wsc^mL3= z2=nxht+{M;?sCHZ>YbZKJ!|`yK&YOKDk(OUV$9c>U(UKlL~|65UjM2)OO%r7Hr~oE z)>L<@GuJLflpz56IV{Y@GqVSwcR2_XHVs0rYoG$3(VC! zdfXs(45aJ%q(Y_zmshk}&M8Vf{+B81zx`J#D3}n^31TN%kBK0LBo~AW_NZ|eC}bg_ zJVBLH!&E^jZ*;oHtG3JwmbZ$Cx(g@j#|>dU?f($ybsQrgE{^raw|}0X54|ca%!$Ad z^)GkoE{~3$sEI=Kp1H2gjH0GXhhJX?JpkwWD9xK6)sua(FexsNmBId)D^NhgFf5xo z;C0%XON=H~x;MTFfqne?U>&OUIScbrOfuTLU9oMY=xo#WXop2NqYpqK5F zSa;Ap31Hvf5`TH1BLG=;vY2&R@32}%pMS@v>2x%w%H*CyR& zYMc#6h#^NpA$83qi59%kwKfZvreMChmig=q@8p~Ug_bQjy^*z@HH>r`cga@Xh2UdF ztC1g(xNv^jPX$g4Sb@#xBO7$2u5%MYy#fMC=K!U!zF1$@Uhlob%k*8Jz7oy4-$D&sdW*oYIV0r|+Ti*6`nj6ay}JVzo+F!eFI;QHm3rLdpPYx& zxqn@c@w}XaUmI>&T@Bherm+YV4zXLN;QwCm4Ff{9GM-Ryn7DI;ESR+A*OwbFhQDTu zOqU4{xDT>t<11FVd|X~VQq8K3<&O~{=ORJEb1+|G zy3ABE;iT}9_LcVCKurBP3D!k>n4hT0lCI*b6ddPaVY&3RzSfwlj;dNyY><{l!;h7d zbnxbEGCefv(`?#U#4&5f{Bsxed%|KI`GI-h;>2Ys7WCs+&DP=K+OE|Sq`{4p+{7dn zOKDw&9CGN+0xpcu(>T!9*W5dta(_athc4ag9sfw@Cj6yBVw*xXU~M_}fO_c1OTWV&DzR<2Ys!t&gxyN|h%Clg z&4h;I4EEb^F`Kit|9BlA$xQkg&QU4@&b>(UpV%H^;bv#lYIXn3?TG#L8}vj?@0yol zU557jUVJdjYXEmVcpKzwm20|Tc<9Y3zNXuON(95PMr~O>*UYozT z*HjZ=2<_rye7KBxakvASa>*FI9taa2W%xPYC^-k!QUjKuz9W8X?zrS2hP83k-p<17 zQCOShsqo3GjF1rtzw|q@FlrxA_h0;{vNIk&?$6YBJjl#t9e(3PynT0Z1~isl3>+m$ z-D4ZpM&sa!I^6y*fN8Qytwf89?v-~NUmv*c`A@Lg#;1bFhf8hm9ioj9&7-OlCuvd? z-R72#C=>eI6zc$BSU?wA@SV!L)*3GVFDZvQ&+?&v@t4RRRg@;=RE zy!Vn;+dQwvdVVi?cn35gRI_jEMUL)hFjmP`>5}NXgnQl|popBj-L`)Oom+VLDzQQ5 zGJxyf3T!msu#O!qTAt&)zllm;gMV&5>@!E@fu=J9I8A1{`I8e#?WWK{5gCGm&&14& z0j?XcnL+PQVv|34_=K8<#|0ii@4XJu!h3`tFQU1}rt?%!Ag`Y*;AxUc;Tw@)zmRRI z@utq%*|+ANbS3fX;`S1ZQR9S!`{RF# zOHJSbR^+hIqe+ZezMbjmTlS`_fb7lc{ooG+$4`h0L62gn z3EA^MUv~Js7GHcU`Zk_iIpJHBfG<)p#Rq+SzO|4-AZ4wQ6j$v5;}KVXX}K>^+etK4 z<60X+G^YEmLU$@y44u)YUmr~17!Ihktl2q+$pt4qp`JqXah6rk{hn#OFgtCZ`2GK| z_ZD7lyxabNODV3!o#L)7PAE{Ic!A;$1xj)EP`qf`;$A_DyGtlqyg+dY?hrgcLh?(` z{oQ*%=X35l=O6g4H7hHV%$k{J&))Owd7k}#4PC{0l_~UPis-+8ppb{>BDjg z7bCf0=))h^Z8AGqd(_krp~3yav~T?QN21{~x^dUxQH$xlv?PR442b*W#{LcKFV$}d zYe_6Jh~LR2FW$3*Y7vH|Gcty4nM9uj`$+xY_SF|21*r9NA>cyCtkjn18hlIiMZ^{_ zfl0Gvv6eLnAC+b07VP>?!(LLGwiIa`U}1mc!f-6YUH}@{A)Qpp*yKiMn9`QpWLP2W zx1N+(A=AN>7mp|AMvt4MbvXi9Dc74H3xp};od6e88MY}=94Ujo9m%W^M!S|K=SHEu z2ft8PTcyO=2a@GLXZ34&FoZXJz}&;K6m?WK0q8I7(yl&5#3yZ zI)_%ewm3T0f7_aEJ;KcX_^g$*%CxZ=>tN37At3cFh4rl;^21HmM*zJPq8T>qb`8&& zGJ>gHAUcgVjO2BSniali46tZh&b#sSh&(>uLH^9pkBqi7rX3AkX@32hMmZoSAYvQ= zXJry)ausB2dNe-O18u**x=|?7i=Ls&%qVQlFG_1;r$6{k%9tApMtt%EO|v8>eXTcW z=})08>*Y72l{Z>2v3{{O>a`Pil~(<IO)txcsU3Zx+?QD_?=vhA-XuTvN^ifulHsX=_y3cy80X`dH^J1>8kjRKG8NX4(Mlk ztUsC$(9%QbFRv));5O8m;`s4&yN_F(8c^$ty+RZp=JkZ!~w~zbLYZDOB(?pIlrr# z`JJk!l&|6ppy`1Pi;XmEzwTe*y_i%rpDSvM8F*3TA+q?`!$_9L z^jLri$(LYqTvwrTo`vM`B|X2}Cn9e?6q7ck5Z@$ZwYrcpxd9ewS;Mq$QFdF;ijPRt z_5LviL+J)AH|h6YOd8v$gZzk6t|TlVrBsE#nZ&+7)blSAkuLI7B#(c@p9 zKYZ)Io$1j1hw_kSWD_g2=v)_tE_M~|bv$@1_FFFIIlvM`e;)Fla(=Jle9ZP6dpm3; zNH&ZlRqU~trvhJsf^$l-(6>pk-XHHt_+Ksb%UdKw$XJ&Yrs3&?QLR5yYQDQ#ROEZP zc*}qW5Gc@-64ZoIe!Wy|MoS>n&P54qYM+{HN}|ETORc^&;GY#yYP z6G-*7&vD(s!f)AUmc*gIAiw66#%7D!hMfVebZa5O7F3{L#jVkE8iO+&+`{hrCWEbI zhxzIv(U1|*Eqx{nXSSkR5wXC#t-O4{vz69SI$7;{eD^6q9tlmzef|lI}><36HY**FiMbdLz^UY1Iw6C3+^-kH=B=Xqa)`W z)wkT~pJ@8nq7*lTZspJl+@yHnUp9f^*%dF3l4D%5&XRbH{M3 zJ>}`z2Y?H~b&=$Vl-jWPA}ydxdg(t>R^@UQVhDHmGZ=boNM`i}q$(YtE`%65o=h@J}!c%bavQ_>v6d zbY%JoZ9;cP&Oy^!pF!Fv86t~F34fO##J8tjWnE0(lW{N60GoP_mj&;jn_&mHP&R=U zimyki70b$7Y60@h`w8GaH11EPLII~90Gj|53<7Q31zy%!rFDL ziM2nR1(WFe?0{im0wrrHJ2Qv`p-8VRD~39ouKDxMZ7Oj6s{`NY= z(he05%)?&8IB=yRoT~}Na(b)wKXju1{qmUzO~g9*m2CNkuJs<1()jg9cl0wMC%)N( z?xMFwYYRm>z8$+pv!OZ}tsEFViTASOYQl^KigSHU<{a`v&W07Y#T_}0Eau2_2{|l7 zF7-o=cmA~vEWd=&hmlt1ApY~;2~8MU`7T}FakY?d{&NgXFDm*2>9I4EgB#DH93Jm! zU`ES@*(OPHIM?)1TDPC}1V(fU@>;Bzfq|$qY3{|zedY+6_oxhAPk_5b{CXPhl_04zlExGRX;|<*Qx{b)xQ7x z?RH|(moC4!slwr3eeBU$?uKA^m`XI=^VVEdM`j{1j= z+xpyJ{{43OoEW;Rp?NEfdHR1h+W)!;+GbXBBxt1DTssf@tAD%Q>iKgtt!;d2ai%Wr z-vaCi=+Fly&NeKJ{P)`h=i&S|SOs4#IOTI%1RDGY1ROQ_pS|MQEB#-w`&UckqU{J4 zweaNsdw~CSBlPzO1$1-df0V!YCu{tx6MYuNXh7G1D{;>LZ3q9ls*i&%qL2Et^zZ0? zXw!8ulc6pCA&gh*KeYM#pHt*X+5AszL99%)OGFTuO~n4&3-kUN1=@y&U)aR|_0<3A z7onejeD?Kf+`oj|-)vQib{#Mtd&_?SC5Fj!po5C}fuZ+59p*1i{r~^|G78-geXha8 ze;a%6a0o=uQIAd2{FUrq`h~y76iFBlx*=5xs;+-K@4v5FeZYMYCik<8BKJQW_!au@ z0Hjd!Wc^RhrSZqPuqt=|ex$$o*JnI*L&{!$qWce?K>hlU_lvkI{iApKH&*yyx@PL-JuT$Nl>ABO;R)GZOU+S)Ou1$VM zp3{VSU50mik?sRecZhJd?PeEb%I{L$qJ{gZMWaytPAJ@g_qY$;;hioaPDm>4b;N#iW@p`Viy=6-V%+;#|$uasH1hEu5 zSpo@U*d2MnTNUp6N7|9a79nlnZjz^%&egF_rg?#S{?~=5n?=nXu8Q;wpVI0p4AH2E z>(X{wFWCP$=+3r};e7utzC0sIwMzNtq*AE{jUIUk2Mj z!CcQmSMJ86VRE+xd_(=0B^_hH-`QvmQ~_Q-hq?2 zOTdu%Krf>Gz!?8W_3 zXX6Yp-2X^$|GU%rMuom}t5m_}{j($umY-RT3|&byyFz0Z1-{fBI88F!sUgAwfR!H2AR&cPsWdLdpL$ zw8JCBwl&o%92P1-FQ%vh}iE-(Y{v|2By_Pd!`Zp@YS47+vAUM~+0l3H4@B*<=4 zuVGUyEygx&`ex1-<3cQaI^EYbK{3)_bzPf>Q*`G2HefTFGcbqcyYZ8{GN$9*k2B`( zMedtL>g;mTh_xB_aWBQT&b{3=<(du2;ykvTn&mj_A>098jlo!Pxx6#$HBECqHmj|l zqE#IXVu(?nC|AmCyV7dN0)Es@Q9fS+#V~F%lf~7u=GCyBLx(+&CjD*vwh9?bFnr|Y z%}o9=PLtf78aT+;`cUGT*VznOHI!*)0g7AWUnj^k*kT-V!rJVQjf0zMy|^~@NFNBp#?q4dn7We($hmH?OHL2UN4d=*VNKra9kq)TU?Fn} z$1>6f54ZP*In8IMyB2t`a~^Tz0UMR?#HW|yBkf?xzt~?+F&hQ z0;h+_4BJEodvlKnp&#T^(V=F6Cf65a#Cfu z`6Uh+%A(;I7e=?|Nx>Pd__`US=1j8{j4HXsC!C6umcCPBXIByP74#GEq8M>DN8k3zwu^it9(&8K8!6WFH9z|@7Q%` ziN+OpCKol4+j6INpB*TGrcJ5$87ma4lsRKY-8}_$P&>#ZlFnqg_4ixdt9zAEq00vE z4U4D}Jdg5@_XE0^A)}y9d-EzIfLk!JoEC(8W~D_#W<_Extz*WC3krSz;GrP+4rnBr zmc671^jZG4R==1(($R=8Pc$BHgN(wX^I-*oHt)zO}yj4@alZ)*SNh3zJI zkJ1Ft5{hgb?v@q=ue$C1wXd*x!v4}U42&K(h(ZsumGR1G%U-@}-u$F4brs)tC3E0L zXKxOS5Za!z(`k>fU$kR460{imM+`CwGj(eNQ#2n^Gul6mBbl zuU6M~HP6gVS@k}x67KzGZ$C9P$kJWAd4GZ`Ml|Vh`W63r*AN!|=p$grhV7b#cwLxN zkx)A~&lf+?&>Pht461?J4g4B{0Ct`RL%HozU1F|J;zn<_PkzOt)YWH~+92<@M$u?5 zZc{E>5EAo7me+?-L zq`g%(Vf#Ygyj1NZZ%+q=565R17;HysK5Y#*lWEdg z1RUm_oCa-C=GcP7ErE12$R)cm*9rkJ*xAR2_0ePnMX#C|7^9)Hk|m z)UDkhk$XFR?aN@qLUSr1+H7i$*b$tqq9q!L@Jf?n7K$N#9*;1 z5Rycv_o$!TOMn`XVBHRXi_+{vm&MYVX^9QXSWjkPi8U4^Pa1lp_05rKkaOhwtTY#0 zk*^(5<;O1Nxoi^WYmLP^jMS(Yg@insg%C|VnvM+a$|`uky*XWD>oB_cjTq82uG~VL*78A1WPsT6eh?gQr0%44aCr)}%(Q}l z4pVCE)sQJ&%N|5QWCb8SRSJ4PxSl1XcM~ z7!F*5I(Sky_|p46FJoi_MXN8Uwr)a-84Re=@D!%Lxkq)H6v*@KAf2_Vz(t=^l_(6R zsHJ9GkkRCNM050|1G@$e*KBFIlQ~Yob|17{EcCiR?!4$_D-DS-{;Bv1T&UcClR~qE zh80OG2*}2r`B`3L$;L+~a%FT){g?@ea2%l%&Tq4OcA`$L6uwRd<2bpP<(kwaed~I- z3n82ZAPcHkw~C@RKmgau9q3Zq)?IeJT5-$T&u=TCUCOcJ;B|seJ{uaJ!pO^;sIolH zgr<8pVmK`VL}f0A79IPQ%Ovi+wxCINj&tKSXK%PehV=xSaxdkP&)O$5+vO!H&Qi6R zoF-9@#rl(lJaPU|*vAMJzCFV}h$6O24*3Zxb~vblCjI8DTY0>k9Yj8gG=5TP96Ce9 zTMSQ^xloW;U58J$+_eRQ8XnMT*+z|9P_&p;AM9J_IdW>Ir^mu*Fomp%qc*@&HpVn* zgElSYJi4iL(C$w3Ap0RW_A5NVq*Z4X{)EIL)!*GAV7gPUQ*fqf2Nc4=7#q=GXGeuZ zSFQ%kPx4d=RI8Sw4B{^#5LZH2?yYS&VWQL-HeC!z?u~^&61xahqSL16)XZkbtR)f1 z(l^k5Z{^_VQ_^3b&%cp|E#L(kmACGfTA%i*7-8w#d7;TlF=#A&&8PE0hivf?)Rr6O zjHa0U7o?4IL2b(vwp&P}@a!2xnnOc)0AriaszqeuQCW;}nmIbppHES>ey&Izb*AXR zG(BGW5VTSo1>riWLLhHdKX&wL$q|r^3z_1@1pQ>)VPMK@+xkQ*r;N;JYc-~Cni`w* z&Shd!irRhvmSbtBO+_hnD<`QRpMC4{+L@eu&ZAmr+EEe0VDiIe=+&CZKD>K8D$8$uj$P+8VP zW{CI^elX}!DCj~qGv{2ajKI8gr1zIP3(Ai6g8*5B;l*I$sS$}FJ+rFL3+Dwh-@4|_ zI9ylGxCa0ZMCX+tn2-)y4Ki07h}T9bHKVqNvn#jcN_oEe$!<33SR;%XW#P>ay89PV z%=}+a+J_)sR)ST%YggnXQjq3)MRnYi#9Px8=L^K(Ail2kaul^p@ETtQUFoyf0G z-hYhgaXW^39rjr-opQcu4S|fNN2zO}>@wVHD0*hEB+4xV$D{%wC!2~}X_fjd#s$C) zleYekekk7&HzkDym^89hVpY_&^=_rjErxd-AkeWx8X?IV972!%bxabuI(b3KeKNaX zGh4lWYx-1a7%qLf%CPadOLXscvkqN?y(TC|$n`YfCs2s_syo+^{b7hNZ+SE9)OsnF z6FZxf{R@dVpfWbVPY;Y`s^NThCZxM$Y)W;2=Fd>Mg_y5YF<$h{2_ znW~O+pqX~-JYL$5l%VyjVS68S45PRWmPh zV1a5aAL&ewTHKx)_3=z{jdTD)p&79jn#%KixLaX9>QeT!E=^9o#+wCczKJI_;1+hZy|$}6UE2p5UZIox zD4YS6c(_401bzh(5^mjxesn}oVkuPL0<4y!dY*3p#lAb73O$JOj~DZ4xSSm29~$o? z0<#%^Ve06cbi`$bGrFHo@iO6sw!$2}@{+iMiI=S=s@2TKmpVPL;$Aw-F;pz9Ifp-$ zGT5u=P3w~{>2QAKIv|`oq^ln`zFo5!w7K4FeH50y1R)=oT`y|Hu4sDE+6YmCMGdbv z9c-1UkB|~sg!bM+^MVYUkC{+cO;i2l<&d643|88&l4Nu-jZ2eL$~$DXdwA_gTVJcEX!^_G@BMqnG!x+-F6hmK1L zoX|VywENv-Q*nXO#`Wm6c+2^3r|_xoy|>J+BNAHmc(54}ZA(9kXF9p@F55qS`1ESp znL=wzFb;ZyP7iF7NGt4THGxpTUMJn; zy~w*pR#B`OiHq_s0-VS&iaDW(drGOWDPb9+UIhXSI>G7+VR6k^>&Myj+q{CG%;M} z4vCWH%yv&TfX_y&y8}(dmKDQ74?9hx#lJQn{D4;jLet)&;>#%LFiLIcrs^2EQFNdW z{5*FzSn0%Bb|eDRrZWj&XJzY;MIIcHwW$e-kR>--fQB((y*m08eYKd2OsoSK)_B-V9jh zDW&0?LT~DT$d~Wsd@awdGW=epX5S2or!*W4FkN4s?5mH@j~B5z%B}YD(&8bCvge7< z&OQdY(yjy?gwE%Zps7FV<+bv2Ttr>|KQK^{5sk!~lCO{Q&3|3U1~l32beQ!I^Ck|j zZ`^7*tWX{YUQI_QPw(VDb~&7D{1?xH zwXL~t;^IwIXtkB7&L1p)Hc}wnp|Ei-kNsLoHXm3b*@M)PjCb}tyIdPIT-ompx^`K@ zx4LPjx;Jw?j99PbIPg#LZ947%f=?<#5QPOe=i<~F)*SEB(b|ZQB9$)!-gnROuHwKi zQSnfA0oC;=zw@13!^`wZ$!v?-8$0o{_-0?&t);U-9WH17TGze4Ww`6F3q}vL)^6N_ z#K^Ob3G*!X`)&t7@1ltADN@+`Y(Rq>e+stVCT1t~BRO41cPE0!IZnoh{zBx(^6bWE z9H*Wg=tJ?A?o6M)@mPq)L{}JELgb(vwLAXJre4E7*6F7u4eaf+q>eS{T8e2tmzRlu zM=3^rSSmL05?7Q?z3Oq&@Hj&!xIcUk;K8&JPWUs| z4^_9Ok}mfKT__^0znY$UTCw7%W4s{vm{qXr2~(tKlM-5oc2Wp2>B%WzwWfbGyoc^4 zI`;wvff};Vb!()ABFzRJ*)8Mva-gyQdZ{Ry_cZ$PpHi`&=x5sG*E0N+*JYKhZws*p z&KU6#BAFhi`rR1WM~vyQHzTFT5pQ%7Saxp~1qIFV`nnY-I&Qx>ER1`aXM!ISa&P1-Pd ztnylv59~enA(^JMm(f-iguUrH;5x@Pt6VkKFE*Fhg@9)%WF5ISJpfhrIB|>aGe~lh zXG#Ie1xy=jQbLl)E~2V`i-&$nxshl-zYfVNpP0vVTHjMPLM-0HB)kT#I9YUWPJK_Y zU1e?>;T+jx%@zdujQ2(uKde%U_fD($;#EE83l}FpH9Tywn5tE{Huqi(>CsS6+^t^n z{mpnk-Y=OZ-AtCRc6tTZKfQ?EdpE;s8DwRA0g}+1 z8xGGtqO`Z%8s3|Xfp$_HOK<(^f27FwQ4|s_9VIzC$Fl4|vKr0ghRS3IzCwx~bnW1F z`(JIxPet1#Ysi`6Wy^%M-yq1=W>~?wV?n1NJJ-(6*^kymk}6y^$8Fpu;rXY-F2jn&j6#X1qRNr#O?K(PSu^u9mMRl7IK^H4@J$7J_DDC3l zrxuVq$nZW!ZQ%v`hoT>}Vz}2Q4S)9dnNzv89G0JWj%Zs@uDq@4`h8d0-PHeV?EuAR zSgB8l@7IFC#5>En?ny$HByBL~7!`n_=E!FF(pnw`KQd4|?oTvGFN*A4KkNDEq`?U~ zg)E*f9EWy_%0T(f!ELt~)*Dd{iE6M9Vg}D|l0>lVI?~@rFjgi}PPB-SM(qx=Qmkw< zI<411fl@NCTj|pl4o%8SvZQ)%;6A&FgE!-2=gP#!m9tOqJ82a#in9#*H9OgYit)@Vbk-Q++dcxQ$URsskx*Y{O3&MNEA~q3 zH@2>_EI#)`o|`rAotV?Q+FJ%})MFA*&HX$L)s|am9>7)Gv;%v+uB~mkdRK)>KB_bs z|McYCeaF~sQOFOW=nAk&mk?cT;oww<`aahU=j6Q!5kH#M`D|OWcrP7QPxW|< zj?>J(MG4VgB{pOoYfAO~M%ytrzjE1QG{7S>XCwRgd_#TlkS5K-Hrf3+HYQR9+EN1v zX{$ao$&R^fT<8H7ZA3JgQwSiINi}EBn98TY%f!ljU!K#3di~V0o}ie~#PeLLl_8A4 z)-ND)4e&pttKJbDQ%zswKJmaLn_~{39aP6gT`fG>J@3{7MMCbpVVh&9bG%?Ie_y~! z@00T|V-g33I=8(uML>d%$1%mV5}uGLD{UdoP#p^mh0|&>kzTaN*cq#{&0eY`SN0gH z|E=SO^3oxlc#7SF0kd}f^5tRvjHAGLkKFG@Qan5v9~hACP9`(OBQ6t{`6|5Uf=awz zlc39xOp)Uhi8nQ7^^>qYMbdz2MyH45J9NnHh5l!;E-8DE1M>+523}_{qlBZwy^ZN+ zwlR|di)1X_YWq;;N?efV6nQqEa6L*2zjzbArChDhPdjgV4sE+quwJz5{DAcuaTxp6 zp~^FHo|cP*G;PId`~Dd!oS~}jZl5fA(#N68=Cf@udO zNtnjVuub`hUo^u>-wvPrC<46_{uQ^k(Ix+ez`$Z@@2o|$qYZc^F7qse>e6jCd{rFDqMfmMNgn?VHdi2tR9^i<96Rq zv|98DMh~XgDUQek?@fv~wRkk|ILc=Vq{5?~?R^V?D@88~$_c*{P>jy)ApV4@NgJrW z98pdYp{dmzc6JqLwe*eyOa5L8m0U2qPl$gKgWmEpoJb^{X`mWE`<^8FOt#+%Fk&$f zE5EtNRDhjQ_3Q>8^O?#n`mD;k?|s*}pUVGP1j|rLg|Q2p0sK&Ef$)`K*u6KNZ*RZQ z32p2uM^K)=xn}=%_&vmLN2KRe^}EZHR>?QNzfO=)6Ndfs$Nf0PKkuVOpa)CjV7L|D>T7l$;&aqgW$}T|0W_TG#kn=XdO5VlRJ?9k82h?xT9*Ou zlO&VAmlTg~(SQ+J@z#NfMW2?cC~Y*LM^VZAFw1Wi-c}sKIbeWrV(?n|{>v}CS0lyD zUGQ9LwvmYH?V^hACV$Cz$8MeY=E~@^gN*rSau+I+Z6T@7$ijTd3k|?GuB%b$Q1(nu z%9)L@2YKg5*|T=9Kt-N9HIEx#Z1NcRUd^x{@tx8QtsR3I1sgGU75<%Sth&@)Z)J#sUD<9`ZNo4&91?r z^Huq&{$n6kiLjd`fXXJjn*KtY*3iDb>U-OhJD(_L{N}@79qL<4lV3ByG6aEaH(0GG zh8O8vjUxfz+T&UGL*045tE?XCFGmS(Iwp9<>U`4LmLL1Ue8d$kK8Qu-D%HM2ZuS>< zSE)1r!^)LT2L@5PlJ$X4519-m+TyQr)3o%&GZcyP@7_{;XuX+Kt^cmGc~;Rjd6z$0 zyZtjDM(pv?2>f$xfhx7BmU#!ez6w81Ny%`HMCXK^W;*R7{X2`hj?3nY%#P{8#FFos zXl0zS+%>Fx)6i=(t91v&vzg+{UboNT<@@l(Y^a#(#Ty+vFVI5Z2n=b)$xD#UoG*P9t$4BK9|c zbg?lC#c8;%Vu!dmRQ7|7t^~o!<3uA zO0&*@S&PCZxr!8Z6N>S5UAHPDkKLSh@qmhsAv@{zrAPf|siBL8AD-_64(+C5)hG9x zQeE?lJ96jq?kv~`KS(4Yih-=HC6M>kX`0JU@s<~F&W*Br znI!ZWCGLXYOcg^fI-kUD_HJeCZnQ-S*s{kTaH>l^L`m}^!Pwwou5H+0VUJhkd&*@) zlyq=E9%0{rc#%)zUERR&mxsyaA+8_p;r`FkZie|)M*Tih6VZJph0ZpNHAW2Jn}_SN zy-NvOv_>`(w`Ou7udc?fRRsDNho?}tv!0X$uc;i#9Y=Oz?kAChXp}^r^CZ-gRMXFz4x1G=eFV8j|~t*aN(@v(YPV!SckzREX5WY7FWboO%#?NOvFgBiB>} z>~s<;w1_QCCJiM_RHQKs)g}396}ucP2)c`pLOaZcND;;b3Pf`vH1zTj5 zUSI%juUr^{t9G4x&vw{XL3`6`xF<d)A@*u#jaf zD+$e< z1{A7()G!h1mreVbq5%wSi=6I2MR{DC6jL8I7+vy~g|+cf zz-gte=jLrL{ISpJZ3e09#Fv>2CC|f2LQqKJToM+^(Ut9XX^1WNRB1MFQC%!Uqfn_ zLPb}4ij+hT>N;dyqnzcoBqRnj0q<|81BEsX4(5b!~U0)7dT+T1viXIfzIPTTU=W>{aJ^`M0 z{a8Fhk(~UX0n3fqxpye&N^6^dz=OW`AuBLr?aKK9-=@S+@lk`a)B=73ea%{xx-2t5 zz1~Cl5W!h3#@hX6c?`B^|Gk`?k@|0A0Bc_l7C257xvFa9Na&2^!vJa|D2%Kx8s-f1 z4Cc6AMN6HY@;G! z`5P{5J20i-?%eRGFXhOI>gPp1R+f3pc)EGlz-YncIKR@+Y^w7^wYYo}*^Ns7I5xjo zF&Q8BGIUqE5?ovQKnEoUJWa}x^Z9+SW`W-Gbr?h7R(RFzu}$}8G4N>XqUO#O+IF}D zev$LqahdV_Rg3M}tf!}odqG{X*vgEY(|z#AxGo6Y7!KkCrm`Q*mgPh-K2RJ3*+=Jx ziE&dWptq2goWo7FOL4C-<%BK`LmsHuWFln)97Kwqt)*Ok@m1-SW`U4~!8;#K%$6bF z&-EL`$(}D$4aRMAbT&D2Kn`&t5i)hmK(0U+6p^$P%jP!f^~1m5&g! zCOuhJii}a|Lg{M?Q0OFUJl6DX5csGBD9Pacje{T_+WNKRA$ZJzcnQ_S1-*0YkD?~B zrv5mekQb!da)6bIP9$kF)9j z@Vv$OTA5qH*v+$Q`+2{|!O1DdiIeDOX%*m?ZOj%i%bVI)L8e4w`LAP#cR_;*)M`tb zpDNyMhB{L{$WD)vrEO*C+^-J3oHU*r>@w)jwz=)vw!it@C@^v7i%;W+0YrEkv)gs* z)>>*-8qLVR6=5l@6+cbPekoG2)t>P|Ub4vxt?*tnbjy}QM~U91AbXSvY^KNG=}QD| zT1!3_KIiTm%wUAdc(^MeX4$j-iA9I+6}~~tsASck2rxWEuqjP zO!^gG8ZYu+w#N(AuT;KB=dapPo$!ji;l=i=Oee$kGijpKSE3wvX(MvzP8%xm^U-BY z@JrKq+=nJdIpS9AugX1HPjzNq(WQ^Q{0Lvn$!=b5Qu)R-*QqSB!}ImqHR&=^4|U~v z73rtrB>3%}8_P8ryE;3R_*%10aoO+f)4swwPV;~gs29Q0%pI2>(AqZWr>48yMOpm& zOleH-iIg10JsQeo1Ap8+d3=nTEH6k3mj&KLQ`##!J4>S*`us~8H5QzF;EmmrsH5IE z?a~8_1CTiylwh!^>|dMtDt1;gC0EUry%*KCQPB9&qcOyP@^&yS7qWUY#Ap|>5tqry zzwFka)4eyKCZQCTipj^W!0T4Vb-~C(%fMnEN)bg2XA**)$MQU!t_oK@Hay4-8u{}4#=h!CoxtZPv}78S4rKWxW(jCh zixGYR8v+#7tbbs(C*W_~kYX+c3Oi(P-*3y9Rj3K~0NgK+5;}c1xd9m!QSZRc!{bmG z;+D=?l{xI{rZreaaU#a-=N5 zS0RIgt}DDo8UNW6cm! z>qvbAHzV$d$&h~g%#NvZn4UP^KtASP9WI8^BYQlcpb)0Bq;_StAlv~}S|Q#e%-8lm zX)F3m`)AC&_;=8q9nK2VCd%NiOD$e1{fTtNa`|bBlZR2S3I?Sys{HksN#x&wLwO|v zM+H_DKbSu~e6W>$%+<|)HO|`yK&TO~@oi^$^suhd<@+Yw|F0Zaa4+TI@LQ1o`yWNG zOFw^I)n_A=*`$KGvVfe)$ci*$K`Jl06C`~i6Q!&C>&s;PvnUaQ$BQfn1K#5171|nD zy;^w&mGtv2)6>+#hT7z2lC3H;!Bc~!16VRu@xIgr93gm0mjdKMZd3A#FdR3PBc`P6(L~W_{Wj1zoh{KqqjnCBFCF zKz|PrEPA?Wd`>}l7uX42ly^KQy+i!?jQdE?`cc@sx9vaaIu}jP$jiQ01wdx>MFL)H zceo(iM=$`-H$a^^<&ce!%aF9;9qsJJTEOscR}PXJ9U$X%XO2w$u#`RIoj)<<)%sX6 z1W3OaH9VcRz%O<1);2p?Mw26;7zQ#KAqu>H*-x~)D$KGBSQ+M9-2mtojhCL|Fl%>r zNH^KN1~ti=h|fc%S(=VmGU|-t4^H|Ou+u0HT4#QzAF1|6pFC1jdfyiRUQD5#bAlpV zf8{r>-9QPiRO#Z0@Le_W{i=#bJ4cUbzuIx~uHjFda*a)Fw(8!6Q8#s(YVs#!wmO<7 zsakH8FqjD2NU*G0(n&3Td%xpK|GtX@V@^_c#XLyQVTX{HSVOl9MMru~az$E!XHD04 zy_wy4{Y2p@2jEy1XEL0x+zo4n|9e!(=Dl~ML$7UMdos#0tez&}9^xc4dOnjW| zFR{)fP-|0L!RoCr{1vaM#vvR;%`Ij0iw1Qnj76;qs$DiJ#| z8?k@s(!$~;XyDlga7f_}B(jfXOT6LfsqvlDV0e;DrC#OT^&=D^L@{{bFe zhd65f0K*y0#ms}2Y_p^Ow?}=kI?Z}wh8b+7fC-eOhy{iJ40^sQH~dJh0vso^#~h1@ zNXM*VM1C=o?bOci7Ff;p$}^KT6gVdCjNS}TGXm^NblOh3Gt}5DbPHg`=Kp`~y=7cf zYu_&}B_%DObR!|5gwioIh;(;J3rKefh%^Y&T|;*>w19#j-6;)2%nZ$0?q}c6z3+XF z`<(xq|EuTo;l-LIjB8!%TG#s4@3-PNy_B3g$5ga9cYaJzOl768bKUO1QNqJnE_R+6 zghm7!{E$YEDZdTYng3p#-<w_iuw!6&_(~JjG>EsBYP$p0;`WmGP{h{JL0F^7P zXvM76JQI@|HZf&VyO@ThD0IB}S%r*5L?yLMUd9Z(bqV~w{fK7V3TRuxc;KZL<9j!S zGb>b)MY5(6*fE>L`?}v526N&v5~(T=*6J{T$k5O5Q0fQ)U8Iw>~xA}un>4zW0i2tof}rcFK6eJW#m?7D^*U8=fhxSAnYD5|A0Jy;A74bEX64(**h=S zH6|{e#tADU)@|y@XpisQ#b^_|$+brXHE`y}@Xp9J4b#Xyj=q&&kRko4ZcgTe9lTmZ z9#^LsAzxm0r{KFOjN%)}pk-$zsOvg`IQqdIUIly0RMkvqyedPYVK z_|HYJ#ZR;u;-svf0fx1z$}B#;3Jq7|(4uU+x>9 zfEhwJlSsWM(@W~UVfBZ+_7R`0pNSO4+*4;v@2T1B>XAXNt_hM?jeO$-s^-v&&|cOW zTP>VH^O@)(z0}&2!lC6Xmwysz8-^c+T;1Gu;^R)rXp3sU2tB4&Cio8LbIY;>Wz#pC zX=4ffT;+`k+Gv+u+q363O}EC|qhdJVli=PJ*1;C9jVJWvohr+ZcKYg@!nOeK@KX^qo zDBQP^2;)Wc(OW^7FBjS}O4*7SPkZ~Xg>MTxl3m*(v|yzXwVO>-7o>9cJfh$@L!5z^ zDIQ7*lLm!Reuuu7Dm&tfU!fyhOhY~WgQ5(#?oj zcaLJzXOzYx;fYQp%Vi%^jd*1qq2`sKWeUZ@?v9@bSeRn{Wi+~|AXviw-D@KKBQPdM zo7Iyu%zUvJ541BzO z94kGR_s4!_%0u3V*7&Y*?Nu3wHL?oZL2Nc}?WZlaXKfoleN9?+-VP0a#IWVcF*3G$ ztC1$#kouG|6;0TK#vO%|1xdI%nELiZ*8!>_>`;C@ofS#f8_}^-D2%!^sm%y|QLS+~ zUeD-Gj|gJEToFjWIX@Wm|2A~*xrhk&pp%g>il~LJdD}}9-#Tcm^rr)rvlOTNlUVC1 zryqASCy#5cj<}I+GgUKW(rosK=am_u6DICqJ^IrsQj3xSjijIzU=fL4(AX-SI!9qKEQq_Q z%1rzWn}1vKqb5>P*o~&CU#*PXb=!>c%CVcj#$@mTTf|dbeIaiNY1kX4otlj}zO3e& zdI3RuG4tgbx|EA6lzxS0Nm~%Z3Ih>NBY!fV_AFmft*RP`;eM{brRf9juG40xgBp-l z0+yTTb#sFBP)n%)e42nAY30d#Q&@-OBAl1i9ilybB-U`vm_H~JOgU$2^{uVb{MN_} zHR5e+RC)=MAH{OuH#W=RuSUWCY?<%LQQ?`QUw`lkbC9m)tbt?5w+HdUkAyq3ww&$f zHAj>E{iqls;tMpvWK7K;Yu@h0)YyzLl)Ub&CplC?G0Op77@SR8MH5d zKk9_iz+cr_ot#HnX^ZDNVeh-2MjSb-K9#)aR-vh<9%zv3 z#fZZiL*UPLtA6xv%V=)AIUrbZyK{KX)Q`y$0X`m+Y4vQ?sJlFinoGSOw_oTXFP6sZ zDMXB<-^KGo&V>L|w5dW~u|#M`B|TwTH_Dz|b^+Vp!#mI(XWv#R>B(-uF;s?pUD%d7K+W_l{}hf_D+i_vah0>KY&@1^F7g)GsPOQ&=i~5 zyL`euM>S^eKUJ7fG`co4)Tef0possjJYLUVYyakWpNjz5WIiDvhM}Uzh%>jf{?b>Y zSW^amTzzoZ*x!tkskcg7d)6Ct^N8u>tv$2mYW z?bWn$O$Ff#<6gJ3;9@V6Bc|EQd1IFGimduwBp7+Wk7c>tlbO<@eDy(h0<<&Pn}NdG znV4!QHTk^X-MC3NV<{mc_`&VG_#2sdNo*!t>d_ZNyG3@RMz1$tHz++~E#l*FE>-|+ zior>!Z{tEmhR_qeewfx^=%~P1S2O_>1qF9638i`RWCPV^jmB%gspY_cxa-0FR*mk} zFhmx}s``#olNY+D}9p&B(?Siy6x zl(6Ig2zUtJuU|Fue^H!F7F9&aJ#*=4%pXjeNAn>k^DH04 zTc64F!6{dO0D!36$$1q_Mf@7|Ilh-5tH6y)o_K@C=tadE$7(5=_`mzytnECrT5Gh~ z1Uc{U>?UvVEz zWd)y0<>S+c8xL7zHbUM8*25!Xso)MM=liDT*6Rc@1hZ8q=Sqz8ig|Qf2WUZSAA+|~ zB{Ez>T7Y%ut9yFQD=%>IoIb1bj~O7@;-sa?78!~(gib{Oqa_X>&Bl^$bD>$7S_kD=*521l-#za__vV<9p2gObdzaS1GT}oGKZ@9i*>c@j!`b2TjFJ&# z{NeV|tKZ@}A;;27{4Kb{pWJ^~^Nab*DSazu2W8oSiJlH6hS@o!gmGz;b5X2Ot zQ+es3RV!QDd_l&cV7^mJu@$$wdw>YFGs+85&TBYcYNKT3y|*MQ$3n3wBo~s;7^3N) z3!=^ouljft#ic*WdNMNLT5!2ONcD|ki}~LMB%tIp0qhaY$DR3OxPTSXvi9D#%epB3 zL}!4Edf+{3QF{_f78hn{&BE)rQTItJS+ucJ{FWpA_9x-5!ib|CuY2d#sc$k84&L*S zMAM##inrLEh%rjHmk>_0)ZSLdHwAE0q*;t2#!w1E*p%8t?5c zF+$A4p)85Knr$GtNv*TESGibhpR>8xv11C#0=S%zu1HA;q3`d7EZVV-!xmtI0xV#c zUSC-=v9}T%%%HNoWCxGB{jNuDNYoLySq&@ca%<-;7{!PEQVhIwrNGN7Ud3KjxpxF4ng(clHi(&3PuH27% z8%oUJL_A+v3AaK9Cp48K>_nU>-}rk(DEI@kGvXW7v6i^=)<@!3%8g^?Qh;Q2#9veF)kcwtTne@KY)uIHgF$@gu7!bo3J#636&7a z3t2cJgDK7j*9|WHiPv|c2iX|RT{-&c!0SeP<~vB!nBH6PQD4oimg^KpMMsbj^= z8SyVrufJU8doI%wW(QEyQBg4<5qiiYkLp73_BLtay*mlx_*qmq%g_i)ftJTY*PT7_ zKF`axOuPv(qV8Q!OuLnoXmO`E`Ka0WkhbM^FI9d#VN<3Md>>pNbMvBck%)#Lp|7p* zF9+=pD~%I5P)ijev*A$?=x^OY-f_gD6>~5-A1>y9#$^|0#n~;n#w+BHET!HNU~U70 z;MB_-f8(d#BkC4F&HOLS4y{A|_zi{KD>d3EC#*-Fh$!l|ZoO6%v&{yz%6X&yqugej zE+q=vqq6)rC3cm@n4xRwR%;rq{!4iOaf1N&$Rp&+^nfFdxYA}FjG9PMM|Ss0BW{iB zj~l3K1;@#%2GW8a@8{#vm+C+bw<5iUefESjNQBVTd+ctvs!KbW*BN*7#M#38?NqTi zax{eaVx}q#h48cXS(3Lpy0;BOjDznO#Cr6AF$MnYzkk9*Pz_%qb#4^p)ghW&tuT@N zt(Si~Ukwpa>$)FklX_w>e2JBm_d6*cAQ$-~jnv1jQ#Q~q^vCGELfs!!&A{DRl)8GQ zP*g&`Kxs;e39>;Rk<*EL0ne}b_PJ@b>J<-V$tv`x++X||z^I`k4%B)D8Tb)NAedPk zYmTuyj z0AFc`8k-0k@wKofeP|BeWcvG%f~b%y^8=_osi=<<{~~7n=b`+vjaD=m#gOhad~4b` z|2;PUJxKrF2ux1BhjyKOd3?O~w-fqr^Xb1f3^kA+LX9Swhp*`VGTQ(CqJQo5D8YOU z@h_pK=FI$mK0plgz$TU-3aPmo8_?WNATI`a`w_zNR|5IB?a>dwL0d_k5Iz zX=B{{+CW@`$f7n16kK~65+RoOMAh@VdIWGWD0I1W;G?&^ii<{t{nj5eN$yG=hZi9V zHE!lsaWXN6g~MC*@qfK>|FR7t1WuZMFc|)m&o){=J59LBTkofP$(~a3+r}<)ae!AE zTvDf;wvxmc;8v|Q6UpkerEb_?M~IB>u2OF99^Z`Kq~BE%B_7?R^~%SqX8Fl2TRLBz zG;g`Fu$&~vBY$gANPII!G2(Oq<vVg7HYGy6m-I3li3nbQ;K`H_Oz4BKRLr^Q5s+bA8^= z;(ZlFC4!OT+Dr8d=(EDp@|9caj1-z(xvwS62bHDe(;x0^>_<-mLO|7)7yX#&xqSMD zHKSLV$EDCknmg%o6Xu2#2{d7gg*KvgBY_BPWgB_#9u1#?)~|BUwr%X{-HQVwI1I~3fOYeyFT#Vm#d_n zrDU1WQ^9hkfwj^jjR!D&AZE#mf0kg$nV&Tp$+|*MDsegPy0H+=>uj?8^R0`e%x`Y1 zz#@7vBvDkqF|)p;GTv0V7Q%Xl(wG>B=2sUMMgn#8A%+CrPu#}URV$`Fe8-cF++rbW zVf1k1%(2-azuU-Oxliy=5~xy$fWyVyV6Z&sR*r*m;r1hj&<&SUd{F{$$Z_T`BX_%~ zg#QR=p4zO`WJPHt@b4JCQF+X-dH~i58q5lIVg7;y8y(hm=Jip2mWY{Y?5Towjr`P0 zwp3!1*H95P5D`)D@|kVL!e`av+uv@k|N6+ui-dLVKxI_c%firF(O*o&NZTMLh@7(U?fR?#7q3?|BnM z`J+sXqLc+!hbhH31BWCK6$FU>cxJeOZkf4l*tw^BXd@bRcjdXq@CJ3fh_5_#t- z?cu*xG)zZ|aD<(Y2$cuKSg~~_XIHMT-gujk6jVDi1bQt8Q7t6zS;g!j?#sQcK0#uq zTEe@yI^{tY8427%ySv@9iXNUMx>~&D*iNgxQ&~8sj4D`iRa9IOqRwWzipDrGFy@79 z_6Wl2(>UH})%A$o=vnT5CpjXz#XO)=qW1gUk|jh5TsJ;H{C=7crlITJG)jqW7RHgo zw2R0EoHjdK$~H`=_BUbTgvt?S_zM}s%^9{9dyc`q8BZKywxvZe&Rs-Ha-?b{?7b8y zEX{Fv%dg*{e?RM9>T z>C~?vClN^VzwPEZJ&(9W)AQwssQu|~9bCLf!x$~`26zoJm%2hG7xuY)>{s3P&n<|4 zj_H`lm+hV<``0cZBu@-DUcsJbpWM%9S04$ibZG@L*EBN8uiVQteSbVGFVnQFd;LjX zuG|daxcGh0J%;0M>te22+v=g5MpKY^<>b(b^8hWzmoQT0xIBehxUTuru^n=`6qe*e z!A`v!e6)k>Z!Pje*A}RzZ7$7DxA}IL)r}_!qMJUlu|>45aUXDD+T6&r&Bkel@eH=& zwn^Az8O!yr_--fk8pARG6GjJ>hy%a#Sh!~>3{V7Kd?Y=CcBC(M=pHV&9KLpR8-iU< zipNUdw5J8uRLMyG=v`-K@^GH;m3fv3-Z~jsY4tTwx&{!4fzpCOETiud`~@y(r*rLZHJu z#0Cq@yN@;nXrrH^#ZpWumQu4bPLLJ+B zrx19Zl;r-~1zJ(sIFr)j6jJXPgm=H+Phb;A9F`1r^56!EFd2Qqdt-LATNR}tHM`d^ z*_mXiO0aH{i*|vrpfva50fh2*&z`pg;SqTYE=)8zt|TfV6+`P3H9V7N5;x z-SaG#lTWb=j&AYb0r>9rc_izzN0{8Shuty)(&^_dEFj@KTr&+$^+!b z`?ArMsVrL2`=2I4*=$z#A?eHYV%TGy=Q2j%aC1?{mA==X9(74@<}XXh-@rE;G4yt zsl;GsUMwBjVP^6t_6?qhAC$S!VLj$!f1(w0 zlswrZs5_9Z^^iiZ0@cUWD2EsnZnk;9S5*y4!EIfmSDqRG`|^VX6kt_8rvEI-ahoQk zhvUsrrzqR}=clUzQaKI23{p$+Ua)~{4p)6U`~6_L2p1>f@|dJ2Ky?G#mRtE`!o#LJ zAxB?3DQm~;RhO5YR>AGyCFy5xW*Utr!`j7S-**ZywZs=sQdny^>nw~`uyi$u07;2j zrs=OCq#=l_M#q`3u}^&7ca(dCpB)_^N;1kv=iVmg*cr4t_mLxY&Y(+{YcN$+&jG1f z!XbXl4ndZrs%Q+?=Ml$cXxHx;ZJsoAC0L*PIjS#PTr+LwY6hE^et(@sebtoQ$9lO; zMI3`VowD6+KGi)+rpp!x6|tyX?7z%hdQpUW9hixBy+ZV1MKB1#Wq(XIwSg49%8wFJ z$+AJN`kVD4&`OeK9P2!shVx>ukwgjuA;^T2eA+s#=c?R_6q(GvOPxp@Ja0W}<8Ee( zb`NB&w!)1=JDzqjL3Q4cAofHlozbY6;QS@|yV#GLiIX2#tr{!izYTTtH2=zhp0Ez% zJ=FFoqZnUmj_B!VL>B2?dnOz-D^{g{u0!95>1dkRhSU(wR3=m$TIZOMLq+ppJC_&MaL zb7M?f>pk}-<|uKJD+EW8!y22B*W}&1Sp(&$9#Y{uF<{hUcXJLiYn59cW#(%yk_c@Rmedi=fSMt zdSQq?2hjRT5uXO$msOU%1IoSLF7&%Zo!sZ;;!b`=VBCxx7rqzD<~#kncy=i#U=0uw zImynls2cSgGZQ-me@dv(IM>E6xy3R$>;H(yfSscOV);OTB0?``6cwEu^IYucVoS!N z#CgWMjungV&mth!ao&;!Q*l(`5Ft=|YDf`)fH$3-Asj2z|5bwoh!uE9or(x*jg#?@ zmsDFUUAPi0t?^0`Be(MJL`rhO?uxhl21MWyJtR@JK55Nf?%XzImenx>xzyTl#(e5@ zewEqbYX@F1(CNdtT0?43(l{)1q&;nVBQv#ETvZoDMBiM}N=!6G^NPF*NRPy-NP*0V z16Z!C*top|t+?mwun(T=R7_7`MR2lv)9C9#F3|)6IVuE&(Bc-uq5U?2Xp2UOp%e5> z!2GM98eJaXENn26@CSv_3y?F`ZP}yxw2wc3a}Hxg)cde6B}J%Zzuv2rI^OuwRt)iClkrfg6)H(`9B zIY?8@*DslC&*0ndr@iF*Alm2ttWCqaFP+dbCU9Bg*8RV;@IND60U%u@>QSn0QbGvb zV4iRnJ-f-jst$J9R7;252}SKcy`J}^Uy;PfI8~{CJy64673m|3MOHY7ekEozKab%< zpX+7T8mND7DLi-y$e3OH;$lCN!rHvOhM&y}_{C0QjKRWd5b9708tLx5MF*L+3gO%t zg3yn|=rHw`-V$s+mL)rXL(C6czI@R5FA@1e03 zp-%+Y8G9Lsc4BB84{?H}3Cqt#>^)HO>C3h#2>-8^jdvDWjul|f)gu5hF1`OjU^W4 zo(Mc#u^~C+v5WkrYW;+{m=ikp_|kn(41mR2SJpJdT@#xMWL6s}iZ+@>k^FEp5U{QH zog(*WteLc<-I1Sqhi_>jQ)|^9lY>>=lv&2BTa37|_qC4n=C5|f@MxKOc%gwjKh=e4 zckFkhh3R6#i3+HptP#(*;w0>^b|b2QL(I_B@Mv*Rh5=Vnb|U?YXpCV2{?s6^@)leZ zq6|m_N#rPO6o>Z>Pk8bx21?`B!ImY&_@@+eee&rN?R)i%7J<)j2~OeC;&@a~ytA3S zh(EMb&1*}AEcZXKSsV7a$)oDz)viVrWG49?0NDCPyoshKhKK~x4e&5W#qUwV|^<$hcVulot8U8)1m#y|m z^FLM$!MHbCh~_58$TI35i}r%v7G0XcN%!wDh);=r5uHX z@Y50@Vt@fo4&aA6lHSE}(s^f0%`q=4s^-uVJ~+DBV$PUf8_Zt#oy6rq1;A+U>{K3a zT4Ix%X!s?c64gR8qrxR$E$Si}{m)&DHwT;L*VPATbk<|I!3=T@K`ob_nCBwgW(t#> zcVk;(`4`oj&-asa8ck}6CYim8F_nS)k=EFXeOWAqvdSdKF6&YH#t%Q!1%EeQf*_zf z4&T!;5=!{`$UJar5zjV1tz~pfEpk$8Vw!fs(rHML-_YIpILnu3Luw_(H+(LZ)?Goc zn%nZtslFdAOSc0ea>fYZ(bJzY0=tWKQqd?3IH3c=4R=OpWj~V23Wz>;j}IgQK#Xmy zId8UJ}G^CWR$&f9ijMRCu zVm)WO{G%7e=iH20d5`Pm`r#5VSBS2*l1!=n3c|$vLKuyB+&>rhh_IglS_*=oyZ+*IG7o=Jgv~ym3GhzzS22kf3fN5xZEuIty^uVH3Yxb zIhsqbqSx&N0_+r;$?1y?s*KaOI$IH3Hy3jMp??4S$qDrVWJtVFPN964siSOrp6?S> zp?bgKak9P)Y{JbBnbEIb#Wm*FJhA5JI40D|I|9fjVGXGuMthZnc()qElW#ZDRo`3k zmDRv_eE2svD~I-B0$Y^N!f=}D5eq*Bv@G{Pem-_(#lV?}ZGAPY z`knGTr?`E<4HPNVja+oEFsy^;NuS2aqZDboNkX}of%=o0x|cae%obfWx^4WX&*h37>ccPhx_`!pql3vILvKhLAHwNcf%M~O^`(6p!D}3zEQazUUw958t5@n`l(fY=+${U z;LfnUisGW9ntvlER~S#1x8hx8zxKM>$0K=3Iq_xVMj4`_gGqg*RltbRt$|eg-9?|W zorVRFO;jajtvqs_tXhe9NYN|2*j#AmZ0BZBRng^$iN)UDaLe~4H63EEj%Bf$D1nKn z3Xup*n*Pw$MZ_}0kC|5OYuER{!t*pi$jiskI7qHUomHONq9=t)a|w^3Ps$J-`m)(A zdjIZ-KWwW+5ceNXrVn_-;VF>1|b107gn{oNY+$W5P8pb!zHbuqgla zcQuYDSD)A?({{qG!-A>YNZ#45Ox5)AG|u~^2y7{1L{*RE>fs{N+vaD=|cJCg|$glU$T2lO82J;7$`>c5G>xt)De#7E3ArLnpszLlzQ2RsO zo|V*5o?lPOXdNUhKb~nVD{E^xkYgHy_s_07JKrF`>@Y2) z>7Gpls!L@@?jL+}D9(a-q4i0S`G2+C)f*H zXRo_2vJ1bpBwvpCChDIfWv8}v_}n_0PWAO{>kPBrcigc({5umgm#w)3VtOYvi-+3x zW|>JBqHK2^420+vuIjm3yRvLtWg2wL&)mOyQnYavHL`2KpP3mXKuZ0*`hs;2)|8IT z<&tvjga=iM%7+o;W~NfIkoRaqBRkZj-sEM8#~MV2RURM6gj?p1u$XYFO7As`X#d;1 z_)mk%kp0)i={gk);h-A_w0m_D5*bNYs{j3>vlpnjKTL>Fz%gk<%Zs1|?|tY4T$-U5 z4jGD`^@Oal5DnHWuUY%c2f%#b{40&+N6hbM=agFXg6NYa~?$$G1v2)&L5%g_%q z>DzbuxU?;0R<`VW$#Uq*X6<&ceg{kvIedp6T^d9BG0v2A%2sC|qmVYU!wRAXp(;hM zY)!HS^#lxf1eyCmmIkF=;u_n1k7X`#lDH%6+@D0n%VY~z<$z&iuOZtlsQJ+t83pW@ z=vCQKw8NmemN+MX-HAsqc%XB<_2S=;qW>;&1UB$LW4wmMC@QBR$aXMkmXYads&j+> zns@rofs$S6V*+fvK0lE*f!{#B|MJ}eW#t2q{TO_qZGV`k|E>G|eIt-G4RFp#uP&gw zzq>g9wV#d!kdfogx=tJZFSelFFI#Ybs|QT~F9-1N|K}h3!}9^;Br}daI?wcvzvof? z%Ra2m!mEt_NBfW_{+FdLM=j)-_K&~!|6u@sNgg78)xDkaW`G?188uUYLXKMW|MvY- zjQG}Q*WCvlu^XNr6pSIXIxo-KNnsbzmjBxT2g_JKm&?=HVp++CPk(ztEhzRFgyw0`@b-560N^N;uDq4jk)F;vlIRt zc!V9!v&3@dWg9Yt+yL#E250ZkVI1n55YKD1s7|+Lan~_`&aH| z3oY;91tufdjK80&9)75XtVp7oYY*cMFo#)Ak|qew?hnt}vsnzE2M!T3e^GC~0rmP# znmn)H_IKDKo8@V!oOc5l$?jz~I)btvbSD!-WxYq)NJ*_Ft#Xhn9ZAxLklk4Im5HS4 zJeOmzj+Ow7fMR_?Cz|}6UVaA&xmb}uOyr8JmmFHk`^o5yj_+q=s6P@)0mfO`WdWh0 z$ASz0P5!|&JoE12_0eNR?5Yv)KgpT-l}>9 zF^-B6;LASEX(~n=b=Tzq9yW|6{B6$t#cim*qLvjB^#PH^Ab8YY$q7ZY@`EWUvyN^= z)|AoVVp~P#m>=x%b~PB*wkTxVra-I1V*v=P*I*t^#KpOsN1MB)mZ=#gt;7H z)Js;QTY70o*i5^&)XtV~Yc0b_ys~L;bkV%z*YCafyZIl z6&LIrl+V8(%t1NBv?uLek1Nijobs}2H2h_MI3=;%L%{Dn5hUg14E$$2W zNEnAvw;KiZ;wG@a32~uLM}$$N3wGti)aQkq0-nFzki@3`rLO%%f2O}*Y@R~VJopS~ z^x$M4ZmO(TRw|j6M*3Ty;mHFE?NCcU)E+9)t*=f+Qs2t#5Q(n*TRcUjn49|-qJsfzQ8*_SBOXbsnmJy6v z(T8!o%kP}6L!WHh^xSG>Zg7{Gy~rXsD<2vlf6;IpmWewhToS21j%j>gA5(s=g&&nE zlYbrmDFG4L)V`Eu~l@@SRKR3B=|L&hH=Kfm$CR*eokWtlFB+ z9k(4dB2I+d8XNEk-c=%Qf~X8Fsk*!}s->}7;RwRC=bylwFZUW7sd#!f00C)m((Fpz z+>=mFudPM?Q>rd?Sa@gg7CCMLCcdeOo?6R1-WsWBbG`pgKj_^tAl!O*KlhcEqEUV};Wt-%AYr$3cQNFFH1V1@TZUbQ_1tVL{*id)Tn zez};aJ>7F1$>9#P>BM$7@<3tS54EvTgP{wKKE+RMeXdRQOgmdAak}F64Gc7Kj2C_- zEG9ySh96tlzH?sm!F=!{AMGIVVpz7LFrz-!e{b!v&Riv0svcSb!(;~*JUGntL1r9_ z_QmU}$*uSowtfboA(gFnxH^!q^N!7FBxjR568q*vaF=%~_I+*GBs%Vt6!(O;X7v$B z!9%p!EfZko7hN4DJq4rkmT{b=xGLhBfMe8)S=r(ezJdYe-)e9DBhFQu@XeJ|1{832JkKb&w? z1u*{^2ej@hlNfgzgEQl6#B}V2fQCGY8Y3R<_ID_89r0daro9oBV66w9S`}c5`-SRM zLf>k%o%!!;8Yf;|YqbXRAasSL=w zAW*IDO(e!SKtg32<|{`r&cp8;@nzQ!GX%6hZ7^e2V%+qKnx1^*f~Y$>YdEC_fzu{Y zWrHHaoz>+1o~aU=f2ja+`+l%<5nscP?pH&e#GZbyk8Ewpe+=%N0&B&2bDn={Zc@@r z2E;2``zgK@Bb;|o_wMTZWJS^Cv5vbCHvsh7dEptTsqym#!s*qE_-5@(<(_#d5;{q)ayvF`!$ZF-EYw%^tW zB{m>w?d!;hftn$Hu+k(LuSBTqft0;exhihQ*f*i|Fklz!m?{2hl7XEn#WUe*xG zgibf|#TYlB%R^jxqw1X~W#;FbHn_bz;Qj9rSR9pzwY{&xv!!UYkF|D0y^g$U_;Sg; zs8kQrvH0@N!v3KQF6X5Ja~LnWP4okjaZc(b7TZpo2AyXE`&n*jSpsV(@E!7M3lKR}S?c|Zs2Dk29T_~Dd$w(fI17v%i z7N$vodi`orSlWkFeb7=(FzochcyDaHP!qS$^Sr~_vJ~HhT}41H>8wR?%4;yc}9=xtujP(ufn>c zYtK-q8JpFRc+%Z!*W$dUF#kVL8AIP+fWdJfOV_i}N=;7Nj7iZ(qbK!eY>nj0mNQ4T z)nZrZvGj3FVsZLQ|A?n5h zh3cru=%F$jZdERwRq)CN-uO8(n;hu; z!m{k$=Fk9;K34G^^B;`8%B{eaKWFq!+r_-+U1V3U7wNxgyhr9yTX|8Ka8tE}3l6C4 zh7|ONHw%zaAW&PWl~ty{5C?4g&-DFL%>~@+D=n?D$(7f9(l>VU?MAa)ujnI-hL-$; znIDuPO}xLk{nZfSmmEz!HIF%NrIvX~S_UeEC*dAyuX_!b4q_&tPU%4SN3k@yhc6pH z>5(e8rV};D11%OHIkZO9$da&}2tejjI!&sek`I4}cVUE?c9R3G(yjSI5qVmU_d zF5l#%)7I3F;U!=t!UgAcKaFNQRXrt>(~wC<=GB z@6&lJ-3xRTV7SyCRF>J@C@$iE>Li+aZXw#HjIt6$xkIJ zvR+czE9xwOBNp17CR-YQ5#gOf(e0k9!&&YfTcDHZcb;jANdL3?S7(vy*j_vjK_zK~ zjHxk+yU%pFMgXK|eo#De+5CAOkSS2(;O8Nm-!pfX^%CgE%=!t+3c04kP7eV9R0Bee z0X)gltyFD1ceeqX+3QnM%QrXHq)-*7ofWr?d=erq%!v=^GlZYpPz(L*wmVeq&)FBL zJuzvnds4&xL5>PQ6WI;Bb-@zD{yR67d7+oU=2UkUj{&x+Sk_Q@7ZY3Pca@Tb_WxnZK zV?8uLA1<@W&ryp%I@Bb5t11O{0WH`%*gF6RTl@1G%NY2jVc}H_E|@~G{f3AR29Tt( zQn~|l*_w2za^Ec+j4OD4Z&M|j!JaMcq64-0z%GnUK(WZ$PlocIEX5k%P=xI^gdqFdi=_Ln2#hSWP^yJ&&bBYTzHy&=I&A6A z@;SW;SHvGPJX=HpfVBuZ61gG=^-@8?R_1I=_k$8q+7bHd%G&T4VtkoTia;8MS*}1_ zjh+0l{(5ev;~OOET=&VG=Vvc6L2p00yxZXkn|!bxJ0n`zHsw^@)4tYRNj@uOu=lFk z`)H4-ShNWb5PBEii-Q3+29`%&g**`+Mt2*iHtn!aE*Sa8E zV^9Y7`K0f`H&31Q8S`8lrmAtelzvZ_kO<$>K!<=9jIDl^L|JqKRDMts7T~G!s%Y0_ z=kn`3oedQUJN|$p3&DARGZ8J;ksoIK_LmE6*2iV4b&L)l-Vw4n$!E;K3r~_dOXwiN z7rWjq=QDC@)_U1`thzwI)6*QU+BDmK2FT?46$Qvyc}uKat^#|Ws?0QiGTKPOLMFd# z#W7Q~{dZUy1IK1jLFK$qE@*Dj7t literal 0 HcmV?d00001 diff --git a/modules/concepts/img/new-ws-resource.png b/modules/concepts/img/new-ws-resource.png new file mode 100644 index 0000000000000000000000000000000000000000..39ec48cee33bba839dec713da8b381a18b0e7ee6 GIT binary patch literal 46787 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 literal 0 HcmV?d00001 diff --git a/modules/concepts/webservice/_index.md b/modules/concepts/webservice/_index.md index 0d1680a680..05c08aa77c 100644 --- a/modules/concepts/webservice/_index.md +++ b/modules/concepts/webservice/_index.md @@ -14,13 +14,10 @@ Since 1.7 version, developers can extend the resources available through the Pre The following example is about an entity that can manage blog articles, the folder where you create your Entity is not relevant. -PS: Remember to create the respective table(s) in the database, usually created during the module installation. Don't forget to set your [composer.json](#composer-configuration-to-use-namespaces-in-your-objectmodel-entity) correctly to use namespaces and autoload of your classes in the PrestaShop environment. +PS: Remember to create the respective table(s) in the database, usually created during the module installation. ```php 'id_article', 'multilang' => true, 'fields' => array( - 'title' => array('type' => self::TYPE_STRING, 'validate' => 'isCleanHtml', 'required' => true, 'size' => 255), 'type' => array('type' => self::TYPE_STRING, 'validate' => 'isCleanHtml', 'required' => true, 'size' => 255), + 'date_add' => ['type' => self::TYPE_DATE, 'validate' => 'isDate'], + 'date_upd' => ['type' => self::TYPE_DATE, 'validate' => 'isDate'], // Lang fields + 'title' => array('type' => self::TYPE_STRING, 'validate' => 'isCleanHtml', 'required' => true, 'size' => 255), 'content' => array('type' => self::TYPE_HTML, 'lang' => true, 'validate' => 'isCleanHtml', 'size' => 4000), 'meta_title' => array('type' => self::TYPE_STRING, 'lang' => true, 'validate' => 'isCleanHtml', 'size' => 255) ) @@ -83,41 +82,110 @@ public function hookAddWebserviceResources($params) { return [ 'articles' => array( - 'description' => 'Blog articles', - 'class' => 'Acme\MyModule\Models\Article', - 'forbidden_method' => array('DELETE') // optional + 'description' => 'Blog articles', // The description for who access to this resource through WS + 'class' => 'Article', // The classname of your Entity + 'forbidden_method' => array('DELETE') // optional if you want to forbid some methods ) ]; } ``` -### Composer configuration to use namespaces in your ObjectModel entity - -To correctly load your class (Entity) you need to configure correctly your composer.json +### Load your entity +Don't forget to include the class file of your entity (i.e. Article.php) at the top of your main module file. The following is an example of a correct configuration to load your entities in whatever folder you want. ```php -// modules/yourmodule/composer.json +include_once dirname(__FILE__).'/src/Entity/Article.php'; ``` -```json + +### Complete example of a main module file + +```php +name = 'wsarticle'; + $this->tab = 'front_office_features'; + $this->version = '1.0.0'; + $this->author = 'PrestaShop'; + $this->need_instance = 0; + $this->secure_key = Tools::encrypt($this->name); + $this->bootstrap = true; + + parent::__construct(); + + $this->displayName = $this->getTranslator()->trans('Extend WS demo module', array(), 'Modules.Wsarticle.Admin'); + } + + public function install() + { + return parent::install() && + $this->installDB() && // Create tables in the DB + $this->registerHook('addWebserviceResources'); // Register the module to the hook + } + + public function installDB() + { + $sql = 'CREATE TABLE IF NOT EXISTS `'._DB_PREFIX_.Article::$definition['table'].'` ( + `id_article` int(10) unsigned NOT NULL AUTO_INCREMENT, + `type` varchar(255), + `date_add` datetime NOT NULL, + `date_upd` datetime NOT NULL, + PRIMARY KEY (`id_article`) + ) ENGINE='._MYSQL_ENGINE_.' DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci'; + + $sql_lang = 'CREATE TABLE IF NOT EXISTS `'._DB_PREFIX_.Article::$definition['table'].'_lang` ( + `id_article` int(10) unsigned NOT NULL, + `id_lang` int(10) unsigned NOT NULL, + `title` varchar(255), + `content` text NOT NULL, + `meta-title` varchar(255) NOT NULL, + PRIMARY KEY (`id_article`, `id_lang`) + ) ENGINE='._MYSQL_ENGINE_.' DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci'; + + if (Db::getInstance()->execute($sql) && Db::getInstance()->execute($sql_lang)) { + return true; } - }, - "type" : "prestashop-module" + + return false; + } + + public function hookAddWebserviceResources($params) + { + return [ + 'articles' => array( + 'description' => 'Blog articles', // The description for who access to this resource through WS + 'class' => 'Article', // The classname of your Entity + 'forbidden_method' => array('DELETE') // optional if you want to forbid some methods + ) + ]; + } } ``` -Don't forget to load the `autoload.php` in your module -```php -// modules/yourmodule/mymodule.php -}} + +And will be accessible through your api url, plus the name that you've decided in `objectsNodeName`, for instance: + +`https://mywebsite.shop/api/articles` + +will give you something similar(in browser): + +{{< figure src="../img/empty-articles.png" title="Webservice articles list (empty)" >}} + +And something similar when you have articles in database: + +{{< figure src="../img/articles-list.png" title="Webservice articles list (one article)" >}} From 76d436b77268a907a733c92aadbbcab0c9b99c54 Mon Sep 17 00:00:00 2001 From: Krystian Podemski Date: Wed, 28 Sep 2022 22:41:02 +0200 Subject: [PATCH 117/310] Apply suggestions from code review --- modules/concepts/webservice/_index.md | 58 +++++++++++++-------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/modules/concepts/webservice/_index.md b/modules/concepts/webservice/_index.md index 05c08aa77c..57b752b4a0 100644 --- a/modules/concepts/webservice/_index.md +++ b/modules/concepts/webservice/_index.md @@ -45,16 +45,16 @@ class Article extends ObjectModel ) ); - protected $webserviceParameters = array( - 'objectNodeName' => 'article', - 'objectsNodeName' => 'articles', - 'fields' => array( - 'title' => array('required' => true), - 'type' => array('required' => true), - 'content' => array(), - 'meta_title' => array(), - ) - ); + protected $webserviceParameters = array( + 'objectNodeName' => 'article', + 'objectsNodeName' => 'articles', + 'fields' => array( + 'title' => array('required' => true), + 'type' => array('required' => true), + 'content' => array(), + 'meta_title' => array(), + ) + ); } ``` @@ -75,27 +75,27 @@ The parameter to set which fields to expose through the webservice and settings 'fields' => array() ``` -### Register it through the addWebserviceResources hook -The hook `addWebserviceResources` must be registered by your module, usually done during the module installation. +### Registration with a hook +The hook `addWebserviceResources` must be registered and implemented by your module. ```php public function hookAddWebserviceResources($params) { - return [ - 'articles' => array( - 'description' => 'Blog articles', // The description for who access to this resource through WS - 'class' => 'Article', // The classname of your Entity - 'forbidden_method' => array('DELETE') // optional if you want to forbid some methods - ) - ]; + return [ + 'articles' => [ + 'description' => 'Blog articles', // The description for those who access to this resource through WS + 'class' => 'Article', // The classname of your Entity + 'forbidden_method' => array('DELETE') // Optional, if you want to forbid some methods + ] + ]; } ``` ### Load your entity Don't forget to include the class file of your entity (i.e. Article.php) at the top of your main module file. -The following is an example of a correct configuration to load your entities in whatever folder you want. +The following is an example of a correct configuration to load your example entity to your module. ```php -include_once dirname(__FILE__).'/src/Entity/Article.php'; +include_once _PS_MODULE_DIR_ . 'wsarticle/src/Entity/Article.php'; ``` ### Complete example of a main module file @@ -107,7 +107,7 @@ if (!defined('_PS_VERSION_')) { exit; } -include_once dirname(__FILE__).'/src/Entity/Article.php'; +include_once _PS_MODULE_DIR_ . 'wsarticle/src/Entity/Article.php'; class WsArticle extends Module { @@ -148,7 +148,7 @@ class WsArticle extends Module `id_lang` int(10) unsigned NOT NULL, `title` varchar(255), `content` text NOT NULL, - `meta-title` varchar(255) NOT NULL, + `meta_title` varchar(255) NOT NULL, PRIMARY KEY (`id_article`, `id_lang`) ) ENGINE='._MYSQL_ENGINE_.' DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci'; @@ -163,9 +163,9 @@ class WsArticle extends Module { return [ 'articles' => array( - 'description' => 'Blog articles', // The description for who access to this resource through WS + 'description' => 'Blog articles', // The description for those who access to this resource through WS 'class' => 'Article', // The classname of your Entity - 'forbidden_method' => array('DELETE') // optional if you want to forbid some methods + 'forbidden_method' => array('DELETE') // Optional, if you want to forbid some methods ) ]; } @@ -174,18 +174,18 @@ class WsArticle extends Module ### Final notes -Following the example above, the new resource will be available in the webservices resources list: +Following the example above, the new resource will be available in the webservice resources list: {{< figure src="../img/new-ws-resource.png" title="New Webservice resource" >}} -And will be accessible through your api url, plus the name that you've decided in `objectsNodeName`, for instance: +This new resource will be accessible through your API endpoint behind the name that you set in `objectsNodeName`, for instance: `https://mywebsite.shop/api/articles` -will give you something similar(in browser): +will return something similar to what you can see on the screenshot below (it is the XML response previewed in the browser): {{< figure src="../img/empty-articles.png" title="Webservice articles list (empty)" >}} -And something similar when you have articles in database: +And something like on the next screenshot, if you have articles in the database: {{< figure src="../img/articles-list.png" title="Webservice articles list (one article)" >}} From 6039070016557d3c814a47be56dbaeb0bd0de632 Mon Sep 17 00:00:00 2001 From: Thomas Nares Date: Fri, 14 Oct 2022 10:15:46 +0200 Subject: [PATCH 118/310] Fix versions of guzzle and smarty, and improve templates doc --- modules/creation/external-services.md | 2 +- .../reference/templates/templates-layouts.md | 58 ++++++++++++++----- 2 files changed, 43 insertions(+), 17 deletions(-) diff --git a/modules/creation/external-services.md b/modules/creation/external-services.md index 382674f01f..d35de1f21a 100644 --- a/modules/creation/external-services.md +++ b/modules/creation/external-services.md @@ -73,7 +73,7 @@ HTTP requests can be triggered from a shop to an external service. Several methods allows requests to be sent (in order of preference): -* [Guzzle](https://github.com/guzzle/guzzle). The version 5 is included from PrestaShop {{< minver v="1.7.0" >}}, but can be included in your module as well for older PS versions. +* [Guzzle](https://github.com/guzzle/guzzle). The version 7.4 is included from PrestaShop {{< minver v="8.0" >}} (version 5 in {{< minver v="1.7.0" >}}), but can be included in your module as well for older PS versions. * Loading in memory another version of guzzle in the same namespace will trigger errors on the shop. * Example with PS Checkout module: [Inclusion in composer.json](https://github.com/PrestaShopCorp/ps_checkout/blob/578135d8bef2d99b8056ebc0bd709e9a87d661e6/composer.json#L28) & [implementation](https://github.com/PrestaShopCorp/ps_checkout/blob/ef48da09735e6e64b42364a703b5a74d41cd24d9/classes/Api/Payment/Dispute.php) * [\Tools::file_get_contents(...)](https://github.com/PrestaShop/PrestaShop/blob/a07a569b45ab6afc777f25aba505997004e5f70a/classes/Tools.php#L2212-L2223) diff --git a/themes/reference/templates/templates-layouts.md b/themes/reference/templates/templates-layouts.md index 95f45fb29f..d6517d4bb5 100644 --- a/themes/reference/templates/templates-layouts.md +++ b/themes/reference/templates/templates-layouts.md @@ -1,18 +1,21 @@ --- title: Templates & layouts weight: 10 +useMermaid: true --- # Templates & layouts -PrestaShop template file are based on the [Smarty 3 template engine](https://www.smarty.net/v3_overview). +PrestaShop template files are based on the [Smarty 4 template engine](https://smarty-php.github.io/smarty/). + +{{% notice note %}} +On PrestaShop `1.7.x`, template files were based on [Smarty 3 template engine](https://www.smarty.net/v3_overview). +{{% /notice %}} All template files must be stored in the theme's `templates/` subfolder. For instance, the default theme has its template files in the following folder: `/themes/classic/templates`. - -Directory structure ------------------------------------- +## Directory structure Templates are then split between various subfolders. @@ -41,14 +44,13 @@ Template files should be written so that a single .tpl can generate a whole HTML inside a `_partials` folder or subfolder (see our coding standard, linked from the Prologue chapter of this documentation). - ## Templates We make a **clear difference between templates and layout**. * A template extends a layout * The layout holds the global organization of the page -* A template a specify to a feature: the product page for example +* A template is specific to a feature: the product page for example There are many templates in a PrestaShop theme, the main ones includes: @@ -71,17 +73,42 @@ When searching for a template, PrestaShop will check many location to determine which file should be used. It make it very easy to have different template for a given locale or a specific entity id. +More details in [TemplateFinder.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Smarty/TemplateFinder.php#L71-L117). + +#### Product page example + With the product page, the core will check the following locations (in order) and return the first template found: -Example with a product with ID = 3 and locale = en-US +

+graph TD; + A(Lookup for template catalog/product with : locale + entity id) + A-->B(Lookup for template catalog/product with : entity id); + B-->C(Lookup for template catalog/product with : locale); + C-->D(Lookup for template catalog/product); +
+ +Example for the product with ID = 3 and locale = en-US: 1. `en-US/catalog/product-3.tpl` 2. `catalog/product-3.tpl` 3. `en-US/catalog/product.tpl` 4. `catalog/product.tpl` -Another example with category template for the category with ID = 9 and locale = en-US. +#### Category page example + +
+graph TD; + A(Lookup for template catalog/listing/category with : locale + entity id) + A-->B(Lookup for template catalog/listing/category with : entity id); + B-->C(Lookup for template catalog/listing/category with : locale); + C-->D(Lookup for template catalog/listing/category); + D-->E(Lookup for template catalog/listing/product-list with locale); + E-->F(Lookup for template catalog/listing/product-list); + +
+ +Example for the category with ID = 9 and locale = en-US: 1. `en-US/catalog/listing/category-9.tpl` 2. `catalog/listing/category-9.tpl` @@ -94,13 +121,12 @@ This feature is mostly made for developer working on a custom template for a cus ## Layouts -The layout is the organisation of the page, the way in which the parts of your design are arranged. -The typical example is the sidebar: is there a sidebar on your category page or is your product listing -is taking the whole space. +The layout is the organisation of the page: how the parts of your design are arranged. + +The typical example is the sidebar: is there a sidebar on your category page or is your product listing taking the whole space? -In PrestaShop, users are given the ability to change the layout of each page -independently. As a template developer, it's your role to ensure your theme is -compatible. +In PrestaShop, users are given the ability to change the layout of each page independently. +As a template developer, it's your role to ensure your theme is compatible. ![Configure layout](../img/configure-layout.png) @@ -109,7 +135,7 @@ compatible. The layout is the very top level of the [template inheritance]({{< relref "/8/themes/reference/template-inheritance/" >}}) tree. Basically it hold the opening and closing `` tags. -Typical layout files look like the following snippet. This one is a full one +Typical layout files look like the following snippet. This one is a full one: {{% notice note %}} Remember to define as many blocks as possible. @@ -185,4 +211,4 @@ Typical layout files look like the following snippet. This one is a full one ``` From there, each part of the theme will do its job and replace content inside these -bricks, keeping the same organization. +bricks, keeping the same organization. \ No newline at end of file From 797f6d2e0240ccce5373beb7538accd3e1592535 Mon Sep 17 00:00:00 2001 From: Thomas Nares Date: Fri, 14 Oct 2022 17:14:09 +0200 Subject: [PATCH 119/310] Re-order changes, fix minot typo --- modules/core-updates/8.0.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/modules/core-updates/8.0.md b/modules/core-updates/8.0.md index f228b8b9ab..885fb08fd0 100644 --- a/modules/core-updates/8.0.md +++ b/modules/core-updates/8.0.md @@ -30,7 +30,7 @@ PrestaShop 8.0 adds supports for PHP 8.0 and PHP 8.1 and requires at least PHP 7 * The live exchange rate feature [has been removed](https://github.com/PrestaShop/PrestaShop/pull/28177). * In Back office, the .rtlfix file [has been removed](https://github.com/PrestaShop/PrestaShop/pull/28277), although support for such files remains. It is recommended to port your changes (if any) inside the `rtl.scss` stylesheets. * The [new Distribution API](https://github.com/PrestaShop/PrestaShop/pull/27632) allows modules to provide Module Manager with information about new and updated modules pulled from remote services. PrestaShop 8 leverages this new feature to handle downloads and updates for the project's modules. -* Because of the [support for PHP 8.1](https://github.com/PrestaShop/PrestaShop/pull/28402) many methods have declare a return types now. +* Because of the [support for PHP 8.1](https://github.com/PrestaShop/PrestaShop/pull/28402) many methods have declared a return type now. * The logic for customers' login and registration [is now](https://github.com/PrestaShop/PrestaShop/pull/27755/) split between two controllers (`RegistrationController`, `AuthController`). This might impact third-party themes and modules as the URL to the registration has changed. * Before PrestaShop places an order [there is an additional request now](https://github.com/PrestaShop/PrestaShop/pull/26048/), to see if the number of products in the cart is still valid. This might require third-party payment modules to implement the checks in their solutions accordingly. * Due to the new [password policy management features](https://github.com/PrestaShop/PrestaShop/pull/28127), third-party solutions that generate customer data might require to implement changes accordingly. @@ -159,6 +159,11 @@ The Bootstrap version used in Symfony-based Back office pages has been updated f --- +* `Tools::displayDate()` + - Two deprecated parameters (`$id_lang`, `$separator`) [have been removed](https://github.com/PrestaShop/PrestaShop/pull/27956/). + +--- + * `Validate` - `isOrderWay()` now returns `bool` instead if `int`. @@ -786,11 +791,6 @@ The Bootstrap version used in Symfony-based Back office pages has been updated f * `PrestaShopBundle\Translation\Provider\SearchProvider` - `__construct()` - The parameter `$modulesDirectory` [has been removed](https://github.com/PrestaShop/PrestaShop/pull/28197/). ---- - -* `Tools::displayDate()` - - Two deprecated parameters (`$id_lang`, `$separator`) [have been removed](https://github.com/PrestaShop/PrestaShop/pull/27956/). - ### Removals #### Removed methods From da953cfe5cbf8139eb23e2640c8296f8c665f75f Mon Sep 17 00:00:00 2001 From: Thomas Nares Date: Sun, 16 Oct 2022 16:28:07 +0200 Subject: [PATCH 120/310] Move some pages, create new one --- .../back-office/order/view-order/_index.md | 2 +- modules/sample-modules/_index.md | 40 ++++++++++++++++++- .../sample-modules/example-hooks/_index.md | 12 ++++++ .../example-hooks/actionValidateOrder.md | 36 +++++++++++++++++ ...nd-identifiable-object-form-hooks-usage.md | 1 + .../order-pages-new-hooks/_index.md | 1 + .../additional-action-buttons.md | 1 + .../order-pages-new-hooks/module-base.md | 1 + .../order-pages-new-hooks/signature-widget.md | 1 + ...tending-sf-form-with-upload-image-field.md | 2 +- 10 files changed, 93 insertions(+), 4 deletions(-) create mode 100644 modules/sample-modules/example-hooks/_index.md create mode 100644 modules/sample-modules/example-hooks/actionValidateOrder.md rename modules/sample-modules/{ => example-hooks}/grid-and-identifiable-object-form-hooks-usage.md (99%) rename modules/sample-modules/{ => example-hooks}/order-pages-new-hooks/_index.md (97%) rename modules/sample-modules/{ => example-hooks}/order-pages-new-hooks/additional-action-buttons.md (96%) rename modules/sample-modules/{ => example-hooks}/order-pages-new-hooks/module-base.md (99%) rename modules/sample-modules/{ => example-hooks}/order-pages-new-hooks/signature-widget.md (99%) diff --git a/development/page-reference/back-office/order/view-order/_index.md b/development/page-reference/back-office/order/view-order/_index.md index f326c5dc01..3a1f7e1d87 100644 --- a/development/page-reference/back-office/order/view-order/_index.md +++ b/development/page-reference/back-office/order/view-order/_index.md @@ -5,7 +5,7 @@ title: Order view # Order View Page {{% notice tip %}} -**New hooks** are available for this page. Check them out [here]({{< relref "/8/modules/sample-modules/order-pages-new-hooks" >}}) {{< minver v="1.7.7.0" >}} +**New hooks** are available for this page. Check them out [here]({{< relref "/8/modules/sample-modules/example-hooks/order-pages-new-hooks" >}}) {{< minver v="1.7.7.0" >}} {{% /notice %}} This page can be reached by visiting `Sell -> Orders -> Orders -> View (grid row action)`. It allows the Back Office user to view the details of selected order and edit it. The **related code can be found in following locations**: diff --git a/modules/sample-modules/_index.md b/modules/sample-modules/_index.md index 9299da1f67..647e599668 100644 --- a/modules/sample-modules/_index.md +++ b/modules/sample-modules/_index.md @@ -1,10 +1,46 @@ --- -title: Sample modules +title: Sample modules and how to's weight: 80 --- -# Sample modules +# Sample modules and how to guides + +The PrestaShop Community made some example modules and how to guides to help you understand how to implement hooks, admin grids, manage entities... and a lot more. {{% children %}} +## Our example modules repository + * [See all our example modules (GitHub)](https://github.com/PrestaShop/example-modules) + +This repository hosts example modules built and maintained by PrestaShop. +These modules demonstrate useful usecases for developers willing to customize the software. + +### Extending Symfony pages + +- [Demo Extending a Symfony Form - 1](https://github.com/PrestaShop/example-modules/tree/master/demoextendsymfonyform1) - how to insert an input inside a Symfony form +- [Demo Extending a Symfony Form - 2](https://github.com/PrestaShop/example-modules/tree/master/demoextendsymfonyform2) - how to insert an input inside a Symfony form - 2 +- [Demo Extending a Symfony Form - 3](https://github.com/PrestaShop/example-modules/tree/master/demoextendsymfonyform3) - how to use CQRS in a module +- [Demo View Order Hooks](https://github.com/PrestaShop/example-modules/tree/master/demovieworderhooks) +- [Demo Extend a Grid](https://github.com/PrestaShop/example-modules/tree/master/demoextendgrid) +- [Demo Extend Product Form V2](https://github.com/PrestaShop/example-modules/tree/master/demoproductform) + +### Using a tool / concept + +#### Symfony + +- [Demo Creating a Symfony Console command](https://github.com/PrestaShop/example-modules/tree/master/democonsolecommand) +- [Demo Using PrestaShop Symfony Form Types](https://github.com/PrestaShop/example-modules/tree/master/demosymfonyform) +- [Demo Creating modern Controllers and associate Tabs to them](https://github.com/PrestaShop/example-modules/tree/master/democontrollertabs) + +#### Database + +- [Demo Using Doctrine entities](https://github.com/PrestaShop/example-modules/tree/master/demodoctrine) +- [Demo How to override an ObjectModel](https://github.com/PrestaShop/example-modules/tree/master/demooverrideobjectmodel) + +#### Other + +- [Demo Adding a Mail Theme](https://github.com/PrestaShop/example-modules/tree/master/example_module_mailtheme) +- [Demo Javascript Router component usage](https://github.com/PrestaShop/example-modules/tree/master/demojsrouting) +- [Demo Multistore form](https://github.com/PrestaShop/example-modules/tree/master/demomultistoreform) +- [Demo Grid](https://github.com/PrestaShop/example-modules/tree/master/demo_grid) \ No newline at end of file diff --git a/modules/sample-modules/example-hooks/_index.md b/modules/sample-modules/example-hooks/_index.md new file mode 100644 index 0000000000..1b46a080c1 --- /dev/null +++ b/modules/sample-modules/example-hooks/_index.md @@ -0,0 +1,12 @@ +--- +title: Hooks examples +weight: 2 +--- + +# Hooks implementation examples + +Hooks is one of the most powerful tools to extend or modify PrestaShop with modules. + +For a complete introduction about hooks, please read [Hooks]({{< relref "/8/modules/concepts/hooks/" >}}) + +{{% children %}} \ No newline at end of file diff --git a/modules/sample-modules/example-hooks/actionValidateOrder.md b/modules/sample-modules/example-hooks/actionValidateOrder.md new file mode 100644 index 0000000000..be9f783083 --- /dev/null +++ b/modules/sample-modules/example-hooks/actionValidateOrder.md @@ -0,0 +1,36 @@ +--- +title: "actionValidateOrder" +weight: 3 +--- + +# Hook example : actionValidateOrder + +This hook is triggered when an `order` is validated. + +actionValidateOrder +: + After an order has been validated. + Doesn't necessarily have to be paid. + + Located in: /classes/PaymentModule.php + + Parameters: + ```php + (object) Cart, + 'order' => (object) Order, + 'customer' => (object) Customer, + 'currency' => (object) Currency, + 'orderStatus' => (object) OrderState + ); + ``` + +A classic use-case for this hook could be : + +> I want to reward my customers on their _n-th_ order + +: +{{% notice info %}} +Insert here contribution from Pululuk +{{% /notice %}} \ No newline at end of file diff --git a/modules/sample-modules/grid-and-identifiable-object-form-hooks-usage.md b/modules/sample-modules/example-hooks/grid-and-identifiable-object-form-hooks-usage.md similarity index 99% rename from modules/sample-modules/grid-and-identifiable-object-form-hooks-usage.md rename to modules/sample-modules/example-hooks/grid-and-identifiable-object-form-hooks-usage.md index b55b51ca37..f14df48751 100644 --- a/modules/sample-modules/grid-and-identifiable-object-form-hooks-usage.md +++ b/modules/sample-modules/example-hooks/grid-and-identifiable-object-form-hooks-usage.md @@ -1,6 +1,7 @@ --- title: Grid and identifiable object form hooks usage example weight: 1 +aliases: ["/8/modules/sample-modules/grid-and-identifiable-object-form-hooks-usage/"] --- # Grid and identifiable object form hooks usage example diff --git a/modules/sample-modules/order-pages-new-hooks/_index.md b/modules/sample-modules/example-hooks/order-pages-new-hooks/_index.md similarity index 97% rename from modules/sample-modules/order-pages-new-hooks/_index.md rename to modules/sample-modules/example-hooks/order-pages-new-hooks/_index.md index f906ec8d2e..0091201f9a 100644 --- a/modules/sample-modules/order-pages-new-hooks/_index.md +++ b/modules/sample-modules/example-hooks/order-pages-new-hooks/_index.md @@ -1,6 +1,7 @@ --- title: Order view page new hooks demo tutorial weight: 2 +aliases: ["/8/modules/sample-modules/order-pages-new-hooks/"] --- # Order pages new hooks demo tutorial diff --git a/modules/sample-modules/order-pages-new-hooks/additional-action-buttons.md b/modules/sample-modules/example-hooks/order-pages-new-hooks/additional-action-buttons.md similarity index 96% rename from modules/sample-modules/order-pages-new-hooks/additional-action-buttons.md rename to modules/sample-modules/example-hooks/order-pages-new-hooks/additional-action-buttons.md index f0da93dac7..2078d648ea 100644 --- a/modules/sample-modules/order-pages-new-hooks/additional-action-buttons.md +++ b/modules/sample-modules/example-hooks/order-pages-new-hooks/additional-action-buttons.md @@ -1,6 +1,7 @@ --- title: Additional action buttons weight: 3 +aliases: ["/8/modules/sample-modules/order-pages-new-hooks/additional-action-buttons"] --- # Additional buttons in the main buttons bar diff --git a/modules/sample-modules/order-pages-new-hooks/module-base.md b/modules/sample-modules/example-hooks/order-pages-new-hooks/module-base.md similarity index 99% rename from modules/sample-modules/order-pages-new-hooks/module-base.md rename to modules/sample-modules/example-hooks/order-pages-new-hooks/module-base.md index 9b976ec983..9485592293 100644 --- a/modules/sample-modules/order-pages-new-hooks/module-base.md +++ b/modules/sample-modules/example-hooks/order-pages-new-hooks/module-base.md @@ -1,6 +1,7 @@ --- title: Module base creation weight: 1 +aliases: ["/8/modules/sample-modules/order-pages-new-hooks/module-base"] --- # Module base creation diff --git a/modules/sample-modules/order-pages-new-hooks/signature-widget.md b/modules/sample-modules/example-hooks/order-pages-new-hooks/signature-widget.md similarity index 99% rename from modules/sample-modules/order-pages-new-hooks/signature-widget.md rename to modules/sample-modules/example-hooks/order-pages-new-hooks/signature-widget.md index dd02c54c85..1fcd6db381 100644 --- a/modules/sample-modules/order-pages-new-hooks/signature-widget.md +++ b/modules/sample-modules/example-hooks/order-pages-new-hooks/signature-widget.md @@ -1,6 +1,7 @@ --- title: Signature card weight: 2 +aliases: ["/8/modules/sample-modules/order-pages-new-hooks/signature-widget"] --- # Signature card diff --git a/modules/sample-modules/extending-sf-form-with-upload-image-field.md b/modules/sample-modules/extending-sf-form-with-upload-image-field.md index 59d64a4a8d..3851ac42e1 100644 --- a/modules/sample-modules/extending-sf-form-with-upload-image-field.md +++ b/modules/sample-modules/extending-sf-form-with-upload-image-field.md @@ -364,7 +364,7 @@ class SupplierExtraImageRepository extends EntityRepository Let's create hook `hookActionSupplierFormBuilderModifier` function inside Main module class. This is a hook available for [CRUD forms] -({{< relref "/8/modules/sample-modules/grid-and-identifiable-object-form-hooks-usage" >}}) in +({{< relref "/8/modules/sample-modules/example-hooks/grid-and-identifiable-object-form-hooks-usage" >}}) in PrestaShop Symfony pages. ```php From 553f3dcaf14f3983066fd71b43e9de2c5d82dbaf Mon Sep 17 00:00:00 2001 From: mattkohl-flex Date: Mon, 17 Oct 2022 10:18:36 +0100 Subject: [PATCH 121/310] Documentation fixes --- basics/keeping-up-to-date/migration.md | 12 ++++++------ contribute/contribution-guidelines/pull-requests.md | 2 +- .../how-pull-requests-are-processed.md | 4 ++-- development/architecture/domain/domain-exceptions.md | 2 +- development/architecture/file-structure/_index.md | 2 +- .../file-structure/understanding-src-folder.md | 2 +- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/basics/keeping-up-to-date/migration.md b/basics/keeping-up-to-date/migration.md index 98e7835972..61cf921aa8 100644 --- a/basics/keeping-up-to-date/migration.md +++ b/basics/keeping-up-to-date/migration.md @@ -15,7 +15,7 @@ The database structure may change with each new release of PrestaShop, but major We will cover the 3 main steps in this chapter: -* Extract data to be transfered +* Extract data to be transferred * Add / modify / delete some values if needed * Import data on the new shop @@ -91,7 +91,7 @@ If you want to export several tables at the same time, this can be done by selec These tables can be ignored as well: * **access**: As said, permissions have been reworked and have to be reset. -* **configuration**. You new shop already has a new configuration, and overwriting it with the old shop content is a bad idea. +* **configuration**. Your new shop already has a new configuration, and overwriting it with the old shop content is a bad idea. * **currency**: Its content will be generated by during another step. * **lang**: Its content will be generated by during another step. * **module_access**: Structure is reworked with the new permission system. As it can’t be migrated easily, we recommend to reconfigure them manually. @@ -431,7 +431,7 @@ PrestaShop, or if you got your data from customized SQL requests. It is convenient thanks to its interface and its management of unprovided columns. Unlike imports with a MySQL client, the PrestaShop -import feature will always be able to apply the default values for a +import feature will always be able to apply the default values for missing information. On the new shop, reach the controller Advanced parameters > Import. @@ -606,7 +606,7 @@ from the source shop. Object Model is an interface in the PHP codebase used by PrestaShop developers to request the database. -This can be used while developing a module responsible of the export +This can be used while developing a module responsible for the export and/or import of the objects from/to the database. For more details, see the page dedicated to [ObjectModels]({{< ref "1.7/development/components/database/objectmodel" >}}) @@ -620,7 +620,7 @@ It must be enabled from the administration panel before being accessible. See the doc for more details: https://doc.prestashop.com/display/PS17/Webservice -Once ready, an API will be available for all the ressources enabled for +Once ready, an API will be available for all the resources enabled for your key. Basically, the web-service in another interface for object models, themselves interfacing the database. @@ -634,7 +634,7 @@ automatic, because: - the webservice has barely changed since PrestaShop 1.5, - you get all the properties of a given object, - if a property is multi-lang, you will get the value or a link to another resource for each lang, -- you can get the images URL of a resource (i.e product), while you can’t find directly from a database column, +- you can get the images URL of a resource (i.e. product), while you can’t find directly from a database column, - getting a resource, or inserting one, is done by manipulating XMLs. Useful links: diff --git a/contribute/contribution-guidelines/pull-requests.md b/contribute/contribution-guidelines/pull-requests.md index 11ae4dc8ba..a6b8770e44 100644 --- a/contribute/contribution-guidelines/pull-requests.md +++ b/contribute/contribution-guidelines/pull-requests.md @@ -100,7 +100,7 @@ We use type & category to group changes in the [changelog](https://github.com/Pr ### BC breaks -It is very important to note if your change introduces backwards incompatible changes (also referred to as "backward compatiblity breaks" or "BC breaks"). +It is very important to note if your change introduces backwards incompatible changes (also referred to as "backward compatibility breaks" or "BC breaks"). Here are some examples of changes that can be considered breaking changes: diff --git a/contribute/contribution-process/how-pull-requests-are-processed.md b/contribute/contribution-process/how-pull-requests-are-processed.md index 3623d86b3c..61d0b3a95b 100644 --- a/contribute/contribution-process/how-pull-requests-are-processed.md +++ b/contribute/contribution-process/how-pull-requests-are-processed.md @@ -48,8 +48,8 @@ The review process is quite thorough in order to make sure that PrestaShop codeb - The start is checking that the code is correct. This means both from a behavior point of view as well as from a technical point of view. This is simply an assessment of the quality of the Pull Request code, just like it happens in a lot of software teams. The Core maintainers check the code works as intended, it uses the right functions, it handles expectable edge-cases, has no obvious vulnerabilities, scales well, etc. The Core maintainers also keep in mind that PrestaShop is a CMS and consequently must provide all the necessary extension points to allow developers to customize or extend its behavior. - The Core maintainers also assess the readability of the code. There is a statement that says "when a code file is opened by a developer, 9 times out of 10 it will only to be read, not to be modified". Because PrestaShop is a huge and complex codebase and because it has so many people reading through it, it is very important that its code is made as readable as possible. This is obtained by adding comments, carefully choosing function and variable names, and building an architecture that makes sense so it is easy to grasp and navigate for people who have never worked on it before. -- The Core maintainers also check that best practices are implemented into the Pull Request, be it standard conventions or practices like [PSR](https://www.php-fig.org/psr/) or best security recommandations like the ones from [OWASP](https://www.owasp.org/). When people use PrestaShop to build a shop, it is likely that they will follow the practices they see implemented in the Core, so the aim is to think of the code merged as an example that people will use. -- PrestaShop has grown huge over the years, both as a codebase and as a software. There are hundreds of features built in the software, and some are more commonly used than others. Some contributions sometimes need to be reworked because they did not take into account one of the less popular features of the software, or are not compatible with them. Common examples are the multi-store mode or the RTL (Right-To-Left) mode, two features that adress very specific needs and that many developers are not aware of. +- The Core maintainers also check that best practices are implemented into the Pull Request, be it standard conventions or practices like [PSR](https://www.php-fig.org/psr/) or best security recommendations like the ones from [OWASP](https://www.owasp.org/). When people use PrestaShop to build a shop, it is likely that they will follow the practices they see implemented in the Core, so the aim is to think of the code merged as an example that people will use. +- PrestaShop has grown huge over the years, both as a codebase and as a software. There are hundreds of features built in the software, and some are more commonly used than others. Some contributions sometimes need to be reworked because they did not take into account one of the less popular features of the software, or are not compatible with them. Common examples are the multi-store mode or the RTL (Right-To-Left) mode, two features that address very specific needs and that many developers are not aware of. - PrestaShop follows [SemVer](https://semver.org/). This means that The Core maintainers strive not to introduce breaking compatibility changes when releasing minor and patch versions. Therefore, each Pull Request must not introduce such changes. - The Core maintainers also have a vision of what PrestaShop should evolve to in order to follow the new trends in the software world. Although a big codebase like PrestaShop evolves slowly, the future architecture and features to come are kept in mind, and the Core maintainers check whether the Pull Request is following this direction. For example today PrestaShop relies heavily on jQuery for its frontend features, and Vue.js is slowly starting to be used in the project. So if tomorrow a Pull Request that is using React.js is submitted, it might be refused in order to keep a consistency in the technology stack used for the project. diff --git a/development/architecture/domain/domain-exceptions.md b/development/architecture/domain/domain-exceptions.md index c26c019777..6430408b72 100644 --- a/development/architecture/domain/domain-exceptions.md +++ b/development/architecture/domain/domain-exceptions.md @@ -118,7 +118,7 @@ Having many different exception classes means that developers can easily recogni Just as we recognized category editing failure in our example, we can catch any particular exception and it will tell us what exactly failed in the runtime. For example, catching a `CategoryNotFoundException` lets us know when category is not found, -or catching `CannotAddCategoryException` means that a category cannot be added. These exceptions carry an accurate information that makes it easier to debug the issue or to handle the usecase gracefully by displaying the right error message for example. +or catching `CannotAddCategoryException` means that a category cannot be added. These exceptions carry accurate information that makes it easier to debug the issue or to handle the use case gracefully by displaying the right error message for example. If we expand our previous example with a better overview with different exception types: diff --git a/development/architecture/file-structure/_index.md b/development/architecture/file-structure/_index.md index 577bf5f2d1..be08fa6c86 100644 --- a/development/architecture/file-structure/_index.md +++ b/development/architecture/file-structure/_index.md @@ -90,7 +90,7 @@ Contains all the legacy classes, including: - Object models - Utility classes (like `Db`, `Helper`, `Tools`...) -- Base controlllers (like `FrontController`, `AdminController`...) +- Base controllers (like `FrontController`, `AdminController`...) ### /config diff --git a/development/architecture/file-structure/understanding-src-folder.md b/development/architecture/file-structure/understanding-src-folder.md index d8611a99d3..4df5615701 100644 --- a/development/architecture/file-structure/understanding-src-folder.md +++ b/development/architecture/file-structure/understanding-src-folder.md @@ -65,7 +65,7 @@ Here are some examples of subsystems belonging to PrestaShopBundle: - DataCollector: Specific collectors for the Symfony profiler (eg. hooks) - Form: Symfony forms and extensions - Resources: Contains services definition files -- Security: Glue between Security Bundle and PrestaShop autorization/authentification +- Security: Glue between Security Bundle and PrestaShop authorization/authentication - Twig: Contains PrestaShop-specific Twig extensions ## Dependency rules From 9bdbcf27ad85cbfe2ed8a440fa63be5a4d1ba096 Mon Sep 17 00:00:00 2001 From: Thomas Nares Date: Mon, 17 Oct 2022 14:57:34 +0200 Subject: [PATCH 122/310] Improve doc from pr21279 --- webservice/resources/carriers.md | 47 ++++++++++++++++---------------- 1 file changed, 23 insertions(+), 24 deletions(-) diff --git a/webservice/resources/carriers.md b/webservice/resources/carriers.md index e9842ddea5..5e347bb36d 100644 --- a/webservice/resources/carriers.md +++ b/webservice/resources/carriers.md @@ -6,30 +6,29 @@ title: Carriers ### Carrier -| Name | Format | Required | Max size | Not filterable | Description | -| :----------------------- | :------------ | :------: | -------: | :------------- | :----------------- | -| **deleted** | isBool | ❌ | | | | -| **is_module** | isBool | ❌ | | | | -| **id_tax_rules_group** | | ❌ | | true | Tax rules group ID | -| **id_reference** | | ❌ | | | Reference ID | -| **name** | isCarrierName | ✔️ | 64 | | | -| **active** | isBool | ✔️ | | | | -| **is_free** | isBool | ❌ | | | | -| **url** | isAbsoluteUrl | ❌ | | | | -| **shipping_handling** | isBool | ❌ | | | | -| **shipping_external** | | ❌ | | | | -| **range_behavior** | isBool | ❌ | | | | -| **shipping_method** | isUnsignedInt | ❌ | | | | -| **max_width** | isUnsignedInt | ❌ | | | | -| **max_height** | isUnsignedInt | ❌ | | | | -| **max_depth** | isUnsignedInt | ❌ | | | | -| **max_weight** | isFloat | ❌ | | | | -| **grade** | isUnsignedInt | ❌ | 1 | | | -| **external_module_name** | | ❌ | 64 | | | -| **need_range** | | ❌ | | | | -| **position** | | ❌ | | | | -| **delay** | isGenericName | ✔️ | 512 | | | - +| Name | Format | Required | Max size | Not filterable | Description | +|--------------------------|---------------|----------|----------|----------------|-------------------------------------------------------------------------------------------------------| +| **deleted** | isBool | ❌ | | | | +| **is_module** | isBool | ❌ | | | | +| **id_tax_rules_group** | | ❌ | | true | Tax rules group ID | +| **id_reference** | | ❌ | | | Reference ID | +| **name** | isCarrierName | ✔️ | 64 | | | +| **active** | isBool | ✔️ | | | | +| **is_free** | isBool | ❌ | | | | +| **url** | isAbsoluteUrl | ❌ | | | | +| **shipping_handling** | isBool | ❌ | | | Defines if extra shipping handling cost should be applied to this Carrier | +| **shipping_external** | | ❌ | | | Defines if external module calculates shipping cost | +| **range_behavior** | isBool | ❌ | | | Defines out-of-range behavior for weight, `true`=disable carrier, `false`=apply highest defined range | +| **shipping_method** | isUnsignedInt | ❌ | | | Calculation method : by weight, by price, or free | +| **max_width** | isUnsignedInt | ❌ | | | | +| **max_height** | isUnsignedInt | ❌ | | | | +| **max_depth** | isUnsignedInt | ❌ | | | | +| **max_weight** | isFloat | ❌ | | | | +| **grade** | isUnsignedInt | ❌ | 1 | | | +| **external_module_name** | | ❌ | 64 | | Name of the external module in charge of calculating the shipping cost | +| **need_range** | | ❌ | | | Defines if module needs core range-based shipping cost to calculate final cost | +| **position** | | ❌ | | | | +| **delay** | isGenericName | ✔️ | 512 | | | ### Blank schema From e8de4669a42048d64265c8cf46e7569ed3f459af Mon Sep 17 00:00:00 2001 From: Thomas Nares Date: Tue, 18 Oct 2022 11:31:11 +0200 Subject: [PATCH 123/310] Add a doc about SelfConfigurator --- modules/configure-with-cli.md | 193 ++++++++++++++++++++++++++++++++++ 1 file changed, 193 insertions(+) create mode 100644 modules/configure-with-cli.md diff --git a/modules/configure-with-cli.md b/modules/configure-with-cli.md new file mode 100644 index 0000000000..61ec77aa53 --- /dev/null +++ b/modules/configure-with-cli.md @@ -0,0 +1,193 @@ +--- +title: Configure with CLI +weight: 0 +--- + +# Configure a module with CLI + +From {{< minver v="1.7.2" >}}, Self Configurator feature was introduced in the `ModuleCommand`. + +Self Configurator is a feature that allows module configuration management from a command, without having to connect on the back office of the shop. + +From a configuration file, the command is able to do some configuration on a specific module, e.g.: + +- change values in the Configuration table +- execute SQL statements from a `.sql` file +- copy files +- execute `php` scripts + +Complete reference of Self Configurator : [ModuleSelfConfigurator.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Module/Configuration/ModuleSelfConfigurator.php) + +## How to use it + +You need to create a configuration file, with the `yaml` [format](https://symfony.com/doc/current/components/yaml/yaml_format.html), and execute: + +`php bin/console prestashop:module configure ` + +{{% notice info %}} +Please note that the third argument `` is optional. If not set, PrestaShop will try to find a file named `self_config.yml` in the module's folder (and sub-folders). +{{% /notice %}} + +## Configuration file reference + +### Change values in the Configuration table + +The Self Configurator feature allows editing values in the `Configuration` table from the configuration file. + +To do so, add a `configuration:` line, choose if you want to update or delete a configuration value, and add the configuration key and its value like in those examples: + +```yaml +configuration: + update: + PAYPAL_SANDBOX: 1 +``` + +```yaml +configuration: + delete: + - "PAYPAL_ONBOARDING" +``` + +{{% notice info %}} +Please note that you can only `update` or `delete` values : `create` values are only done when installing the module. +{{% /notice %}} + +### Execute SQL statements from a `.sql` file + +The Self Configurator feature allows to execute a `.sql` file with statements on your database. + +To do so, add the path of your `.sql` file like in this example: + +```yaml +sql: + - "myscript.sql" +``` + +{{% notice info %}} +Please note that your paths are relative to the configuration file. +{{% /notice %}} + +### Copy files + +The Self Configurator feature allows to copy files (or URLs) from the configuration file. + +To do so, add your source and destination path like in those examples: + +```yaml +files: + - source: "../source/file.txt" + dest: "docs/file.txt" +``` + +```yaml +files: + - source: "https://www.prestashop-project.org" + dest: "webpage.html" +``` + +```yaml +files: + - source: "../source/file1.txt" + dest: "docs/file1.txt" + - source: "../source/file2.txt" + dest: "docs/file2.txt" +``` + +{{% notice info %}} +Please note that if you use paths, your paths should be relative to the configuration file. +{{% /notice %}} + +### Execute `php` scripts + +For complex actions, you can execute `php` code from your configuration file. + +Your file must contain a class implementing the interface `PrestaShop\PrestaShop\Adapter\Module\Configuration\ModuleComplexConfigurationInterface`: [see reference here](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Module/Configuration/ModuleComplexConfigurationInterface.php). + +**The class name needs to match the file name..** + +You have to declare a method : `public function run(ModuleInterface $module, array $params);` + +Create a file named `ConfigurationScript.php` with this content : + +```php +use PrestaShop\PrestaShop\Adapter\Module\Configuration\ModuleComplexConfigurationInterface; + +class ConfigurationScript implements ModuleComplexConfigurationInterface +{ + public function run(ModuleInterface $module, array $params) + { + + } +} +``` + +And add to the configuration file: + +```yaml +php: + - file: "ConfigurationScript.php" +``` + +The method will receive the module's name, and an empty `array $params`. + +To add a parameter with key `myParam1` and value `1`, do the following: + +```yaml +php: + - file: "ConfigurationScript.php" + params: + - myParam1: 1 +``` + +To add a parameter of type `array`, with key `oneArrayParam` and the following value `["value1", "value2", "withSpecificKey" => "value3"]`, do the following: + +```yaml +php: + - file: "ConfigurationScript.php" + params: + - oneArrayParam: + - "value1" + - "value2" + - withSpecificKey: "value3" +``` + +## Complete config file example + +```yaml +# This file is an example of data configuration which can be applied to a module +# Paths are relative to the config file! + +# Update data in Configuration table +configuration: + update: + # Option 1: having a pair key/value + PAYPAL_SANDBOX: 1 + PAYPAL_API_CARD: 0 + # Option 2: use "value" subkey. Will allow to use addtionnal keys later + PAYPAL_SANDBOX_2: + value: 1 + delete: + - "PAYPAL_ONBOARDING" + +# Execute sql files +sql: + - "sql/default-config.sql" + +# Copy files +files: + - source: "../source/file.txt" + dest: "docs/file.txt" + + - source: "https://www.prestashop.com" + dest: "webpage.html" + +# Execute php script +php: + - file: "ConfigurationScript.php" + params: + - myParam1: 1 + - oneArrayParam: + - "value1" + - "value2" + - withSpecificKey: "value3" +``` \ No newline at end of file From 9fd6c6afde452d305953021cd33984430b3025bd Mon Sep 17 00:00:00 2001 From: Thomas Nares Date: Tue, 18 Oct 2022 11:36:02 +0200 Subject: [PATCH 124/310] fix typos --- modules/configure-with-cli.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/modules/configure-with-cli.md b/modules/configure-with-cli.md index 61ec77aa53..8a6d3d9f81 100644 --- a/modules/configure-with-cli.md +++ b/modules/configure-with-cli.md @@ -11,12 +11,12 @@ Self Configurator is a feature that allows module configuration management from From a configuration file, the command is able to do some configuration on a specific module, e.g.: -- change values in the Configuration table +- change values in the `Configuration` table - execute SQL statements from a `.sql` file - copy files - execute `php` scripts -Complete reference of Self Configurator : [ModuleSelfConfigurator.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Module/Configuration/ModuleSelfConfigurator.php) +Complete reference of Self Configurator: [ModuleSelfConfigurator.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Module/Configuration/ModuleSelfConfigurator.php) ## How to use it @@ -49,7 +49,7 @@ configuration: ``` {{% notice info %}} -Please note that you can only `update` or `delete` values : `create` values are only done when installing the module. +Please note that you can only `update` or `delete` values: `create` values are only done when installing the module. {{% /notice %}} ### Execute SQL statements from a `.sql` file @@ -103,11 +103,11 @@ For complex actions, you can execute `php` code from your configuration file. Your file must contain a class implementing the interface `PrestaShop\PrestaShop\Adapter\Module\Configuration\ModuleComplexConfigurationInterface`: [see reference here](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Module/Configuration/ModuleComplexConfigurationInterface.php). -**The class name needs to match the file name..** +**The class name needs to match the file name.** -You have to declare a method : `public function run(ModuleInterface $module, array $params);` +You have to declare a method: `public function run(ModuleInterface $module, array $params);` -Create a file named `ConfigurationScript.php` with this content : +Create a file named `ConfigurationScript.php` with this content: ```php use PrestaShop\PrestaShop\Adapter\Module\Configuration\ModuleComplexConfigurationInterface; From 19ce97b79fa5d3fca7284453be3350a3cdd80ea0 Mon Sep 17 00:00:00 2001 From: Thomas Nares Date: Tue, 18 Oct 2022 11:42:53 +0200 Subject: [PATCH 125/310] add multishop feature --- modules/configure-with-cli.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/modules/configure-with-cli.md b/modules/configure-with-cli.md index 8a6d3d9f81..545c49e5c7 100644 --- a/modules/configure-with-cli.md +++ b/modules/configure-with-cli.md @@ -28,6 +28,17 @@ You need to create a configuration file, with the `yaml` [format](https://symfon Please note that the third argument `` is optional. If not set, PrestaShop will try to find a file named `self_config.yml` in the module's folder (and sub-folders). {{% /notice %}} +## Apply configuration file on a specific shop or group + +The Prestashop `prestashop:module` command allows you to restrict its actions on a specific shop (or group). + +To do so, add an `--id_shop` or an `--id_shop_group` argument to the command: + +```bash +php bin/console prestashop:module configure --id_shop= +php bin/console prestashop:module configure --id_shop_group= +``` + ## Configuration file reference ### Change values in the Configuration table From 609c97aee35407ad6230e4576551a3958cad349b Mon Sep 17 00:00:00 2001 From: PululuK Date: Tue, 18 Oct 2022 18:17:06 +0200 Subject: [PATCH 126/310] add hookActionValidateOrder concrete use case example #1543 --- .../example-hooks/actionValidateOrder.md | 61 +++++++++++++++++-- 1 file changed, 57 insertions(+), 4 deletions(-) diff --git a/modules/sample-modules/example-hooks/actionValidateOrder.md b/modules/sample-modules/example-hooks/actionValidateOrder.md index be9f783083..d7e72783ab 100644 --- a/modules/sample-modules/example-hooks/actionValidateOrder.md +++ b/modules/sample-modules/example-hooks/actionValidateOrder.md @@ -30,7 +30,60 @@ A classic use-case for this hook could be : > I want to reward my customers on their _n-th_ order -: -{{% notice info %}} -Insert here contribution from Pululuk -{{% /notice %}} \ No newline at end of file +```php +registerHook('actionValidateOrder') ; + } + public function hookActionValidateOrder($params) + { + $orderObject = $params['order']; + $customerObject = $params['customer']; + $hasValidParams = Validate::isLoadedObject($orderObject) && Validate::isLoadedObject($orderObject); + if ($hasValidParams && !$this->customerAlreadyRewarded((int) $customerObject->id)) { + $hasConfiguredState = in_array((int) $orderObject->getCurrentState(), $this->getConfuredOrdersStatesIds()); + $hasCustomerRequiredNbrOfTheOrderToReward = $this->getCustomerValidOrdersNbr((int) $customerObject->id) == $this->getRequiredNbrOfTheOrderToReward(); + if($hasConfiguredState && $hasCustomerRequiredNbrOfTheOrderToReward) { + $customerReward = $this->createCustomerReward($customerObject, $orderObject); + if(Validate::isLoadedObject($customerReward)) { + $this->setAlreadyRewarded($customerObject); + $this->notifyCustomer($customerObject, $customerReward); + + //TODO : of course don't forget to log if something fails here :) + } + } + } + } + protected function customerAlreadyRewarded(int $idCustomer): bool + { + //TODO : check if customer already rewarded + } + protected setAlreadyRewarded(): void + { + //TODO: set customer was rewarded + } + protected function getConfuredOrdersStatesIds(): array + { + //TODO : return array with configured states ids in your module + } + protedect function getCustomerValidOrdersNbr(int $idCustomer): int + { + //TODO : return number of total order valid by customer + } + protected function getRequiredNbrOfTheOrderToReward(): int + { + //TODO : return configured number of orders required to reward the customer + } + protected function createCustomerReward(Customer $customer, Order $order): ?CartRule + { + //TODO: generate customer cart rule (according to the order amount for example) + } + protected function notifyCustomer(Customer $customer, CartRule $cartRule): bool + { + //TODO: notify the customer + } +} +``` \ No newline at end of file From bec400abc82361bd22434243ca0f87afbd8958af Mon Sep 17 00:00:00 2001 From: Jonathan Danse Date: Sat, 22 Oct 2022 14:33:20 +0200 Subject: [PATCH 127/310] Does not use deprecated/alias hook name --- modules/carrier/_index.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/carrier/_index.md b/modules/carrier/_index.md index 8e12e31fae..59709793d6 100644 --- a/modules/carrier/_index.md +++ b/modules/carrier/_index.md @@ -47,12 +47,12 @@ Note about deletion: ## Controlling the change of the carrier's ID -To control the change of the carrier's ID (id_carrier), the module must use the `updateCarrier` hook. +To control the change of the carrier's ID (id_carrier), the module must use the `actionCarrierUpdate` hook. For instance: ```php -public function hookUpdateCarrier($params) +public function hookActionCarrierUpdate($params) { $id_carrier_old = (int) $params['id_carrier']; $id_carrier_new = (int) $params['carrier']->id; From b5d9cf36a101595ac1b5b4bb5b7bce9ca28e2321 Mon Sep 17 00:00:00 2001 From: Thomas NARES Date: Mon, 24 Oct 2022 10:26:16 +0200 Subject: [PATCH 128/310] Update modules/configure-with-cli.md --- modules/configure-with-cli.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/configure-with-cli.md b/modules/configure-with-cli.md index 545c49e5c7..8ebf98c466 100644 --- a/modules/configure-with-cli.md +++ b/modules/configure-with-cli.md @@ -60,7 +60,7 @@ configuration: ``` {{% notice info %}} -Please note that you can only `update` or `delete` values: `create` values are only done when installing the module. +Please note that you can `create` values by specifying them in the `update` section. {{% /notice %}} ### Execute SQL statements from a `.sql` file From 59bf6784c72c41f8bcec4357a752ae630ed89055 Mon Sep 17 00:00:00 2001 From: Thomas Nares Date: Mon, 24 Oct 2022 11:11:48 +0200 Subject: [PATCH 129/310] Re-move pages, fix indentation on exampel --- .../back-office/order/view-order/_index.md | 2 +- .../example-hooks/actionValidateOrder.md | 106 ++++++++++-------- ...tending-sf-form-with-upload-image-field.md | 2 +- ...nd-identifiable-object-form-hooks-usage.md | 1 - .../order-pages-new-hooks/_index.md | 1 - .../additional-action-buttons.md | 1 - .../order-pages-new-hooks/module-base.md | 1 - .../order-pages-new-hooks/signature-widget.md | 1 - 8 files changed, 59 insertions(+), 56 deletions(-) rename modules/sample-modules/{example-hooks => }/grid-and-identifiable-object-form-hooks-usage.md (99%) rename modules/sample-modules/{example-hooks => }/order-pages-new-hooks/_index.md (97%) rename modules/sample-modules/{example-hooks => }/order-pages-new-hooks/additional-action-buttons.md (96%) rename modules/sample-modules/{example-hooks => }/order-pages-new-hooks/module-base.md (99%) rename modules/sample-modules/{example-hooks => }/order-pages-new-hooks/signature-widget.md (99%) diff --git a/development/page-reference/back-office/order/view-order/_index.md b/development/page-reference/back-office/order/view-order/_index.md index 3a1f7e1d87..f326c5dc01 100644 --- a/development/page-reference/back-office/order/view-order/_index.md +++ b/development/page-reference/back-office/order/view-order/_index.md @@ -5,7 +5,7 @@ title: Order view # Order View Page {{% notice tip %}} -**New hooks** are available for this page. Check them out [here]({{< relref "/8/modules/sample-modules/example-hooks/order-pages-new-hooks" >}}) {{< minver v="1.7.7.0" >}} +**New hooks** are available for this page. Check them out [here]({{< relref "/8/modules/sample-modules/order-pages-new-hooks" >}}) {{< minver v="1.7.7.0" >}} {{% /notice %}} This page can be reached by visiting `Sell -> Orders -> Orders -> View (grid row action)`. It allows the Back Office user to view the details of selected order and edit it. The **related code can be found in following locations**: diff --git a/modules/sample-modules/example-hooks/actionValidateOrder.md b/modules/sample-modules/example-hooks/actionValidateOrder.md index d7e72783ab..c2d8130948 100644 --- a/modules/sample-modules/example-hooks/actionValidateOrder.md +++ b/modules/sample-modules/example-hooks/actionValidateOrder.md @@ -32,58 +32,66 @@ A classic use-case for this hook could be : ```php registerHook('actionValidateOrder') ; - } - public function hookActionValidateOrder($params) - { - $orderObject = $params['order']; - $customerObject = $params['customer']; - $hasValidParams = Validate::isLoadedObject($orderObject) && Validate::isLoadedObject($orderObject); - if ($hasValidParams && !$this->customerAlreadyRewarded((int) $customerObject->id)) { - $hasConfiguredState = in_array((int) $orderObject->getCurrentState(), $this->getConfuredOrdersStatesIds()); - $hasCustomerRequiredNbrOfTheOrderToReward = $this->getCustomerValidOrdersNbr((int) $customerObject->id) == $this->getRequiredNbrOfTheOrderToReward(); - if($hasConfiguredState && $hasCustomerRequiredNbrOfTheOrderToReward) { - $customerReward = $this->createCustomerReward($customerObject, $orderObject); - if(Validate::isLoadedObject($customerReward)) { - $this->setAlreadyRewarded($customerObject); - $this->notifyCustomer($customerObject, $customerReward); - - //TODO : of course don't forget to log if something fails here :) - } + return parent::install() && $this->registerHook('actionValidateOrder'); + } + + public function hookActionValidateOrder($params) + { + $orderObject = $params['order']; + $customerObject = $params['customer']; + $hasValidParams = Validate::isLoadedObject($orderObject) && Validate::isLoadedObject($orderObject); + if ($hasValidParams && !$this->customerAlreadyRewarded((int) $customerObject->id)) { + $hasConfiguredState = in_array((int) $orderObject->getCurrentState(), $this->getConfuredOrdersStatesIds()); + $hasCustomerRequiredNbrOfTheOrderToReward = $this->getCustomerValidOrdersNbr((int) $customerObject->id) == $this->getRequiredNbrOfTheOrderToReward(); + if($hasConfiguredState && $hasCustomerRequiredNbrOfTheOrderToReward) { + $customerReward = $this->createCustomerReward($customerObject, $orderObject); + if(Validate::isLoadedObject($customerReward)) { + $this->setAlreadyRewarded($customerObject); + $this->notifyCustomer($customerObject, $customerReward); + + //TODO : of course don't forget to log if something fails here :) } } } - protected function customerAlreadyRewarded(int $idCustomer): bool - { - //TODO : check if customer already rewarded - } - protected setAlreadyRewarded(): void - { - //TODO: set customer was rewarded - } - protected function getConfuredOrdersStatesIds(): array - { - //TODO : return array with configured states ids in your module - } - protedect function getCustomerValidOrdersNbr(int $idCustomer): int - { - //TODO : return number of total order valid by customer - } - protected function getRequiredNbrOfTheOrderToReward(): int - { - //TODO : return configured number of orders required to reward the customer - } - protected function createCustomerReward(Customer $customer, Order $order): ?CartRule - { - //TODO: generate customer cart rule (according to the order amount for example) - } - protected function notifyCustomer(Customer $customer, CartRule $cartRule): bool - { - //TODO: notify the customer - } + } + + protected function customerAlreadyRewarded(int $idCustomer): bool + { + //TODO : check if customer already rewarded + } + + protected setAlreadyRewarded(): void + { + //TODO: set customer was rewarded + } + + protected function getConfuredOrdersStatesIds(): array + { + //TODO : return array with configured states ids in your module + } + + protected function getCustomerValidOrdersNbr(int $idCustomer): int + { + //TODO : return number of total order valid by customer + } + + protected function getRequiredNbrOfTheOrderToReward(): int + { + //TODO : return configured number of orders required to reward the customer + } + + protected function createCustomerReward(Customer $customer, Order $order): ?CartRule + { + //TODO: generate customer cart rule (according to the order amount for example) + } + + protected function notifyCustomer(Customer $customer, CartRule $cartRule): bool + { + //TODO: notify the customer + } } ``` \ No newline at end of file diff --git a/modules/sample-modules/extending-sf-form-with-upload-image-field.md b/modules/sample-modules/extending-sf-form-with-upload-image-field.md index 3851ac42e1..59d64a4a8d 100644 --- a/modules/sample-modules/extending-sf-form-with-upload-image-field.md +++ b/modules/sample-modules/extending-sf-form-with-upload-image-field.md @@ -364,7 +364,7 @@ class SupplierExtraImageRepository extends EntityRepository Let's create hook `hookActionSupplierFormBuilderModifier` function inside Main module class. This is a hook available for [CRUD forms] -({{< relref "/8/modules/sample-modules/example-hooks/grid-and-identifiable-object-form-hooks-usage" >}}) in +({{< relref "/8/modules/sample-modules/grid-and-identifiable-object-form-hooks-usage" >}}) in PrestaShop Symfony pages. ```php diff --git a/modules/sample-modules/example-hooks/grid-and-identifiable-object-form-hooks-usage.md b/modules/sample-modules/grid-and-identifiable-object-form-hooks-usage.md similarity index 99% rename from modules/sample-modules/example-hooks/grid-and-identifiable-object-form-hooks-usage.md rename to modules/sample-modules/grid-and-identifiable-object-form-hooks-usage.md index f14df48751..b55b51ca37 100644 --- a/modules/sample-modules/example-hooks/grid-and-identifiable-object-form-hooks-usage.md +++ b/modules/sample-modules/grid-and-identifiable-object-form-hooks-usage.md @@ -1,7 +1,6 @@ --- title: Grid and identifiable object form hooks usage example weight: 1 -aliases: ["/8/modules/sample-modules/grid-and-identifiable-object-form-hooks-usage/"] --- # Grid and identifiable object form hooks usage example diff --git a/modules/sample-modules/example-hooks/order-pages-new-hooks/_index.md b/modules/sample-modules/order-pages-new-hooks/_index.md similarity index 97% rename from modules/sample-modules/example-hooks/order-pages-new-hooks/_index.md rename to modules/sample-modules/order-pages-new-hooks/_index.md index 0091201f9a..f906ec8d2e 100644 --- a/modules/sample-modules/example-hooks/order-pages-new-hooks/_index.md +++ b/modules/sample-modules/order-pages-new-hooks/_index.md @@ -1,7 +1,6 @@ --- title: Order view page new hooks demo tutorial weight: 2 -aliases: ["/8/modules/sample-modules/order-pages-new-hooks/"] --- # Order pages new hooks demo tutorial diff --git a/modules/sample-modules/example-hooks/order-pages-new-hooks/additional-action-buttons.md b/modules/sample-modules/order-pages-new-hooks/additional-action-buttons.md similarity index 96% rename from modules/sample-modules/example-hooks/order-pages-new-hooks/additional-action-buttons.md rename to modules/sample-modules/order-pages-new-hooks/additional-action-buttons.md index 2078d648ea..f0da93dac7 100644 --- a/modules/sample-modules/example-hooks/order-pages-new-hooks/additional-action-buttons.md +++ b/modules/sample-modules/order-pages-new-hooks/additional-action-buttons.md @@ -1,7 +1,6 @@ --- title: Additional action buttons weight: 3 -aliases: ["/8/modules/sample-modules/order-pages-new-hooks/additional-action-buttons"] --- # Additional buttons in the main buttons bar diff --git a/modules/sample-modules/example-hooks/order-pages-new-hooks/module-base.md b/modules/sample-modules/order-pages-new-hooks/module-base.md similarity index 99% rename from modules/sample-modules/example-hooks/order-pages-new-hooks/module-base.md rename to modules/sample-modules/order-pages-new-hooks/module-base.md index 9485592293..9b976ec983 100644 --- a/modules/sample-modules/example-hooks/order-pages-new-hooks/module-base.md +++ b/modules/sample-modules/order-pages-new-hooks/module-base.md @@ -1,7 +1,6 @@ --- title: Module base creation weight: 1 -aliases: ["/8/modules/sample-modules/order-pages-new-hooks/module-base"] --- # Module base creation diff --git a/modules/sample-modules/example-hooks/order-pages-new-hooks/signature-widget.md b/modules/sample-modules/order-pages-new-hooks/signature-widget.md similarity index 99% rename from modules/sample-modules/example-hooks/order-pages-new-hooks/signature-widget.md rename to modules/sample-modules/order-pages-new-hooks/signature-widget.md index 1fcd6db381..dd02c54c85 100644 --- a/modules/sample-modules/example-hooks/order-pages-new-hooks/signature-widget.md +++ b/modules/sample-modules/order-pages-new-hooks/signature-widget.md @@ -1,7 +1,6 @@ --- title: Signature card weight: 2 -aliases: ["/8/modules/sample-modules/order-pages-new-hooks/signature-widget"] --- # Signature card From e15ee6db682110334c6dc673672fb3d5f42a3628 Mon Sep 17 00:00:00 2001 From: Thomas Nares Date: Thu, 27 Oct 2022 11:49:38 +0200 Subject: [PATCH 130/310] Change current version --- _index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_index.md b/_index.md index 8c0b96dce1..984b552966 100644 --- a/_index.md +++ b/_index.md @@ -3,7 +3,7 @@ title: PrestaShop 8 Documentation menuTitle: PrestaShop 8 versionId: "8" # this should match the physical directory in devdocs-site versionGithubPath: "8.x" # this should match the branch name in github -versionMeta: Dev # only one version can be current! +versionMeta: Current # only one version can be current! chapter: true --- From ccc235e4e38bd966be9200e17dfb57854422e39b Mon Sep 17 00:00:00 2001 From: Sarah Dib Date: Fri, 28 Oct 2022 09:50:26 +0200 Subject: [PATCH 131/310] Update good-practices.md --- modules/creation/good-practices.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/creation/good-practices.md b/modules/creation/good-practices.md index 0319d05bc6..fa79b02cce 100644 --- a/modules/creation/good-practices.md +++ b/modules/creation/good-practices.md @@ -54,7 +54,7 @@ menuTitle: Good practices - show a confirmation message if everything went fine or an error message if it did not. - make sure information entered by customers are correct. If you ask a sum, it has to be only numbers. More information about the Validate class of PrestaShop [here](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Validate.php). -- Consider carefully casting your variables and use pSQL/bqSQL in the SQL requests to avoid any injections (read [Best Practices of the Db Class](https://doc.prestashop.com/display/PS16/Best+Practices+of+the+Db+Class)). Make sure your files are properly protected (especially if your module uses a cron for example) to avoid anyone being able to execute them. As a result, you are required to use a token! +- Consider carefully casting your variables and use pSQL/bqSQL in the SQL requests to avoid any injections (read [Best Practices of the Db Class](https://docs.prestashop-project.org/1-6-documentation/developer-guide/developer-tutorials/best-practices-of-the-db-class)). Make sure your files are properly protected (especially if your module uses a cron for example) to avoid anyone being able to execute them. As a result, you are required to use a token! - The use of overrides is permitted, however if we decide that too many (2 / 3 max) have been used and/or the modifications are too dangerous, we will refuse your module. If you're unsure, don't hesitate to get in touch. From 561e9857a8fc9dcb90e5d0b69f86fe05a544e336 Mon Sep 17 00:00:00 2001 From: Sarah Dib Date: Fri, 28 Oct 2022 09:51:52 +0200 Subject: [PATCH 132/310] Update i-need-help.md --- faq/i-need-help.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/faq/i-need-help.md b/faq/i-need-help.md index e1e44a1de2..8f2a60ab7e 100644 --- a/faq/i-need-help.md +++ b/faq/i-need-help.md @@ -9,7 +9,7 @@ If you have questions or need help, please do not open a GitHub issue as we use The very best place to start looking for an answer is: - Here (the Developer documentation), if you are a developer -- The [User's guide](https://doc.prestashop.com/display/PS17/User+Guide) if you are a user +- The [User's guide](https://docs.prestashop-project.org/1.7-documentation/user-guide) if you are a user {{% notice tip %}} If you are a developer and you think there is a missing item in the Developer documentation, consider [creating an issue on the Documentation Repository](https://github.com/PrestaShop/docs/issues). This will help us discuss what to do to improve it. From 32aa196c4ba57d91445d5dc679fe5333f00bb72a Mon Sep 17 00:00:00 2001 From: Sarah Dib Date: Fri, 28 Oct 2022 09:52:51 +0200 Subject: [PATCH 133/310] Update contribute_using_localhost.md --- .../contribute-pull-requests/contribute_using_localhost.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contribute/contribute-pull-requests/contribute_using_localhost.md b/contribute/contribute-pull-requests/contribute_using_localhost.md index 924648a5ba..f083d57d0b 100644 --- a/contribute/contribute-pull-requests/contribute_using_localhost.md +++ b/contribute/contribute-pull-requests/contribute_using_localhost.md @@ -144,6 +144,6 @@ A good practice is to write meaningful commits labels: it's better to have "Corr See [Submit a Pull Request]({{< relref "create-pull-request" >}}). -[getting-started-guide]: https://doc.prestashop.com/display/PS17/Getting+Started +[getting-started-guide]: https://docs.prestashop-project.org/1.7-documentation/user-guide [system-requirements]: {{< relref "/8/basics/installation/system-requirements" >}} [compile-assets]: {{< relref "/8/development/compile-assets" >}} From 74ca38c2df33794b4c1b705923f4691bb654a65c Mon Sep 17 00:00:00 2001 From: Thomas Nares Date: Fri, 28 Oct 2022 11:18:10 +0200 Subject: [PATCH 134/310] Change other referencces to doc.prestashop.com --- basics/installation/configuration.md | 2 +- basics/installation/localhost.md | 2 +- basics/keeping-up-to-date/migration.md | 2 +- development/components/back-office-help-sidebar.md | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/basics/installation/configuration.md b/basics/installation/configuration.md index b0ae071a25..97c47f9f17 100644 --- a/basics/installation/configuration.md +++ b/basics/installation/configuration.md @@ -48,7 +48,7 @@ Enabling the multistore mode is easy: go to the general preferences page, and pu You can switch back and forth between single store and multistore mode. In single store mode, only the main store is used. -You can read more about the multistore mode in [PrestaShop 1.7 User Guide](https://doc.prestashop.com/display/PS17/Managing+Multiple+Shops). +You can read more about the multistore mode in [PrestaShop 1.7 User Guide](https://docs.prestashop-project.org/1.7-documentation/user-guide/managing-multiple-stores). ## About the configuration files diff --git a/basics/installation/localhost.md b/basics/installation/localhost.md index 2926ff62c7..26e921da58 100644 --- a/basics/installation/localhost.md +++ b/basics/installation/localhost.md @@ -227,7 +227,7 @@ You may find this error message the first time you open up the Back Office. This problem may arise in case-insensitive file systems like MacOS due to a misconfiguration. Check your Apache configuration and make sure that the root directory path to your PrestaShop matches the capitalization of the actual system path exactly. A typical error is for example having a folder named `/path/to/PrestaShop` (capital P, capital S) and then configuring it in Apache as `/path/to/Prestashop` (missing the capital S). -[getting-started-guide]: https://doc.prestashop.com/display/PS17/Getting+Started +[getting-started-guide]: https://docs.prestashop-project.org/1.7-documentation/getting-started [system-requirements]: {{< relref "system-requirements" >}} [clone-the-repository]: {{< relref "/8/themes/getting-started/setting-up-your-local-environment" >}} [compile-assets]: {{< relref "/8/development/compile-assets" >}} diff --git a/basics/keeping-up-to-date/migration.md b/basics/keeping-up-to-date/migration.md index 61cf921aa8..c9ffd3c39f 100644 --- a/basics/keeping-up-to-date/migration.md +++ b/basics/keeping-up-to-date/migration.md @@ -618,7 +618,7 @@ PrestaShop. It must be enabled from the administration panel before being accessible. See the doc for more details: -https://doc.prestashop.com/display/PS17/Webservice +https://docs.prestashop-project.org/1.7-documentation/user-guide/configuring-shop/advanced-parameters/webservice Once ready, an API will be available for all the resources enabled for your key. Basically, the web-service in another interface for object diff --git a/development/components/back-office-help-sidebar.md b/development/components/back-office-help-sidebar.md index e90d556e6b..8bbd802dae 100644 --- a/development/components/back-office-help-sidebar.md +++ b/development/components/back-office-help-sidebar.md @@ -16,7 +16,7 @@ Most of these Back Office pages have a common HTML structure: When the BO user clicks on the 'Help' button, the sidebar opens and displays the related Documentation page for the Back Office page that the user browses. -This documentation page comes from help.prestashop.com which is a gateway that returns the content of doc.prestashop.com in the right format to be inserted into the Back Office. +This documentation page comes from help.prestashop.com which is a gateway that returns the content of docs.prestashop-project.org in the right format to be inserted into the Back Office. ## How it is built for modern controllers From fcaf047ee4d6f37d26a72c3230d8c3caa26b0d15 Mon Sep 17 00:00:00 2001 From: Thomas Nares Date: Mon, 31 Oct 2022 10:47:01 +0100 Subject: [PATCH 135/310] add symfony hooks --- modules/concepts/hooks/_index.md | 31 ++++++++++++++++++------- modules/concepts/hooks/list-of-hooks.md | 12 +--------- 2 files changed, 23 insertions(+), 20 deletions(-) diff --git a/modules/concepts/hooks/_index.md b/modules/concepts/hooks/_index.md index 5fa61aae9c..4867172ce2 100644 --- a/modules/concepts/hooks/_index.md +++ b/modules/concepts/hooks/_index.md @@ -29,7 +29,6 @@ Hook names are prefixed with "action" or "display". This prefix indicates if a h Every hook you want to use must be registered first. This is usually done during the installation of your module, by calling the method `Module::registerHook($hookName)`. ```php -context->smarty->assign( 'HOOK_LEFT_COLUMN', Hook::exec('displayLeftColumn') ); ``` +### In a controller (Symfony) -#### In a theme +In a Symfony controller, please use the dispatchHook method of the inherited `FrameworkBundleAdminController` class: + +```php +protected function dispatchHook($hookName, array $parameters); +``` + + +### In a theme, with Smarty It is easy to call a hook from within a template file (`.tpl`): you simply have to use its name with the hook function. You can add the name of a module that you want the hook execute. Basic call of a hook: ``` -{hook h='displayLeftColumn'} +{hook h='hookName'} ``` Call of a hook for a specific module: ``` -{hook h='displayLeftColumn' mod='blockcart'} +{hook h='hookName' mod='modulename'} +``` + +### In a theme, with Twig + +It is easy to call a hook from within a twig template file (`.html.twig`): you simply have to use its name with the renderHook twig function. You can add params as a second argument. + +Basic call of a hook: + +``` +{{ renderHook('hookName', { params }) }} ``` ## Going further: Creating your own hook @@ -106,7 +121,6 @@ Call of a hook for a specific module: You can create new PrestaShop hooks by adding a new record in the Hook table. This can be done with the Hook class, which inherit ObjectModel features: ```php -name = 'displayAtSpecificPlace'; $hook->title = 'The name of your hook'; @@ -120,7 +134,6 @@ You can check if hook exists before this with Hook::getIdByName('hook_name') ...but PrestaShop enables you to do it the easy way: ```php -registerHook('displayAtSpecificPlace'); ``` diff --git a/modules/concepts/hooks/list-of-hooks.md b/modules/concepts/hooks/list-of-hooks.md index 47abc8ce0a..1bdab9bbb0 100644 --- a/modules/concepts/hooks/list-of-hooks.md +++ b/modules/concepts/hooks/list-of-hooks.md @@ -3,17 +3,7 @@ title: List of hooks weight: 2 --- -# List of hooks in PrestaShop 1.7 - -## Update notes - -A couple of hooks were modified between 1.7.0.x and 1.7.1.x. - -* `actionDeleteProductInCartAfter` has been divided into two hooks: - * `actionObjectProductInCartDeleteBefore`. - * `actionObjectProductInCartDeleteAfter`. -* `displayProductButtons` has been renamed into `displayProductAdditionalInfo`.
- Don’t worry, we kept an alias :) +# List of hooks in PrestaShop 8 ## Full list From e835af524454f5e06e71906566aef1a6e2db61b4 Mon Sep 17 00:00:00 2001 From: Pablo Borowicz Date: Tue, 11 Oct 2022 12:50:48 +0200 Subject: [PATCH 136/310] Move configuration into its own category & add list of configurations --- basics/deployment/_index.md | 2 +- basics/installation/_index.md | 2 +- basics/installation/configuration.md | 119 ------- basics/introduction.md | 2 +- basics/keeping-up-to-date/_index.md | 2 +- contribute/documentation/shortcodes/ref.md | 4 +- development/configuration/_index.md | 10 + .../configuration/configuring-prestashop.md | 105 ++++++ development/configuration/list-of-settings.md | 315 ++++++++++++++++++ 9 files changed, 436 insertions(+), 125 deletions(-) delete mode 100644 basics/installation/configuration.md create mode 100644 development/configuration/_index.md create mode 100644 development/configuration/configuring-prestashop.md create mode 100644 development/configuration/list-of-settings.md diff --git a/basics/deployment/_index.md b/basics/deployment/_index.md index 0b78074608..c8bcba8b23 100644 --- a/basics/deployment/_index.md +++ b/basics/deployment/_index.md @@ -1,6 +1,6 @@ --- title: Deployment -weight: 18 +weight: 40 --- # Deployment diff --git a/basics/installation/_index.md b/basics/installation/_index.md index 229d8e08b8..787d82a696 100644 --- a/basics/installation/_index.md +++ b/basics/installation/_index.md @@ -1,6 +1,6 @@ --- title: Installation -weight: 15 +weight: 20 --- # Installation diff --git a/basics/installation/configuration.md b/basics/installation/configuration.md deleted file mode 100644 index 97c47f9f17..0000000000 --- a/basics/installation/configuration.md +++ /dev/null @@ -1,119 +0,0 @@ ---- -title: Configuration -weight: 30 ---- - -# Configuring PrestaShop - -By default, PrestaShop is configured to provide a secure and stable environment to both the shop administrator and the customers. - -As a developer, there are several changes that you could and should bring to the default installation in order to help you code better, spot bugs faster, and generally make a great PrestaShop product. - -## Disabling the cache and forcing Smarty compilation - -When your development has an impact on the front office, whether you are building a theme or simply a module which displays information to the customer, you should force the template file compilation and disable the cache, so as to always see the result of your changes directly. - -Go to the “Performance” page under the “Advanced parameters” menu to change the following Smarty settings: - -* Template cache: switch it to “Force compilation”. -* Cache: disable it. - -Forcing the compilation of Smarty will always slow down the loading time of the page. Make sure that your production store is set to only recompile templates if there are updated files, and that its cache is enabled. - -## Displaying error messages - -PrestaShop’s default settings prevent the customer to see any server error message or any debugging code. - -You, on the other hand, need this information in order to correct any potential mistake in your code. To that end, open the `/config/defines.inc.php` file, and edit it to set `_PS_MODE_DEV_` to `true`: - -```php -caching = false;` as it is. - -`$smarty->compile_check` should be left to `false` in development mode. - -`$smarty->debugging` gives access to Smarty debug information when displaying a page. That setting is more easily modified in the “Performance” page of the advanced parameters menu : the “Debug console” option enables you to choose between never displaying Smarty’s debug information, always displaying it, or only displaying it when you add `?SMARTY_DEBUG` to the URL of the page you want to test, which can be very useful. - -When in production mode, `$smarty->force_compile` must be set to `false`, as it will give a 30% boost to your page load time. - -On the other hand, when editing a `.tpl` file, you must delete the `/var/cache/(dev|prod)/smarty/compile` folder (except the `index.php` file) in order to see your changes applied or clear cache directly from Back-Office. - -Note that this setting can be made directly from the back office, in the “Performance” page under the “Advanced parameters” menu. - -### parameters.php - -This file contains some of important settings such as database connection details and caching mechanism. If you change something in this file, make sure to delete cache files manually from `/var/cache/(dev|prod)` folder. - -## Disable the Back-Office token protection - -Back-Office pages require the use of a token. If needed, this protection can be disabled using an environment variable: - -### Apache with mod_headers - -```bash -SetEnv _TOKEN_ disabled -``` - -### Nginx with ngx_http_headers_module - -```bash -add_header _TOKEN_ disabled; -``` diff --git a/basics/introduction.md b/basics/introduction.md index 068a48c2db..bb91cb12eb 100644 --- a/basics/introduction.md +++ b/basics/introduction.md @@ -1,6 +1,6 @@ --- title: Introduction -weight: 5 +weight: 10 --- # Fundamentals of PrestaShop Development diff --git a/basics/keeping-up-to-date/_index.md b/basics/keeping-up-to-date/_index.md index 40288e332a..2eabb20e36 100644 --- a/basics/keeping-up-to-date/_index.md +++ b/basics/keeping-up-to-date/_index.md @@ -1,7 +1,7 @@ --- menuTitle: Staying up-to-date title: Keep PrestaShop up-to-date -weight: 20 +weight: 50 --- # Keep PrestaShop up-to-date diff --git a/contribute/documentation/shortcodes/ref.md b/contribute/documentation/shortcodes/ref.md index dbcfb254ff..f47f505c57 100644 --- a/contribute/documentation/shortcodes/ref.md +++ b/contribute/documentation/shortcodes/ref.md @@ -9,13 +9,13 @@ weight: 1 To link to another page in the documentation, use `ref`: - [This is a link to Configuration]({{}}) + [This is a link to Configuration]({{}}) Rendered result: {{% callout %}} -[This is a link to Configuration]({{< ref "/8/basics/installation/configuration" >}}) +[This is a link to Configuration]({{< ref "/8/development/configuration" >}}) {{% /callout %}} {{% notice tip %}} diff --git a/development/configuration/_index.md b/development/configuration/_index.md new file mode 100644 index 0000000000..30c5f85049 --- /dev/null +++ b/development/configuration/_index.md @@ -0,0 +1,10 @@ +--- +title: Configuration +weight: 40 +aliases: + - /8/basics/installation/configuration +--- + +# PrestaShop configuration reference + +{{% children %}} diff --git a/development/configuration/configuring-prestashop.md b/development/configuration/configuring-prestashop.md new file mode 100644 index 0000000000..3c0f31b750 --- /dev/null +++ b/development/configuration/configuring-prestashop.md @@ -0,0 +1,105 @@ +--- +title: Configuring PrestaShop +--- + +# Introduction to configuration + +## Storage & access + +Most of PrestaShop's configuration is stored in the `ps_configuration` database table and is accessible through the [Configuration storage service][configuration-storage]. + +Some settings are hard coded as constants. + +## Configuration files + +PrestaShop has four main configuration files: + +* `/config/config.inc.php` +* `/config/defines.inc.php` +* `/config/smarty.config.inc.php` +* `/app/config/parameters.php` + +### config.inc.php + +It is the main configuration file for PrestaShop. You should not need to touch anything in there. + +### defines.inc.php + +This file contains PrestaShop constant values. + +It also contains the location of all the files and folders. If you need to change their location, do not forget to keep the original path nearby, for instance in a PHP comment, in case you need to revert back to it later on. + +You can override constant values from this file by setting them in `/config/defines_custom.inc.php`. This is also a great place to put your custom constants which needs to be available globally in the system. + +### smarty.config.inc.php + +This file contains all the Smarty-related settings. + +The Smarty cache system should always be disabled, as it is not compatible with PrestaShop: keep `$smarty->caching = false;` as it is. + +`$smarty->compile_check` should be left to `false` in development mode. + +`$smarty->debugging` gives access to Smarty debug information when displaying a page. That setting is more easily modified in the “Performance” page of the advanced parameters menu : the “Debug console” option enables you to choose between never displaying Smarty’s debug information, always displaying it, or only displaying it when you add `?SMARTY_DEBUG` to the URL of the page you want to test, which can be very useful. + +When in production mode, `$smarty->force_compile` must be kept to `false`, as it will give a 30% boost to your page load time. + +On the other hand, when editing a `.tpl` file, you must delete the `/var/cache/(dev|prod)/smarty/compile` folder (except the `index.php` file) in order to see your changes applied or clear cache directly from Back-Office. + +Note that this setting can be made directly from the back office, in the “Performance” page under the “Advanced parameters” menu. + +### parameters.php + +This file contains some of important settings such as database connection details and caching mechanism. If you change something in this file, make sure to delete cache files manually from `/var/cache/(dev|prod)` folder. + +## Enabling debug mode + +PrestaShop’s default settings prevent customers from seeing any server error message or debugging code. + +You, on the other hand, might need this information in order to correct any potential problem. To that end, you can activate the Debug mode. + +Open the `/config/defines.inc.php` file, and edit it to set `_PS_MODE_DEV_` to `true`: + +```php +define('_PS_MODE_DEV_', true); +``` + +You can also enable developer mode directly from your Back office: go to _Advanced parameters > Performance_, then change the "Debug mode" setting to "Yes". + +{{% notice tip %}} +**Inspecting variables** + +You can use Symfony's powerful [`dump()`](https://symfony.com/doc/current/components/var_dumper.html#the-dump-function) function to display the content of a variable. This function is only available when the Debug mode is on. +{{% /notice %}} + +**The Debug mode produces a significant performance hit**, don't forget to disable it as soon as you finish debugging your code! + +## Disabling the cache and forcing Smarty compilation + +When your development has an impact on the front office, whether you are building a theme or simply a module which displays information to the customer, you should force the template file compilation and disable the cache, so as to always see the result of your changes directly. + +Go to the “Performance” page under the “Advanced parameters” menu to change the following Smarty settings: + +* Template compilation: switch it to “Force compilation”. +* Cache: disable it. + +Forcing the compilation of Smarty will always slow down the loading time of the page. Make sure that your production store is set to only recompile templates if there are updated files, and that its cache is enabled. + + +## Disable the Back-Office token protection + +Back-Office pages require the use of a token. If needed, this protection can be disabled using an environment variable: + +### Apache with mod_headers + +```bash +SetEnv _TOKEN_ disabled +``` + +### Nginx with ngx_http_headers_module + +```bash +add_header _TOKEN_ disabled; +``` + +[configuration-storage]: {{< relref "/8/development/components/configuration/" >}} + diff --git a/development/configuration/list-of-settings.md b/development/configuration/list-of-settings.md new file mode 100644 index 0000000000..39a33ce70e --- /dev/null +++ b/development/configuration/list-of-settings.md @@ -0,0 +1,315 @@ +--- +title: List of settings +--- + +# List of configuration settings + +The following settings are set up in `ps_configuration` by default when installing PrestaShop. + +## Core + +| Configuration name | Type | Default | Description +|--------------------------------------------|:------:|:--------:|-------------------------------------------------------------------------- +| ADDONS_API_MODULE_CHANNEL | string | "stable" | (Deprecated since 8.0) Addons marketplace stability channel +| CONF_AVERAGE_PRODUCT_MARGIN | int | 40 | Average gross margin percentage per sale, used to calculate profits on the Dashboard +| PRESTASTORE_LIVE | | | +| PS_ADVANCED_STOCK_MANAGEMENT | | | +| PS_ALIAS_FEATURE_ACTIVE | | | +| PS_ALLOWED_COUNTRIES | | | +| PS_ALLOW_MOBILE_DEVICE | | | +| PS_ATTACHMENT_MAXIMUM_SIZE | | | +| PS_ATTRIBUTE_ANCHOR_SEPARATOR | | | +| PS_ATTRIBUTE_CATEGORY_DISPLAY | | | +| PS_BACKUP_ALL | | | +| PS_BACKUP_DROP_TABLE | | | +| PS_BASE_DISTANCE_UNIT | | | +| PS_BLOCK_BESTSELLERS_DISPLAY | | | +| PS_BLOCK_CART_AJAX | | | +| PS_BLOCK_NEWPRODUCTS_DISPLAY | | | +| PS_BLOCK_SPECIALS_DISPLAY | | | +| PS_CANONICAL_REDIRECT | | | +| PS_CARRIER_DEFAULT | int | 1 | Default carrier Id +| PS_CARRIER_DEFAULT_ORDER | | | +| PS_CARRIER_DEFAULT_SORT | | | +| PS_CART_RULE_FEATURE_ACTIVE | | | +| PS_CATALOG_MODE | | | +| PS_CATALOG_MODE_WITH_PRICES | | | +| PS_CIPHER_ALGORITHM | | | +| PS_COMBINATION_FEATURE_ACTIVE | | | +| PS_CONDITIONS | | | +| PS_CONDITIONS_CMS_ID | | | +| PS_CONFIGURATION_AGREMENT | | | +| PS_COOKIE_CHECKIP | | | +| PS_COOKIE_LIFETIME_BO | | | +| PS_COOKIE_LIFETIME_FO | | | +| PS_COOKIE_SAMESITE | | | +| PS_COUNTRY_DEFAULT | int | 8 | Shop's default country Id (chosen during install) +| PS_CURRENCY_DEFAULT | int | 1 | Default currency Id +| PS_CUSTOMER_BIRTHDATE | | | +| PS_CUSTOMER_CREATION_EMAIL | | | +| PS_CUSTOMER_GROUP | | | +| PS_CUSTOMER_OPTIN | | | +| PS_CUSTOMER_SERVICE_FILE_UPLOAD | | | +| PS_CUSTOMER_SERVICE_SIGNATURE | | | +| PS_CUSTOMIZATION_FEATURE_ACTIVE | | | +| PS_DASHBOARD_SIMULATION | | | +| PS_DELIVERY_NUMBER | | | +| PS_DELIVERY_PREFIX | | | +| PS_DETECT_COUNTRY | | | +| PS_DETECT_LANG | | | +| PS_DIMENSION_UNIT | | | +| PS_DISALLOW_HISTORY_REORDERING | | | +| PS_DISPLAY_BEST_SELLERS | | | +| PS_DISPLAY_MANUFACTURERS | | | +| PS_DISPLAY_PRODUCT_WEIGHT | | | +| PS_DISPLAY_QTIES | | | +| PS_DISPLAY_SUPPLIERS | | | +| PS_DISP_UNAVAILABLE_ATTR | | | +| PS_DISTANCE_UNIT | | | +| PS_FAVICON | | | +| PS_FEATURE_FEATURE_ACTIVE | | | +| PS_GEOLOCATION_BEHAVIOR | | | +| PS_GEOLOCATION_ENABLED | | | +| PS_GEOLOCATION_WHITELIST | | | +| PS_GIFT_WRAPPING | | | +| PS_GIFT_WRAPPING_PRICE | | | +| PS_GROUP_FEATURE_ACTIVE | bit | 1 | Enable/disable customer groups +| PS_GUEST_CHECKOUT_ENABLED | | | +| PS_GUEST_GROUP | | | +| PS_HOME_CATEGORY | | | +| PS_IMAGE_QUALITY | | | +| PS_IMG_UPDATE_TIME | | | +| PS_INVCE_DELIVERY_ADDR_RULES | | | +| PS_INVCE_INVOICE_ADDR_RULES | | | +| PS_INVOICE | | | +| PS_INVOICE_MODEL | | | +| PS_INVOICE_PREFIX | | | +| PS_JPEG_QUALITY | | | +| PS_LABEL_IN_STOCK_PRODUCTS | | | +| PS_LABEL_OOS_PRODUCTS_BOA | | | +| PS_LABEL_OOS_PRODUCTS_BOD | | | +| PS_LAST_QTIES | | | +| PS_LEGACY_IMAGES | | | +| PS_LIMIT_UPLOAD_FILE_VALUE | | | +| PS_LIMIT_UPLOAD_IMAGE_VALUE | | | +| PS_LOCALE_COUNTRY | | | +| PS_LOCALE_LANGUAGE | | | +| PS_LOGO | | | +| PS_LOGS_BY_EMAIL | | | +| PS_LOGS_EMAIL_RECEIVERS | | | +| PS_LOG_EMAILS | | | +| PS_LOG_MODULE_PERFS_MODULO | | | +| PS_MAIL_COLOR | | | +| PS_MAIL_DKIM_DOMAIN | | | +| PS_MAIL_DKIM_ENABLE | | | +| PS_MAIL_DKIM_KEY | | | +| PS_MAIL_DKIM_SELECTOR | | | +| PS_MAIL_METHOD | | | +| PS_MAIL_PASSWD | | | +| PS_MAIL_SERVER | | | +| PS_MAIL_SMTP_ENCRYPTION | | | +| PS_MAIL_SMTP_PORT | | | +| PS_MAIL_THEME | | | +| PS_MAIL_TYPE | | | +| PS_MAIL_USER | | | +| PS_MAINTENANCE_TEXT | | | +| PS_NAVIGATION_PIPE | | | +| PS_NB_DAYS_NEW_PRODUCT | | | +| PS_ORDER_OUT_OF_STOCK | | | +| PS_ORDER_PRODUCTS_NB_PER_PAGE | | | +| PS_ORDER_RECALCULATE_SHIPPING | | | +| PS_ORDER_RETURN | | | +| PS_ORDER_RETURN_NB_DAYS | | | +| PS_OS_BANKWIRE | | | +| PS_OS_CANCELED | | | +| PS_OS_CHEQUE | | | +| PS_OS_COD_VALIDATION | | | +| PS_OS_DELIVERED | | | +| PS_OS_ERROR | | | +| PS_OS_OUTOFSTOCK | | | +| PS_OS_OUTOFSTOCK_PAID | | | +| PS_OS_OUTOFSTOCK_UNPAID | | | +| PS_OS_PAYMENT | | | +| PS_OS_PREPARATION | | | +| PS_OS_REFUND | | | +| PS_OS_SHIPPING | | | +| PS_OS_WS_PAYMENT | | | +| PS_PACK_FEATURE_ACTIVE | | | +| PS_PACK_STOCK_TYPE | | | +| PS_PASSWD_RESET_VALIDITY | | | +| PS_PASSWD_TIME_BACK | | | +| PS_PASSWD_TIME_FRONT | | | +| PS_PAYMENT_LOGO_CMS_ID | | | +| PS_PNG_QUALITY | | | +| PS_PRICE_ROUND_MODE | | | +| PS_PRODUCTS_ORDER_BY | | | +| PS_PRODUCTS_ORDER_WAY | | | +| PS_PRODUCTS_PER_PAGE | | | +| PS_PRODUCT_PICTURE_HEIGHT | | | +| PS_PRODUCT_PICTURE_MAX_SIZE | | | +| PS_PRODUCT_PICTURE_WIDTH | | | +| PS_PRODUCT_SHORT_DESC_LIMIT | | | +| PS_PRODUCT_WEIGHT_PRECISION | | | +| PS_PURCHASE_MINIMUM | | | +| PS_RECYCLABLE_PACK | | | +| PS_RESTRICT_DELIVERED_COUNTRIES | | | +| PS_RETURN_PREFIX | | | +| PS_ROOT_CATEGORY | | | +| PS_ROUND_TYPE | | | +| PS_SEARCH_AJAX | | | +| PS_SEARCH_BLACKLIST | | | +| PS_SEARCH_FUZZY | | | +| PS_SEARCH_FUZZY_MAX_LOOP | | | +| PS_SEARCH_INDEXATION | | | +| PS_SEARCH_MAX_WORD_LENGTH | | | +| PS_SEARCH_MINWORDLEN | | | +| PS_SEARCH_WEIGHT_ATTRIBUTE | | | +| PS_SEARCH_WEIGHT_CNAME | | | +| PS_SEARCH_WEIGHT_DESC | | | +| PS_SEARCH_WEIGHT_FEATURE | | | +| PS_SEARCH_WEIGHT_MNAME | | | +| PS_SEARCH_WEIGHT_PNAME | | | +| PS_SEARCH_WEIGHT_REF | | | +| PS_SEARCH_WEIGHT_SHORTDESC | | | +| PS_SEARCH_WEIGHT_TAG | | | +| PS_SECURITY_PASSWORD_POLICY_MAXIMUM_LENGTH | | | +| PS_SECURITY_PASSWORD_POLICY_MINIMUM_LENGTH | | | +| PS_SECURITY_PASSWORD_POLICY_MINIMUM_SCORE | | | +| PS_SECURITY_TOKEN | | | +| PS_SHIPPING_FREE_PRICE | | | +| PS_SHIPPING_FREE_WEIGHT | | | +| PS_SHIPPING_HANDLING | | | +| PS_SHIPPING_METHOD | | | +| PS_SHOP_ACTIVITY | | | +| PS_SHOP_DEFAULT | | | +| PS_SHOP_DOMAIN | | | +| PS_SHOP_DOMAIN_SSL | | | +| PS_SHOP_EMAIL | | | +| PS_SHOP_ENABLE | | | +| PS_SHOP_NAME | | | +| PS_SHOW_ALL_MODULES | | | +| PS_SHOW_LABEL_OOS_LISTING_PAGES | | | +| PS_SHOW_NEW_CUSTOMERS | | | +| PS_SHOW_NEW_MESSAGES | | | +| PS_SHOW_NEW_ORDERS | | | +| PS_SMARTY_CACHE | | | +| PS_SMARTY_CLEAR_CACHE | | | +| PS_SMARTY_CONSOLE | | | +| PS_SMARTY_CONSOLE_KEY | | | +| PS_SMARTY_FORCE_COMPILE | | | +| PS_SMARTY_LOCAL | | | +| PS_SPECIFIC_PRICE_FEATURE_ACTIVE | | | +| PS_SPECIFIC_PRICE_PRIORITIES | | | +| PS_SSL_ENABLED | | | +| PS_STATSDATA_CUSTOMER_PAGESVIEWS | | | +| PS_STATSDATA_PAGESVIEWS | | | +| PS_STATSDATA_PLUGINS | | | +| PS_STATS_GRID_RENDER | | | +| PS_STATS_OLD_CONNECT_AUTO_CLEAN | | | +| PS_STATS_RENDER | | | +| PS_STOCK_CUSTOMER_ORDER_CANCEL_REASON | | | +| PS_STOCK_CUSTOMER_ORDER_REASON | | | +| PS_STOCK_CUSTOMER_RETURN_REASON | | | +| PS_STOCK_MANAGEMENT | | | +| PS_STOCK_MVT_DEC_EMPLOYEE_EDITION | | | +| PS_STOCK_MVT_DEC_REASON_DEFAULT | | | +| PS_STOCK_MVT_INC_EMPLOYEE_EDITION | | | +| PS_STOCK_MVT_INC_REASON_DEFAULT | | | +| PS_STOCK_MVT_REASON_DEFAULT | | | +| PS_STOCK_MVT_SUPPLY_ORDER | | | +| PS_STOCK_MVT_TRANSFER_FROM | | | +| PS_STOCK_MVT_TRANSFER_TO | | | +| PS_STORES_DISPLAY_CMS | | | +| PS_STORES_ICON | | | +| PS_TAX | | | +| PS_TAX_ADDRESS_TYPE | | | +| PS_TAX_DISPLAY | | | +| PS_THEME_V11 | | | +| PS_TIMEZONE | | | +| PS_TIN_ACTIVE | | | +| PS_TOKEN_ENABLE | | | +| PS_UNIDENTIFIED_GROUP | | | +| PS_USE_ECOTAX | | | +| PS_USE_HTMLPURIFIER | | | +| PS_VIRTUAL_PROD_FEATURE_ACTIVE | | | +| PS_VOLUME_UNIT | | | +| PS_WEBP_QUALITY | | | +| PS_WEIGHT_UNIT | | | +| SHOP_LOGO_HEIGHT | | | +| SHOP_LOGO_WIDTH | | | +| blockcontact_email | | | +| blockcontact_telnumber | | | +| blockcontactinfos_address | | | +| blockcontactinfos_company | | | +| blockcontactinfos_email | | | +| blockcontactinfos_phone | | | + +## Modules + +| Configuration name | Type | Default | Module +|--------------------------------------------|:--------:|:----------:|------------------------------ +| BLOCK_CATEG_MAX_DEPTH | int | 4 | ps_categorytree +| BLOCK_CATEG_ROOT_CATEGORY | int | 1 | ps_categorytree +| BLOCK_CATEG_NBR_COLUMN_FOOTER | | | +| CHECKUP_DESCRIPTIONS_GT | | | statscheckup +| CHECKUP_DESCRIPTIONS_LT | | | statscheckup +| CHECKUP_IMAGES_GT | | | statscheckup +| CHECKUP_IMAGES_LT | | | statscheckup +| CHECKUP_SALES_GT | | | statscheckup +| CHECKUP_SALES_LT | | | statscheckup +| CHECKUP_STOCK_GT | | | statscheckup +| CHECKUP_STOCK_LT | | | statscheckup +| HOME_FEATURED_NBR | | | ps_featuredproducts +| MOD_BLOCKTOPMENU_ITEMS | | | ps_mainmenu +| MOD_BLOCKTOPMENU_SEARCH | | | ps_mainmenu +| NEW_PRODUCTS_NBR | | | ps_newproducts +| NW_SALT | | | ps_emailsubscription +| PRODUCTS_VIEWED_NBR | | | ps_viewedproduct +| SUPPLIER_DISPLAY_FORM | | | ps_supplierlist +| SUPPLIER_DISPLAY_TEXT | | | ps_supplierlist +| SUPPLIER_DISPLAY_TEXT_NB | | | ps_supplierlist +| BLOCKSOCIAL_FACEBOOK | | | ps_socialfollow +| BLOCKSOCIAL_RSS | | | ps_socialfollow +| BLOCKSOCIAL_TWITTER | | | ps_socialfollow + +## Obsolete + +| Configuration name +|-------------------------------------------- +| BANK_WIRE_CURRENCIES +| BLOCKADVERT_IMG_EXT +| BLOCKADVERT_LINK +| BLOCKREINSURANCE_NBBLOCKS +| BLOCKSTORE_IMG +| BLOCKTAGS_NBR +| BLOCK_CATEG_DHTML +| CHEQUE_CURRENCIES +| EDITORIAL_IMAGE_HEIGHT +| EDITORIAL_IMAGE_WIDTH +| FOOTER_BLOCK_ACTIVATION +| FOOTER_CMS +| FOOTER_POWEREDBY +| HOMESLIDER_LOOP +| HOMESLIDER_PAUSE +| HOMESLIDER_SPEED +| HOMESLIDER_WIDTH +| MANUFACTURER_DISPLAY_FORM +| MANUFACTURER_DISPLAY_TEXT +| MANUFACTURER_DISPLAY_TEXT_NB +| MB_CANCEL_URL +| MB_DISPLAY_MODE +| MB_HIDE_LOGIN +| MB_ID_LOGO +| MB_ID_LOGO_WALLET +| MB_INTER_METHODS +| MB_LOCAL_METHODS +| MB_PARAMETERS +| MB_PARAMETERS_2 +| MB_PAY_TO_EMAIL +| MB_SECRET_WORD +| PS_1_3_2_UPDATE_DATE +| PS_1_3_UPDATE_DATE +| SEK_FILTER_KW +| SEK_MIN_OCCURENCES +| UPGRADER_BACKUPDB_FILENAME +| UPGRADER_BACKUPFILES_FILENAME From 56b90c38fef5304f67a46bf21f0c386572acfa63 Mon Sep 17 00:00:00 2001 From: Pablo Borowicz Date: Wed, 12 Oct 2022 16:38:59 +0200 Subject: [PATCH 137/310] Rewording Co-authored-by: Thomas NARES --- development/configuration/configuring-prestashop.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/development/configuration/configuring-prestashop.md b/development/configuration/configuring-prestashop.md index 3c0f31b750..252aab5eb6 100644 --- a/development/configuration/configuring-prestashop.md +++ b/development/configuration/configuring-prestashop.md @@ -45,7 +45,7 @@ When in production mode, `$smarty->force_compile` must be kept to `false`, as it On the other hand, when editing a `.tpl` file, you must delete the `/var/cache/(dev|prod)/smarty/compile` folder (except the `index.php` file) in order to see your changes applied or clear cache directly from Back-Office. -Note that this setting can be made directly from the back office, in the “Performance” page under the “Advanced parameters” menu. +Note that this configuration can be set up directly from the back office, in the “Performance” page under the “Advanced parameters” menu. ### parameters.php @@ -55,7 +55,7 @@ This file contains some of important settings such as database connection detail PrestaShop’s default settings prevent customers from seeing any server error message or debugging code. -You, on the other hand, might need this information in order to correct any potential problem. To that end, you can activate the Debug mode. +You, on the other hand, might need this information in order to correct any potential problem. For this purpose, you can activate the Debug mode. Open the `/config/defines.inc.php` file, and edit it to set `_PS_MODE_DEV_` to `true`: @@ -75,7 +75,7 @@ You can use Symfony's powerful [`dump()`](https://symfony.com/doc/current/compon ## Disabling the cache and forcing Smarty compilation -When your development has an impact on the front office, whether you are building a theme or simply a module which displays information to the customer, you should force the template file compilation and disable the cache, so as to always see the result of your changes directly. +When your development has an impact on the front office, whether you are building a theme or simply a module which displays information to the customer, you should force the template file compilation and disable the cache, in order to always see the result of your changes directly. Go to the “Performance” page under the “Advanced parameters” menu to change the following Smarty settings: From 631e419540040a0840dbcd2185ab2b877366057b Mon Sep 17 00:00:00 2001 From: Pablo Borowicz Date: Mon, 31 Oct 2022 18:59:43 +0100 Subject: [PATCH 138/310] Fix typos Co-authored-by: Krystian Podemski --- development/configuration/configuring-prestashop.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/development/configuration/configuring-prestashop.md b/development/configuration/configuring-prestashop.md index 252aab5eb6..a952b750bd 100644 --- a/development/configuration/configuring-prestashop.md +++ b/development/configuration/configuring-prestashop.md @@ -39,7 +39,7 @@ The Smarty cache system should always be disabled, as it is not compatible with `$smarty->compile_check` should be left to `false` in development mode. -`$smarty->debugging` gives access to Smarty debug information when displaying a page. That setting is more easily modified in the “Performance” page of the advanced parameters menu : the “Debug console” option enables you to choose between never displaying Smarty’s debug information, always displaying it, or only displaying it when you add `?SMARTY_DEBUG` to the URL of the page you want to test, which can be very useful. +`$smarty->debugging` gives access to Smarty debug information when displaying a page. That setting is more easily modified in the “Performance” page of the advanced parameters menu: the “Debug console” option enables you to choose between never displaying Smarty’s debug information, always displaying it, or only displaying it when you add `?SMARTY_DEBUG` to the URL of the page you want to test, which can be very useful. When in production mode, `$smarty->force_compile` must be kept to `false`, as it will give a 30% boost to your page load time. @@ -85,9 +85,9 @@ Go to the “Performance” page under the “Advanced parameters” menu to cha Forcing the compilation of Smarty will always slow down the loading time of the page. Make sure that your production store is set to only recompile templates if there are updated files, and that its cache is enabled. -## Disable the Back-Office token protection +## Disable the Back office token protection -Back-Office pages require the use of a token. If needed, this protection can be disabled using an environment variable: +Back office pages require the use of a token. If needed, this protection can be disabled using an environment variable: ### Apache with mod_headers From 448276694ace238cb34f5b10975b940e671c1c64 Mon Sep 17 00:00:00 2001 From: Thomas NARES Date: Wed, 2 Nov 2022 18:59:31 +0100 Subject: [PATCH 139/310] Apply suggestions from code review Co-authored-by: Pablo Borowicz Co-authored-by: Krystian Podemski --- modules/sample-modules/_index.md | 10 +++---- .../sample-modules/example-hooks/_index.md | 8 ++--- .../example-hooks/actionValidateOrder.md | 30 +++++++++---------- 3 files changed, 24 insertions(+), 24 deletions(-) diff --git a/modules/sample-modules/_index.md b/modules/sample-modules/_index.md index 647e599668..e43c0eba7a 100644 --- a/modules/sample-modules/_index.md +++ b/modules/sample-modules/_index.md @@ -5,20 +5,20 @@ weight: 80 # Sample modules and how to guides -The PrestaShop Community made some example modules and how to guides to help you understand how to implement hooks, admin grids, manage entities... and a lot more. +The PrestaShop Community has made example modules and how-to guides to help you understand how to implement hooks, admin grids, manage entities... and a lot more. {{% children %}} -## Our example modules repository +## Example modules repository * [See all our example modules (GitHub)](https://github.com/PrestaShop/example-modules) -This repository hosts example modules built and maintained by PrestaShop. -These modules demonstrate useful usecases for developers willing to customize the software. +This repository hosts example modules built and maintained by project members and the community. +These modules demonstrate good use cases for developers willing to customize the software. ### Extending Symfony pages -- [Demo Extending a Symfony Form - 1](https://github.com/PrestaShop/example-modules/tree/master/demoextendsymfonyform1) - how to insert an input inside a Symfony form +- [Extending a Symfony form - how to insert a field inside an existing form](https://github.com/PrestaShop/example-modules/tree/master/demoextendsymfonyform1) - [Demo Extending a Symfony Form - 2](https://github.com/PrestaShop/example-modules/tree/master/demoextendsymfonyform2) - how to insert an input inside a Symfony form - 2 - [Demo Extending a Symfony Form - 3](https://github.com/PrestaShop/example-modules/tree/master/demoextendsymfonyform3) - how to use CQRS in a module - [Demo View Order Hooks](https://github.com/PrestaShop/example-modules/tree/master/demovieworderhooks) diff --git a/modules/sample-modules/example-hooks/_index.md b/modules/sample-modules/example-hooks/_index.md index 1b46a080c1..2cf191db0b 100644 --- a/modules/sample-modules/example-hooks/_index.md +++ b/modules/sample-modules/example-hooks/_index.md @@ -1,12 +1,12 @@ --- -title: Hooks examples +title: Hook examples weight: 2 --- -# Hooks implementation examples +# Hook implementation examples -Hooks is one of the most powerful tools to extend or modify PrestaShop with modules. +Hooks are one of the most powerful tools to extend or modify PrestaShop using modules. -For a complete introduction about hooks, please read [Hooks]({{< relref "/8/modules/concepts/hooks/" >}}) +For a complete introduction to hooks, please read [Hooks]({{< relref "/8/modules/concepts/hooks/" >}}) {{% children %}} \ No newline at end of file diff --git a/modules/sample-modules/example-hooks/actionValidateOrder.md b/modules/sample-modules/example-hooks/actionValidateOrder.md index c2d8130948..1a2cba6b72 100644 --- a/modules/sample-modules/example-hooks/actionValidateOrder.md +++ b/modules/sample-modules/example-hooks/actionValidateOrder.md @@ -3,7 +3,7 @@ title: "actionValidateOrder" weight: 3 --- -# Hook example : actionValidateOrder +# Hook example: actionValidateOrder This hook is triggered when an `order` is validated. @@ -26,9 +26,9 @@ actionValidateOrder ); ``` -A classic use-case for this hook could be : +A classic use case for this hook could be: -> I want to reward my customers on their _n-th_ order +_I want to reward my customers on their n-th order_ ```php customerAlreadyRewarded((int) $customerObject->id)) { $hasConfiguredState = in_array((int) $orderObject->getCurrentState(), $this->getConfuredOrdersStatesIds()); $hasCustomerRequiredNbrOfTheOrderToReward = $this->getCustomerValidOrdersNbr((int) $customerObject->id) == $this->getRequiredNbrOfTheOrderToReward(); - if($hasConfiguredState && $hasCustomerRequiredNbrOfTheOrderToReward) { + if ($hasConfiguredState && $hasCustomerRequiredNbrOfTheOrderToReward) { $customerReward = $this->createCustomerReward($customerObject, $orderObject); - if(Validate::isLoadedObject($customerReward)) { - $this->setAlreadyRewarded($customerObject); - $this->notifyCustomer($customerObject, $customerReward); + if (Validate::isLoadedObject($customerReward)) { + $this->setAlreadyRewarded($customerObject); + $this->notifyCustomer($customerObject, $customerReward); - //TODO : of course don't forget to log if something fails here :) + // of course don't forget to log if something fails here :) } } } @@ -61,37 +61,37 @@ class MyModuleRewardCustomerWhenOrder extends Module protected function customerAlreadyRewarded(int $idCustomer): bool { - //TODO : check if customer already rewarded + // check if customer already rewarded } protected setAlreadyRewarded(): void { - //TODO: set customer was rewarded + // set customer was rewarded } protected function getConfuredOrdersStatesIds(): array { - //TODO : return array with configured states ids in your module + // return array with configured states ids in your module } protected function getCustomerValidOrdersNbr(int $idCustomer): int { - //TODO : return number of total order valid by customer + // return number of total order valid by customer } protected function getRequiredNbrOfTheOrderToReward(): int { - //TODO : return configured number of orders required to reward the customer + // return configured number of orders required to reward the customer } protected function createCustomerReward(Customer $customer, Order $order): ?CartRule { - //TODO: generate customer cart rule (according to the order amount for example) + // generate customer cart rule (according to the order amount for example) } protected function notifyCustomer(Customer $customer, CartRule $cartRule): bool { - //TODO: notify the customer + // notify the customer } } ``` \ No newline at end of file From 3ea1ce9469d7dbbfd5144359eeefc3287a753f36 Mon Sep 17 00:00:00 2001 From: leemyongpakvn Date: Tue, 8 Nov 2022 15:19:11 +0700 Subject: [PATCH 140/310] exclude Back Office page --- modules/concepts/hooks/list-of-hooks.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/concepts/hooks/list-of-hooks.md b/modules/concepts/hooks/list-of-hooks.md index 1bdab9bbb0..d706156a2f 100644 --- a/modules/concepts/hooks/list-of-hooks.md +++ b/modules/concepts/hooks/list-of-hooks.md @@ -2145,7 +2145,7 @@ displayFooterProduct displayHeader : - Added in the header of every page + Added in the header of every Front Office page Located in: /classes/controller/FrontController.php From 53af245de6160053b99b3adf9990fb4c996bac9c Mon Sep 17 00:00:00 2001 From: marsaldev Date: Wed, 9 Nov 2022 12:21:38 +0100 Subject: [PATCH 141/310] fix typo --- webservice/tutorials/creating-access.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webservice/tutorials/creating-access.md b/webservice/tutorials/creating-access.md index b7563956ac..9ed3f6b4d8 100644 --- a/webservice/tutorials/creating-access.md +++ b/webservice/tutorials/creating-access.md @@ -16,7 +16,7 @@ Go in the PrestaShop back office, open the "Web service" page under the "Advance {{< figure src="../../img/enable_webservice.png" title="Enabling Webservice" >}} -### Programatically +### Programmatically The Webservice switch is stored in the configuration table of PrestaShop. From ecd0053b80054bfb7a223940ca484a6441bd6927 Mon Sep 17 00:00:00 2001 From: Thomas Nares Date: Thu, 10 Nov 2022 11:35:23 +0100 Subject: [PATCH 142/310] Fix identation issues, breaks DOM/search --- modules/concepts/hooks/list-of-hooks.md | 226 ++++++++++++++---------- 1 file changed, 128 insertions(+), 98 deletions(-) diff --git a/modules/concepts/hooks/list-of-hooks.md b/modules/concepts/hooks/list-of-hooks.md index 47abc8ce0a..04e19a466b 100644 --- a/modules/concepts/hooks/list-of-hooks.md +++ b/modules/concepts/hooks/list-of-hooks.md @@ -507,7 +507,7 @@ actionDownloadAttachment actionEmailAddAfterContent : Add extra content after mail content -This hook is called just after fetching mail template + This hook is called just after fetching mail template Located in: /classes/Mail.php @@ -515,7 +515,7 @@ This hook is called just after fetching mail template actionEmailAddBeforeContent : Add extra content before mail content -This hook is called just before fetching mail template + This hook is called just before fetching mail template Located in: /classes/Mail.php @@ -523,7 +523,7 @@ This hook is called just before fetching mail template actionEmailSendBefore : Before sending an email -This hook is used to filter the content or the metadata of an email before sending it or even prevent its sending + This hook is used to filter the content or the metadata of an email before sending it or even prevent its sending Located in: /classes/Mail.php @@ -836,7 +836,7 @@ actionOrderReturn actionOrderSlipAdd : Called when the quantity of a product changes in an order. -WARNING: only invoked when a product is actually removed from an order. + WARNING: only invoked when a product is actually removed from an order. Located in: /controllers/admin/AdminOrdersController.php @@ -866,7 +866,7 @@ actionOrderStatusPostUpdate Called after the status of an order changes. **Note:** This hook is fired BEFORE the new OrderStatus is saved into the database. - If you need to register after this insertion, use `actionOrderHistoryAddAfter` or `actionObjectOrderHistoryAddAfter` instead. + If you need to register after this insertion, use `actionOrderHistoryAddAfter` or `actionObjectOrderHistoryAddAfter` instead. Located in: /classes/order/OrderHistory.php @@ -901,7 +901,7 @@ actionOutputHTMLBefore Available since: {{< minver v="1.7.1" >}} Before HTML output -This hook is used to filter the whole HTML page before it is rendered (only front) + This hook is used to filter the whole HTML page before it is rendered (only front) Located in: /classes/controller/FrontController.php @@ -1108,7 +1108,7 @@ actionUpdateLangAfter actionUpdateQuantity : After updating the quantity of a product. -Quantity is updated only when a customer effectively places their order + Quantity is updated only when a customer effectively places their order Located in: /classes/stock/StockAvailable.php @@ -1265,7 +1265,7 @@ actionAdminAdminPreferencesControllerPostProcessBefore additionalCustomerFormFields : Add fields to the Customer form -This hook returns an array of FormFields to add them to the customer registration form + This hook returns an array of FormFields to add them to the customer registration form Located in: /classes/form/CustomerFormatter.php @@ -1308,8 +1308,8 @@ dashboardZoneTwo dashboardZoneThree : -Available since: {{< minver v="8.0.0" >}} -Located in: /controllers/admin/AdminDashboardController.php + Available since: {{< minver v="8.0.0" >}} + Located in: /controllers/admin/AdminDashboardController.php Parameters: ```php @@ -1331,7 +1331,7 @@ displayAdminAfterHeader displayAdminCustomers : Display new elements in the Back Office, tab AdminCustomers -This hook launches modules when the AdminCustomers tab is displayed in the Back Office + This hook launches modules when the AdminCustomers tab is displayed in the Back Office Located in: admin-dev/themes/default/template/controllers/customers/helpers/view/view.tpl @@ -1348,16 +1348,16 @@ displayAdminCustomersAddressesItemAction Available since: {{< minver v="1.7.3" >}} Display new elements in the Back Office, tab AdminCustomers, Addresses actions. -This hook launches modules when the Addresses list into the AdminCustomers tab is displayed in the Back Office + This hook launches modules when the Addresses list into the AdminCustomers tab is displayed in the Back Office Located in: /admin-dev/themes/default/template/controllers/customers/helpers/view/view.tpl Parameters: ```php (int) Address ID - ) + array( + 'id_address' => (int) Address ID + ) ``` displayAdminEndContent @@ -1365,13 +1365,13 @@ displayAdminEndContent Available since: {{< minver v="1.7.4" >}} Administration end of content. -This hook is displayed at the end of the main content, before the footer + This hook is displayed at the end of the main content, before the footer Located in: - - /admin-dev/themes/default/template/footer.tpl - - /admin-dev/themes/new-theme/template/layout.tpl + - /admin-dev/themes/default/template/footer.tpl + - /admin-dev/themes/new-theme/template/layout.tpl - + displayAdminForm : Located in: admin-dev/themes/default/template/helpers/form/form.tpl @@ -1438,7 +1438,7 @@ displayAdminLogin displayAdminNavBarBeforeEnd : Display new elements in the Back Office, tab AdminCustomers -This hook launches modules when the AdminCustomers tab is displayed in the Back Office + This hook launches modules when the AdminCustomers tab is displayed in the Back Office Located in: @@ -1454,7 +1454,7 @@ displayAdminOptions displayAdminOrder : Display new elements in the Back Office, tab AdminOrder -This hook launches modules when the AdminOrder tab is displayed in the Back Office + This hook launches modules when the AdminOrder tab is displayed in the Back Office Located in: @@ -1475,7 +1475,7 @@ displayAdminOrderContentOrder → `displayAdminOrderTabContent` Display new elements in Back Office, AdminOrder, panel Order -This hook launches modules when the AdminOrder tab is displayed in the Back Office and extends / override Order panel content + This hook launches modules when the AdminOrder tab is displayed in the Back Office and extends / override Order panel content Located in: /controllers/admin/AdminOrdersController.php @@ -1486,7 +1486,7 @@ displayAdminOrderContentShip → `displayAdminOrderTabContent` Display new elements in Back Office, AdminOrder, panel Shipping -This hook launches modules when the AdminOrder tab is displayed in the Back Office and extends / override Shipping panel content + This hook launches modules when the AdminOrder tab is displayed in the Back Office and extends / override Shipping panel content Located in: /controllers/admin/AdminOrdersController.php @@ -1598,7 +1598,7 @@ displayAdminOrderTabOrder → `displayAdminOrderTabLink` Display new elements in Back Office, AdminOrder, panel Order -This hook launches modules when the AdminOrder tab is displayed in the Back Office and extends / override Order panel tabs + This hook launches modules when the AdminOrder tab is displayed in the Back Office and extends / override Order panel tabs Located in: /controllers/admin/AdminOrdersController.php @@ -1609,7 +1609,7 @@ displayAdminOrderTabShip → `displayAdminOrderTabLink` Display new elements in Back Office, AdminOrder, panel Shipping -This hook launches modules when the AdminOrder tab is displayed in the Back Office and extends / override Shipping panel tabs + This hook launches modules when the AdminOrder tab is displayed in the Back Office and extends / override Shipping panel tabs Located in: /controllers/admin/AdminOrdersController.php @@ -1632,7 +1632,9 @@ displayAdminOrderTabLink displayAdminProductsExtra : - + Located in: /src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/product.html.twig + + displayAdminProductsCombinationBottom : Located in: /templates/bundles/PrestaShopBundle/views/Admin/Product/Include/form_combination.html.twig @@ -1641,7 +1643,7 @@ displayAdminProductsCombinationBottom displayAdminProductsMainStepLeftColumnBottom : Display new elements in back office product page, left column of -This hook launches modules when the back office product page is displayed + This hook launches modules when the back office product page is displayed Located in: /templates/bundles/PrestaShopBundle/views/Admin/Product/ProductPage/Panels/essentials.html.twig @@ -1649,7 +1651,7 @@ This hook launches modules when the back office product page is displayed displayAdminProductsMainStepLeftColumnMiddle : Display new elements in back office product page, left column of -This hook launches modules when the back office product page is displayed + This hook launches modules when the back office product page is displayed Located in: /templates/bundles/PrestaShopBundle/views/Admin/Product/ProductPage/Panels/essentials.html.twig @@ -1657,7 +1659,7 @@ This hook launches modules when the back office product page is displayed displayAdminProductsMainStepRightColumnBottom : Display new elements in back office product page, right column of -This hook launches modules when the back office product page is displayed + This hook launches modules when the back office product page is displayed Located in: /templates/bundles/PrestaShopBundle/views/Admin/Product/ProductPage/Panels/essentials.html.twig @@ -1665,7 +1667,7 @@ This hook launches modules when the back office product page is displayed displayAdminProductsOptionsStepBottom : Display new elements in back office product page, Options tab -This hook launches modules when the back office product page is displayed + This hook launches modules when the back office product page is displayed Located in: /templates/bundles/PrestaShopBundle/views/Admin/Product/form.html.twig @@ -1673,7 +1675,7 @@ This hook launches modules when the back office product page is displayed displayAdminProductsOptionsStepTop : Display new elements in back office product page, Options tab -This hook launches modules when the back office product page is displayed + This hook launches modules when the back office product page is displayed Located in: /templates/bundles/PrestaShopBundle/views/Admin/Product/form.html.twig @@ -1681,7 +1683,7 @@ This hook launches modules when the back office product page is displayed displayAdminProductsPriceStepBottom : Display new elements in back office product page, Price tab -This hook launches modules when the back office product page is displayed + This hook launches modules when the back office product page is displayed Located in: /templates/bundles/PrestaShopBundle/views/Admin/Product/form.html.twig @@ -1689,7 +1691,7 @@ This hook launches modules when the back office product page is displayed displayAdminProductsQuantitiesStepBottom : Display new elements in back office product page, Quantities/Com -This hook launches modules when the back office product page is displayed + This hook launches modules when the back office product page is displayed Located in: /templates/bundles/PrestaShopBundle/views/Admin/Product/form.html.twig @@ -1697,7 +1699,7 @@ This hook launches modules when the back office product page is displayed displayAdminProductsSeoStepBottom : Display new elements in back office product page, SEO tab -This hook launches modules when the back office product page is displayed + This hook launches modules when the back office product page is displayed Located in: /templates/bundles/PrestaShopBundle/views/Admin/Product/Include/form_seo.html.twig @@ -1705,7 +1707,7 @@ This hook launches modules when the back office product page is displayed displayAdminProductsShippingStepBottom : Display new elements in back office product page, Shipping tab -This hook launches modules when the back office product page is displayed + This hook launches modules when the back office product page is displayed Located in: /templates/bundles/PrestaShopBundle/views/Admin/Product/Include/form_shipping.html.twig @@ -1736,7 +1738,7 @@ displayAfterTitleTag Available since: {{< minver v="1.7.8" >}} In html header -Use this hook to add content after title tag + Use this hook to add content after title tag Located in: @@ -1746,7 +1748,7 @@ Use this hook to add content after title tag displayAfterBodyOpeningTag : Very top of pages -Use this hook for advertisement or modals you want to load first + Use this hook for advertisement or modals you want to load first Located in: @@ -1757,7 +1759,7 @@ Use this hook for advertisement or modals you want to load first displayAfterCarrier : After carriers list -This hook is displayed after the carrier list in Front Office + This hook is displayed after the carrier list in Front Office Located in: /classes/checkout/CheckoutDeliveryStep.php @@ -1767,7 +1769,7 @@ displayAfterProductThumbs Available since: {{< minver v="1.7.1" >}} Display extra content below product thumbs -This hook displays new elements below product images ex. additional media + This hook displays new elements below product images ex. additional media Located in: /themes/classic/templates/catalog/_partials/product-cover-thumbnails.tpl @@ -1780,7 +1782,7 @@ displayAfterThemeInstallation displayAttributeForm : Add fields to the form 'attribute value' -This hook adds fields to the form 'attribute value' + This hook adds fields to the form 'attribute value' Located in: admin-dev/themes/default/template/controllers/attributes/helpers/form/form.tpl @@ -1788,7 +1790,7 @@ This hook adds fields to the form 'attribute value' displayAttributeGroupForm : Add fields to the form 'attribute group' -This hook adds fields to the form 'attribute group' + This hook adds fields to the form 'attribute group' Located in: admin-dev/themes/default/template/controllers/attributes_groups/helpers/form/form.tpl @@ -1796,7 +1798,7 @@ This hook adds fields to the form 'attribute group' displayBackOfficeCategory : Display new elements in the Back Office, tab AdminCategories -This hook launches modules when the AdminCategories tab is displayed in the Back Office + This hook launches modules when the AdminCategories tab is displayed in the Back Office Located in: /controllers/admin/AdminCategoriesController.php @@ -1864,7 +1866,7 @@ displayBanner displayBeforeBodyClosingTag : Very bottom of pages -Use this hook for your modals or any content you want to load at the very end + Use this hook for your modals or any content you want to load at the very end Located in: @@ -1952,7 +1954,7 @@ displayCarrierList displayCartExtraProductActions : Extra buttons in shopping cart -This hook adds extra buttons to the product lines, in the shopping cart + This hook adds extra buttons to the product lines, in the shopping cart Located in: /themes/classic/templates/checkout/_partials/cart-detailed-product-line.tpl @@ -1961,7 +1963,7 @@ displayCartModalContent Available since: {{< minver v="1.7.8" >}} Content of Add-to-cart modal -This hook displays content in the middle of the window that appears after adding product to cart + This hook displays content in the middle of the window that appears after adding product to cart Located in: /themes/classic/modules/ps_shoppingcart/modal.tpl @@ -1970,7 +1972,7 @@ displayCartModalFooter Available since: {{< minver v="1.7.8" >}} Bottom of Add-to-cart modal -This hook displays content in the bottom of window that appears after adding product to cart + This hook displays content in the bottom of window that appears after adding product to cart Located in: /themes/classic/modules/ps_shoppingcart/modal.tpl @@ -1997,7 +1999,7 @@ displayCMSPrintButton displayContentWrapperBottom : Content wrapper section (bottom) -This hook displays new elements in the bottom of the content wrapper + This hook displays new elements in the bottom of the content wrapper Located in: @@ -2011,7 +2013,7 @@ This hook displays new elements in the bottom of the content wrapper displayContentWrapperTop : Content wrapper section (top) -This hook displays new elements in the top of the content wrapper + This hook displays new elements in the top of the content wrapper Located in: @@ -2065,11 +2067,11 @@ displayDashboardToolbarIcons Available since: {{< minver v="1.7.3" >}} Display new elements in back office page with dashboard, on icons list. -This hook launches modules when the back office with dashboard is displayed + This hook launches modules when the back office with dashboard is displayed Located in: - - /templates/bundles/PrestaShopBundle/views/Admin/Configure/AdvancedParameters/LogsPage/Blocks/actions.html.twig - - /templates/bundles/PrestaShopBundle/views/Admin/Product/CatalogPage/Blocks/tools.html.twig + - /templates/bundles/PrestaShopBundle/views/Admin/Configure/AdvancedParameters/LogsPage/Blocks/actions.html.twig + - /templates/bundles/PrestaShopBundle/views/Admin/Product/CatalogPage/Blocks/tools.html.twig displayDashboardToolbarTopMenu @@ -2077,17 +2079,17 @@ displayDashboardToolbarTopMenu Available since: {{< minver v="1.7.3" >}} Display new elements in back office page with a dashboard, on top Menu. -This hook launches modules when a page with a dashboard is displayed + This hook launches modules when a page with a dashboard is displayed Located in: - - /admin-dev/themes/default/template/page_header_toolbar.tpl - - /admin-dev/themes/new-theme/template/page_header_toolbar.tpl + - /admin-dev/themes/default/template/page_header_toolbar.tpl + - /admin-dev/themes/new-theme/template/page_header_toolbar.tpl displayDashboardTop : Dashboard Top -Displays the content in the dashboard's top area + Displays the content in the dashboard's top area Located in: admin-dev/themes/default/template/page_header_toolbar.tpl @@ -2100,7 +2102,7 @@ displayExpressCheckout displayFeatureForm : Add fields to the form 'feature' -This hook adds fields to the form 'feature' + This hook adds fields to the form 'feature' Located in: admin-dev/themes/default/template/controllers/features/helpers/form/form.tpl @@ -2108,7 +2110,7 @@ This hook adds fields to the form 'feature' displayFeaturePostProcess : On post-process in admin feature -This hook is called on post-process in admin feature + This hook is called on post-process in admin feature Located in: /controllers/admin/AdminFeaturesController.php @@ -2116,7 +2118,7 @@ This hook is called on post-process in admin feature displayFeatureValueForm : Add fields to the form 'feature value' -This hook adds fields to the form 'feature value' + This hook adds fields to the form 'feature value' Located in: admin-dev/themes/default/template/controllers/feature_value/helpers/form/form.tpl @@ -2124,7 +2126,7 @@ This hook adds fields to the form 'feature value' displayFeatureValuePostProcess : On post-process in admin feature value -This hook is called on post-process in admin feature value + This hook is called on post-process in admin feature value Located in: /controllers/admin/AdminFeaturesController.php @@ -2173,10 +2175,11 @@ displayInvoice → `displayAdminOrderTop` Invoice -This hook displays new blocks on the invoice (order) + This hook displays new blocks on the invoice (order) Located in: admin-dev/themes/default/template/controllers/orders/helpers/view/view.tpl + displayAdminOrderTop : Available since: {{< minver v="1.7.7" >}} @@ -2197,7 +2200,7 @@ displayAdminOrderTop displayInvoiceLegalFreeText : PDF Invoice - Legal Free Text -This hook allows you to modify the legal free text on PDF invoices + This hook allows you to modify the legal free text on PDF invoices Located in: /classes/pdf/HTMLTemplateInvoice.php @@ -2219,7 +2222,7 @@ displayLeftColumnProduct displayMaintenance : Maintenance Page -This hook displays new elements on the maintenance page + This hook displays new elements on the maintenance page Located in: /classes/controller/FrontController.php @@ -2250,7 +2253,7 @@ displayNav2 displayNavFullWidth : Navigation -This hook displays full width navigation menu at the top of your pages + This hook displays full width navigation menu at the top of your pages Located in: @@ -2277,6 +2280,7 @@ displayOrderConfirmation ); ``` + displayOrderConfirmation1 : Located in: /themes/classic/templates/checkout/order-confirmation.tpl @@ -2304,6 +2308,7 @@ displayOrderDetail ); ``` + displayOrderPreview : Available since: {{< minver v="1.7.7" >}} @@ -2320,10 +2325,11 @@ displayOrderPreview ); ``` + displayPaymentByBinaries : Payment form generated by binaries -This hook displays form generated by binaries during the checkout + This hook displays form generated by binaries during the checkout Located in: /themes/classic/templates/checkout/_partials/steps/payment.tpl @@ -2343,7 +2349,7 @@ displayPaymentReturn displayPaymentTop : Top of payment page -This hook is displayed at the top of the payment page + This hook is displayed at the top of the payment page Located in: /themes/classic/templates/checkout/_partials/steps/payment.tpl @@ -2371,7 +2377,7 @@ displayProductAdditionalInfo Available since: {{< minver v="1.7.1" >}} Product page additional info -This hook adds additional information on the product page + This hook adds additional information on the product page Located in: @@ -2384,11 +2390,11 @@ displayProductExtraContent Available since: {{< minver v="1.7.0" >}} Display extra content on the product page. -This hook expects ProductExtraContent instances, which will be properly displayed by the template on the product page + This hook expects ProductExtraContent instances, which will be properly displayed by the template on the product page Located in: /controllers/front/ProductController.php - - Parameters: + + Parameters: ```php }} Product Page Drawer. -This hook displays content in the right sidebar of the product page + This hook displays content in the right sidebar of the product page Located in: /src/PrestaShopBundle/Controller/Admin/ProductController.php @@ -2479,7 +2485,7 @@ displayShoppingCart displayShoppingCartFooter : Shopping cart footer -This hook displays some specific information on the shopping cart's page + This hook displays some specific information on the shopping cart's page Located in: /themes/classic/templates/checkout/cart.tpl @@ -2487,7 +2493,7 @@ This hook displays some specific information on the shopping cart's page displayTop : Top of pages -This hook displays additional elements at the top of your pages + This hook displays additional elements at the top of your pages Located in: @@ -2498,7 +2504,7 @@ This hook displays additional elements at the top of your pages displayWrapperBottom : Main wrapper section (bottom) -This hook displays new elements in the bottom of the main wrapper + This hook displays new elements in the bottom of the main wrapper Located in: @@ -2509,13 +2515,14 @@ This hook displays new elements in the bottom of the main wrapper displayWrapperTop : Main wrapper section (top) -This hook displays new elements in the top of the main wrapper + This hook displays new elements in the top of the main wrapper Located in: - themes/classic/templates/checkout/checkout.tpl - themes/classic/templates/layouts/layout-both-columns.tpl + displayAdditionalCustomerAddressFields : Available since: {{< minver v="1.7.7" >}} @@ -2524,6 +2531,7 @@ displayAdditionalCustomerAddressFields Located in: /themes/classic/templates/customer/_partials/block-address.tpl + displayFooterCategory : Available since: {{< minver v="1.7.7" >}} @@ -2547,7 +2555,7 @@ filterCategoryContent Available since: {{< minver v="1.7.1" >}} Filter the content page category. -This hook is called just before fetching content page category + This hook is called just before fetching content page category Located in: /controllers/front/listing/CategoryController.php @@ -2563,7 +2571,7 @@ This hook is called just before fetching content page category filterCmsCategoryContent : Filter the content page category -This hook is called just before fetching content page category + This hook is called just before fetching content page category Located in: /controllers/front/CmsController.php @@ -2571,7 +2579,7 @@ This hook is called just before fetching content page category filterCmsContent : Filter the content page -This hook is called just before fetching content page + This hook is called just before fetching content page Located in: /controllers/front/CmsController.php @@ -2579,7 +2587,7 @@ This hook is called just before fetching content page filterHtmlContent : Filter HTML field before rending a page -This hook is called just before fetching a page on HTML field + This hook is called just before fetching a page on HTML field Located in: /src/Adapter/ObjectPresenter.php @@ -2587,7 +2595,7 @@ This hook is called just before fetching a page on HTML field filterManufacturerContent : Filter the content page manufacturer -This hook is called just before fetching content page manufacturer + This hook is called just before fetching content page manufacturer Located in: /controllers/front/listing/ManufacturerController.php @@ -2595,7 +2603,7 @@ This hook is called just before fetching content page manufacturer filterProductContent : Filter the content page product -This hook is called just before fetching content page product + This hook is called just before fetching content page product Located in: /controllers/front/ProductController.php @@ -2647,6 +2655,7 @@ validateCustomerFormFields : Located in: /classes/form/CustomerForm.php + action<KpiIdentifier>KpiRowModifier : Available since: {{< minver v="1.7.6" >}} @@ -2664,6 +2673,7 @@ action<KpiIdentifier>KpiRowModifier ), ``` + action<HookName>Form : Available since: {{< minver v="1.7.4" >}} @@ -2680,6 +2690,7 @@ action<HookName>Form ] ``` + action<HookName>Save : Available since: {{< minver v="1.7.4" >}} @@ -2711,6 +2722,7 @@ action<GridDefinitionId>GridDefinitionModifier ] ``` + action<GridDefinitionId>GridQueryBuilderModifier : Available since: {{< minver v="1.7.5" >}} @@ -2726,6 +2738,7 @@ action<GridDefinitionId>GridQueryBuilderModifier ] ``` + action<GridDefinitionId>GridDataModifier : Available since: {{< minver v="1.7.5" >}} @@ -2739,6 +2752,7 @@ action<GridDefinitionId>GridDataModifier ] ``` + action<GridDefinitionId>GridFilterFormModifier : Available since: {{< minver v="1.7.5" >}} @@ -2752,6 +2766,7 @@ action<GridDefinitionId>GridFilterFormModifier ] ``` + action<GridDefinitionId>GridPresenterModifier : Available since: {{< minver v="1.7.5" >}} @@ -2765,6 +2780,7 @@ action<GridDefinitionId>GridPresenterModifier ] ``` + action<FormName>FormBuilderModifier : Available since: {{< minver v="1.7.6" >}} @@ -2780,10 +2796,11 @@ action<FormName>FormBuilderModifier ] ``` + action<FormName>FormDataProviderDefaultData, : -Available since: {{< minver v="8.0.0" >}} -Located in: /src/Core/Form/IdentifiableObject/Builder/FormBuilder.php + Available since: {{< minver v="8.0.0" >}} + Located in: /src/Core/Form/IdentifiableObject/Builder/FormBuilder.php Parameters: ```php @@ -2794,10 +2811,11 @@ Located in: /src/Core/Form/IdentifiableObject/Builder/FormBuilder.php ] ``` + action<FormName>FormDataProviderData, : -Available since: {{< minver v="8.0.0" >}} -Located in: /src/Core/Form/IdentifiableObject/Builder/FormBuilder.php + Available since: {{< minver v="8.0.0" >}} + Located in: /src/Core/Form/IdentifiableObject/Builder/FormBuilder.php Parameters: ```php @@ -2809,6 +2827,7 @@ Located in: /src/Core/Form/IdentifiableObject/Builder/FormBuilder.php ] ``` + actionBeforeUpdate<FormName>FormHandler : Available since: {{< minver v="1.7.6" >}} @@ -2823,6 +2842,7 @@ actionBeforeUpdate<FormName>FormHandler ] ``` + actionAfterUpdate<FormName>FormHandler : Available since: {{< minver v="1.7.6" >}} @@ -2836,6 +2856,7 @@ actionAfterUpdate<FormName>FormHandler ] ``` + actionBeforeCreate<FormName>FormHandler : Available since: {{< minver v="1.7.6" >}} @@ -2849,6 +2870,7 @@ actionBeforeCreate<FormName>FormHandler ] ``` + actionAfterCreate<FormName>FormHandler : Available since: {{< minver v="1.7.6" >}} @@ -2862,10 +2884,11 @@ actionAfterCreate<FormName>FormHandler ] ``` + actionFilterDeliveryOptionList : -Available since: {{< minver v="8.0.0" >}} -Located in: /classes/Cart.php + Available since: {{< minver v="8.0.0" >}} + Located in: /classes/Cart.php Parameters: ```php @@ -2875,10 +2898,11 @@ Located in: /classes/Cart.php ] ``` + actionValidateOrderAfter : -Available since: {{< minver v="8.0.0" >}} -Located in: /classes/PaymentModule.php + Available since: {{< minver v="8.0.0" >}} + Located in: /classes/PaymentModule.php Parameters: ```php @@ -2893,10 +2917,11 @@ Located in: /classes/PaymentModule.php ] ``` + actionPresentPaymentOptions : -Available since: {{< minver v="8.0.0" >}} -Located in: /classes/checkout/PaymentOptionsFinder.php + Available since: {{< minver v="8.0.0" >}} + Located in: /classes/checkout/PaymentOptionsFinder.php Parameters: ```php @@ -2906,10 +2931,11 @@ Located in: /classes/checkout/PaymentOptionsFinder.php ] ``` + actionGetAdminToolbarButtons : -Available since: {{< minver v="8.0.0" >}} -Located in: /classes/controller/AdminController.php + Available since: {{< minver v="8.0.0" >}} + Located in: /classes/controller/AdminController.php Parameters: ```php @@ -2920,10 +2946,11 @@ Located in: /classes/controller/AdminController.php ] ``` + actionGetAlternativeSearchPanels : -Available since: {{< minver v="8.0.0" >}} -Located in: /controllers/admin/AdminSearchController.php + Available since: {{< minver v="8.0.0" >}} + Located in: /controllers/admin/AdminSearchController.php Parameters: ```php @@ -2934,10 +2961,11 @@ Located in: /controllers/admin/AdminSearchController.php ] ``` + displayBackOfficeEmployeeMenu : -Available since: {{< minver v="8.0.0" >}} -Located in: /src/PrestaShopBundle/Bridge/Smarty/HeaderConfigurator.php + Available since: {{< minver v="8.0.0" >}} + Located in: /src/PrestaShopBundle/Bridge/Smarty/HeaderConfigurator.php Parameters: ```php @@ -2947,10 +2975,11 @@ Located in: /src/PrestaShopBundle/Bridge/Smarty/HeaderConfigurator.php ] ``` + displayEmptyModuleCategoryExtraMessage : -Available since: {{< minver v="8.0.0" >}} -Located in: /src/PrestaShopBundle/Resources/views/Admin/Module/Includes/grid_manage_empty.html.twig + Available since: {{< minver v="8.0.0" >}} + Located in: /src/PrestaShopBundle/Resources/views/Admin/Module/Includes/grid_manage_empty.html.twig Parameters: ```html.twig @@ -2959,4 +2988,5 @@ Located in: /src/PrestaShopBundle/Resources/views/Admin/Module/Includes/grid_man } ``` + {{% /funcdef %}} From c2c61918955c773f7d0e1a699af67fecc12211ed Mon Sep 17 00:00:00 2001 From: Thomas Nares Date: Fri, 18 Nov 2022 10:23:08 +0100 Subject: [PATCH 143/310] Improve order lifecycle doc --- development/orders-lifecycle/_index.md | 84 +++++++++++++++----------- 1 file changed, 50 insertions(+), 34 deletions(-) diff --git a/development/orders-lifecycle/_index.md b/development/orders-lifecycle/_index.md index d527097c5a..92dc7a003c 100644 --- a/development/orders-lifecycle/_index.md +++ b/development/orders-lifecycle/_index.md @@ -4,7 +4,7 @@ weight: 42 useMermaid: true --- -# Order lifecycle : from Cart to Order +# Order lifecycle: Cart, Checkout, and Order {{% notice note %}} Orders can be created from a cart either in Front Office (FO) by the customer or in Back Office (BO) `Sell -> Orders -> "Add new order"` by the shop admin. See [Add new order page]({{< relref "../page-reference/back-office/order/add-new-order" >}}). @@ -21,8 +21,8 @@ creating a new one.
flowchart LR - A(Guest with empty cart)-->|Action : Add item to Cart|B{{Cart creation}}-->C(Cart)-->|Action : Login|D{{Associate cart to customer}}-->F - A-->|Action : Login|G{{Cart creation}}-->E{{Associate cart to customer}}-->F(Associated Cart) + A(Guest with empty cart)-->|Add item to Cart|B{{Cart creation}}-->C(Cart)-->|Login|D{{Associate cart to customer}}-->F + A-->|Login|G{{Cart creation}}-->E{{Associate cart to customer}}-->F(Associated Cart)
{{% notice note %}} @@ -33,40 +33,45 @@ can be adjusted in BO `Configure -> Administration -> General "lifetime of front ### Cart in Back Office (BO) -When creating an order in the BO, a new empty cart is created once the customer is selected. An existing cart can also -be selected, or existing order can be used to create a new cart. +When creating an order in the BO, a new empty cart is created once the customer is selected. An existing cart (already associated to the customer) can also be selected, or an existing order can be used to create a new cart.
flowchart LR - A{{Select Customer}}-->|New cart|E{{Cart creation}}-->G - A-->|From existing cart|B{{Select existing Cart}}-->F - A-->|From order|C{{Select existing Order}}-->D{{Cart creation from Order content}}-->G{{Associate cart to customer}}-->F(Associated Cart) + A{{Select Customer}}-->|Create new cart|E{{Cart creation}}-->G + A-->|Use existing cart|B{{Select existing Cart}}-->F + A-->|Create new cart from order|C{{Select existing Order}}-->D{{Cart creation from Order content}}-->G{{Associate cart to customer}}-->F(Associated Cart)
-## Convert a Cart to an Order +## The Checkout: from Cart to Order -For a Cart to be able to convert to an Order, we need the following steps : +For a Cart to convert to an Order, the following steps need to be completed: -
From 6185b09664580028d8be7114b988871449209ce8 Mon Sep 17 00:00:00 2001 From: Thomas Nares Date: Mon, 6 Feb 2023 10:54:56 +0100 Subject: [PATCH 245/310] move some files, refresh other ones --- basics/keeping-up-to-date/_index.md | 5 +- basics/keeping-up-to-date/backup.md | 24 +++++--- basics/keeping-up-to-date/img/image38.png | Bin 78355 -> 15142 bytes basics/keeping-up-to-date/migration.md | 10 +-- .../upgrade-module/_index.md | 2 + .../upgrade-module/channels.md | 2 + .../upgrade-module/img/upgrade-process.png | Bin .../upgrade-module/upgrade-cli.md | 2 + .../upgrade-module-internal-behavior.md | 2 + .../upgrade-module/upgrade-process-steps.md | 2 + basics/keeping-up-to-date/upgrade.md | 57 +++++++++--------- .../use-autoupgrade-module.md | 9 +-- 12 files changed, 67 insertions(+), 48 deletions(-) rename {development => basics/keeping-up-to-date}/upgrade-module/_index.md (97%) rename {development => basics/keeping-up-to-date}/upgrade-module/channels.md (96%) rename {development => basics/keeping-up-to-date}/upgrade-module/img/upgrade-process.png (100%) rename {development => basics/keeping-up-to-date}/upgrade-module/upgrade-cli.md (95%) rename {development => basics/keeping-up-to-date}/upgrade-module/upgrade-module-internal-behavior.md (98%) rename {development => basics/keeping-up-to-date}/upgrade-module/upgrade-process-steps.md (98%) diff --git a/basics/keeping-up-to-date/_index.md b/basics/keeping-up-to-date/_index.md index 2eabb20e36..fc3778eab1 100644 --- a/basics/keeping-up-to-date/_index.md +++ b/basics/keeping-up-to-date/_index.md @@ -29,7 +29,7 @@ It does not require any additional tools to run if you follow the manual process #### Impact on existing data -As long as you stay on the same major version (ex. 1.6.0 >> 1.6.1 or 1.7.1 >> 1.7.2 upgrade), we make sure that the available features remain the same. +As long as you stay on the same major version (ex. 1.7.1 >> 1.7.2, 8.0 >> 8.1 upgrade), we make sure that the available features remain the same. This means that your current theme and all your modules should continue to work as before, and no functionality or data will be lost during the upgrade, even if the database structure may change. This can be explained by the [semantic versioning](https://semver.org/) we follow, that forbids any compatibility-breaking change in the core, such as removing a feature or modifying our APIs. @@ -43,7 +43,6 @@ Note that once an upgrade has started, there is no way to rollback the changes. - Run the database upgrade. This could be enough for completing an upgrade, but additional tasks like cleanup and modules upgrade will bring you stability and security. - ### Migration ![Migration schema](img/migration-schema.png) @@ -62,7 +61,7 @@ The main advantage of this option is it does not require the shop in production The impact on the existing data is very different from an upgrade, as it depends on what you transfer to the new shop. -When switching to another major version (i.e 1.6.x >> 1.7.x), this will imply that some resources will be lost: +When switching to another major version (i.e 1.7.x >> 8.x), this will imply that some resources will be lost: * **Permissions** diff --git a/basics/keeping-up-to-date/backup.md b/basics/keeping-up-to-date/backup.md index 7437b71094..48e3ed00e9 100644 --- a/basics/keeping-up-to-date/backup.md +++ b/basics/keeping-up-to-date/backup.md @@ -25,6 +25,18 @@ The first elements to backup are the files on the web server where you have depl To complete this step, your shop folder must be copied somewhere else. Although it can be simply copied on another folder on your server, making an additional copy of your files on another computer is a nice additional security measure. To do so, connect to your server using an FTP, SSH or RDP connection (depending on your server and hosting provider), copy the files in another location, then download them on your computer. +With SSH, you may use `scp` or `rsync` command to backup your shop folder from a server to another. For example, backup from a remote server to your local machine (or the one you are connected on) with `scp` ([scp man page](https://linuxcommand.org/lc3_man_pages/scp1.html)): + +``` +scp -r user@host:/var/www/prestashop_folder_path /local_path_for_backup/ +``` + +Or with `rsync` ([rsync man page](https://linux.die.net/man/1/rsync)): + +``` +rsync -avz user@host:/var/www/prestashop_folder_path /local_path_for_backup/ +``` + Note that depending on the number of files and your internet connection, this may take a few hours to complete. But if you’re an advanced user and have a complete access to your server, the next part may help you go faster. #### Bonus: Compress your files before download @@ -32,9 +44,9 @@ Note that depending on the number of files and your internet connection, this ma As said before, downloading the whole PrestaShop folder one file at a time will take a long time to complete. If you can run commands on your server, you can make a backup faster by compressing the whole content in a single archive file, then downloading this file locally. -* On Windows-based servers, this requires a remote desktop access. Once logged on your remote environment, use the Windows explorer to reach your www folder and compress all its content into a ZIP file. +* On Windows-based servers, this requires a remote desktop access. Once logged on your remote environment, use the Windows explorer to reach your www folder and compress all its content into a `ZIP` file. -* On Linux-based servers, you need to access your server terminal using SSH. Once logged in, reach your folder and use the following command to create a TAR file: +* On Linux-based servers, you need to access your server terminal using SSH. Once logged in, reach your folder and use the following command to create a `TAR` file: ``` tar -czf .tar @@ -46,8 +58,7 @@ For instance: tar -czf backup.tar /var/www/html ``` -When your archive is ready, you may copy it on your computer. - +When your archive is ready, you may copy it on your computer or to any other safe location. ## Database backup @@ -67,7 +78,7 @@ With `yourdbname` an example name for the PrestaShop database. Your server is likely to require credentials. These details can also be provided as parameters: ``` -mysqldump -h -u --single-transaction --create-options -ecqQ -p db1 > dump.sql +mysqldump --host= --user= --password --single-transaction --create-options --extended-insert --complete-insert yourdbname > dump.sql ``` If you do not remember your database name or credentials, you can find them in your configuration files: @@ -100,5 +111,4 @@ There are a lot of ways to connect to a MySQL server. Many different softwares a * MySQL Workbench: https://dev.mysql.com/doc/workbench/en/wb-migration-wizard.html * Navicat MySQL: https://www.navicat.com/manual/online_manual/en/navicat/win_manual/#/dump_execute_sql * Adminer, a very easy to use and complete MySQL client in php: https://www.adminer.org/ -* Sequel Pro (Mac): https://www.sequelpro.com/ -* ... +* Sequel Pro (Mac): https://www.sequelpro.com/ \ No newline at end of file diff --git a/basics/keeping-up-to-date/img/image38.png b/basics/keeping-up-to-date/img/image38.png index c99f3fe7fba6db8fae09cdb168a809a0a5cefad7..ebf9cfbcaff78db58f619c20f604fa0e8a5e3251 100644 GIT binary patch literal 15142 zcmeIZbx>VFus4W?0Kwhe-RS0xJz)Cpuydp;1VFXI|SFg@ZS60+ueWm zpRL-h`fk;^XU@!Y_jHe(>EHB;P*RXYfWw6Y0|P^lmJ(9|0|WN~rAI%10{s_5K4F3~ z41uDeO46dD#7a)~=0F=WFfi(P+qf=S2xIJ_t_;%tX{LNqT)S{ecs_WYc~Z!rKGgEl z_BQsJf4gVo%lKAU<#`M?K-;pSytiCp%kb}wfrFz(J6;9@3Ke&|n-3SePXK@qcy%sw z%0KX7yvFp**za@|)+QS`2KUop2485)2T1EOiQzLkUexV3H($&%&yRSciP{-4xny_m z!i-PFUykj)voh=)C$W+XS!X{1NK8D(%rj;CUnmL0+b4NuH_(0`elncn9~;5Gx}mT95RqOaZdE zhMAVMxx73WEhzmN3_J`71_erigDzaq1qKG05DEqZx}$Ip~R>)Y8SpftQKN-QAthosH4n$%2W6hlhuWnU#r^l>tta;|49g7de{7aSmHm-{E-W?vj7}`>3{W^0346v zL>m|wmw>dGu$l+>X%>tR`T*9DAua{U+>|$LM}bPAbakMMI5gCAP#~#%*$j%fPa>NN==$1c`j$m z2wu3@Vh?p@#d_&J__=d>Vw4+cP+FUO=50LsWkdj92~GR;0?A288rjGCB$5WMqDvWR znnWrxcP_4y3MS2PSaN6(M`_`#YG8`cR0VSD-90S7*KJ@nbVs2P3*=|-mt`9tL?Z~f zZYK!FqEYqwCE5M{>6euKah7y2wD;FrQ_3wu?m=7HGo{-=yga5N9R&*bI3)hoF)^QE(KxgIxHS^#bB$1Is^ z+sV$ySku#lN=Tw;%-_HazLSUTJ~`)Qw^pZj_PdZO7SC(tl#C}XF~qQ~WNWK3(@5sI=K zDjZdP6Y{=5GWPHSMG*2<_w7}ZFf4576`D&b?K8~LJ_M)jn#^Q2KUeeCvMb(h?RQh; z10k3uyT8Q^$DB%9T3VU1wg5~nff(n(T5^1ct4}YxZ_FuL_~TG%V4ulbd+l$h!|IK< z%^@Ev7OSW-7srz6G|Oh+T1QY^erebu$Z_7C3+CFbUndynxF5)+GU_iRDCDq2rqJt_ z5g2wHDW3AVO~>5uHGk@5ZoAKS)`a`qT!pl7%VseumQ1H!c*<8`j*^y)&+QR@v{+Fv z(B^%fomtdw*nnxw`RnT;9K%ohF5!Bc0a~kv%l+Vs_yYgDlF96m3kT!YZWeRFdm=u& zd`@^?*GKxBgPRVyAOIc*kYqwd%ChR&pFu~4PP3X~Tt=yB*5bF-E_1{7>8bosOitlm z;J;!9|HMkZwIPz~vbn)u?7O}E5Ehq~C~_YZ`t-NnUZ$*jseihi-k`N(OX^7FxIe z%Lf>G9(!h7uj>aLUx1@IxIsizT^uh|Ngs#w`d@B^eD&VkqVRfs=1FGM?)`RC6K`57 z^y*XZHDF@(Hy_9KeELUVP>@+>%RelY`yUQEonOIyuNUP|mgdNv>2;adBn9 z7v<@k^a`H6&!<8g#>#T5ndF~Li)GAf5D?&tB%+UIk2sDS{^>T^mU!J*C5DByxiL1l zTRrA_sp~X)2p|yghD*FX({=dZDDQdSoz3R3?aws*ZJROtXEE)M#W+=^@BLLrQxl6; zznuIs7{Auzluk$XjHgv&w8E~;i_f z3CVfZq7>!tMbgqi-z^H94m%DM9H{fisIwOmLzBl9xB^9Xy}(HQT$ggDT8ML&wP%$$ zC%+z{wwpoNLkEay-fRE*ng_SLK5KJ^$7Nd-o54ObnUaXLz9Q!l@DlfRzB94 zC=yXC&gJ*MQyxOh8AHr7$kLf>R)(y=J06)Wxx$Ucog>rK(o$w_ZS*IifHdMW4Iwli1nb7Ugl?BOd>fyOhjcYAE>|U8yAW=6E_lR8kF@ z!$v6;4)dCVNl}qjIls9blQ;4oXlkD)(aDY^cq+BjnH~Jj;$xM!*`18%$Me0LSggY* zBqUsRHCY}>rlUf5awNV%UiH2?RAjT5jHYRwH&!}O>Sd$bA+gWvpO^9-`fHKInEnGG zSf_?qp7Ljf_?)pby|m(z*GDGoCYu;Bf#(XQM#EB5m+%%r~EXV=O~ zsf)2vzbjyGGMz*ouKY8VViu+0Is_DSd7;>)iObwMwz0Q-nt=~Ix{`1bg)C*O+r%~X zYeTv#xC?cheMpO#bf=H!VNYLJ62I=Xp`nPjk=rsgZwM}tTB0>dkxWXVy2vHn!(A8r zbz2%mCaFSQGe&xA2s!tf;6n= z;Lq5%)A(PIY2nvS{M5mIXk<@}CQ0l2ORl)Cdzcf{IjN(?cXN{4zLXntPzhq2n$;S~ zk4U&Ok*SPW-x;daYHCR6M$)Fk7~xcr##yXfydFj|coHwG4^4lHaVreera4y9S$;atN5~;W_D3*DmMxWr@xY1oA_v8o0iB+D&2JyL! zQIq}e2ypMl6t5-HGRysx7KvlO5*EvUmQAfD9kq=)y*AcAr0C_^&;Xs$a;$OwFK?jXXk>fU&Iy#giU zE>~w2uY|>)r?#_tB^SR2>-ie3KNZ&v!TN+`2L>iP?T?S9M?O=AjKd3)DH7uGx@j7F zux2ljHM@d77?ifRpTCvCm}iWbC}Y7__5g`;zL;D->PL=R z#W7zQ1!MazBFlIuE8X&k%&b$PJGA)-TDAe!>RZw zaEp+NH}I9pP9;dHD7uD{XJ({%ov4chQ@?t8sD*8#p7Jl8S@BT5s%66+Yb6!|G-gN_ zL#B4dH=VN@g9EW`)Z4g#!U(N$|xnfPI!p{SPg+`+e*MX`u<2QY;ip)$Or6g zW~uYxMj9}Dc#)aYaeNP+E z*hlR~IIPPt{KnHB{mLF(gaY3dDp4PfZxE?~vWeY5*Rw>hc!RDAsn}HNh_K}u4)0++ z+T9Da#tNalj?7otYyggn#nNz}XYCxQ(5n(bLnQl8>2j*4U;GbQhoe4!$k6X!`;(s| zyK4UA@V!;*E!p1vp*nJMvL3s_`)acbe)2Fly2cIP&r)=P!c?hrut#3Z%*8@5L+8B{ z5Yr>M2wv)AIx0D^$$;jd0pV7Ck%iGtaZ|4U5Ay1+OQPcmF>bHQ$xL>3DMwP8OI~(n zMHXK(FK#n5Vww*gwB?tU>^_s{l@1H7e&4jBIWR)l47*g_?kt16gKnsCRHG1kOaz#Z zhs;PYI-h+j#VUjkzk(j*mzYmG{D+g#^0}th{eP4Fzhsi=!*3TCT(GWUOw@A++UnRbvKwpU?PM14V>IJNi-~0si>Tz%p@82 z`u-BlSE>CjEEb>a-`St1FpvFRdK{2H6?S_jD744h6BbLToI~_UrR7S!^is02RO9d9 zwcor>z0>N4aW^*zaO1(&7^V+_+o(j zv4R$}q0v7YsNwe~Ntu|KPPtj!di(ks#@apqNvt#t#0c2y?(83U8qKXW>PvcEAF#MS z9myVDi+cyrk~~K$=pX8Iy9WIW5Ef42b7#z8c4TGH@BIE9olz_jbDT5WR1v0jel~k_ z)XdT5-63Eho%I*yvVZ-t>^H-!@f~|}BI^!obL=O%oX@5$+T!pk8FO>3!#yXUu8A5&vd$W!&FwS~rNFOPwPZ4bzND><543#* z^Ia+p7!mF{WJ5W;+8vX9JAQ^PlFrJAqwL~#b9OG66nsg;ytQ%J-ecgw?ZfK)8eu{^yyJFrO@$8e&*0;`wMXq`+fl z*yLv#1^0HF)#kK`cw@a>h$5fELbp)f%jl)*LakZ#IQs&FM6LNdGfB|j;A$j}WT8I% zVxvd2)#I@4AjxjDJ_H^siEKCxwa*3l`ii1RF*SzOY}As~%E5v8!4N*qxD)znEWUIk z++3k|JOH{AK9zBVwbvzH&`>}om9a7%eNWM_#VJ`N*g`4b`C(@m+dw3BpyhpkZdX;6 zM5n1hdvGk9olP@gfr@i=^2fRL=$y&3L@HinFQU%V!y`@3`)Urj+~^zjrOj{q)63I3 zG=ssyPi^*v@~DG@8`t3UodwX|exgFN`pXPm70AIRPD3`{V=-e@!4dgkgnegtXtke~ zD2a~OR4*}Exv!96X_>HU6*}pmUykf^0oTAyJ06p3>{{-2aetjNF8hUGE46CO({|oV z-?ttW?MC2ypx?oYY8K~Gwt#aCulph8r0w74L7O3?IO?m7y-MA=wsSB~gl&g3c3yWI zCX6P>w3cm!eEgbtrc5qbH#VEus=l*%(Kvhz@rjjIqU8Hp0(ARr|zK_k4wKI$S+Cz zuCU^MlJIua4{~IS0>gs3^C`x5j7-)}aA>tw)>>VEe0t@MiXjjz%bGox`vC}`)$mZv z7AdK7xMbBKS%79{F(_=@fc>;R63x^+*WS_}Ew^{bmQ{wfZ)<^P;`V zm6`EFRciY+fDYh<_U>MqhWx zi}9u(m3njcN(ai-+?E}<*LEHcQE zY!qy-U=R}gd6HgHWTT56TTILx!H zEgAps-s(IE?W$GuW@9PhG1o{$mx-CJzO#|nSsp$|W%^nt{rlM(5A;Uok`ja z_XlcTw}(_+nO#v&(Zve5)gi_fH_Heabwku0_UD8qouidn0tf6a@e6P=}o6O_-L+N800R;ZDOP3 zlQBIRnBg>;K26FucJvI8A{qHT+OAGseTKvP-lkBQVQ!&TeAV3`370LSRK1+Z7G(9;o}Q01)ZP7Pula!<8wg#P&AE7F@q>kHwwjiJp>Li{qAP;%xT3N%D8?U z2wfYkY#<^Fd$Y_viSN|=Gjpw+ILJyj9(Nt6JrEcYxm%{VT%TmXF7s!b+#{NREy2h; z>>1z|xVqdov|zi^5aYX3LxhmTKMK>v&P!$5v&CYbH&`s0=E&?2(A{Y-8!^dms~00+ z0#=}T`*|{fht2iH&;keJS85m%5pZPcQn*~R+9dbH5phjvcimgEYJMYafCcof?hQlL zfY2>4Fk)S*_pAUEp~niWdb~~LkzLJ&MdPJ4MEA)fkzo#Rl1c7j5@~%_7g*2nvw3U* zE3~H9gF@52B?6E$!4@H+CDsZZ_Vt7FFkx>0Oa@_GiN6?B58<$AsTECw!_z|(KoC)x z{$sPNtgT^JP?_J8o9!-*ixzYApCEibH$6}XHS?D6I{4v6sV#J9@h#qKX{)_`VhqJ)c=Kvv9xCW`8e-Jmf}842@{tff8c;nf(-J|>V>-M{ z%|CE(6gDDiG_x>{&NRb9)IMqiLi!8oCN-zssJa}yl4);aq0I{AXM|1d0&+^EG!bYr z-Y@+F`M-{Y)RqgEKIwJQFu}J8N|Y~r#=I%IODPpRy6&xGI7qKCr(P5!?b7IR1Di=)!x^l-mS#9O=AUN5!mUcl zmmJ!3E8oqCE&$-03(~Ug@1?QH-w$4|zDfz;QnX0`Xge`{U%SrDnmY{+4IL@?I#Mum z5Qrd$_4se8$xX~MlW>%~DllD^E(J=D4QD=iI!=xcM)uOm zg~OP^1o%0FM}<)Ub|CZ_Z?8N@n^L%z<`w#{xroGKAR$v@c^Jd_A-eh5&C)1bksz>F ztJP_jwoJ}$yKh+V!6OJk?Zm!LzTUvfac*o!x!waRbvrvCjLG>ZrC@%xg|vbFTPPN?OoD-O9fr-RaeBfY@P z7T;9tkox*u?bk<$5|3cns&i~Qm3=K@-rYFVl>%*;%4cis#*$(#lDM&3JgjNKF$3qN z5bV{|K=3og5dp)IR@cqqpO>5cTBMLKp4S((s~L~YE)UWBsTzd!+Z_{G!Z0BngO3uKGo+A-d~S~v zfq4qT7q3PpEx~Iu??J~4IFNGJc3!pQvQtLB7Cg?kfJAdxvuVo=ff-2J=#d&7^%ERTHw#ufc@9aX&^)`n0g z5}S~bwZ{~M5G=QzF|b6K2}y!3i`8ApNH5fQtl7D9g1tzK@*P}AooN>qVMeWQr|!PH zZB`CZ9N2nQkq6sDujEWY(ERNhA`Cu#zDU;0Ieu%($IX{kP^QXk zsRVrPXlpzL?hy$pm&09^Y(_&e^2W*OSI5wzgdnE&>B{ z$+T!rmPJFO6NdH#wp1tYS7-M|O%ES({0OOXg1h`)LKpJ3vx9#1-NPoDaURsy7WZsn zL)qASL`inAT=gOpO5E+OC0L%JVhbx^b4hrwzO7{YnyHzsXdYg)hS;~ds)sE%nnxe0 zRSd#h6&ZMV)oFAL&QPG+xtGf+wIBTfV=&%9Y>(b!(jxD`sVNQdZ@{kH+Ug-tJwH_5 z+-vOUZws~ij@4qk7kIsQ)$P5BCd>Tq;Lg_`m*1S;_T`D_0SQaz1`tFGvlbmxQXai) zdfC0u-P1?D;%4})Sk=>g0{%;SKjt*LVCCAQ8>yqrJ9e$kIfwH_vA3(%$Soq>q9F99 zC||N;qb$hZdYMDuChC2%QCY`S>vhns$FoyhMd*%yyXi6uX#W%egEPHHA0tdWEqPzH zl|_!+9zCtK!4Np0`x!IhI~JW4euy3!(O=1Lk@swv9;MF$uK7M;t#GQdw$y&lPBSNh z{#*}kLQz-#IBX)FmNI|)?-NA-Y?}|MwvxG?Yq-0z{e&ESEAfy-B0N(G`~v}X)6@1h z?1fti8Ypmj6g)aPz~R-gfe`3)_gK}Y#z`CP2S15oRyCCqYr8&CO89tRF8ApC=-ciM zeWS9++)+35B10isFdr8M-t`mIl6Q~ zs?n5(dnA$(mcpUJ@oE0X*XSC>SQEK8=m`?H66U16OS?0Y2~_z;1FPy~T7>F+v?O{7 zHsyNByY67j*n6C|IgNsKH@Z~)Rr^bt@r9N^yHopsHO59=sU{)IZlEDso9k2K*AOfZ zvuGa$(qi^TL{Uj+-F7>kHlbd|yA(+6Z<9$V$f`?cA}E3MX8>rbD5 zDb%DLdPRoSGapY2##sOb@R<%_xf^;Fz1sC4KyY5#w-@Aa0r$q7I!Eb`1An>h(DwiU zWJ-&Hcl58u0^;YzX^U&Kjodd-cmUoz`X`!}iSdE=Wy99=HtjEL*0H=JgEms2-~a?; zCykGq-jv;N>)EhP4*$Fqr zM_=c?qr#6kW3V$5G~EB#NTcjE0^oacsXA8aYGQRWa^t9?2}Vwl)tx z_pP_*EpFOVvjg<(Z2gpfPno|D(=QYj{ZN@dgy7t{t{fum(7$cDyP^>Ue1`WWQ0OtP z&cX|ZT#Ui!gydRV(YuZdai+0(!u0ax=~Z81=wfPFER`J*0N!z$O4qcOTsu&?vy_MR z_Y=yji@Sg^iT0uXq|bC*g>6ov)x3-@8d1dmYY$Y58G=F$7P_CnLkBc7b-bQujy(T` z!ze=U^P^lm;i-3U8=F(=2TDetR2o-HJf5WBQ0>5`P(MD?_b?9Num#+sP0@L$)*n)9 zk2UTXbfl!P@Iv$(*CK!ef5ozIiOcYM;CV>`zumjPhTgjAWF^ zyi>mj>~Pq(FmKNl@91~tsr|S^ZjscYMuBnE-ckgEuSbTw1LRBpKn5E*59HJYS<$ec*vZv{f<{ z&=(2`XhtD9JM!Jo;Yi@AQRy_hHHOq4JGu8?`+$`sU~H2=E=tjR-?9@*!g=@j+bBTG zirtS;cyl?hs#GsW=|gD)=M<%blpFL%#iSM($EfY2*~`vds0$?wu}QY)X;CNX91>bI zCMGZE{S>#KTjljSVCUpK?-5jMP#YCkW~GMM*sh@nip+Sl&`e_ljKX!+Y5R$# zr%kWAJbxI3h|xb{r(SO+maqb-xtF+y%eNn_xu*M}W$6{zoCkC=8ow3|TxOAMO?cnI zo*L8Jlfj#Q8XS6$Y}%j9!OJP$*wA$Ow>M$AU&(_4LQ7kH{v_M2g&PVi=*`YFU$h5o zA$@@*8_&Fm_02S`#+Rj`)Nd!(yx-nu%r~AjpSh~!lT*Rwy-~#J96ApkagbG9^SuwZ zTlcpFx`;ftA<@U$I}W&0BVp-DM~R9~F)yQ!R7t-!y6 zUy}~k{VV0xsVZ6Yk4j%_PQ#CcqnjIs7py zORQtrU!=3e*~)QVq4Zujj3zQ=wq;Bc_F+3?-ETQVrQ|BVX0iG()~w>N{WCnO>f<#~ zMYX|wRH@)7S>35^-EPfWsIKeno~3f7Hq6UsZO|s&_%^`vi_GfZiRd*3<)qI0(s&QV zA@#=j4QcQhVbUltQ2ii(QBy+19cSS^u6sAZ}poUTW!%BzVehF#yj9kUy+Lh+PO z#4S2lJMI(1YHnI4(GheNYw3AGi)4s^o-@ZV#L_zfx;-O5hrEacv7VFdE zF62JQOD20B7r>#8Zbsoci+K!4j+;{Ab-sj~uev7ei12C0yElx?QNjZ}AeCw1s#S_L z(00mlovjx1Bo=SKXse{ytw~_lE_ikU8tj+jMEXPyzuV1yZ@+xgp|+yH{=21Dlim<~ z`43YXbllBG&%FAufHkHfq z8stcYd5HVr^}v{laT+bRoS>jWw(tS*3g=JRWSP|5mm$UJI))W97iQ?8X|}zDCM6dF zG0AV-^J@%reQiy)G`#yMB4s5B1c4T#=+_e^m8H_rv^!);>N->^x1|?k#<-aPAY9Mh zn`l?3TD5^b$b%Qj5MN}sMCuYH8*IQl3cJI6FG9u&a(d-@f1G~oMd@Wic z23MG?YCRVOw~uVp?T#u%XAmjHlZF5fYKY3*&$F+dlSWhv>(1xO$b44{_z3>-DVX}> zQ1vkyG)s|%#uk>(m(TQ%pp_~YgeEcQYPj;O@v;PjlY|neT?Ae2?pU7hR%j-vv>&+* z84EtB0@VkkJbPLvbYR^h@vz{a$u3QxuSWhoIDIWyAAmTHpWQ#;XIWl#-D$>W;H-WL z_)@Lci0+Ef6^O3sNhzWJX3!yVV5FAK)E{nj+$pMZX)Kr?29r#qrxbHPh8f}IY@}D6 zo_5H2vMfoHKvh8caHRy!(hFsOAsGgwe+qUQg77{^w59R?eZqR5kDYhM?-r=DSY0GO zNn>ss)G8K@%@P?@$_ej>LCSXp(c(0m9^z+SVzwp5Cy0n6N25YsB6F^pPdu&7Xiy)_ z>oc8=NB|Iv9ry`XaPISPrBZ7mP9wWO&tBs{H?}boseN`QDE3l1_VOeT?7feelcl}` z1^&GsJN!k1KkJ0{rKrVXGMM_lOD7KVkDtR*OYllBSLwb>C8x84S}E<6m_i1#1mJn4 zlqVA7+BMqyPcrizmKc)qy%B6X$bpnBr1|<|DTP)|DC5gD2Yj=uq#Klyf($Z})6E_O z(BPX0EompfYlPMuF!y{=E^f3! z{4Z`2zp4bz2Qggp6+IkV>lL1k*ig_-lGH+<3v73!qpj7FGFoHVM%^=h}}21PQd`51H>sObOX z9VdHtK!V6B$c9@W#ZuOoVwo^Y`uhM?DVY=9ZsAH6gAjidLb$zax;x^D@sO0Fm%BF zBc61UT*6R`FKwxd%682=j`Ng9D2P&_#H}|8im$T+-dsG5#S?aR6vucpfE>-ud}+=8 z^KRe`QU^6=8b?{95Vy^PS8ZY6@!YfMAC_*YCaJUm&NBg_F26Sho?h=c)$pgA=>o|| zT98hP*G!(M-^ zYvnJu>UhSS@eI10LCi!f7njJVd{)<=dHqhfUv3sjAM2d4fL-?Md0E1G0uBQ2CJAWt zOa5-c;y^Qj44+#zK&San95h;%;P*zv`C{=CIX%r(xZQWl*^zdJGnM@ubA5ipqeU6i z2!+SfLBR*dJ@vXFw6TaqZ|w$5hpBj#^-KM%O%GYxF$s=}_baeU1`a3T)N9a7@CNn{ zwMt{=K}p;kl+WWv&gc(p9X)1wmqjX<{Lp6(H8R!}9GgM?@kcoeGAVv5wv_qM2>k9D z!@oD<^Mc44gWX%fM5am4bq?rAU-zzhM1Jv)?VAM*2EE$Uw_XnaKJUxxky%ziwAN~v z^e0LJ`f>B$_{O)bzQ>IzgpF@~VTiN2J&-$=_~0dqS<}6>kd1k*4JALd>xLcZrxwcf zXNjwLg)-_)@-W{jG^&anyJAW>iJDl_B1)UvT?rxFIQ$tIY&MieFO~x2*OQXa_wf1y zCI}7q{q|prczV&nDO8l{5k+J$Zj%Wh076Di>A$=n`Ta0&;-XY^=w8=IUQRbrdHqi% zR8tf8StFpAe&Vo&Hw2j0%cNy(q$1A#9<}8&hny&lNM5gYZ-;NkPFDwQIc$1%R3UtsYertNI8Jl^51vuwt<+mkif z3QfGnH!NB`sp7sM9WAKPiMJr!d0&G5BXmbioP|(8;nNJiuX%st34P6SYLR)Yp{u+;$a;?!L&P5j@yWMY*3}&X@JM6vB z^rYn|0DyCDQl8R9>_z^=znOxP$*(EH1?gH-f2mgmo}zPTC)H^*b!Zu!_k!051SmX? zy3J7DkfWl0%$GAJQxejutcj(w78Wp8e(Abq4ao8pdI%IevZF_+=w#}!M-+>ZQ1_6j zy;zd035_hTdm#Jr3&&SrSd$57ra1l>?|}Rg$@y=JFO1m}G2t@e;dCBfU^kulwIUgC zrk_S7pkVxPrl?@e*GswM@#af8XhHVm_1>drK;J`?nzvGC#~PmNr30?s*RuO8Nm)Hz zmasloRJTp-%BBw7^@?X0w)(F`zux6-^@ca%3a~F%>>eGth@(ULhGB*wbmZA- z1l*S2^ekOnUD+zMas+&3*4B#8#dqH1##M|zu~J=3hdog)U?mwvgB`hsCC@kg?dwy$?Mi%srdyG&ezw3?MI=s>8nA16b+?W?6F5g7+5rP@xT`xR_vUV zA?BBwc73Rm(a<-yy#3`5NCGwWn`rC>8Wx6OG_00l?sOQ!VS@vfxiQ485D4DluZKwO z0m5FW{#010N7QEFJmmiR%Q5fc#Q%_hhFmjR=zO^)PF2dPxoJyQQ)D^XR5|LVYPf*oHj7?I ztU=>*J_kIhxYomcCjil>f&Flyml#0#FkOs1s71eiz_i^WJf7FU{8<(j(tH4jV)A>$?DMPEf;Q{`%>8 zeMld8@3^S%WFO-O{|Cq*Lw16U{2$UyKwKF9zoOo~Aj$E$^{TMoH5lk8Ev_I|C1Mo# Fe*ifSi*Nt{ literal 78355 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 DESCRIBE prestashop16.ps_product; +mysql> DESCRIBE dbname.ps_product; ``` You should expect the following result before proceeding to the next table: diff --git a/development/upgrade-module/_index.md b/basics/keeping-up-to-date/upgrade-module/_index.md similarity index 97% rename from development/upgrade-module/_index.md rename to basics/keeping-up-to-date/upgrade-module/_index.md index 31c9d8c65f..373d478000 100644 --- a/development/upgrade-module/_index.md +++ b/basics/keeping-up-to-date/upgrade-module/_index.md @@ -1,6 +1,8 @@ --- title: Upgrade Module weight: 80 +aliases: + - /8/development/upgrade-module/ --- # Upgrade module diff --git a/development/upgrade-module/channels.md b/basics/keeping-up-to-date/upgrade-module/channels.md similarity index 96% rename from development/upgrade-module/channels.md rename to basics/keeping-up-to-date/upgrade-module/channels.md index 8337cfca3c..701d35a13a 100644 --- a/development/upgrade-module/channels.md +++ b/basics/keeping-up-to-date/upgrade-module/channels.md @@ -1,6 +1,8 @@ --- title: Upgrade channels weight: 40 +aliases: + - /8/development/upgrade-module/channels --- # Upgrade channels diff --git a/development/upgrade-module/img/upgrade-process.png b/basics/keeping-up-to-date/upgrade-module/img/upgrade-process.png similarity index 100% rename from development/upgrade-module/img/upgrade-process.png rename to basics/keeping-up-to-date/upgrade-module/img/upgrade-process.png diff --git a/development/upgrade-module/upgrade-cli.md b/basics/keeping-up-to-date/upgrade-module/upgrade-cli.md similarity index 95% rename from development/upgrade-module/upgrade-cli.md rename to basics/keeping-up-to-date/upgrade-module/upgrade-cli.md index 0f4aeffa40..8e134e6c9a 100644 --- a/development/upgrade-module/upgrade-cli.md +++ b/basics/keeping-up-to-date/upgrade-module/upgrade-cli.md @@ -1,6 +1,8 @@ --- title: Upgrade CLI weight: 40 +aliases: + - /8/development/upgrade-module/upgrade-cli --- # Module CLI diff --git a/development/upgrade-module/upgrade-module-internal-behavior.md b/basics/keeping-up-to-date/upgrade-module/upgrade-module-internal-behavior.md similarity index 98% rename from development/upgrade-module/upgrade-module-internal-behavior.md rename to basics/keeping-up-to-date/upgrade-module/upgrade-module-internal-behavior.md index dd2699a0d7..7d753a9c73 100644 --- a/development/upgrade-module/upgrade-module-internal-behavior.md +++ b/basics/keeping-up-to-date/upgrade-module/upgrade-module-internal-behavior.md @@ -1,6 +1,8 @@ --- title: Upgrade Module internal behavior weight: 20 +aliases: + - /8/development/upgrade-module/upgrade-module-internal-behavior --- # Upgrade module internal behavior diff --git a/development/upgrade-module/upgrade-process-steps.md b/basics/keeping-up-to-date/upgrade-module/upgrade-process-steps.md similarity index 98% rename from development/upgrade-module/upgrade-process-steps.md rename to basics/keeping-up-to-date/upgrade-module/upgrade-process-steps.md index 9a99058f52..5f7b5298ff 100644 --- a/development/upgrade-module/upgrade-process-steps.md +++ b/basics/keeping-up-to-date/upgrade-module/upgrade-process-steps.md @@ -1,6 +1,8 @@ --- title: Upgrade Process Steps weight: 30 +aliases: + - /8/development/upgrade-module/ --- # Upgrade process stems diff --git a/basics/keeping-up-to-date/upgrade.md b/basics/keeping-up-to-date/upgrade.md index 52597f6b7b..6e8f0b171e 100644 --- a/basics/keeping-up-to-date/upgrade.md +++ b/basics/keeping-up-to-date/upgrade.md @@ -33,10 +33,10 @@ The first step is to download the latest version on https://github.com/PrestaSho If you upgrade to another version of PrestaShop 1.6, the release files can be found in a [dedicated archives list](https://www.prestashop.com/en/previous-versions?version=1.6). Download can also be done in command line, as done here with the version -1.7.7.5: +8.0.1: ```bash -wget -O prestashop-upgrade.zip https://github.com/PrestaShop/PrestaShop/releases/download/1.7.7.5/prestashop_1.7.7.5.zip +wget -O prestashop-upgrade.zip https://github.com/PrestaShop/PrestaShop/releases/download/8.0.1/prestashop_8.0.1.zip ``` ### Archive extraction @@ -63,13 +63,12 @@ default data. These folders can be removed from the new release: - img/ - override/ -All the other files present in the new release will overwrite the -existing files. All changes you made on the original source code will be -lost (by the way, this is not recommended, you should never modify the -core files). +{{% notice warning %}} +All the other files present in the new release will overwrite the existing files. +All changes you made on the original source code will be lost (this is not recommended, you should never modify the core files). +{{% /notice %}} -Also, rename the “admin” folder to match your shop’s admin folder name. -This will prevent an unwanted duplication of the administration content. +Also, rename the “admin” folder to match your shop’s admin folder name. This will prevent an unwanted duplication of the administration content. ### Turning on maintenance mode @@ -78,30 +77,32 @@ turn on maintenance mode during the upgrade. This can be done in your administration panel: -- On PrestaShop 1.7, in Shop parameters > General > Maintenance tab +- On PrestaShop >= 1.7, in Shop parameters > General > Maintenance tab - On PrestaShop 1.6, in Shop parameters > Maintenance -Adding your IP address will allow you to access your shop while it’s in -maintenance mode. That way, you can make sure everything is working -right before allowing your customers to access it again. +Adding your IP address will allow you to access your shop while it’s in maintenance mode. +That way, you can make sure everything is working right before allowing your customers to access it again. ### File copy -In this step, we "upgrade" the PrestaShop files by copying the new -release content in the existing shop. +In this step, we "upgrade" the PrestaShop files by copying the new release content in the existing shop. ### Disable cache You may have activated a caching system (e.g. Memcache) on your shop. In that case, make sure to disable it in "Advanced Parameters" > "Performance". You can enable it again once the upgrade process is done. You might want to also delete the `var/cache/prod` and `var/cache/dev` folders. -**Note about `vendor` folder**: Previous upgrades of PrestaShop 1.7 -showed that conflicts may occur when merging the new vendor/ folder with -the old one. To avoid this problem, we recommend to delete this folder -in the existing shop before copying the new one. +{{% notice warning %}} +**Note about `vendor` folder**: Previous upgrades of PrestaShop 1.7 showed that conflicts may occur when merging the new vendor/ folder with the old one. +To avoid this problem, we recommend to delete this folder in the existing shop before copying the new one. -On Windows, copy the new folder content and paste it in your shop -folder. You will get warnings that files already exists in the -destination folder. Choose “overwrite” to continue. +```bash +rm -rf vendor/ +``` + +{{% /notice %}} + +On Windows, copy the new folder content and paste it in your shop folder. +You will get warnings that files already exists in the destination folder. Choose “overwrite” to continue. On linux, the copy can be done in your terminal: @@ -117,15 +118,13 @@ cp -R ~/Downloads/prestashop/* /var/www/html/ ### Database upgrade -Once the files have been copied, your shop database is ready to be -upgraded. +Once the files have been copied, your shop database is ready to be upgraded. {{% notice note %}} Some web hosting providers gives you two user accounts to access your database. One with full privileges the other for using in scripts with limited rights. To be able to use this Database upgrade script you have to use the account with full privileges. {{% /notice %}} -All the changes to apply have been defined in the `install` folder, -running them can be done with a specific PHP script. +All the changes to apply have been defined in the `install` folder, running them can be done with a specific PHP script. When you’re ready, run the file `upgrade/upgrade.php` from the `autoupgrade` module. @@ -165,8 +164,7 @@ some cases, you may need to restore your database backup and start over. #### Error codes -An error code can also be displayed. Each code is related to a message -described here: +An error code can also be displayed. Each code is related to a message described here: * Error #27: The shop is running a newer version than the content provided by the install folder. * Error #28: The shop is already at the version you try to upgrade to. @@ -203,8 +201,7 @@ on “Update all” at the top of the page to run all available upgrades: {{< figure src="../img/image63.png" >}} -On PrestaShop 1.7, the same feature can be found in the Improve >> -Modules page, under the tab “Notifications”: +On PrestaShop >= 1.7, the same feature can be found in the Improve >> Modules page, under the tab "Updates": {{< figure src="../img/image38.png" >}} @@ -229,3 +226,5 @@ theme. Many agencies and freelancers in your area may also provide this kind of service. + +More information about support: [PrestaShop project support page](https://www.prestashop-project.org/support/) \ No newline at end of file diff --git a/basics/keeping-up-to-date/use-autoupgrade-module.md b/basics/keeping-up-to-date/use-autoupgrade-module.md index ba1de2d411..233d1ac56d 100644 --- a/basics/keeping-up-to-date/use-autoupgrade-module.md +++ b/basics/keeping-up-to-date/use-autoupgrade-module.md @@ -15,7 +15,8 @@ The same note as above, in order to have this module working you must have set i {{% /notice %}} {{% notice note %}} -The latest versions of this module allow updates from PS 1.6 to PS 1.7 only. +The latest version of this module allow updates from PS 1.7.x to PS 8.0.x versions only. +If you upgrade from a version older than 1.7, please use a previous version of this module. {{% /notice %}} ### Note about version +4.0.0 @@ -28,10 +29,10 @@ Documentation about this major version is documented in [Upgrade module pages]({ - Download the latest release from GitHub https://github.com/PrestaShop/autoupgrade/releases -Then, import your module archive on the modules page. To do so, you can find the button “Upload a module” (PrestaShop 1.7) or “Add a module” +Then, import your module archive on the modules page. To do so, you can find the button “Upload a module” (PrestaShop >= 1.7.x) or “Add a module” (PrestaShop 1.6) at the top right of the page. Clicking on it will open a form that will allow you to upload your module zip. -On PrestaShop 1.7: +On PrestaShop >= 1.7: {{< figure src="../img/image70.png" >}} @@ -41,7 +42,7 @@ On PrestaShop 1.6: - From the administration panel -On PrestaShop 1.7: +On PrestaShop >= 1.7: {{< figure src="../img/image33.png" >}} From 2b604f6a8d7b603b42ff3c3ce5b5db069ef222d2 Mon Sep 17 00:00:00 2001 From: Thomas Nares Date: Tue, 14 Feb 2023 09:49:22 +0100 Subject: [PATCH 246/310] update autoupgrade doc --- .../upgrade-module/_index.md | 9 +-- .../upgrade-module/channels.md | 1 - .../upgrade-module/upgrade-cli.md | 15 ++-- .../upgrade-module-internal-behavior.md | 20 +++--- .../upgrade-module/upgrade-process-steps.md | 70 +++++++++++++------ .../use-autoupgrade-module.md | 2 +- 6 files changed, 68 insertions(+), 49 deletions(-) diff --git a/basics/keeping-up-to-date/upgrade-module/_index.md b/basics/keeping-up-to-date/upgrade-module/_index.md index 373d478000..621e5dd99b 100644 --- a/basics/keeping-up-to-date/upgrade-module/_index.md +++ b/basics/keeping-up-to-date/upgrade-module/_index.md @@ -13,12 +13,7 @@ Details on how to use the web interface are documented in [Keep up-to-date: Upgr {{% children %}} -## New features of v4 - -Although v4 of the module was scoped to be a refactoring, some features were added at the same time to improve the support. - - -### New loggers +## New loggers Reporting is now using [PSR-3](https://www.php-fig.org/psr/psr-3/), allowing incomers in the module code to recognize some common code in PHP. @@ -30,4 +25,4 @@ New loggers have been created: ## How to download it -You can download it from [the module GitHub repository](https://github.com/PrestaShop/autoupgrade/releases) or from your shop administration panel. +You can download it from [the module GitHub repository](https://github.com/PrestaShop/autoupgrade/releases) or from your shop administration panel. \ No newline at end of file diff --git a/basics/keeping-up-to-date/upgrade-module/channels.md b/basics/keeping-up-to-date/upgrade-module/channels.md index 701d35a13a..48c609693f 100644 --- a/basics/keeping-up-to-date/upgrade-module/channels.md +++ b/basics/keeping-up-to-date/upgrade-module/channels.md @@ -11,7 +11,6 @@ Different channels are available for upgrade. Depending on the channel, the archive that will be used to upgrade the shop will be different. - ### Major This channel will look at the latest version, even if it is a different major version. diff --git a/basics/keeping-up-to-date/upgrade-module/upgrade-cli.md b/basics/keeping-up-to-date/upgrade-module/upgrade-cli.md index 8e134e6c9a..62af228851 100644 --- a/basics/keeping-up-to-date/upgrade-module/upgrade-cli.md +++ b/basics/keeping-up-to-date/upgrade-module/upgrade-cli.md @@ -7,6 +7,9 @@ aliases: # Module CLI +The Autoupgrade module is accessible via `cli`. Its advantages is to be used in conjunction with a CI/CD pipeline to automate your upgrade process. +It can be aswell used manually via regular `cli` to avoid regular configuration limits on Apache or Nginx (`php-cgi`, `php-fpm` limitations such as `memory_limit`, `max_execution_time`, ...). + ## Upgrade CLI Upgrade module can be used as a Command Line Interface. @@ -16,9 +19,9 @@ Upgrade module can be used as a Command Line Interface. Entry point is *cli-upgrade.php*. The following parameters are mandatory: -* **--dir**: Tells where the admin directory is -* **--channel**: Selects what upgrade to run (minor, major etc.) -* **--action**: Sets the step you want to start from (Default: `UpgradeNow`) +* **--dir**: Specify the admin directory name +* **--channel**: Specify the [channel to use]({{< ref "/8/basics/keeping-up-to-date/upgrade-module/channels.md" >}}) +* **--action**: Specify the [step you want to start from]({{< ref "/8/basics/keeping-up-to-date/upgrade-module/upgrade-process-steps.md" >}}) (Default: `UpgradeNow`) If you use default `action` parameter, it will run the full upgrade process. @@ -38,11 +41,11 @@ In case you lost the page from your backoffice, note it can be triggered via CLI Entry point is *cli-rollback.php*. The following parameters are mandatory: -* **--dir**: Tells where the admin directory is. -* **--backup**: Select the backup to restore (this can be found in your folder `/autoupgrade/backup/`) +* **--dir**: Specify the admin directory name +* **--backup**: Specify the backup name to restore (this can be found in your folder `/autoupgrade/backup/`) Example: ``` -$ php cli-rollback.php --dir=admin-dev --backup=V1.7.5.1_20190502-191341-22e883bd +$ php cli-rollback.php --dir=admin-dev --backup=V1.7.5.1_20190502-191341-22e883bd ``` diff --git a/basics/keeping-up-to-date/upgrade-module/upgrade-module-internal-behavior.md b/basics/keeping-up-to-date/upgrade-module/upgrade-module-internal-behavior.md index 7d753a9c73..b408a667a1 100644 --- a/basics/keeping-up-to-date/upgrade-module/upgrade-module-internal-behavior.md +++ b/basics/keeping-up-to-date/upgrade-module/upgrade-module-internal-behavior.md @@ -7,33 +7,29 @@ aliases: # Upgrade module internal behavior -This is how the module is built, for version 4 and higher. - -Most of the information is however valid with the previous versions too. - ## Entrypoints The upgrade module aims to be a PrestaShop module AND be as independent as possible. Which means its content can be reached from several way: - **autoupgrade.php** -Every module developer will recognize its content. This file is used to manage the module part of the project: installation, uninstallation, then automatic redirection to the next file. +This file is used to manage the module part of the project: installation, uninstallation, then automatic redirection to the next file. - **AdminSelfUpgrade.php** This controller uses the AdminController features from PrestaShop. It allows the upgrade configuration to be displayed in the back office. The merchant will see the configuration options. -In previous versions it was used to handle everything, displaying answers, handle and dispatching requests... In the latest version, its responsibilities were restricted, which should be displaying the configuration page. +In previous versions it was used to handle everything, displaying answers, handle and dispatching requests... +In the latest version, its responsibilities were restricted, which should be displaying the configuration page. - **ajax-upgradetab.php** -This file is called from ajax requests. This is the only file responsible of the initialization and upgrade / rollback steps. This file is not a PrestaShop controller for a simple but important reason, we do not want to rely on the core during an upgrade or a rollback, this would increase the risk of crashes. +This file is called from ajax requests. This is the only file responsible of the initialization and upgrade / rollback steps. This file is not a PrestaShop controller for stability reasons during upgrade/rollback processes. - **cli-upgrade.php** This is the equivalent of `ajax-upgradetab.php` file for CLI calls. It will instantiate some specific features to the CLI, like a logger displaying informations on the fly. This entrypoint is also useful for testing, or for a user who does not want to use the web version. - ## What version to use The objective is to have a single module version to handle these PrestaShop upgrades: @@ -90,7 +86,7 @@ In order to work properly, the upgrade module needs to write some files to your ### Folders -- backup: Folder in which the current state of the shop will be saved before upgrade. It contains files archive, DB structure & data. -- download: Destination folder of the downloaded PrestaShop archive, before unzip. -- latest: Working directory of the autoupgrade. This is where the "lastest" version of PrestaShop will be unziped, before copy. -- tmp: Temporary resources not specifically used for upgrade. For instance, logs will be stored in that folder. +- `backup`: Folder in which the current state of the shop will be saved before upgrade. It contains files archive, DB structure & data. +- `download`: Destination folder of the downloaded PrestaShop archive, before unzip. +- `latest`: Working directory of the autoupgrade. This is where the "lastest" version of PrestaShop will be unziped, before copy. +- `tmp`: Temporary resources not specifically used for upgrade. For instance, logs will be stored in that folder. diff --git a/basics/keeping-up-to-date/upgrade-module/upgrade-process-steps.md b/basics/keeping-up-to-date/upgrade-module/upgrade-process-steps.md index 5f7b5298ff..01a5f94984 100644 --- a/basics/keeping-up-to-date/upgrade-module/upgrade-process-steps.md +++ b/basics/keeping-up-to-date/upgrade-module/upgrade-process-steps.md @@ -3,42 +3,68 @@ title: Upgrade Process Steps weight: 30 aliases: - /8/development/upgrade-module/ +useMermaid: true --- -# Upgrade process stems +# Upgrade process steps -All these steps are called from the entrypoint `ajax-upgradetab.php`. +All these steps are called from the entrypoint `ajax-upgradetab.php` (or from `upgrade-cli.php` when in a `CLI` context). -{{< figure src="../img/upgrade-process.png" title="Upgrade process schema" >}} +
+stateDiagram-v2 + [*] --> UpgradeNow + UpgradeNow --> Download + Download --> Unzip + UpgradeNow --> Unzip : Personal Archive + Unzip --> RemoveSamples + UpgradeNow --> RemoveSamples : Unzipped folder + RemoveSamples --> BackupFiles + BackupFiles --> BackupDb + BackupDb --> UpgradeFiles + UpgradeFiles --> UpgradeDb + UpgradeDb --> UpgradeModules + UpgradeModules --> CleanDatabase + CleanDatabase --> UpgradeComplete + UpgradeComplete --> [*] +
## Upgrade The following steps will be executed during the upgrade: -1. UpgradeNow: Start of the whole process. The next step will be chosen depending on the configuration. -2. Download: Download the proper archive depending on the selected channel -3. Unzip: Unzip the downloaded archive -4. RemoveSamples: The changes made by the merchant on his shop, like images, must not be deleted! This step removes the example files from the downloaded archive. -5. BackupFiles: In case the upgrade does not went well, or if the merchant wants to rollback later, we save the files of the shop. Note this can be filtered, for example if a file is too big. -6. BackupDb: Like the files, we save the current database structure and content, in case a rollback is needed. -7. UpgradeFiles: Now the current content is saved, we can alter the shop content. This step will run several time. The first call will initialize the files list, then the next ones will copy a part of this list. -8. UpgradeDb: This step does much more than you can think. Its initial purpose is to run all the upgrade SQL files available in the install folder. Then, it will run some additional steps, such as theme enabling, cache deletion, language update... -9. UpgradeModules: With the list downloaded from the PrestaShop Marketplace in the first steps, we now request updated module zips and update the installed ones. -10. CleanDatabase: This step run some SQL queries in order to remove obsolete or wrong data. Note the concerned data is not coming from the upgrade itself, but from the use of PrestaShop. -11. UpgradeComplete: The upgrade completed and we want you to know it. This step will display a success message and will end the process. +1. **UpgradeNow**: Start of the whole process. The next step will be chosen depending on the configuration. +2. **Download**: Download the proper archive depending on the selected channel +3. **Unzip**: Unzip the downloaded archive +4. **RemoveSamples**: This step removes the example files (example products, orders, customers, ...) from the downloaded archive +5. **BackupFiles**: In case the upgrade fails, or if the merchant wants to rollback later, it saves the files of the shop. Note this can be filtered, for example if a file is too large. +6. **BackupDb**: It saves the current database structure and content, in case a rollback is needed. +7. **UpgradeFiles**: Now the current content is saved, it can alter the shop content. This step will run several time. The first call will initialize the files list, then the next ones will copy a part of this list. +8. **UpgradeDb**: This step runs all the upgrade SQL files available in the install folder. Then, it will run some additional steps, such as theme enabling, cache deletion, language update... +9. **UpgradeModules**: With the list downloaded from the PrestaShop Marketplace in the first steps, it now requests updated module zips and updates the installed ones. +10. **CleanDatabase**: This step run some SQL queries in order to remove obsolete or wrong data. Note the concerned data is not coming from the upgrade itself, but from the use of PrestaShop. +11. **UpgradeComplete**: This step will display a success message and will end the process. ## Rollback -1. Rollback: This is the entrypoint of the rollback process. It will find all the available backups regarding the given parameters (basically, the restore backup must be sent from the backup name you generated). If a backup matches the given parameters, the process starts the file restoration. -2. NoRollbackFound: A classic task used to display a message saying no backup matches the given parameters, and terminates the process. -3. RollbackFiles: Like the step UpgradeFiles, this step copies the files from the archive and remove the files absent from the original environment. -4. RollbackDb: This task reads and runs the files generated by BackupDb. -5. RollbackComplete: The upgrade may have failed or you were not completely satisfied by the new version, but we brought everything back. You can reuse the shop as before. +
+stateDiagram-v2 + [*] --> Rollback + Rollback --> RollbackFiles + RollbackFiles --> RollbackDb + RollbackDb --> RollbackComplete + Rollback --> NoRollbackFound : Error +
+ +1. **Rollback**: This is the entrypoint of the rollback process. It will find all the available backups regarding the given parameters (basically, the restore backup must be sent from the backup name you generated). If a backup matches the given parameters, the process starts the file restoration. +2. **NoRollbackFound**: A classic task used to display a message saying no backup matches the given parameters, and terminates the process. +3. **RollbackFiles**: Like the step UpgradeFiles, this step copies the files from the archive and remove the files missing from the original environment. +4. **RollbackDb**: This task reads and runs the files generated by BackupDb. +5. **RollbackComplete**: The upgrade may have failed or the user was not completely satisfied by the new version. The shop was rollbacked in its initial state. ## Other These steps don't follow any process and are independent between each others. -- CheckFilesVersion: This task is responsible to detect all local files has been modified by the merchant / developer. This is an important pre-requisite which warn about the potential loss of changes. -- Error: This task can be called from any other one, and will display a specific message saying the upgrade / restore process failed. In case of upgrade, a restore will be suggested. -- UpdateConfig: This task will store in a configuration file the different options selected in the web version of the module. +- **CheckFilesVersion**: This task is responsible to detect all local files has been modified by the merchant / developer. This is an important pre-requisite which warn about the potential loss of changes. +- **Error**: This task can be called from any other one, and will display a specific message saying the upgrade / restore process failed. In case of upgrade, a restore will be suggested. +- **UpdateConfig**: This task will store in a configuration file the different options selected in the web version of the module. diff --git a/basics/keeping-up-to-date/use-autoupgrade-module.md b/basics/keeping-up-to-date/use-autoupgrade-module.md index 233d1ac56d..73e4e7b062 100644 --- a/basics/keeping-up-to-date/use-autoupgrade-module.md +++ b/basics/keeping-up-to-date/use-autoupgrade-module.md @@ -23,7 +23,7 @@ If you upgrade from a version older than 1.7, please use a previous version of t This module has been reworked internally for PrestaShop 1.6 & 1.7. -Documentation about this major version is documented in [Upgrade module pages]({{< ref "/8/development/upgrade-module/_index.md" >}}). +Documentation about this major version is documented in [Upgrade module pages]({{< ref "/8/basics/keeping-up-to-date/upgrade-module/_index.md" >}}). ## Download / Installation From fcefa9cb950d57c7d84f55b7befa47587033a4b4 Mon Sep 17 00:00:00 2001 From: Thomas Nares Date: Tue, 14 Feb 2023 10:36:22 +0100 Subject: [PATCH 247/310] Remove <1.7 references --- basics/keeping-up-to-date/upgrade.md | 71 +++++-------------- .../use-autoupgrade-module.md | 25 +------ 2 files changed, 21 insertions(+), 75 deletions(-) diff --git a/basics/keeping-up-to-date/upgrade.md b/basics/keeping-up-to-date/upgrade.md index 6e8f0b171e..d03b61d4a5 100644 --- a/basics/keeping-up-to-date/upgrade.md +++ b/basics/keeping-up-to-date/upgrade.md @@ -7,20 +7,15 @@ weight: 30 # How to upgrade PrestaShop - {{% notice warning %}} **Important** Do not go further if you haven’t made a backup of your shop. - -Rollback will be the only way to go back if something does not go well, -and this requires a backup. - +Rollback will be the only way to go back if something does not go well, and this requires a backup. Learn [how to backup your shop]({{< ref "/8/basics/keeping-up-to-date/backup" >}}) {{% /notice %}} -This chapter describes several ways to complete an upgrade of -PrestaShop. +This chapter describes several ways to complete an upgrade of PrestaShop. ## Manual upgrade – Process details @@ -30,10 +25,7 @@ This guide gives you the full control on the process. This one has been applied The first step is to download the latest version on https://github.com/PrestaShop/PrestaShop/releases. -If you upgrade to another version of PrestaShop 1.6, the release files can be found in a [dedicated archives list](https://www.prestashop.com/en/previous-versions?version=1.6). - -Download can also be done in command line, as done here with the version -8.0.1: +Download can also be done in command line, as done here with the version 8.0.1: ```bash wget -O prestashop-upgrade.zip https://github.com/PrestaShop/PrestaShop/releases/download/8.0.1/prestashop_8.0.1.zip @@ -43,8 +35,7 @@ wget -O prestashop-upgrade.zip https://github.com/PrestaShop/PrestaShop/releases Extract the files from the archive with a tool like 7zip -Note starting from PrestaShop 1.7.0.0, the release package contains a -zip file itself, which must be extracted as well. +Note starting from PrestaShop 1.7.0.0, the release package contains a zip file itself, which must be extracted as well. On a Linux terminal, you can use the command \`unzip\`: @@ -52,13 +43,11 @@ On a Linux terminal, you can use the command \`unzip\`: unzip prestashop-upgrade.zip && unzip prestashop.zip ``` -Once you have the folders like `classes/`, `modules/`, `themes/`, etc. you may -go on the next step. +Once you have the folders like `classes/`, `modules/`, `themes/`, etc. you may go on the next step. ### Sample files cleanup -Avoid overwrite the production resources (images, conf ...) with the -default data. These folders can be removed from the new release: +Avoid overwrite the production resources (images, conf ...) with the default data. These folders can be removed from the new release: - img/ - override/ @@ -72,13 +61,11 @@ Also, rename the “admin” folder to match your shop’s admin folder name. Th ### Turning on maintenance mode -The shop will now be modified. As it may cause unexpected behavior for you and your customers during the upgrade, we highly recommend you to -turn on maintenance mode during the upgrade. +The shop will now be modified. As it may cause unexpected behavior for you and your customers during the upgrade, we highly recommend you to turn on maintenance mode during the upgrade. This can be done in your administration panel: - On PrestaShop >= 1.7, in Shop parameters > General > Maintenance tab -- On PrestaShop 1.6, in Shop parameters > Maintenance Adding your IP address will allow you to access your shop while it’s in maintenance mode. That way, you can make sure everything is working right before allowing your customers to access it again. @@ -128,16 +115,13 @@ All the changes to apply have been defined in the `install` folder, running them When you’re ready, run the file `upgrade/upgrade.php` from the `autoupgrade` module. -This can be done with a browser, by reaching the address -`http:///modules/autoupgrade/upgrade/upgrade.php`, or from your -server's command line: +This can be done with a browser, by reaching the address `http:///modules/autoupgrade/upgrade/upgrade.php`, or from your `CLI`: ```bash php modules/autoupgrade/upgrade/upgrade.php ``` -In both cases, an XML log will be displayed. The result can be found in -the attribute `result` of the first tag ``: +In both cases, an XML log will be displayed. The result can be found in the attribute `result` of the first tag ``: * `ok` if updates have been found and executed * `error` if something went wrong @@ -145,8 +129,7 @@ the attribute `result` of the first tag ``: #### Execution log -When the upgrade script found some upgrades to apply, the SQL queries -run will be listed along their respective result. +When the upgrade script found some upgrades to apply, the SQL queries run will be listed along their respective result. ```xml @@ -157,10 +140,7 @@ run will be listed along their respective result. [...] ``` -You can double check that each action is marked as “OK”. If not, -additional details will be shown after the request, which can help you -fix the issue and re-execute the request manually on your database. In -some cases, you may need to restore your database backup and start over. +You can double check that each action is marked as “OK”. If not, additional details will be shown after the request, which can help you fix the issue and re-execute the request manually on your database. In some cases, you may need to restore your database backup and start over. #### Error codes @@ -183,25 +163,16 @@ Before going further, a few things should now be cleaned. - The `install` folder, used to run the database upgrades, is not needed anymore and can be safely deleted. - When opening your shop (in the front or back office) on your browser, you may see some visual issues. This can be due to your old assets being still served by a cache. + Reload them by force-refreshing the page (press ctrl+R on Windows / Linux or cmd+R on Mac OS) or clearing your browser’s cache. ### Modules upgrade -Your modules files have been upgraded during the file copy, however many -of them may require additional changes on the database. Please check the -module page in your Back Office to see if upgrades are waiting to be -run. - -Go to your administration panel and login. You will notice the version -displayed has changed on the login page. Then in the menu, click on the -module page to reach your catalog. - -On PrestaShop 1.6, this page can be found in “Module & Services”. Click -on “Update all” at the top of the page to run all available upgrades: +Your modules files have been upgraded during the file copy, however many of them may require additional changes on the database. Please check the module page in your Back Office to see if upgrades are waiting to be run. -{{< figure src="../img/image63.png" >}} +Go to your administration panel and login. You will notice the version displayed has changed on the login page. Then in the menu, click on the module page to reach your catalog. -On PrestaShop >= 1.7, the same feature can be found in the Improve >> Modules page, under the tab "Updates": +On PrestaShop >= 1.7, this page can be found in the Improve >> Modules page, under the tab "Updates": {{< figure src="../img/image38.png" >}} @@ -215,16 +186,10 @@ You can read more about it [here]({{< ref "/8/basics/keeping-up-to-date/use-auto ## Support service -Doing an upgrade by yourself can be risky. If you feel uncomfortable -with doing it on your own, you can leave it to our support team who will -handle the backup and the upgrade to the last **minor** version for you -(1.6 → 1.6, 1.7 → 1.7 etc.). +Doing an upgrade by yourself can be risky. If you feel uncomfortable with doing it on your own, you can leave it to our support team who will handle the backup and the upgrade to the last **minor** version for you (8.0 → 8.1). -Basically, the process and the result will be the same. The existing -data on the shop will be kept, as well as your module and your current -theme. +Basically, the process and the result will be the same. The existing data on the shop will be kept, as well as your module and your current theme. -Many agencies and freelancers in your area may also provide this kind of -service. +Many agencies and freelancers in your area may also provide this kind of service. More information about support: [PrestaShop project support page](https://www.prestashop-project.org/support/) \ No newline at end of file diff --git a/basics/keeping-up-to-date/use-autoupgrade-module.md b/basics/keeping-up-to-date/use-autoupgrade-module.md index 73e4e7b062..723c2c6a1d 100644 --- a/basics/keeping-up-to-date/use-autoupgrade-module.md +++ b/basics/keeping-up-to-date/use-autoupgrade-module.md @@ -15,41 +15,22 @@ The same note as above, in order to have this module working you must have set i {{% /notice %}} {{% notice note %}} -The latest version of this module allow updates from PS 1.7.x to PS 8.0.x versions only. -If you upgrade from a version older than 1.7, please use a previous version of this module. +The latest version (v4.15+) of this module allow updates from PS 1.7.x to PS 8.0.x versions only. +If you upgrade from a version older than 1.7, please use a previous version of this module (v4.14.1 and less) and refer to [previous major version upgrade guide]({{< ref "/1.7/basics/keeping-up-to-date/_index.md" >}}). {{% /notice %}} -### Note about version +4.0.0 - -This module has been reworked internally for PrestaShop 1.6 & 1.7. - -Documentation about this major version is documented in [Upgrade module pages]({{< ref "/8/basics/keeping-up-to-date/upgrade-module/_index.md" >}}). - ## Download / Installation - Download the latest release from GitHub https://github.com/PrestaShop/autoupgrade/releases -Then, import your module archive on the modules page. To do so, you can find the button “Upload a module” (PrestaShop >= 1.7.x) or “Add a module” -(PrestaShop 1.6) at the top right of the page. Clicking on it will open a form that will allow you to upload your module zip. - -On PrestaShop >= 1.7: +Then, import your module archive on the modules page. To do so, you can find the button “Upload a module” (PrestaShop >= 1.7.x) at the top right of the page. Clicking on it will open a form that will allow you to upload your module zip. {{< figure src="../img/image70.png" >}} -On PrestaShop 1.6: - -{{< figure src="../img/image79.png" >}} - - From the administration panel -On PrestaShop >= 1.7: - {{< figure src="../img/image33.png" >}} -On PrestaShop 1.6: - -{{< figure src="../img/image66.png" >}} - ## Usage The configuration page of the module displays some checks and the options available for an upgrade. From ba45e92cdd32049c3083500265900ea680c93c48 Mon Sep 17 00:00:00 2001 From: Thomas Nares Date: Tue, 14 Feb 2023 10:41:31 +0100 Subject: [PATCH 248/310] Remove outdated new logger information --- basics/keeping-up-to-date/upgrade-module/_index.md | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/basics/keeping-up-to-date/upgrade-module/_index.md b/basics/keeping-up-to-date/upgrade-module/_index.md index 621e5dd99b..8bee78042c 100644 --- a/basics/keeping-up-to-date/upgrade-module/_index.md +++ b/basics/keeping-up-to-date/upgrade-module/_index.md @@ -13,16 +13,6 @@ Details on how to use the web interface are documented in [Keep up-to-date: Upgr {{% children %}} -## New loggers - -Reporting is now using [PSR-3](https://www.php-fig.org/psr/psr-3/), allowing incomers in the module code to recognize some common code in PHP. - -New loggers have been created: - -- **LegacyLogger**: The existing logger still stores its content in lists before being displayed in a sigle row, and at the same time in a log file. By doing this, we still can get details on what happened if the script execution stopped prematurerly. -- **StreamLogger**: New logger, used in CLI mode. We do not need to use memory to store the logs, we can display them directly on the terminal. -- **Error handler**: This was done for debugging. In case of a server error (in web, HTTP 500), the module was unable to display anything to the user. It is then needed to read PHP logs in order to get error details, and some users have trouble doing it. Thanks to this logger, the error is displayed directly on the screen. - ## How to download it You can download it from [the module GitHub repository](https://github.com/PrestaShop/autoupgrade/releases) or from your shop administration panel. \ No newline at end of file From 8382e8f8c9357bc95ad678bc137ce12e30a09778 Mon Sep 17 00:00:00 2001 From: Thomas Nares Date: Tue, 14 Feb 2023 11:52:00 +0100 Subject: [PATCH 249/310] Prioritise upgrade module --- basics/keeping-up-to-date/upgrade.md | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/basics/keeping-up-to-date/upgrade.md b/basics/keeping-up-to-date/upgrade.md index d03b61d4a5..a92d6c1aed 100644 --- a/basics/keeping-up-to-date/upgrade.md +++ b/basics/keeping-up-to-date/upgrade.md @@ -15,7 +15,13 @@ Rollback will be the only way to go back if something does not go well, and this Learn [how to backup your shop]({{< ref "/8/basics/keeping-up-to-date/backup" >}}) {{% /notice %}} -This chapter describes several ways to complete an upgrade of PrestaShop. +This chapter describes several ways to complete an upgrade of PrestaShop: 1-click upgrade module or manual upgrade. + +## Upgrade module (1-click upgrade module) + +PrestaShop provides the module 1-click upgrade for free on the marketplace and your shop administration panel. + +You can read more about it [here]({{< ref "/8/basics/keeping-up-to-date/use-autoupgrade-module" >}}). ## Manual upgrade – Process details @@ -176,14 +182,6 @@ On PrestaShop >= 1.7, this page can be found in the Improve >> Modules pag {{< figure src="../img/image38.png" >}} -## 1-click upgrade module - -If the manual process seems too tedious, other solutions exist to complete an upgrade. - -PrestaShop provides the module 1-click upgrade for free on the marketplace and your shop administration panel. It executes the previously given process automatically, and is available for almost all versions of PrestaShop. - -You can read more about it [here]({{< ref "/8/basics/keeping-up-to-date/use-autoupgrade-module" >}}). - ## Support service Doing an upgrade by yourself can be risky. If you feel uncomfortable with doing it on your own, you can leave it to our support team who will handle the backup and the upgrade to the last **minor** version for you (8.0 → 8.1). From 131c273ba2b5b162206673298fb0c3c182fd1147 Mon Sep 17 00:00:00 2001 From: Krystian Podemski Date: Fri, 17 Mar 2023 11:47:16 +0100 Subject: [PATCH 250/310] further improvements --- basics/keeping-up-to-date/_index.md | 11 ++- basics/keeping-up-to-date/backup.md | 24 +++---- .../upgrade-module/upgrade-cli.md | 68 ++++++++++++++++++- .../upgrade-module-internal-behavior.md | 10 +-- basics/keeping-up-to-date/upgrade.md | 23 +++++-- 5 files changed, 104 insertions(+), 32 deletions(-) diff --git a/basics/keeping-up-to-date/_index.md b/basics/keeping-up-to-date/_index.md index fc3778eab1..c2d7680dae 100644 --- a/basics/keeping-up-to-date/_index.md +++ b/basics/keeping-up-to-date/_index.md @@ -8,13 +8,11 @@ weight: 50 ## Introduction -The purpose of this chapter is to provide the best practices and tips for keeping your PrestaShop up-to-date. Its compatibility range should cover at least shops running on versions 1.6 through 8. +The purpose of this chapter is to provide the best practices and tips for keeping your PrestaShop up-to-date. Its compatibility range should cover at least shops running on versions 1.7 through 8. Keeping a shop updated to the latest available version ensures you have the latest changes brought by the core team and the developer community. Depending on the version you upgrade to, you can get new features, security or performance improvements, or simply bug fixes. -Furthermore, the support of PrestaShop 1.6 [is now ended](https://build.prestashop-project.org/news/1.6.1.x-what-s-next/). We recommend using recent PrestaShop versions to get support, along with core and modules upgrades. - ## Upgrade and migration, two different processes Keeping PrestaShop up-to-date can be done via different methods. Choose the best update method depending on your needs. @@ -32,7 +30,7 @@ It does not require any additional tools to run if you follow the manual process As long as you stay on the same major version (ex. 1.7.1 >> 1.7.2, 8.0 >> 8.1 upgrade), we make sure that the available features remain the same. This means that your current theme and all your modules should continue to work as before, and no functionality or data will be lost during the upgrade, even if the database structure may change. -This can be explained by the [semantic versioning](https://semver.org/) we follow, that forbids any compatibility-breaking change in the core, such as removing a feature or modifying our APIs. +This can be explained by the [semantic versioning](https://semver.org/) we follow, that forbids any compatibility-breaking change in the core, such as removing a feature or modifying our APIs in versions other than major. Note that once an upgrade has started, there is no way to rollback the changes. The only solution you have is restoring the backup you made before. @@ -41,13 +39,14 @@ Note that once an upgrade has started, there is no way to rollback the changes. - Prepare your upgrade by getting the latest release zip file, unpacking it and removing its demo content. - Apply the new files by copy-pasting them in the production folder. - Run the database upgrade. -This could be enough for completing an upgrade, but additional tasks like cleanup and modules upgrade will bring you stability and security. + +This could be enough for completing an upgrade, but additional tasks like cleanup and modules upgrade will bring you stability and security. This is how the `autoupgrade` module works. ### Migration ![Migration schema](img/migration-schema.png) -Upgrading is not the only way to update your shop to the latest version of PrestaShop. In some cases, migrating your data is a better option. +Upgrading is not the only way to get your shop to the latest version of PrestaShop. In some cases, migrating your data is a better option. This option is recommended when you switch on a new major version. As it brings a lot of changes in the core with many potential incompatibilities with the current theme and modules, starting fresh is less risky for stability. diff --git a/basics/keeping-up-to-date/backup.md b/basics/keeping-up-to-date/backup.md index 48e3ed00e9..8859001507 100644 --- a/basics/keeping-up-to-date/backup.md +++ b/basics/keeping-up-to-date/backup.md @@ -9,21 +9,21 @@ weight: 10 {{% notice warning %}} **Important** -It is strongly recommended not to leave your backups at the root of your store or in another place where could be exposed on publicly. +It is strongly recommended not to leave your backups at the root of your store or in another place that could be publicly exposed. {{% /notice %}} Before starting anything, you must think first about safety. -Any modification made on a shop could break it, so you must make sure all your data has been backed up before going further. This basically implies saving two things: your files and your database. +Any modification to a shop could break it, so you must ensure all your data has been backed up before going further. This implies saving two things: your files and your database. -We will give you all the details you may need to run an upgrade, but we can’t be held responsible for any damage caused to your shop during the process. That’s why we strongly recommend you to follow this backup step. +This documentation can help to run an upgrade, but we can’t be held responsible for any damage caused to your shop during the process. That’s why we strongly recommend you follow this backup step. ## File backup -The first elements to backup are the files on the web server where you have deployed your PrestaShop. The PrestaShop folder not only contains the source code, but also your modules & themes, pictures, and all other resources needed to run your shop successfully. +The first elements to backup are the files on the web server where you have deployed your PrestaShop. The PrestaShop folder contains the source code and your modules & themes, pictures, and all other resources needed to run your shop successfully. ### Copy files -To complete this step, your shop folder must be copied somewhere else. Although it can be simply copied on another folder on your server, making an additional copy of your files on another computer is a nice additional security measure. To do so, connect to your server using an FTP, SSH or RDP connection (depending on your server and hosting provider), copy the files in another location, then download them on your computer. +To complete this step, your shop folder must be copied somewhere else. Although it can be copied to another folder on your server, making an additional copy of your files on another computer is a nice additional security measure. To do so, connect to your server using an FTP, SSH, or RDP connection (depending on your server and hosting provider), copy the files to another location, then download them on your computer. With SSH, you may use `scp` or `rsync` command to backup your shop folder from a server to another. For example, backup from a remote server to your local machine (or the one you are connected on) with `scp` ([scp man page](https://linuxcommand.org/lc3_man_pages/scp1.html)): @@ -37,12 +37,12 @@ Or with `rsync` ([rsync man page](https://linux.die.net/man/1/rsync)): rsync -avz user@host:/var/www/prestashop_folder_path /local_path_for_backup/ ``` -Note that depending on the number of files and your internet connection, this may take a few hours to complete. But if you’re an advanced user and have a complete access to your server, the next part may help you go faster. +Note that this may take a few hours to complete depending on the number of files and your internet connection. But if you’re an advanced user with complete access to your server, the next part may help you go faster. #### Bonus: Compress your files before download As said before, downloading the whole PrestaShop folder one file at a time will take a long time to complete. -If you can run commands on your server, you can make a backup faster by compressing the whole content in a single archive file, then downloading this file locally. +If you can run commands on your server, you can make a backup faster by compressing the entire content in a single archive file, then downloading this file locally. * On Windows-based servers, this requires a remote desktop access. Once logged on your remote environment, use the Windows explorer to reach your www folder and compress all its content into a `ZIP` file. @@ -58,11 +58,11 @@ For instance: tar -czf backup.tar /var/www/html ``` -When your archive is ready, you may copy it on your computer or to any other safe location. +When your archive is ready, copy it on your computer or any other safe location. ## Database backup -The database on which PrestaShop runs must be saved as well. There are many ways to get a dump of the database content, and we cannot cover all of them. Feel free to use your tools, we just cover the main ones here. You can consider your dump is complete when you get a SQL file with the structure AND the content of each table in it. +The database on which PrestaShop runs must be saved as well. There are many ways to get a dump of the database content, and we cannot cover all of them. Feel free to use your tools. We cover the main ones here. You can consider your dump complete when you get a SQL file with the structure AND the content of each table. ### Using MySQL client in command line @@ -92,17 +92,17 @@ More details about backup & recoveries with MySQL binaries can be found on the [ PhpMyAdmin, provided by several hosting providers, offers another way to get a complete dump of your database. -Log on your PhpMyAdmin interface, select the database where PrestaShop is installed and chose the “export” tab. +Log on to your PhpMyAdmin interface, select the database where PrestaShop is installed, and choose the “export” tab. {{< figure src="../img/backup-phpmyadmin-export-database.png" title="Exporting a database in SQL format" >}} -We advise to select the “custom” method, as it offers more options to customize your dump. Make sure all your tables, views, etc are selected for backup. +We advise selecting the “custom” method, as it offers more options to customize your dump. Ensure all your tables, views, etc., are selected for backup. To get the same file content as the `mysqldump` method, the following options should be checked as well: * Use LOCK TABLES statement * Add DROP TABLE / VIEW / PROCEDURE / FUNCTION / EVENT / TRIGGER statement -Click on “Go”, wait for the dump to be generated, then download it. +Click on the “Go” button, wait for the dump to be generated, then download it. ## Other MySQL clients diff --git a/basics/keeping-up-to-date/upgrade-module/upgrade-cli.md b/basics/keeping-up-to-date/upgrade-module/upgrade-cli.md index 62af228851..6c338df96d 100644 --- a/basics/keeping-up-to-date/upgrade-module/upgrade-cli.md +++ b/basics/keeping-up-to-date/upgrade-module/upgrade-cli.md @@ -16,10 +16,13 @@ Upgrade module can be used as a Command Line Interface. ### Command line parameters -Entry point is *cli-upgrade.php*. +Entry point is *cli-upgrade.php* from the module's directory. The following parameters are mandatory: * **--dir**: Specify the admin directory name + +You can also use these parameters: + * **--channel**: Specify the [channel to use]({{< ref "/8/basics/keeping-up-to-date/upgrade-module/channels.md" >}}) * **--action**: Specify the [step you want to start from]({{< ref "/8/basics/keeping-up-to-date/upgrade-module/upgrade-process-steps.md" >}}) (Default: `UpgradeNow`) @@ -28,11 +31,17 @@ If you use default `action` parameter, it will run the full upgrade process. Example: ``` -$ php cli-upgrade.php --dir=admin-dev --channel=major +$ php modules/autoupgrade/cli-upgrade.php --dir=admin-dev --channel=major ``` ## Rollback CLI +{{% notice warning %}} +**Important** + +It is not recommended to use this option. It's always better to manager your backup manually. +{{% /notice %}} + If an error occurs during the upgrade process, the rollback will be suggested. In case you lost the page from your backoffice, note it can be triggered via CLI. @@ -49,3 +58,58 @@ Example: ``` $ php cli-rollback.php --dir=admin-dev --backup=V1.7.5.1_20190502-191341-22e883bd ``` + +## Full example + +To upgrade your PrestaShop store to the latest version using the command line interface, follow the steps outlined below. Make sure to execute all commands from the root directory of your PrestaShop installation and replace `admin-dev` with the name of your back office directory. + +### Step 1: Uninstall and remove the old autoupgrade module + +1. Uninstall the old AutoUpgrade module: + +`php bin/console prestashop:module uninstall autoupgrade` + +2. Remove the old module's directory: + +`rm -rf modules/autoupgrade` + +### Step 2: Install the new autoupgrade module + +1. Download the latest version of the autoupgrade module and place it in the /modules directory: + +`curl -L https://github.com/PrestaShop/autoupgrade/releases/download/v4.15.0/autoupgrade.zip -o modules/autoupgrade.zip && unzip modules/autoupgrade.zip` + +2. Install the new version of the autoupgrade module: + +`php bin/console prestashop:module install autoupgrade` + +### Step 3: Download the latest PrestaShop files + +1. Download the latest version of PrestaShop (.zip and .xml files): + +`curl -L https://github.com/PrestaShop/PrestaShop/releases/download/8.0.2/prestashop_8.0.2.zip -o admin-dev/autoupgrade/download/prestashop.zip` +`curl -L https://github.com/PrestaShop/PrestaShop/releases/download/8.0.2/prestashop_8.0.2.xml -o admin-dev/autoupgrade/download/prestashop.xml` + +### Step 4: Configure the autoupgrade module + +1. Create a configuration file for the AutoUpgrade module to use the local archive. Adjust the settings as needed: + +`echo "{\"channel\":\"archive\",\"archive_prestashop\":\"prestashop.zip\",\"archive_num\":\"8.0.2\", \"archive_xml\":\"prestashop.xml\", \"PS_AUTOUP_CHANGE_DEFAULT_THEME\":0, \"skip_backup\": 1}" > modules/autoupgrade/config.json` + + +2. Apply the configuration to the `autoupgrade` module: + +`php modules/autoupgrade/cli-updateconfig.php --from=modules/autoupgrade/config.json --dir=admin-dev` + +### Step 5: Start the Upgrade Process + + +1. Initiate the upgrade process: + +`php modules/autoupgrade/cli-upgrade.php --dir=admin-dev` + +The upgrade process is divided into multiple parts by default. To automate the entire process, use the `testCliProcess.php` script, which runs all the steps automatically: + +`php modules/autoupgrade/tests/testCliProcess.php modules/autoupgrade/cli-upgrade.php --dir=admin-dev` + +By following these steps, your PrestaShop store should be successfully upgraded to the latest version. \ No newline at end of file diff --git a/basics/keeping-up-to-date/upgrade-module/upgrade-module-internal-behavior.md b/basics/keeping-up-to-date/upgrade-module/upgrade-module-internal-behavior.md index b408a667a1..e65e87cffb 100644 --- a/basics/keeping-up-to-date/upgrade-module/upgrade-module-internal-behavior.md +++ b/basics/keeping-up-to-date/upgrade-module/upgrade-module-internal-behavior.md @@ -34,16 +34,16 @@ This is the equivalent of `ajax-upgradetab.php` file for CLI calls. It will inst The objective is to have a single module version to handle these PrestaShop upgrades: -- 1.6 >> to >> 1.6 / 1.7 -- 1.7 >> to >> 1.7 +- 1.7.x >> to >> 1.7.y +- 1.7 >> to >> 8.x -The other versions are not supported anymore. We recommend to use the previous versions of the module available on the PrestaShop marketplace. +The other versions are not supported anymore. We recommend to use the previous versions of the module [available on GitHub](https://github.com/PrestaShop/autoupgrade/releases/tag/v4.12.0). ## Technical choices -### Compatibility with PrestaShop 1.6 & 1.7 +### Compatibility with PrestaShop 1.7 & 8 -Aim is to help as many merchants as possible to upgrade from 1.6 to 1.7. This required to do the following implementation choices: +Aim is to help as many merchants as possible to upgrade from 1.7 to 8. This required to do the following implementation choices: - **Twig as template engine** diff --git a/basics/keeping-up-to-date/upgrade.md b/basics/keeping-up-to-date/upgrade.md index a92d6c1aed..846f654e12 100644 --- a/basics/keeping-up-to-date/upgrade.md +++ b/basics/keeping-up-to-date/upgrade.md @@ -15,15 +15,24 @@ Rollback will be the only way to go back if something does not go well, and this Learn [how to backup your shop]({{< ref "/8/basics/keeping-up-to-date/backup" >}}) {{% /notice %}} -This chapter describes several ways to complete an upgrade of PrestaShop: 1-click upgrade module or manual upgrade. +There are a few ways of upgrading the PrestaShop store. This chapter provides information about two methods of getting the software to the latest version. -## Upgrade module (1-click upgrade module) +## Upgrade assistant module (formerly 1-click upgrade module) -PrestaShop provides the module 1-click upgrade for free on the marketplace and your shop administration panel. +You can use provided `autoupgrade` module to upgrade your store to the newest version using web interface. You can read more about the module and how to use it [here]({{< ref "/8/basics/keeping-up-to-date/use-autoupgrade-module" >}}). -You can read more about it [here]({{< ref "/8/basics/keeping-up-to-date/use-autoupgrade-module" >}}). +## Upgrade assistant module - CLI method -## Manual upgrade – Process details +Upgrade assistant module (autoupgrade) is fully accessible through `cli`. You can read all the details [here]({{< ref "/8/basics/keeping-up-to-date/upgrade-module/upgrade-cli" >}}). + +## Manual upgrade + +{{% notice warning %}} +**Important** + +Manual upgrade without `autoupgrade` module is not possible at the moment. We recommend using [cli]({{< ref "/8/basics/keeping-up-to-date/upgrade-module/upgrade-cli" >}}) +mechanism from the upgrade assistant module. +{{% /notice %}} This guide gives you the full control on the process. This one has been applied by PrestaShop for several major versions, and thus can be applied on very old shops. @@ -31,10 +40,10 @@ This guide gives you the full control on the process. This one has been applied The first step is to download the latest version on https://github.com/PrestaShop/PrestaShop/releases. -Download can also be done in command line, as done here with the version 8.0.1: +Download can also be done in command line, as done here with the version 8.0.2: ```bash -wget -O prestashop-upgrade.zip https://github.com/PrestaShop/PrestaShop/releases/download/8.0.1/prestashop_8.0.1.zip +wget -O prestashop-upgrade.zip https://github.com/PrestaShop/PrestaShop/releases/download/8.0.2/prestashop_8.0.2.zip ``` ### Archive extraction From 8a6a5a7275451b754224d31aa3a13f18c82562d7 Mon Sep 17 00:00:00 2001 From: Justine <69111099+justeen35@users.noreply.github.com> Date: Fri, 17 Mar 2023 14:54:09 +0100 Subject: [PATCH 251/310] Improve Integration tests desc --- testing/integration-tests/_index.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/testing/integration-tests/_index.md b/testing/integration-tests/_index.md index 7ee3c6a94e..791b24a3de 100644 --- a/testing/integration-tests/_index.md +++ b/testing/integration-tests/_index.md @@ -6,8 +6,7 @@ chapter: true # Integration tests ## Introduction -Unit tests can validate the behavior of a PHP class when it can be isolated. -However, some classes cannot be validated this way. Moreover, a lot of logic from PrestaShop is written into complex SQL queries that this kind of test cannot validate. This is why we also need integration tests. +While unit tests can effectively validate the behavior of an isolated PHP class, there are certain classes that cannot be validated in this manner. Additionally, as a significant portion of PrestaShop's logic is written in complex SQL queries, this type of test may not be sufficient to validate them. Therefore, integration tests are also necessary to ensure proper validation and coverage. ### Stack @@ -18,4 +17,4 @@ We use the following stack: ## Execute & Create tests -{{% children %}} \ No newline at end of file +{{% children %}} From 3d77d88bf6b92652640e8524b3cbbe9ee78a48a7 Mon Sep 17 00:00:00 2001 From: Justine <69111099+justeen35@users.noreply.github.com> Date: Fri, 17 Mar 2023 14:56:05 +0100 Subject: [PATCH 252/310] Improve webservice doc --- webservice/getting-started.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/webservice/getting-started.md b/webservice/getting-started.md index 587dfac12d..f189e7e9be 100644 --- a/webservice/getting-started.md +++ b/webservice/getting-started.md @@ -32,8 +32,7 @@ Reach the [dedicated page]({{< relref "tutorials/creating-access" >}}). ## Accessing the webservice -Now that your access key is generated you can test your store's webservice, its endpoint is located in the `/api/` folder at the root of your installation of Prestashop. -The quickest way to test your API is to use your browser: +After generating your access key, you can proceed to test your store's webservice. The webservice endpoint is located in the '/api/' folder at the root of your PrestaShop installation. To test your API quickly, you can simply use your browser: * If PrestaShop is installed at the root of your server, you can access the API here: http://example.com/api/ * If PrestaShop is installed in a subfolder of your server, you can access the API here: http://example.com/prestashop/api/ From 474a4bdc9be697a34af11c006c2167fc3eb47a04 Mon Sep 17 00:00:00 2001 From: Thomas Nares Date: Mon, 20 Mar 2023 12:27:49 +0100 Subject: [PATCH 253/310] Add hooklisturl variable in firstsection to be able to personalize future V9 doc --- _index.md | 1 + 1 file changed, 1 insertion(+) diff --git a/_index.md b/_index.md index 984b552966..7e56c7d17e 100644 --- a/_index.md +++ b/_index.md @@ -5,6 +5,7 @@ versionId: "8" # this should match the physical directory in devdocs- versionGithubPath: "8.x" # this should match the branch name in github versionMeta: Current # only one version can be current! chapter: true +hookListUrl: "/8/modules/concepts/hooks/list-of-hooks" # this allows for dynamic hook results in algolia's docsearch --- # PrestaShop 8 Documentation From 1a91629c62986ee587d90d392f641b787724d3bd Mon Sep 17 00:00:00 2001 From: Thomas Nares Date: Mon, 20 Mar 2023 14:32:33 +0100 Subject: [PATCH 254/310] Begin Link doc --- development/components/link.md | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 development/components/link.md diff --git a/development/components/link.md b/development/components/link.md new file mode 100644 index 0000000000..f1dfef1c79 --- /dev/null +++ b/development/components/link.md @@ -0,0 +1,9 @@ +--- +title: The Link component +useMermaid: true +menuTitle: Link +--- + +# The Link component + + From 283cdc7b895eabceeb558b18f6b83d485768762e Mon Sep 17 00:00:00 2001 From: Thomas Nares Date: Mon, 20 Mar 2023 17:01:17 +0100 Subject: [PATCH 255/310] Create Link component --- development/components/link.md | 97 ++++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) diff --git a/development/components/link.md b/development/components/link.md index f1dfef1c79..e7797df996 100644 --- a/development/components/link.md +++ b/development/components/link.md @@ -6,4 +6,101 @@ menuTitle: Link # The Link component +The `Link` component is responsible of generating URLs for various Prestashop routes. It provides a simple mecanism to handle: +- URL Rewriting (friendly URLs) +- HTTP/HTTPS schemes +- routing to entities, controllers, modules, ... + +## How to use `Link` component + +`Link` is available through the [`Context`]({{< relref "/8/development/components/context" >}}), and provides several useful methods such as those documented methods below: + +- `getProductLink()` +- `getCategoryLink()` +- `getModuleLink()` +- `getPageLink()` + +and many more, please explore the [Link class](https://github.com/PrestaShop/PrestaShop/blob/8.1.x/classes/Link.php). + +{{% notice info %}} +While possible, it is discouraged to instanciate the `Link` class by yourself, please use the `Link` provided by a `Context`. +{{% /notice %}} + +### Use Link to get the URL of a Product: getProductLink() method + +To obtain the URL of a product, with the right HTTP scheme, and URL rewriting (if enabled), use : + +```php +// obtain $context from a controller or from a module with: +$context = $this->context; + +// or from anywhere else: +$context = Context::getContext(); + +// get your product instance (from ObjectModel in this example) +$product = new Product(123); + +// get your product URL +$link = $context->link->getProductLink($product); +``` + +More parameters are available for this method, please refer to the [method definition for details](https://github.com/PrestaShop/PrestaShop/blob/8.1.x/classes/Link.php#L122-L141). + +### Use Link to get the URL of a Category: getCategoryLink() method + +To obtain the URL of a category, with the right HTTP scheme, and URL rewriting (if enabled), use : + +```php +// get your category instance (from ObjectModel in this example) +$category = new Category(123); + +// get your category URL +$link = $context->link->getCategoryLink($category); +``` + +More parameters are available for this method, please refer to the [method definition for details](https://github.com/PrestaShop/PrestaShop/blob/8.1.x/classes/Link.php#L411-L422). + +### Use Link to get the URL of a Module controller : getModuleLink() method + +To obtain the URL of a module controller, with the right HTTP scheme, and URL rewriting (if enabled), use : + +```php +// get your module's default controller URL +$link = $context->link->getModuleLink("mymodulename"); + +// get your module's specific controller URL +$link = $context->link->getModuleLink("mymodulename", "controllerName"); + +// get your module's specific controller URL with params +$params = [ + "id_item" => 2, + "action" => "showTodo" +]; +$link = $context->link->getModuleLink("mymodulename", "controllerName", $params); +``` + +More parameters are available for this method, please refer to the [method definition for details](https://github.com/PrestaShop/PrestaShop/blob/8.1.x/classes/Link.php#L670-L684). + +### Use Link to get the URL of a page : getPageLink() method + +To obtain the URL of a page controller, with the right HTTP scheme, and URL rewriting (if enabled), use : + +```php +// get the cart link +$link = $context->link->getPageLink("cart"); + +// get the cart link to delete the product with id=1 and product attribute=101; +$idProduct = 1; +$idProductAttribute = 101; + +$params = [ + 'delete' => 1, + 'id_product' => $idProduct, + 'id_product_attribute' => $idProductAttribute, +]; + +$link = $context->link->getPageLink('cart', true, null, $params,false); +``` + +More parameters are available for this method, please refer to the [method definition for details](https://github.com/PrestaShop/PrestaShop/blob/8.1.x/classes/Link.php#L1109-L1121). From 13eafb54f33f0e67521cb972e32c4158872e9d0d Mon Sep 17 00:00:00 2001 From: Thomas Nares Date: Mon, 20 Mar 2023 17:03:27 +0100 Subject: [PATCH 256/310] Remove mermaid dep --- development/components/link.md | 1 - 1 file changed, 1 deletion(-) diff --git a/development/components/link.md b/development/components/link.md index e7797df996..35be2fa4bd 100644 --- a/development/components/link.md +++ b/development/components/link.md @@ -1,6 +1,5 @@ --- title: The Link component -useMermaid: true menuTitle: Link --- From 73eda0944a7808d0f59d11725435ad071dc935f9 Mon Sep 17 00:00:00 2001 From: Thomas Nares Date: Mon, 20 Mar 2023 17:28:23 +0100 Subject: [PATCH 257/310] Make getRow() method description visible in Algolia --- development/components/database/db.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/development/components/database/db.md b/development/components/database/db.md index e36b2be8b1..a98913564c 100644 --- a/development/components/database/db.md +++ b/development/components/database/db.md @@ -51,7 +51,9 @@ As the method deals with raw SQL requests, the `_DB_PREFIX_` must be used. The result is an array of associative arrays, containing an array for each row. It should only be used for read only queries: SELECT, SHOW, etc. -#### Retrieving only the first row +#### Retrieving only the first row: getRow() + +Using getRow() method will retrieve the first row of your query: ```php $request = "SELECT `id_table` FROM `' . _DB_PREFIX_ . 'some_table` ..."; From f1a8b1d8888cdcf743c5f717bf58fe553479c86b Mon Sep 17 00:00:00 2001 From: Thomas NARES Date: Tue, 21 Mar 2023 18:30:54 +0100 Subject: [PATCH 258/310] Apply suggestions from code review Co-authored-by: Krystian Podemski --- development/components/link.md | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/development/components/link.md b/development/components/link.md index 35be2fa4bd..e307c8a87b 100644 --- a/development/components/link.md +++ b/development/components/link.md @@ -5,7 +5,7 @@ menuTitle: Link # The Link component -The `Link` component is responsible of generating URLs for various Prestashop routes. It provides a simple mecanism to handle: +The `Link` component generates URLs for various PrestaShop routes. It provides a simple mechanism to handle: - URL Rewriting (friendly URLs) - HTTP/HTTPS schemes @@ -20,15 +20,15 @@ The `Link` component is responsible of generating URLs for various Prestashop ro - `getModuleLink()` - `getPageLink()` -and many more, please explore the [Link class](https://github.com/PrestaShop/PrestaShop/blob/8.1.x/classes/Link.php). +and many more. To discover all available methods, you can explore the [Link class](https://github.com/PrestaShop/PrestaShop/blob/8.1.x/classes/Link.php). {{% notice info %}} -While possible, it is discouraged to instanciate the `Link` class by yourself, please use the `Link` provided by a `Context`. +While possible, it is discouraged to instantiate the `Link` class by yourself. Please use the `Link` provided by a `Context`. {{% /notice %}} -### Use Link to get the URL of a Product: getProductLink() method +### Use the Link component to get the URL of a Product with getProductLink() method -To obtain the URL of a product, with the right HTTP scheme, and URL rewriting (if enabled), use : +To obtain the URL of a product, with the right HTTP scheme, and URL rewriting (if enabled), use: ```php // obtain $context from a controller or from a module with: @@ -46,9 +46,9 @@ $link = $context->link->getProductLink($product); More parameters are available for this method, please refer to the [method definition for details](https://github.com/PrestaShop/PrestaShop/blob/8.1.x/classes/Link.php#L122-L141). -### Use Link to get the URL of a Category: getCategoryLink() method +### Use the Link component to get the URL of a Category with getCategoryLink() method -To obtain the URL of a category, with the right HTTP scheme, and URL rewriting (if enabled), use : +To obtain the URL of a category, with the right HTTP scheme, and URL rewriting (if enabled), use: ```php // get your category instance (from ObjectModel in this example) @@ -60,7 +60,7 @@ $link = $context->link->getCategoryLink($category); More parameters are available for this method, please refer to the [method definition for details](https://github.com/PrestaShop/PrestaShop/blob/8.1.x/classes/Link.php#L411-L422). -### Use Link to get the URL of a Module controller : getModuleLink() method +### Use the Link component to get the URL of a Module front controller with getModuleLink() method To obtain the URL of a module controller, with the right HTTP scheme, and URL rewriting (if enabled), use : @@ -81,13 +81,13 @@ $link = $context->link->getModuleLink("mymodulename", "controllerName", $params) More parameters are available for this method, please refer to the [method definition for details](https://github.com/PrestaShop/PrestaShop/blob/8.1.x/classes/Link.php#L670-L684). -### Use Link to get the URL of a page : getPageLink() method +### Use the Link component to get the URL of a page with getPageLink() method -To obtain the URL of a page controller, with the right HTTP scheme, and URL rewriting (if enabled), use : +To obtain the URL of a page controller, with the right HTTP scheme, and URL rewriting (if enabled), use: ```php // get the cart link -$link = $context->link->getPageLink("cart"); +$link = $context->link->getPageLink('cart'); // get the cart link to delete the product with id=1 and product attribute=101; $idProduct = 1; From c2c84c6a4b0b2d02c62bcaae613c90f56af69d26 Mon Sep 17 00:00:00 2001 From: Thomas Nares Date: Tue, 21 Mar 2023 18:37:26 +0100 Subject: [PATCH 259/310] Link Smarty url helper to Link component --- development/components/smarty-extensions/_index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/development/components/smarty-extensions/_index.md b/development/components/smarty-extensions/_index.md index 2e2408ed46..02ad555d58 100644 --- a/development/components/smarty-extensions/_index.md +++ b/development/components/smarty-extensions/_index.md @@ -98,7 +98,7 @@ So far, it is only used for forms (customer information and checkout). This helper is used to generate URLs. This will take care of the HTTP scheme (`http` or `https`), domain name, virtual and physical base URI, parameters concatenation, and URL rewriting. -[`{url}` uses the `Link` class internally](https://github.com/PrestaShop/PrestaShop/blob/8.1.x/classes/Link.php#L1446-L1611). +[`{url}` uses the `Link` component]({{< relref "/8/development/components/link" >}}). {{% notice note %}} Please see the `$urls` dataset to find already regenerated urls (such as home, cart, login and so on). From 4d680671c07d669f9eb5830109c3af3ff16536be Mon Sep 17 00:00:00 2001 From: Thomas Nares Date: Tue, 21 Mar 2023 19:22:25 +0100 Subject: [PATCH 260/310] Add mentions to unfound algolia requests --- development/components/helpers/helperform.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/development/components/helpers/helperform.md b/development/components/helpers/helperform.md index 71fdb5e7cf..4077fb976d 100644 --- a/development/components/helpers/helperform.md +++ b/development/components/helpers/helperform.md @@ -442,3 +442,8 @@ Note that you have to use the "t" CSS class on your labels in order to have the The type variable of the element declaration makes it possible to generate just about any kind of `` element: `text`, `select`, `textarea`, `radio`, `checkbox`, `file` and many others! See the list of available types [here](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/Input). You can also use some PrestaShop specific: `shop`, `asso_shop`, `free`, `color`. Try them out! + +#### Miscellaneous + +This helper is sometimes known as `FormHelper`. +`HelperTable` may refer to `$helper->table`. \ No newline at end of file From 45bb1eec07b915ba4928f21e9679e1837fa4a79a Mon Sep 17 00:00:00 2001 From: Thomas Nares Date: Wed, 22 Mar 2023 08:59:09 +0100 Subject: [PATCH 261/310] Begin PSCollection component --- development/components/database/prestashopcollection.md | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 development/components/database/prestashopcollection.md diff --git a/development/components/database/prestashopcollection.md b/development/components/database/prestashopcollection.md new file mode 100644 index 0000000000..bc131d04b8 --- /dev/null +++ b/development/components/database/prestashopcollection.md @@ -0,0 +1,9 @@ +--- +title: PrestaShopCollection class +--- + +# The PrestaShopCollection component + +## Introduction + + From 2d9420572c5c1ab5f89715248fbd027b0add3bb4 Mon Sep 17 00:00:00 2001 From: Thomas Nares Date: Wed, 22 Mar 2023 09:58:39 +0100 Subject: [PATCH 262/310] Document moduleRoutes hook --- .../hooks/list-of-hooks/moduleRoutes.md | 108 ++++++++++++++++++ 1 file changed, 108 insertions(+) diff --git a/modules/concepts/hooks/list-of-hooks/moduleRoutes.md b/modules/concepts/hooks/list-of-hooks/moduleRoutes.md index 66ee502cbc..33ae457636 100644 --- a/modules/concepts/hooks/list-of-hooks/moduleRoutes.md +++ b/modules/concepts/hooks/list-of-hooks/moduleRoutes.md @@ -9,12 +9,20 @@ locations: - front office type: hookAliases: +hasExample: true --- # Hook moduleRoutes ## Information +{{% notice tip %}} +**Adds route to the PrestaShop router** + +This hook allows your module to add routes to the PrestaShop router with parameters, wildcards, ... +{{% /notice %}} + + Hook locations: - front office @@ -29,4 +37,104 @@ This hook has a `$check_exception` parameter set to `false` (check permission ex ```php Hook::exec('moduleRoutes', ['id_shop' => $id_shop], null, true, false) +``` + +## Example implementation + +This hook must return an `array` of routes, keyed by the names of the routes, and each route structured by: + +```php +array( + 'rule' => string, + 'keywords' => array(), + 'controller' => string, + 'params' => array( + 'fc' => string, + 'module' => string + ) +) +``` + +### `rule` and `keywords` parameters + +`rule` is the URL that will be matched by the router. `rule` can contain parameters, enclosed with `{}`. +For example, to add an `id` parameter in your route, use the following `rule`: + +`myrule/{id}` + +Multiple parameters can be used, for example: + +`myrule/{id}/{slug}` + +Each parameter in your `rule` must be declared in the `keywords` array. + +In our example, `id` must be an integer and `slug` a string, and will be forwarded to the controller with `id` and `slug` parameter names: + +```php +[ + 'rule' => 'myrule/{id}/{slug}', + 'keywords' => [ + 'id' => [ + 'regexp' => '[0-9]*', + 'param' => 'id' + ], + 'slug' => [ + 'regexp' => '.*', + 'param' => 'slug' + ] + ], + 'controller' => 'myrulecontroller', + 'params' => [ + 'fc' => 'module', + 'module' => 'mymodulename' + ] +] +``` + +### Implementation + +This example adds two routes for your module, one for listing items, the other one for showing one specific item: + +```php +registerHook('moduleRoutes'); + } + + public function hookModuleRoutes() + { + return [ + 'module-mymoduleaddingroutes-list' => [ + 'rule' => 'mymoduleaddingroutes/list', + 'keywords' => [], + 'controller' => 'list', + 'params' => [ + 'fc' => 'module', + 'module' => 'mymoduleaddingroutes' + ] + ], + 'module-mymoduleaddingroutes-show' => [ + 'rule' => 'mymoduleaddingroutes/show/{id}/{slug}', + 'keywords' => [ + 'id' => [ + 'regexp' => '[0-9]*', + 'param' => 'id' + ], + 'slug' => [ + 'regexp' => '.*', + 'param' => 'slug' + ] + ], + 'controller' => 'show', + 'params' => [ + 'fc' => 'module', + 'module' => 'mymoduleaddingroutes' + ] + ] + ]; + } +} ``` \ No newline at end of file From 374606db8931f373e73dcc48fe396a4342c3ad89 Mon Sep 17 00:00:00 2001 From: Thomas Nares Date: Wed, 22 Mar 2023 17:02:02 +0100 Subject: [PATCH 263/310] Add search tags to help unfound algolia requests --- development/components/helpers/helperform.md | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/development/components/helpers/helperform.md b/development/components/helpers/helperform.md index 4077fb976d..6f4ce3cef7 100644 --- a/development/components/helpers/helperform.md +++ b/development/components/helpers/helperform.md @@ -10,6 +10,8 @@ This helper can used to generate HTML forms easily. Note that HelperForm is based on Smarty and Bootstrap 3, and therefore is discouraged in Symfony controllers. {{% /notice %}} +{{< searchTags tags="FormHelper, HelperTable" >}} + ## Basic usage Removing all the optional fields, this is how to build a basic HelperForm element: @@ -441,9 +443,4 @@ Note that you have to use the "t" CSS class on your labels in order to have the The type variable of the element declaration makes it possible to generate just about any kind of `` element: `text`, `select`, `textarea`, `radio`, `checkbox`, `file` and many others! See the list of available types [here](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/Input). -You can also use some PrestaShop specific: `shop`, `asso_shop`, `free`, `color`. Try them out! - -#### Miscellaneous - -This helper is sometimes known as `FormHelper`. -`HelperTable` may refer to `$helper->table`. \ No newline at end of file +You can also use some PrestaShop specific: `shop`, `asso_shop`, `free`, `color`. Try them out! \ No newline at end of file From f79054614cb0466fcc9510cfcb2f08ad94d644fa Mon Sep 17 00:00:00 2001 From: Thomas NARES Date: Mon, 27 Mar 2023 08:34:50 +0200 Subject: [PATCH 264/310] Update modules/concepts/hooks/list-of-hooks/moduleRoutes.md Co-authored-by: Krystian Podemski --- modules/concepts/hooks/list-of-hooks/moduleRoutes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/concepts/hooks/list-of-hooks/moduleRoutes.md b/modules/concepts/hooks/list-of-hooks/moduleRoutes.md index 33ae457636..fabe47f0ed 100644 --- a/modules/concepts/hooks/list-of-hooks/moduleRoutes.md +++ b/modules/concepts/hooks/list-of-hooks/moduleRoutes.md @@ -19,7 +19,7 @@ hasExample: true {{% notice tip %}} **Adds route to the PrestaShop router** -This hook allows your module to add routes to the PrestaShop router with parameters, wildcards, ... +This hook allows your module to extend default PrestaShop routes with custom ones and map them to your module front controllers. {{% /notice %}} From 421ca04adf69a3b0f5c132e6396583febae37c32 Mon Sep 17 00:00:00 2001 From: Thomas Nares Date: Tue, 28 Mar 2023 15:22:03 +0200 Subject: [PATCH 265/310] Add controllers to example, add link to example modules repo --- .../hooks/list-of-hooks/moduleRoutes.md | 54 ++++++++++++++++++- 1 file changed, 52 insertions(+), 2 deletions(-) diff --git a/modules/concepts/hooks/list-of-hooks/moduleRoutes.md b/modules/concepts/hooks/list-of-hooks/moduleRoutes.md index fabe47f0ed..5796421042 100644 --- a/modules/concepts/hooks/list-of-hooks/moduleRoutes.md +++ b/modules/concepts/hooks/list-of-hooks/moduleRoutes.md @@ -93,7 +93,55 @@ In our example, `id` must be an integer and `slug` a string, and will be forward ### Implementation -This example adds two routes for your module, one for listing items, the other one for showing one specific item: +This example creates two `ModuleFrontController` controllers, and extends PrestaShop routes to map 2 routes to those controllers: one for listing items, the other one for showing one specific item. + +Create a `list.php` `ModuleFrontController` in `mymoduleaddingroutes/controllers/front/`: + +```php +class MyModuleAddingRoutesListModuleFrontController extends ModuleFrontController +{ + public function initContent() + { + $this->setTemplate('module:mymoduleaddingroutes/views/templates/front/list.tpl'); + } +} +``` + +and a `show.php` `ModuleFrontController` in `mymoduleaddingroutes/controllers/front/`: + +```php +class MyModuleAddingRoutesShowModuleFrontController extends ModuleFrontController +{ + public function initContent() + { + $this->context->smarty->assign( + array( + 'id' => Tools::getValue('id'), + 'slug' => Tools::getValue('slug') + )); + + $this->setTemplate('module:mymoduleaddingroutes/views/templates/front/show.tpl'); + } +} +``` + +Now, create two templates in `mymoduleaddingroutes/views/templates/front/`: + +`list.tpl`: + +```html +

List template

+``` + +`show.tpl`: + +```html +

Show template

+Id: {$id} +Slug: {$slug} +``` + +Now we have 2 controllers, rendering 2 templates, we can create our routes with `moduleRoutes` hook, in `mymoduleaddingroutes/mymoduleaddingroutes.php`: ```php Date: Tue, 28 Mar 2023 18:38:39 +0300 Subject: [PATCH 266/310] Add example of placeholders in translation When one does these only once in a while its nice to have a quick reference to double check and placeholder usage was not documented on the page at all (and the links to other pages have way too much information for just a simple "what was the syntax again" problem) --- modules/creation/module-translation/new-system.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/modules/creation/module-translation/new-system.md b/modules/creation/module-translation/new-system.md index 12aec1246e..ca0940e515 100644 --- a/modules/creation/module-translation/new-system.md +++ b/modules/creation/module-translation/new-system.md @@ -126,8 +126,10 @@ class MyModule extends Module { public function __construct() { + $this->version = '1.0.0'; + $this->author = 'Me'; $this->displayName = $this->trans('My module', [], 'Modules.Mymodule.Mymodule'); - $this->description = $this->trans('Description of my module.', [], 'Modules.Mymodule.Mymodule'); + $this->description = $this->trans('Description of my module. Made by: %author%, Current Version: %version%', ['%version%' => $this->version ,'%author% => $this->author], 'Modules.Mymodule.Mymodule'); } } ``` From a9908d0b65f29dd680118ce6aca70e4dbbbc1fbb Mon Sep 17 00:00:00 2001 From: Thomas NARES Date: Tue, 28 Mar 2023 17:44:50 +0200 Subject: [PATCH 267/310] Update modules/concepts/hooks/list-of-hooks/moduleRoutes.md Co-authored-by: Krystian Podemski --- modules/concepts/hooks/list-of-hooks/moduleRoutes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/concepts/hooks/list-of-hooks/moduleRoutes.md b/modules/concepts/hooks/list-of-hooks/moduleRoutes.md index 5796421042..6bb422286e 100644 --- a/modules/concepts/hooks/list-of-hooks/moduleRoutes.md +++ b/modules/concepts/hooks/list-of-hooks/moduleRoutes.md @@ -187,4 +187,4 @@ class MyModuleAddingRoutes extends Module } ``` -The complete implementation example is available in our [example modules repository](https://github.com/PrestaShop/example-modules). \ No newline at end of file +The complete implementation example is available in our [example modules repository](https://github.com/PrestaShop/example-modules/demomoduleroutes). \ No newline at end of file From cc376d7b3908c47fc642bbc3bcc62cf70eac84e1 Mon Sep 17 00:00:00 2001 From: Krystian Podemski Date: Wed, 29 Mar 2023 11:04:17 +0200 Subject: [PATCH 268/310] Update modules/concepts/hooks/list-of-hooks/moduleRoutes.md --- modules/concepts/hooks/list-of-hooks/moduleRoutes.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/modules/concepts/hooks/list-of-hooks/moduleRoutes.md b/modules/concepts/hooks/list-of-hooks/moduleRoutes.md index 6bb422286e..f12d7a205e 100644 --- a/modules/concepts/hooks/list-of-hooks/moduleRoutes.md +++ b/modules/concepts/hooks/list-of-hooks/moduleRoutes.md @@ -114,11 +114,13 @@ class MyModuleAddingRoutesShowModuleFrontController extends ModuleFrontControlle { public function initContent() { + // It is just an example. Remember to always validate the input data! $this->context->smarty->assign( - array( + [ 'id' => Tools::getValue('id'), 'slug' => Tools::getValue('slug') - )); + ] + ); $this->setTemplate('module:mymoduleaddingroutes/views/templates/front/show.tpl'); } From fa38b193cab2db727ca5c28e831274842f299140 Mon Sep 17 00:00:00 2001 From: Thomas Nares Date: Sun, 2 Apr 2023 13:34:47 +0200 Subject: [PATCH 269/310] Add example from native module for HelperForm --- development/components/helpers/helperform.md | 48 +++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/development/components/helpers/helperform.md b/development/components/helpers/helperform.md index 6f4ce3cef7..8968845735 100644 --- a/development/components/helpers/helperform.md +++ b/development/components/helpers/helperform.md @@ -443,4 +443,50 @@ Note that you have to use the "t" CSS class on your labels in order to have the The type variable of the element declaration makes it possible to generate just about any kind of `` element: `text`, `select`, `textarea`, `radio`, `checkbox`, `file` and many others! See the list of available types [here](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/Input). -You can also use some PrestaShop specific: `shop`, `asso_shop`, `free`, `color`. Try them out! \ No newline at end of file +You can also use some PrestaShop specific: `shop`, `asso_shop`, `free`, `color`. Try them out! + +## Example usage in native modules + +`HelperForm` is implemented into several native modules, such as [`ContactForm`](https://github.com/PrestaShop/contactform). + +In this module, + +- a [`renderForm()` method is created](https://github.com/PrestaShop/contactform/blob/v4.4.1/contactform.php#L108), +- the [`$form` is declared with its form declaration](https://github.com/PrestaShop/contactform/blob/v4.4.1/contactform.php#L120-L189), +- then a [`HelperForm` is instantiated](https://github.com/PrestaShop/contactform/blob/v4.4.1/contactform.php#L190), +- finally the html content is [generated and returned](https://github.com/PrestaShop/contactform/blob/v4.4.1/contactform.php#L203). + +```php +/** + * @return string +*/ +protected function renderForm() +{ + $form = [ + // ... form declaration as described on this page + // refer to https://github.com/PrestaShop/contactform/blob/v4.4.1/contactform.php#L120-L189 + // for complete implementation + ]; + + $helper = new HelperForm(); + // HelperForm settings, refer to https://github.com/PrestaShop/contactform/blob/v4.4.1/contactform.php#L190-L201 + // for complete implementation + + return $helper->generateForm([$form]); +} +``` + +Then, in the `getContent()` method of this module, the `renderForm()` method is called: + +```php +/** + * @return string + */ +public function getContent() +{ + // ... + $html .= $this->renderForm(); + // ... + return $html; +} +``` \ No newline at end of file From 4175987106fd23e9aab6d4691ba7c5bba08c93e1 Mon Sep 17 00:00:00 2001 From: Thomas Nares Date: Sun, 2 Apr 2023 13:50:06 +0200 Subject: [PATCH 270/310] Add example from native module for HelperList --- development/components/helpers/helperform.md | 2 +- development/components/helpers/helperlist.md | 50 ++++++++++++++++++++ 2 files changed, 51 insertions(+), 1 deletion(-) diff --git a/development/components/helpers/helperform.md b/development/components/helpers/helperform.md index 8968845735..fa3778c12f 100644 --- a/development/components/helpers/helperform.md +++ b/development/components/helpers/helperform.md @@ -452,7 +452,7 @@ You can also use some PrestaShop specific: `shop`, `asso_shop`, `free`, `color`. In this module, - a [`renderForm()` method is created](https://github.com/PrestaShop/contactform/blob/v4.4.1/contactform.php#L108), -- the [`$form` is declared with its form declaration](https://github.com/PrestaShop/contactform/blob/v4.4.1/contactform.php#L120-L189), +- the [`form declaration is declared](https://github.com/PrestaShop/contactform/blob/v4.4.1/contactform.php#L120-L189), - then a [`HelperForm` is instantiated](https://github.com/PrestaShop/contactform/blob/v4.4.1/contactform.php#L190), - finally the html content is [generated and returned](https://github.com/PrestaShop/contactform/blob/v4.4.1/contactform.php#L203). diff --git a/development/components/helpers/helperlist.md b/development/components/helpers/helperlist.md index 5e7fb4281a..e8a0011548 100644 --- a/development/components/helpers/helperlist.md +++ b/development/components/helpers/helperlist.md @@ -213,3 +213,53 @@ The expected JSON format: data: '

My HTML content

' } ``` + +## Example usage in native modules + +`HelperList` is implemented into several native modules, such as [`ps_emailsubscription`](https://github.com/PrestaShop/ps_emailsubscription). + +In this module, + +- a [`renderList()` method is created](https://github.com/PrestaShop/ps_emailsubscription/blob/v2.7.1/ps_emailsubscription.php#L255), +- the [`$field_ist` is declared](https://github.com/PrestaShop/ps_emailsubscription/blob/v2.7.1/ps_emailsubscription.php#L257-L297), +- then a [`HelperList` is instantiated](https://github.com/PrestaShop/ps_emailsubscription/blob/v2.7.1/ps_emailsubscription.php#L303), +- finally the html content is [generated and returned](https://github.com/PrestaShop/ps_emailsubscription/blob/v2.7.1/ps_emailsubscription.php#L328). + +```php +public function renderList() +{ + $fields_list = [ + // ... fields list declaration, refer to https://github.com/PrestaShop/ps_emailsubscription/blob/v2.7.1/ps_emailsubscription.php#L257-L297 + // for complete implementation + ]; + + // ... + + $helper_list = new HelperList(); + // HelperList settings, refer to https://github.com/PrestaShop/ps_emailsubscription/blob/v2.7.1/ps_emailsubscription.php#L303-L317 + // for complete implementation + + /* Retrieve list data */ + $subscribers = $this->getSubscribers(); + + // paginate results, refer to https://github.com/PrestaShop/ps_emailsubscription/blob/v2.7.1/ps_emailsubscription.php#L321-L326 + // for complete implementation + + return $helper_list->generateList($subscribers, $fields_list); +} +``` + +Then, in the `getContent()` method of this module, the `renderList()` method is called: + +```php +/** + * @return string + */ +public function getContent() +{ + // ... + $this->_html .= $this->renderList(); + // ... + return $this->_html; +} +``` \ No newline at end of file From 87de35ec0062998ea3b3f2bedd0fd7992b3f7daa Mon Sep 17 00:00:00 2001 From: Thomas Nares Date: Sun, 2 Apr 2023 17:08:29 +0200 Subject: [PATCH 271/310] Document Locale component --- development/components/context.md | 1 + development/components/locale.md | 65 +++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+) create mode 100644 development/components/locale.md diff --git a/development/components/context.md b/development/components/context.md index c54b12e7f2..fb26d0796d 100644 --- a/development/components/context.md +++ b/development/components/context.md @@ -24,6 +24,7 @@ These objects are always accessible through the context: - **Cookie.** Cookie instance. - **Link.** Link instance. - **Smarty.** Smarty instance. +- **CurrentLocale.** [Current Locale]({{< relref "/8/development/components/locale" >}}). These objects are only accessible for the customer Context: diff --git a/development/components/locale.md b/development/components/locale.md new file mode 100644 index 0000000000..238acd45ab --- /dev/null +++ b/development/components/locale.md @@ -0,0 +1,65 @@ +--- +title: The Locale component +menuTitle: Locale +--- + +# The Locale component + +The `Locale` component is in charge of formating numbers, prices and percentages. + +It is accessible through the [`Context`]({{< relref "/8/development/components/context" >}}) + +It provides useful methods such as `formatNumber()` and `formatPrice()`. + +## Initialization of Locale + +The `Locale` is initialized with : + +- a `code` in [IETF tag](https://en.wikipedia.org/wiki/IETF_language_tag) format (`en-US`, `fr-FR`, ...), +- a `PrestaShop\PrestaShop\Core\Localization\Specification\Number` [`NumberSpecification`](https://github.com/PrestaShop/PrestaShop/blob/8.0.0/src/Core/Localization/Specification/Number.php) +- a `PrestaShop\PrestaShop\Core\Localization\Specification\NumberCollection` [`PriceSpecificationMap`](https://github.com/PrestaShop/PrestaShop/blob/8.0.0/src/Core/Localization/Specification/NumberCollection.php) +- a `PrestaShop\PrestaShop\Core\Localization\Number\Formatter` [`Number formatter`](https://github.com/PrestaShop/PrestaShop/blob/8.0.0/src/Core/Localization/Number/Formatter.php) + +## formatNumber() method + +This method receives one parameter `$number` as `int`, `float` or `string`. It returns a formatted number, as a `string`, taking the `NumberSpecification` used by the locale, set during its initialization. + +### example of use + +With a `en-US` locale, + +```php +$number = 1234.56; + +var_dump(Context::getContext()->getCurrentLocale()->formatNumber($number)); +``` + +Will dump: + +```php +string(8) "1,234.56" +``` + +## formatPrice() method + +This method receives two parameters, the first one `$number` as `int`, `float` or `string`, and the second one `$currencyCode` as `string`. It returns a formatted price, as a `string`, taking the matching `PriceSpecification` identified by the `$currencyCode`. + +### example of use + +With a `en-US` locale, and a `GBP` currency code: + +```php +$price = 1234.56; + +var_dump(Context::getContext()->getCurrentLocale()->formatPrice($price, 'GBP')); +// string(10) "£1,234.56" +``` + +With a `en-US` locale, and a `EUR` currency code, + +```php +$price = 1234.56; + +var_dump(Context::getContext()->getCurrentLocale()->formatPrice($price, 'EUR')); +// string(10) "€1,234.56" +``` \ No newline at end of file From 4a65412f5dc06b985c957ddc66b90bb77830fad6 Mon Sep 17 00:00:00 2001 From: Dindault Lucas <64981161+LaBisquerie@users.noreply.github.com> Date: Tue, 4 Apr 2023 14:44:32 +0200 Subject: [PATCH 272/310] Update helperoptions.md --- development/components/helpers/helperoptions.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/development/components/helpers/helperoptions.md b/development/components/helpers/helperoptions.md index 7bf374a7ba..c8bbe60e0a 100644 --- a/development/components/helpers/helperoptions.md +++ b/development/components/helpers/helperoptions.md @@ -33,6 +33,7 @@ $this->fields_options = [ 'type' => {'text', 'hidden', 'select', 'bool', 'radio', // The kind of input field you want to use. 'checkbox', 'password', 'textarea', 'file', 'textLang', 'textareaLang', 'selectLang'}, + 'autoload_rte' => 'true' // Display a TinyMCE editor for textarea field only 'suffix' => 'kg', // Display after the field (ie. currency). // For text fields or password fields only. 'identifier' => 'id_carrier', // The unique ID for the form. @@ -57,6 +58,8 @@ $this->fields_options = [ For multilang configuration fields you can use `Lang` version i.e. `textLang` is the multilang version of `text` field. +To save the HTML content of the TinyMCE editor, remember to use `'validation' => 'isCleanHtml'`. + ## Basic declaration Removing all the optional fields, this is how to build a basic HelperOptions element: @@ -158,4 +161,4 @@ This specific code generates this HTML code (simplified here for readability rea ['id' => 'myconfigvalue2', 'name' => $this->module->l('My value 2')], ], ], -``` \ No newline at end of file +``` From e17914a984628843172a69757f72a45a2758dc3c Mon Sep 17 00:00:00 2001 From: Thomas Nares Date: Mon, 10 Apr 2023 19:57:45 +0200 Subject: [PATCH 273/310] pending changes - new product page customisation --- modules/sample-modules/extend-product-page.md | 238 +++++++++++++----- .../img/new-product-form/seo-custom-field.png | Bin 0 -> 34761 bytes .../img/old-product-form/seo-custom-field.png | Bin 0 -> 16558 bytes 3 files changed, 172 insertions(+), 66 deletions(-) create mode 100644 modules/sample-modules/img/new-product-form/seo-custom-field.png create mode 100644 modules/sample-modules/img/old-product-form/seo-custom-field.png diff --git a/modules/sample-modules/extend-product-page.md b/modules/sample-modules/extend-product-page.md index 8683897dd1..324451593e 100644 --- a/modules/sample-modules/extend-product-page.md +++ b/modules/sample-modules/extend-product-page.md @@ -3,110 +3,216 @@ title: Extending the new product page form weight: 3 --- -# Extending the new product page form -{{< minver v="8.0" title="true" >}} +# Extending the new product page form {{< minver v="8.1.0" >}} -To allow the new product page to be easily extendable by modules, a new feature was introduced in {{< minver v="8.1.0" title="true" >}} -This features allows to add new custom tabs with the `NavigationTabType`. +The new Back Office product page introduced in {{< minver v="8.1.0" >}} removed several hooks previously available: -The goal of this How-to is to show how to customize the new product page with all this new introduced features, and older ones. +- `displayAdminProductsCombinationBottom` +- `displayAdminProductsSeoStepBottom` +- `displayAdminProductsShippingStepBottom` +- `displayAdminProductsQuantitiesStepBottom` +- `displayAdminProductsMainStepLeftColumnBottom` +- `displayAdminProductsMainStepLeftColumnMiddle` +- `displayAdminProductsMainStepRightColumnBottom` +- `displayAdminProductsOptionsStepTop` +- `displayAdminProductsOptionsStepBottom` +- `displayAdminProductsPriceStepBottom` -The example module we are going to create can be found [here](https://github.com/PrestaShop/example-modules/tree/master/demoproductform) in our [example modules repository](https://github.com/PrestaShop/example-modules). +The only `displayAdminProduct*` hook that was not removed is: -## What will be achieved with this how-to ? +- `displayAdminProductsExtra` -In this how-to, we will create a new module, and add a new custom field in the native description tab. +In this guide, we will discover how to extend the product page by adding custom fields, in the old and new way of doing this. -![custom field in product form](../img/productform-customfield.png) +Finally, we will discover how to add a new Tab to the product page. -Then, we will create a new empty tab, and we will add a new custom field in this module created tab. +## Add a custom field, before {{< minver v="8.1.0" >}} -![custom tab in product form](../img/productform-customtab.png) +A custom field, before {{< minver v="8.1.0" >}}, was added by hooking to one of the `displayAdminProducts` hook. -Finally, we will experience how those features work in older versions of PrestaShop since they are backward compatible. +For example, to add a custom field, in the `SEO` tab, you had to create a module with this content: -![custom field and tabs in older versions of PrestaShop](../img/productform-backward.png) +`demooldhooks.php`: +```php +declare(strict_types=1); -## Create the module +use Symfony\Component\Form\Extension\Core\Type\TextType; -To create the module, we use the [regular module creation method]({{< ref "8/modules/creation/tutorial" >}}). +class DemoOldHooks extends Module +{ + public function __construct() + { + // [...] + } -Our regular module skeleton: + /** + * @return bool + */ + public function install() + { + return parent::install() && $this->registerHook(['displayAdminProductsSeoStepBottom']); + } -```php -get('form.factory'); + $twig = $this->get('twig'); -declare(strict_types=1); + $product = new Product($productId); + + $form = $formFactory + ->createNamedBuilder('seo_special_field', TextType::class, "") + ->getForm(); + + $template = '@Modules/demooldhooks/views/templates/seo_special_field.html.twig'; -if (!defined('_PS_VERSION_')) { - exit; + return $twig->render($template, [ + 'seo_special_field' => $form->createView() + ]); + } } +``` + +`views/templates/seo_special_field.html.twig`: + +```php +

SEO Special field

+{{ form_widget(seo_special_field) }} +``` + +Before {{< minver v="8.1.0" >}}, that would produce: + +![custom field in SEO tab in older versions of PrestaShop](../img/old-product-form/seo-custom-field.png) + +From {{< minver v="8.1.0" >}}, that would produce nothing, since this hook (`displayAdminProductsSeoStepBottom`) is no more used. + +## Add a custom field, from {{< minver v="8.1.0" >}} + +To do exactly the same, from {{< minver v="8.1.0" >}}, we will implement `actionProductFormBuilderModifier` hook and modify the Product FormBuilder. + +First, create a module, with a `composer.json` file, [as instructed here]({{< relref "/8/modules/concepts/composer" >}}). + +`demonewhooks.php`: -require_once __DIR__ . '/vendor/autoload.php'; +```php +declare(strict_types=1); + +use DemoNewHooks\Form\Modifier\ProductFormModifier; -class DemoProductForm extends Module +class DemoNewHooks extends Module { public function __construct() { - $this->name = 'demoproductform'; - $this->author = 'PrestaShop'; - $this->version = '1.0.0'; - $this->ps_versions_compliancy = ['min' => '8.1.0', 'max' => _PS_VERSION_]; + // [...] + } - parent::__construct(); + /** + * @return bool + */ + public function install() + { + return parent::install() && $this->registerHook(['actionProductFormBuilderModifier']); + } + + /** + * Modify product form builder + * + * @param array $params + */ + public function hookActionProductFormBuilderModifier(array $params): void + { + /** @var ProductFormModifier $productFormModifier */ + $productFormModifier = $this->get(ProductFormModifier::class); + $productId = (int) $params['id']; - $this->displayName = $this->trans('DemoProductForm', [], 'Modules.Demoproductform.Config'); - $this->description = $this->trans('DemoProductForm module description', [], 'Modules.Demoproductform.Config'); + $productFormModifier->modify($productId, $params['form_builder']); } } ``` -In this example module, we use the [new translation system]({{< ref "/8/modules/creation/module-translation/new-system" >}}), so we need to add this method to enable the translation system: +`config/services.yml`: -```php - public function isUsingNewTranslationSystem(): bool - { - return true; - } +```yml +services: + DemoNewHooks\Form\Modifier\ProductFormModifier: + autowire: true + public: true + arguments: + $formBuilderModifier: '@form.form_builder_modifier' ``` -This module is also PSR4 compliant, and namespaced, so we require the `autoload.php`, and our `composer.json` contains the following content: +`src/Form/Modifier/ProductFormModifier.php` + +```php +declare(strict_types=1); + +namespace DemoNewHooks\Form\Modifier; -```json +use PrestaShopBundle\Form\FormBuilderModifier; +use Symfony\Component\Form\Extension\Core\Type\TextType; +use Symfony\Component\Form\FormBuilderInterface; + +final class ProductFormModifier { - "name": "prestashop/demoproductform", - "authors": [ - { - "name": "Julius Zukauskas", - "email": "julius.zukauskas@invertus.eu" - }, - { - "name": "PrestaShop Core team" + /** + * @var FormBuilderModifier + */ + private $formBuilderModifier; + + /** + * @param FormBuilderModifier $formBuilderModifier + */ + public function __construct( + FormBuilderModifier $formBuilderModifier + ) { + $this->formBuilderModifier = $formBuilderModifier; + } + + /** + * @param int|null $productId + * @param FormBuilderInterface $productFormBuilder + */ + public function modify( + int $productId, + FormBuilderInterface $productFormBuilder + ): void { + + $seoTabFormBuilder = $productFormBuilder->get('seo'); + $this->formBuilderModifier->addAfter( + $seoTabFormBuilder, + 'tags', + 'demo_module_custom_field', + TextType::class, + [ + // you can remove the label if you dont need it by passing 'label' => false + 'label' => 'SEO Special Field', + // customize label by any html attribute + 'label_attr' => [ + 'title' => 'h2', + 'class' => 'text-info', + ], + 'attr' => [ + 'placeholder' => 'SEO Special field', + ], + // this is just an example, but in real case scenario you could have some data provider class to wrap more complex cases + 'data' => "", + 'empty_data' => '', + 'form_theme' => '@PrestaShop/Admin/TwigTemplateForm/prestashop_ui_kit_base.html.twig', + ] + ); } - ], - "autoload": { - "psr-4": { - "PrestaShop\\Module\\DemoProductForm\\": "src/" - }, - "config": { - "prepend-autoloader": false - }, - "type": "prestashop-module" - }, - "require-dev": { - "friendsofphp/php-cs-fixer": "^3.14" - } } ``` +This module is creating a Form Builder Modifier (`ProductFormModifier`), adding a `TextType` field to the `seo` tab form builder from the `ProductForm Builder`, added after the `tags` form element. -## Create a custom field in description tab - -## Create a new tab - -## Create a custom field in the new tab +This Form Builder Modifier is hooked to the `actionProductFormBuilderModifier` hook. -## Backward compatibility of those features +This produces this form: +![custom field in SEO tab in newer versions of PrestaShop](../img/new-product-form/seo-custom-field.png) -## Next steps \ No newline at end of file +{{% notice note %}} +This new way of adding custom fields to the product page allows you for more precise positioning, you can now position your fields/forms exactly where you want. +{{% /notice %}} \ No newline at end of file diff --git a/modules/sample-modules/img/new-product-form/seo-custom-field.png b/modules/sample-modules/img/new-product-form/seo-custom-field.png new file mode 100644 index 0000000000000000000000000000000000000000..237180702e2a9ff0ad8753ff02d620a9b03f1b11 GIT binary patch literal 34761 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 U8H>5U9!l5KHqt`gy#MU~0Jts_rT_o{ literal 0 HcmV?d00001 From 94b7b628c524e6f5e17453ef47eb90c36e10e57c Mon Sep 17 00:00:00 2001 From: boubkerbribri Date: Tue, 11 Apr 2023 09:20:59 +0200 Subject: [PATCH 274/310] fix: update password on docker docs to use the new one --- contribute/contribute-pull-requests/contribute_using_docker.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contribute/contribute-pull-requests/contribute_using_docker.md b/contribute/contribute-pull-requests/contribute_using_docker.md index 1ca44edbb4..5190124696 100644 --- a/contribute/contribute-pull-requests/contribute_using_docker.md +++ b/contribute/contribute-pull-requests/contribute_using_docker.md @@ -60,7 +60,7 @@ prestashop-git | \n* Almost ! Starting web server now\n At this point, your PrestaShop installation is ready and the website is available at http://localhost:8001. -The default credentials for the back-office are `demo@prestashop.com` / `prestashop_demo`. +The default credentials for the back-office are `demo@prestashop.com` / `Correct Horse Battery Staple`. Default MySQL credentials to connect using 3rd party programs like Sequel Pro and others: Username: `root` From e45e6153d8d79beaeba1b928fab7e4e384caac4b Mon Sep 17 00:00:00 2001 From: Thomas Nares Date: Tue, 11 Apr 2023 16:23:58 +0200 Subject: [PATCH 275/310] Add examples, create new tab, BC indication --- modules/sample-modules/extend-product-page.md | 354 +++++++++++++++++- 1 file changed, 344 insertions(+), 10 deletions(-) diff --git a/modules/sample-modules/extend-product-page.md b/modules/sample-modules/extend-product-page.md index 324451593e..78fbb5dba8 100644 --- a/modules/sample-modules/extend-product-page.md +++ b/modules/sample-modules/extend-product-page.md @@ -22,6 +22,10 @@ The only `displayAdminProduct*` hook that was not removed is: - `displayAdminProductsExtra` +{{% notice info %}} +Altough conserved for Backwards compatibility, usage of this hook (`displayAdminProductsExtra`) is not recommended for new modules. +{{% /notice %}} + In this guide, we will discover how to extend the product page by adding custom fields, in the old and new way of doing this. Finally, we will discover how to add a new Tab to the product page. @@ -142,7 +146,7 @@ services: $formBuilderModifier: '@form.form_builder_modifier' ``` -`src/Form/Modifier/ProductFormModifier.php` +`src/Form/Modifier/ProductFormModifier.php`: ```php declare(strict_types=1); @@ -180,15 +184,13 @@ final class ProductFormModifier $seoTabFormBuilder = $productFormBuilder->get('seo'); $this->formBuilderModifier->addAfter( - $seoTabFormBuilder, - 'tags', - 'demo_module_custom_field', - TextType::class, + $seoTabFormBuilder, // the tab + 'tags', // the input/form from which to insert after/before + 'demo_module_custom_field', // your field name + TextType::class, // your field type [ - // you can remove the label if you dont need it by passing 'label' => false - 'label' => 'SEO Special Field', - // customize label by any html attribute - 'label_attr' => [ + 'label' => 'SEO Special Field', // you can remove the label if you dont need it by passing 'label' => false + 'label_attr' => [ // customize label by any html attribute 'title' => 'h2', 'class' => 'text-info', ], @@ -215,4 +217,336 @@ This produces this form: {{% notice note %}} This new way of adding custom fields to the product page allows you for more precise positioning, you can now position your fields/forms exactly where you want. -{{% /notice %}} \ No newline at end of file +{{% /notice %}} + +## Cheatsheet for old hooks / new hooks + +### Hook: actionProductFormBuilderModifier + +- Hook : [`actionFormBuilderModifier`]({{< relref "/8/modules/concepts/hooks/list-of-hooks/actionFormBuilderModifier" >}}) + +| Old hook | Location on page | Form tab | Inserted | +| --- | --- | --- | --- | +| `displayAdminProductsSeoStepBottom` | Bottom of SEO tab | `seo` | after `tags` | +| `displayAdminProductsCombinationBottom` | Bottom of Combinations tab | `combinations` | after `availability` | +| `displayAdminProductsShippingStepBottom` | Bottom of Shipping tab | `shipping` | after `carriers` | +| `displayAdminProductsQuantitiesStepBottom` | Bottom of Quantities tab | `stock` | after `low_stock_threshold` | +| `displayAdminProductsMainStepLeftColumnBottom` | Basic settings tab, under related product | `description` | after `related_products` | +| `displayAdminProductsMainStepLeftColumnMiddle` | Basic settings tab, under description | `description` | after `description` | +| `displayAdminProductsMainStepRightColumnBottom` | Basic settings tab, under create a category | `description` | after `categories` | +| `displayAdminProductsOptionsStepTop` | Top of Options tab | `options` | before `visibility` | +| `displayAdminProductsOptionsStepBottom` | Bottom of Options tab | `options` | after `product_suppliers` | +| `displayAdminProductsPriceStepBottom` | Bottom of Pricing tab | `pricing` | after `priority_management` | + +Form Type details: [`EditProductFormType`](https://github.com/PrestaShop/PrestaShop/blob/8.1.0-beta.1/src/PrestaShopBundle/Form/Admin/Sell/Product/EditProductFormType.php) + +## Extend a sub form + +Sub forms can be extended aswell, for example, to add a new input on each combination of a product: + +- Hook to actionProductCombinationFormBuilderModifier ([`actionFormBuilderModifier`]({{< relref "/8/modules/concepts/hooks/list-of-hooks/actionFormBuilderModifier" >}})) + +```php +/** + * Hook that modifies the combination form structure. + * + * @param array $params + */ +public function hookActionCombinationFormFormBuilderModifier(array $params): void +{ + /** @var CombinationFormModifier $productFormModifier */ + $productFormModifier = $this->get(CombinationFormModifier::class); + $combinationId = isset($params['id']) ? new CombinationId((int) $params['id']) : null; + + $productFormModifier->modify($combinationId, $params['form_builder']); +} +``` + +`src/Form/Modifier/CombinationFormModifier.php`: + +```php +// [...] +class CombinationFormModifier +{ + // [...] + + /** + * @param CombinationId|null $combinationId + * @param FormBuilderInterface $combinationFormBuilder + */ + public function modify( + ?CombinationId $combinationId, + FormBuilderInterface $combinationFormBuilder + ): void { + $idValue = $combinationId ? $combinationId->getValue() : null; + $customCombination = new CustomCombination($idValue); + $this->addCustomField($customCombination, $combinationFormBuilder); + } + + /** + * @param CustomCombination $customCombination + * @param FormBuilderInterface $combinationFormBuilder + * + * @see demoproductform::hook + */ + private function addCustomField(CustomCombination $customCombination, FormBuilderInterface $combinationFormBuilder): void + { + $this->formBuilderModifier->addAfter( + $combinationFormBuilder, + 'references', + 'demo_module_custom_field', + TextType::class, + [ + 'label' => $this->translator->trans('Demo custom field', [], 'Modules.Demoproductform.Admin'), + 'label_attr' => [ + 'title' => 'h2', + 'class' => 'text-info', + ], + 'attr' => [ + 'placeholder' => $this->translator->trans('Your example text here', [], 'Modules.Demoproductform.Admin'), + ], + 'data' => $customCombination->custom_field, + 'empty_data' => '', + 'form_theme' => '@PrestaShop/Admin/TwigTemplateForm/prestashop_ui_kit_base.html.twig', + ] + ); + } +} +``` + +This example will add a `TextType` input on each `Combination` of a `Product`. +A complete working example and implementation is available in our [example-module repository](https://github.com/PrestaShop/example-modules/tree/master/demoproductform). + +## Add a custom Tab to Product Page + +{{< minver v="8.1.0" >}} introduced a new feature : Custom tabs in product page. + +A complete working example and implementation is available in our [example-module repository](https://github.com/PrestaShop/example-modules/tree/master/demoproductform). + +- Modify the Product Form builder with `actionProductFormBuilderModifier` hook, and create a modifier: + +`demonewhooks.php`: + +```php +declare(strict_types=1); + +use DemoNewHooks\Form\Modifier\ProductFormModifier; + +class DemoNewHooks extends Module +{ + public function __construct() + { + // [...] + } + + /** + * @return bool + */ + public function install() + { + return parent::install() && $this->registerHook(['actionProductFormBuilderModifier']); + } + + /** + * Modify product form builder + * + * @param array $params + */ + public function hookActionProductFormBuilderModifier(array $params): void + { + /** @var ProductFormModifier $productFormModifier */ + $productFormModifier = $this->get(ProductFormModifier::class); + $productId = (int) $params['id']; + + $productFormModifier->modify($productId, $params['form_builder']); + } +} +``` + +`config/services.yml`: + +```yml +services: + DemoNewHooks\Form\Modifier\ProductFormModifier: + autowire: true + public: true + arguments: + $formBuilderModifier: '@form.form_builder_modifier' +``` + +`src/Form/Modifier/ProductFormModifier.php`: + +```php +declare(strict_types=1); + +namespace DemoNewHooks\Form\Modifier; + +use PrestaShopBundle\Form\FormBuilderModifier; +use Symfony\Component\Form\Extension\Core\Type\TextType; +use Symfony\Component\Form\FormBuilderInterface; + +final class ProductFormModifier +{ + /** + * @var FormBuilderModifier + */ + private $formBuilderModifier; + + /** + * @param FormBuilderModifier $formBuilderModifier + */ + public function __construct( + FormBuilderModifier $formBuilderModifier + ) { + $this->formBuilderModifier = $formBuilderModifier; + } + + /** + * @param int|null $productId + * @param FormBuilderInterface $productFormBuilder + */ + public function modify( + int $productId, + FormBuilderInterface $productFormBuilder + ): void { + + } +} +``` + +- Create a new Type for your custom tab, for example `CustomTabType`, and add a `MoneyType` input in this tab: + +`src/Form/Type/CustomTabType.php`: + +```php +declare(strict_types=1); + +namespace PrestaShop\Module\DemoProductForm\Form\Type; + +use PrestaShopBundle\Form\Admin\Type\TranslatorAwareType; +use Symfony\Component\Form\Extension\Core\Type\MoneyType; +use Symfony\Component\Form\FormBuilderInterface; +use Symfony\Component\OptionsResolver\OptionsResolver; +use Symfony\Component\Translation\TranslatorInterface; +use Symfony\Component\Validator\Constraints\NotBlank; +use Symfony\Component\Validator\Constraints\PositiveOrZero; +use Symfony\Component\Validator\Constraints\Type; + +class CustomTabType extends TranslatorAwareType +{ + /** + * @var \Currency + */ + private $defaultCurrency; + + /** + * @param TranslatorInterface $translator + * @param array $locales + * @param \Currency $defaultCurrency + */ + public function __construct( + TranslatorInterface $translator, + array $locales, + \Currency $defaultCurrency + ) { + parent::__construct($translator, $locales); + $this->defaultCurrency = $defaultCurrency; + } + + /** + * {@inheritDoc} + */ + public function buildForm(FormBuilderInterface $builder, array $options) + { + parent::buildForm($builder, $options); + $builder + ->add('custom_price', MoneyType::class, [ + 'label' => $this->trans('My custom price', 'Modules.Demoproductform.Admin'), + 'label_tag_name' => 'h3', + 'currency' => $this->defaultCurrency->iso_code, + 'required' => false, + 'constraints' => [ + new NotBlank(), + new Type(['type' => 'float']), + new PositiveOrZero(), + ], + ]) + ; + } + + /** + * {@inheritDoc} + */ + public function configureOptions(OptionsResolver $resolver) + { + parent::configureOptions($resolver); + + $resolver + ->setDefaults([ + 'label' => $this->trans('Customization', 'Modules.Demoproductform.Admin'), + ]) + ; + } +} +``` + +Finally, add this `CustomTabType` to the `$productFormBuilder` variable in your `modify` method in the `ProductFormModifier`: + +```php + +/** + * @param int|null $productId + * @param FormBuilderInterface $productFormBuilder + */ +public function modify( + int $productId, + FormBuilderInterface $productFormBuilder +): void { + + $idValue = $productId ? $productId->getValue() : null; + $customProduct = new CustomProduct($idValue); + + $this->formBuilderModifier->addAfter( + $productFormBuilder, + 'pricing', + 'custom_tab', + CustomTabType::class, + [ + 'data' => [ + 'custom_price' => $customProduct->custom_price, + ], + ] + ); +} +``` + +{{% notice note %}} +Any type added directly to the `$productFormBuilder` (and not to a sub tab) will be considered as a tab. +{{% /notice %}} + +## Backwards compatibility for displayAdminProductsExtra hook + +A custom Form Type `ExtraModulesType` as been added to {{< minver v="8.1.0" >}}, to allow backwards compatibility for modules implementing `displayAdminProductsExtra` hook. + +If a module has registered a hook on `displayAdminProductsExtra`, a custom tab will be added on the new product page, handled by `ExtraModulesType`. + +{{% notice info %}} +Altough conserved for Backwards compatibility, usage of this hook (`displayAdminProductsExtra`) is not recommended for new modules. +{{% /notice %}} + +```php +public function hookDisplayAdminProductsExtra(array $params): string +{ + $productId = $params['id_product']; + $customProduct = new CustomProduct($productId); + + /** @var EngineInterface $twig */ + $twig = $this->get('twig'); + + return $twig->render('@Modules/demoproductform/views/templates/admin/extra_module.html.twig', [ + 'customProduct' => $customProduct, + ]); +} +``` + +A complete working example and implementation is available in our [example-module repository](https://github.com/PrestaShop/example-modules/tree/master/demoproductform). \ No newline at end of file From f82d2f109d2eb4ec8f11356ea117b5cfd7fb3434 Mon Sep 17 00:00:00 2001 From: Thomas Nares Date: Tue, 11 Apr 2023 18:50:32 +0200 Subject: [PATCH 276/310] Self-review fixes --- modules/sample-modules/extend-product-page.md | 22 +++++++++++++++++- .../img/productform-backward.png | Bin 40886 -> 0 bytes .../img/productform-customfield.png | Bin 18955 -> 0 bytes .../img/productform-customtab.png | Bin 15880 -> 0 bytes 4 files changed, 21 insertions(+), 1 deletion(-) delete mode 100644 modules/sample-modules/img/productform-backward.png delete mode 100644 modules/sample-modules/img/productform-customfield.png delete mode 100644 modules/sample-modules/img/productform-customtab.png diff --git a/modules/sample-modules/extend-product-page.md b/modules/sample-modules/extend-product-page.md index 78fbb5dba8..83f75630cf 100644 --- a/modules/sample-modules/extend-product-page.md +++ b/modules/sample-modules/extend-product-page.md @@ -37,6 +37,7 @@ A custom field, before {{< minver v="8.1.0" >}}, was added by hooking to one of For example, to add a custom field, in the `SEO` tab, you had to create a module with this content: `demooldhooks.php`: + ```php declare(strict_types=1); @@ -490,10 +491,29 @@ class CustomTabType extends TranslatorAwareType } ``` -Finally, add this `CustomTabType` to the `$productFormBuilder` variable in your `modify` method in the `ProductFormModifier`: +Declare your service in your `config.yml`: + +```yml +services: + DemoNewHooks\Form\Type\CustomTabType: + class: DemoNewHooks\Form\Type\CustomTabType + parent: 'form.type.translatable.aware' + public: true + arguments: + - '@=service("prestashop.adapter.data_provider.currency").getDefaultCurrency()' + tags: + - { name: form.type } +``` + +Add a `use` statement in your `ProductFormModifier`: ```php +use DemoNewHooks\Form\Type\CustomTabType; +``` +Finally, add this `CustomTabType` to the `$productFormBuilder` variable in your `modify` method in the `ProductFormModifier`: + +```php /** * @param int|null $productId * @param FormBuilderInterface $productFormBuilder diff --git a/modules/sample-modules/img/productform-backward.png b/modules/sample-modules/img/productform-backward.png deleted file mode 100644 index a89a6d67de105c6df981704c670fa554f8f818bd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 40886 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 diff --git a/modules/sample-modules/img/productform-customfield.png b/modules/sample-modules/img/productform-customfield.png deleted file mode 100644 index 62bd03907e884d5fafd13280b56081b01a271542..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18955 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 Date: Wed, 12 Apr 2023 08:42:47 +0200 Subject: [PATCH 277/310] Update modules/concepts/services/_index.md --- modules/concepts/services/_index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/concepts/services/_index.md b/modules/concepts/services/_index.md index b554a70979..2cfa6a8b62 100644 --- a/modules/concepts/services/_index.md +++ b/modules/concepts/services/_index.md @@ -247,7 +247,7 @@ As you can see, interfaces lay the ground for easy extension and customization, Since {{< minver v=8.1 >}}, [modules autoloaders and service configurations loading are now registered before compiler passes](https://github.com/PrestaShop/PrestaShop/pull/30588). That means that you can now use native Symfony service configuration features in your modules. -Those features are : +Those features are: - [applying configuration based on the extended classes or implemented interfaces](https://symfony.com/blog/new-in-symfony-3-3-simpler-service-configuration#interface-based-service-configuration) - [autoconfiguration](https://symfony.com/blog/new-in-symfony-3-3-simpler-service-configuration#interface-based-service-configuration) From 055287586627a95a0a156d20e83bde2897771bb4 Mon Sep 17 00:00:00 2001 From: Thomas NARES Date: Mon, 17 Apr 2023 08:50:00 +0200 Subject: [PATCH 278/310] Apply suggestions from code review Co-authored-by: Krystian Podemski --- modules/sample-modules/extend-product-page.md | 34 +++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/modules/sample-modules/extend-product-page.md b/modules/sample-modules/extend-product-page.md index 83f75630cf..6866ed3db0 100644 --- a/modules/sample-modules/extend-product-page.md +++ b/modules/sample-modules/extend-product-page.md @@ -23,12 +23,12 @@ The only `displayAdminProduct*` hook that was not removed is: - `displayAdminProductsExtra` {{% notice info %}} -Altough conserved for Backwards compatibility, usage of this hook (`displayAdminProductsExtra`) is not recommended for new modules. +Although kept for backward compatibility, this hook (`displayAdminProductsExtra`) is not recommended for new modules. {{% /notice %}} -In this guide, we will discover how to extend the product page by adding custom fields, in the old and new way of doing this. +In this guide, we will discover how to extend the product page by adding custom fields, in the old and new ways of doing this. -Finally, we will discover how to add a new Tab to the product page. +Finally, we will discover how to add a new tab to the product page, which is possible for a new product page from PrestaShop 8.1. ## Add a custom field, before {{< minver v="8.1.0" >}} @@ -90,7 +90,7 @@ Before {{< minver v="8.1.0" >}}, that would produce: ![custom field in SEO tab in older versions of PrestaShop](../img/old-product-form/seo-custom-field.png) -From {{< minver v="8.1.0" >}}, that would produce nothing, since this hook (`displayAdminProductsSeoStepBottom`) is no more used. +From {{< minver v="8.1.0" >}}, this field won't be displayed since this hook (`displayAdminProductsSeoStepBottom`) is no longer available. ## Add a custom field, from {{< minver v="8.1.0" >}} @@ -191,14 +191,14 @@ final class ProductFormModifier TextType::class, // your field type [ 'label' => 'SEO Special Field', // you can remove the label if you dont need it by passing 'label' => false - 'label_attr' => [ // customize label by any html attribute + 'label_attr' => [ // customize label with any HTML attribute 'title' => 'h2', 'class' => 'text-info', ], 'attr' => [ 'placeholder' => 'SEO Special field', ], - // this is just an example, but in real case scenario you could have some data provider class to wrap more complex cases + // this is just an example, but in real case scenario, you could have some data provider class to handle more complex cases 'data' => "", 'empty_data' => '', 'form_theme' => '@PrestaShop/Admin/TwigTemplateForm/prestashop_ui_kit_base.html.twig', @@ -208,7 +208,7 @@ final class ProductFormModifier } ``` -This module is creating a Form Builder Modifier (`ProductFormModifier`), adding a `TextType` field to the `seo` tab form builder from the `ProductForm Builder`, added after the `tags` form element. +This module uses a Form Builder Modifier (`FormBuilderModifier `), and adds a `TextType` field to the `SEO` tab form builder from the `ProductForm Builder`, after the existing `tags` form element. This Form Builder Modifier is hooked to the `actionProductFormBuilderModifier` hook. @@ -217,7 +217,7 @@ This produces this form: ![custom field in SEO tab in newer versions of PrestaShop](../img/new-product-form/seo-custom-field.png) {{% notice note %}} -This new way of adding custom fields to the product page allows you for more precise positioning, you can now position your fields/forms exactly where you want. +This new way of adding custom fields to the product page allows you for more precise positioning. You can now position your fields/forms exactly where you want. {{% /notice %}} ## Cheatsheet for old hooks / new hooks @@ -241,9 +241,9 @@ This new way of adding custom fields to the product page allows you for more pre Form Type details: [`EditProductFormType`](https://github.com/PrestaShop/PrestaShop/blob/8.1.0-beta.1/src/PrestaShopBundle/Form/Admin/Sell/Product/EditProductFormType.php) -## Extend a sub form +## Extend a subform -Sub forms can be extended aswell, for example, to add a new input on each combination of a product: +Subforms can be extended as well, for example, to add a new input on each combination of a product: - Hook to actionProductCombinationFormBuilderModifier ([`actionFormBuilderModifier`]({{< relref "/8/modules/concepts/hooks/list-of-hooks/actionFormBuilderModifier" >}})) @@ -320,11 +320,11 @@ A complete working example and implementation is available in our [example-modul ## Add a custom Tab to Product Page -{{< minver v="8.1.0" >}} introduced a new feature : Custom tabs in product page. +{{< minver v="8.1.0" >}} introduced a new feature: custom tabs on the product page. -A complete working example and implementation is available in our [example-module repository](https://github.com/PrestaShop/example-modules/tree/master/demoproductform). +A complete working example of implementation is available in our [example-module repository](https://github.com/PrestaShop/example-modules/tree/master/demoproductform). -- Modify the Product Form builder with `actionProductFormBuilderModifier` hook, and create a modifier: +- You can extend the product form builder with `actionProductFormBuilderModifier` hook with a created modifier: `demonewhooks.php`: @@ -541,17 +541,17 @@ public function modify( ``` {{% notice note %}} -Any type added directly to the `$productFormBuilder` (and not to a sub tab) will be considered as a tab. +Any type added directly to the `$productFormBuilder` (and not to a sub-tab) will be considered as a tab. {{% /notice %}} ## Backwards compatibility for displayAdminProductsExtra hook -A custom Form Type `ExtraModulesType` as been added to {{< minver v="8.1.0" >}}, to allow backwards compatibility for modules implementing `displayAdminProductsExtra` hook. +A custom Form Type `ExtraModulesType` has been added to {{< minver v="8.1.0" >}}, to allow backward compatibility for modules implementing `displayAdminProductsExtra` hook. -If a module has registered a hook on `displayAdminProductsExtra`, a custom tab will be added on the new product page, handled by `ExtraModulesType`. +If a module registers to `displayAdminProductsExtra` hook, a custom tab will be added on the new product page, handled by `ExtraModulesType`. {{% notice info %}} -Altough conserved for Backwards compatibility, usage of this hook (`displayAdminProductsExtra`) is not recommended for new modules. +Although kept for backward compatibility, this hook (`displayAdminProductsExtra`) is not recommended for new modules. {{% /notice %}} ```php From e92755bc28443e453137af00455f09e4ec4c2b3e Mon Sep 17 00:00:00 2001 From: Thomas Nares Date: Mon, 17 Apr 2023 15:09:24 +0200 Subject: [PATCH 279/310] add handler informations and map pages --- .../list-of-hooks/actionFormBuilderModifier.md | 4 +++- .../actionAfterUpdateFormHandler.md | 4 +++- modules/core-updates/8.1.md | 7 ++++++- modules/sample-modules/extend-product-page.md | 8 ++++++-- 4 files changed, 18 insertions(+), 5 deletions(-) diff --git a/modules/concepts/hooks/list-of-hooks/actionFormBuilderModifier.md b/modules/concepts/hooks/list-of-hooks/actionFormBuilderModifier.md index 6d33e56353..18d4dea813 100644 --- a/modules/concepts/hooks/list-of-hooks/actionFormBuilderModifier.md +++ b/modules/concepts/hooks/list-of-hooks/actionFormBuilderModifier.md @@ -52,4 +52,6 @@ This hook has been implemented as an example in our [modules examples repository This hook has been implemented as an example in our [modules examples repository - demoextendsymfonyform3](https://github.com/PrestaShop/example-modules/tree/master/demoextendsymfonyform3). -This hook has been implemented as an example in our [modules examples repository - demoproductform](https://github.com/PrestaShop/example-modules/tree/master/demoproductform). \ No newline at end of file +This hook has been implemented as an example in our [modules examples repository - demoproductform](https://github.com/PrestaShop/example-modules/tree/master/demoproductform). + +This hook has been described in the context of Product Page in Back Office in [Extending the new product page form page]({{< relref "/8/modules/sample-modules/extend-product-page" >}}) \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionAfterUpdateFormHandler.md b/modules/concepts/hooks/list-of-hooks/actionAfterUpdateFormHandler.md index 86a8ac1fe1..7dd78ab963 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAfterUpdateFormHandler.md +++ b/modules/concepts/hooks/list-of-hooks/actionAfterUpdateFormHandler.md @@ -39,4 +39,6 @@ This hook has been implemented as an example in our [modules examples repository This hook has been implemented as an example in our [modules examples repository - demoextendsymfonyform2](https://github.com/PrestaShop/example-modules/tree/master/demoextendsymfonyform2). -This hook has been implemented as an example in our [modules examples repository - demoextendsymfonyform3](https://github.com/PrestaShop/example-modules/tree/master/demoextendsymfonyform3). \ No newline at end of file +This hook has been implemented as an example in our [modules examples repository - demoextendsymfonyform3](https://github.com/PrestaShop/example-modules/tree/master/demoextendsymfonyform3). + +This hook has been implemented as an example in our [modules examples repository - demoproductform](https://github.com/PrestaShop/example-modules/tree/master/demoproductform). \ No newline at end of file diff --git a/modules/core-updates/8.1.md b/modules/core-updates/8.1.md index a96589ce6f..42de965866 100644 --- a/modules/core-updates/8.1.md +++ b/modules/core-updates/8.1.md @@ -19,6 +19,10 @@ PrestaShop 8.1 has the same PHP requirement as Prestashop 8.0. [PrestaShop 8.0][80-changes] added support for PHP 8.0 and PHP 8.1 and required at least PHP 7.2.5. +## New product page + +The new Product page in Back Office has been introduced. [Discover how to extend it with modules in this chapter][new-product-page]. + ## Notable changes * Introduction of `_raw` parameter on translations to avoid html escaping in translator. [PR#30415](https://github.com/PrestaShop/PrestaShop/pull/30415) @@ -95,4 +99,5 @@ Please refer to: [PR#28463](https://github.com/PrestaShop/PrestaShop/pull/28463) {{% /notice %}} [80-changes]: {{< relref "8/modules/core-updates/8.0.md" >}} -[corejs-informations]: {{< relref "8/themes/getting-started/theme-yml" >}} \ No newline at end of file +[corejs-informations]: {{< relref "8/themes/getting-started/theme-yml" >}} +[new-product-page]: {{< relref "8/modules/sample-modules/extend-product-page" >}} \ No newline at end of file diff --git a/modules/sample-modules/extend-product-page.md b/modules/sample-modules/extend-product-page.md index 6866ed3db0..002ad9ac7d 100644 --- a/modules/sample-modules/extend-product-page.md +++ b/modules/sample-modules/extend-product-page.md @@ -208,7 +208,7 @@ final class ProductFormModifier } ``` -This module uses a Form Builder Modifier (`FormBuilderModifier `), and adds a `TextType` field to the `SEO` tab form builder from the `ProductForm Builder`, after the existing `tags` form element. +This module uses a Form Builder Modifier (`FormBuilderModifier`), and adds a `TextType` field to the `SEO` tab form builder from the `ProductForm Builder`, after the existing `tags` form element. This Form Builder Modifier is hooked to the `actionProductFormBuilderModifier` hook. @@ -569,4 +569,8 @@ public function hookDisplayAdminProductsExtra(array $params): string } ``` -A complete working example and implementation is available in our [example-module repository](https://github.com/PrestaShop/example-modules/tree/master/demoproductform). \ No newline at end of file +A complete working example and implementation is available in our [example-module repository](https://github.com/PrestaShop/example-modules/tree/master/demoproductform). + +## Handle data modified by FormBuilderModifier + +You need to implement the corresponding [`actionAfterCreateFormHandler`]({{< relref "/8/modules/concepts/hooks/list-of-hooks/actionAfterCreateFormHandler" >}}) or [`actionAfterUpdateFormHandler`]({{< relref "/8/modules/concepts/hooks/list-of-hooks/actionAfterUpdateFormHandler" >}}) hook, as shown in our [example-module repository](https://github.com/PrestaShop/example-modules/tree/master/demoproductform). \ No newline at end of file From 63dc5ec8b9abee836d0db41b448d7941066f32ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?fabien=20Verni=C3=A8res?= <106905008+fabienVernieres@users.noreply.github.com> Date: Mon, 17 Apr 2023 17:31:49 +0200 Subject: [PATCH 280/310] Template display.tpl must extend page.tpl Currently the template displays raw non-nested content. --- modules/creation/displaying-content-in-front-office.md | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/modules/creation/displaying-content-in-front-office.md b/modules/creation/displaying-content-in-front-office.md index ea1e84e9c0..7a68d6ee5f 100644 --- a/modules/creation/displaying-content-in-front-office.md +++ b/modules/creation/displaying-content-in-front-office.md @@ -309,7 +309,10 @@ class mymoduledisplayModuleFrontController extends ModuleFrontController - *display.tpl* ``` -Welcome to my shop! +{extends file='page.tpl'} +{block name='page_content'} + Welcome to my shop! +{/block} ``` Let's explore `display.php`, our first PrestaShop front-end controller, @@ -391,7 +394,10 @@ in our TPL file. - *mymodule.tpl* ``` -{$my_module_message} +{extends file='page.tpl'} +{block name='page_content'} + {$my_module_message} +{/block} ``` PrestaShop adds its own set of variables. For instance, From a9c48f7b64d04c05c8a259405eaeab02ec2e293c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?fabien=20Verni=C3=A8res?= <106905008+fabienVernieres@users.noreply.github.com> Date: Tue, 18 Apr 2023 16:24:14 +0200 Subject: [PATCH 281/310] Update modules/creation/displaying-content-in-front-office.md Co-authored-by: Krystian Podemski --- modules/creation/displaying-content-in-front-office.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/creation/displaying-content-in-front-office.md b/modules/creation/displaying-content-in-front-office.md index 7a68d6ee5f..bdaf1e1b49 100644 --- a/modules/creation/displaying-content-in-front-office.md +++ b/modules/creation/displaying-content-in-front-office.md @@ -393,7 +393,7 @@ in our TPL file. - *mymodule.tpl* -``` +```smarty {extends file='page.tpl'} {block name='page_content'} {$my_module_message} From ad4b2bea0d37bc39cf5b0e570a4a276cc24367b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?fabien=20Verni=C3=A8res?= <106905008+fabienVernieres@users.noreply.github.com> Date: Tue, 18 Apr 2023 16:24:34 +0200 Subject: [PATCH 282/310] Update modules/creation/displaying-content-in-front-office.md Co-authored-by: Krystian Podemski --- modules/creation/displaying-content-in-front-office.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/creation/displaying-content-in-front-office.md b/modules/creation/displaying-content-in-front-office.md index bdaf1e1b49..75479654b2 100644 --- a/modules/creation/displaying-content-in-front-office.md +++ b/modules/creation/displaying-content-in-front-office.md @@ -308,7 +308,7 @@ class mymoduledisplayModuleFrontController extends ModuleFrontController - *display.tpl* -``` +```smarty {extends file='page.tpl'} {block name='page_content'} Welcome to my shop! From d697b5be53968474c96d2a40b3d809d735f10736 Mon Sep 17 00:00:00 2001 From: Thomas Nares Date: Tue, 18 Apr 2023 20:23:16 +0200 Subject: [PATCH 283/310] Almost finished page for PrestaShopCollection --- .../database/prestashopcollection.md | 213 ++++++++++++++++++ 1 file changed, 213 insertions(+) diff --git a/development/components/database/prestashopcollection.md b/development/components/database/prestashopcollection.md index bc131d04b8..cf3c1524a1 100644 --- a/development/components/database/prestashopcollection.md +++ b/development/components/database/prestashopcollection.md @@ -6,4 +6,217 @@ title: PrestaShopCollection class ## Introduction +The PrestaShopCollection component is a Collection of ObjectModel objects. It implements common useful `php` interfaces: +- `Iterator`: allows for `foreach` loop on the Collection +- `ArrayAccess`: allows for offset/index access on the Collection +- `Countable`: allow for `count()` function to be used on the Collection + +It eases fetching / filtering selections of ObjectModel objects. + +```php +use PrestaShopCollection; + +$productCollection = new PrestaShopCollection('Product') + ->where('on_sale', '=', true) + ->orderBy('reference', 'desc') + ->setPageSize(100); + +if(count($productCollection) > 0){ + foreach($productCollection as $product){ + // do something with your product + } +} + +``` + +## Create a PrestaShopCollection + +To create a PrestaShopCollection, simply instanciate a PrestaShopCollection with the ObjectModel type as constructor parameter. + +```php +use PrestaShopCollection; + +$productCollection = new PrestaShopCollection('Product'); +``` + +A second parameter can be used, to set the id of the lang to use (`$id_lang`), set at null by default. + +```php +use PrestaShopCollection; + +$idLang=1; +$productCollection = new PrestaShopCollection('Product', $idLang); +``` + +## Get results, count results + +When your collection is created, you may need to get its content. Several methods are available to retrieve its content: + +- `getFirst()`: gets first item of the Collection +- `getLast()`: gets last item of the Collection + +```php +$productCollection = new PrestaShopCollection('Product'); + +$firstProduct = $productCollection->getFirst(); +$lastProduct = $productCollection->getLast(); + +// you can access items in the collection by offset, like a regular array (the class implements ArrayAccess). Index starts at 0 +$thirdProduct = $productCollection[2]; + +// The collection is also iterable (the class implements Iterator): +foreach($productCollection as $product){ + +} + +// Or you can use the count() function (the class implements Countable): +count($productCollection); +``` + +## Joining to associated entities (join) + +When building the Collection, you may need to join with other ObjectModel entities. +You can join on associations that are declared in the $definition of the ObjectModel. + +```php +public function join($association, $on = '', $type = null) +``` + +Join `manufacturer` to your `Product` collection: + +```php +$productCollection = new PrestaShopCollection('Product'); +$productCollection->join('manufacturer'); +``` + +You can join on a different field by specifying the field name as a second parameter: + +```php +$productCollection = new PrestaShopCollection('Product'); +$productCollection->join('categories', 'id_category'); +``` + +By default, a `LEFT JOIN` will be used. `INNER JOIN` or `LEFT OUTER JOIN` are also available using the third parameter: + +```php +$productCollection->join('categories', 'id_category', PrestaShopCollection::LEFT_JOIN); +$productCollection->join('categories', 'id_category', PrestaShopCollection::INNER_JOIN); +$productCollection->join('categories', 'id_category', PrestaShopCollection::LEFT_OUTER_JOIN); +``` + +## Filtering a Collection (where, having) + +When building the Collection, you may need to filter its content. To do so, use the `where()` method. + +```php +public function where($field, $operator, $value, $method = 'where') +``` + +- `$field` is the field's name to filter +- `$operator` is the operator to use for filtering (complete list below) +- `$value` is the value to filter against (can be a scalar or array value) +- `$method` is the method to use (defaults to `where`, or can be `having`, see below for more informations) + +### List of operators + +| Operator | SQL equivalent | Accept | +| --- | --- | --- | +| = | = | Scalar, Array | +| in | IN | Array | +| != | != | Scalar, Array | +| <> | != | Scalar, Array | +| notin (or NOTIN) | NOT IN | Scalar, Array | +| > | > | Scalar | +| >= | >= | Scalar | +| < | < | Scalar | +| <= | <= | Scalar | +| like (or LIKE) | LIKE | Scalar | +| notlike (or NOTLIKE) | NOT LIKE | Scalar | +| regexp (or REGEXP) | REGEXP | Scalar | +| notregexp (or NOTREGEXP) | NOT REGEXP | Scalar | + +### Examples of usage + +```php +$productCollection = new PrestaShopCollection('Product'); +$productCollection->where('on_sale', '=', true); // find products on sale +``` + +```php +$productCollection = new PrestaShopCollection('Product'); +$productCollection->where('reference', 'LIKE', 'REF-%'); // find products with reference beginning by "REF-" +``` + +### Having method + +Another method is available, `having()`, which calls `where()` with the parameter `$method` set to `having`. + +```php +public function having($field, $operator, $value) +``` + +## Ordering a Collection (order by) + +To order your collection, use the `orderBy()` method. + +```php +public function orderBy($field, $order = 'asc') +``` + +Ordering can be done in ascending or descending, with `asc` or `desc` `$order` parameter. + +```php +$productCollection = new PrestaShopCollection('Product'); +$productCollection->orderBy('reference', 'desc'); +``` + +## Grouping (group by) + +To group your collection items on a field, use the `groupBy()` method. + +```php +public function groupBy($field) +``` + +```php +$productCollection = new PrestaShopCollection('Product'); +$productCollection->groupBy('id_supplier'); +``` + +## Paginating a Collection (offset / limit) + +When fetching large quantities of items, you may need to paginate your collection, with SQL `OFFSET / LIMIT` equivalent mecanismes. + +To do so, use those two methods: + +```php +public function setPageNumber($page_number) +public function setPageSize($page_size) +``` + +To use this feature, first, set the $page_size: + +```php +$productCollection = new PrestaShopCollection('Product'); +$productCollection->setPageSize(100); // will get only 100 items +``` + +If only `$page_size` is set, the collection will return the first `$page_size` items. + +To do a pagination, and get the page 2 of the collection, use the following example: + +```php +$productCollection = new PrestaShopCollection('Product'); +$productCollection->setPageSize(100); // will get only 100 items +$productCollection->setPageNumber(2); // but from page 2, equivalent to offset=(pageNumber - 1) * page_size. +``` + +- Getting the page: `1` of a collection with a page_size of: `100` is the `PrestaShopCollection` equivalent of this `SQL` statement: + `LIMIT 100` or `LIMIT 100 OFFSET 0` or `LIMIT 0,100` + +- Getting the page: `2` of a collection with a page_size of: `100` is the `PrestaShopCollection` equivalent of this `SQL` statement: + `LIMIT 100 OFFSET 100` or `LIMIT 100,100` + +- Getting the page: `3` of a collection with a page_size of: `100` is the `PrestaShopCollection` equivalent of this `SQL` statement: + `LIMIT 100 OFFSET 200` or `LIMIT 200,100` \ No newline at end of file From bf3c38696b54d1add530cbc336918c9549935550 Mon Sep 17 00:00:00 2001 From: Thomas Nares Date: Wed, 19 Apr 2023 10:12:14 +0200 Subject: [PATCH 284/310] Finish collection doc --- .../database/prestashopcollection.md | 97 +++++++++++-------- 1 file changed, 55 insertions(+), 42 deletions(-) diff --git a/development/components/database/prestashopcollection.md b/development/components/database/prestashopcollection.md index cf3c1524a1..5e64d9dc10 100644 --- a/development/components/database/prestashopcollection.md +++ b/development/components/database/prestashopcollection.md @@ -17,7 +17,7 @@ It eases fetching / filtering selections of ObjectModel objects. ```php use PrestaShopCollection; -$productCollection = new PrestaShopCollection('Product') +$productCollection = (new PrestaShopCollection('Product')) ->where('on_sale', '=', true) ->orderBy('reference', 'desc') ->setPageSize(100); @@ -27,7 +27,6 @@ if(count($productCollection) > 0){ // do something with your product } } - ``` ## Create a PrestaShopCollection @@ -49,6 +48,10 @@ $idLang=1; $productCollection = new PrestaShopCollection('Product', $idLang); ``` +{{% notice note %}} +Using `$id_lang` parameter will allow to set a Lang Context when querying / filtering multilang fields. If not set, multilang fields will be returned as `array` in the Collection. +{{% /notice %}} + ## Get results, count results When your collection is created, you may need to get its content. Several methods are available to retrieve its content: @@ -74,37 +77,6 @@ foreach($productCollection as $product){ count($productCollection); ``` -## Joining to associated entities (join) - -When building the Collection, you may need to join with other ObjectModel entities. -You can join on associations that are declared in the $definition of the ObjectModel. - -```php -public function join($association, $on = '', $type = null) -``` - -Join `manufacturer` to your `Product` collection: - -```php -$productCollection = new PrestaShopCollection('Product'); -$productCollection->join('manufacturer'); -``` - -You can join on a different field by specifying the field name as a second parameter: - -```php -$productCollection = new PrestaShopCollection('Product'); -$productCollection->join('categories', 'id_category'); -``` - -By default, a `LEFT JOIN` will be used. `INNER JOIN` or `LEFT OUTER JOIN` are also available using the third parameter: - -```php -$productCollection->join('categories', 'id_category', PrestaShopCollection::LEFT_JOIN); -$productCollection->join('categories', 'id_category', PrestaShopCollection::INNER_JOIN); -$productCollection->join('categories', 'id_category', PrestaShopCollection::LEFT_OUTER_JOIN); -``` - ## Filtering a Collection (where, having) When building the Collection, you may need to filter its content. To do so, use the `where()` method. @@ -156,6 +128,47 @@ Another method is available, `having()`, which calls `where()` with the paramete public function having($field, $operator, $value) ``` +## Joining to associated entities (join) + +When building the Collection, you may need to join with other ObjectModel entities. +You can join on associations that are declared in the $definition of the ObjectModel. + +```php +public function join($association, $on = '', $type = null) +``` + +Join `manufacturer` to your `Product` collection: + +```php +$productCollection = new PrestaShopCollection('Product'); +$productCollection->join('manufacturer'); +``` + +You can join on a different field by specifying the field name as a second parameter: + +```php +$productCollection = new PrestaShopCollection('Product'); +$productCollection->join('categories', 'id_category'); +``` + +By default, a `LEFT JOIN` will be used. `INNER JOIN` or `LEFT OUTER JOIN` are also available using the third parameter: + +```php +$productCollection->join('categories', 'id_category', PrestaShopCollection::LEFT_JOIN); +$productCollection->join('categories', 'id_category', PrestaShopCollection::INNER_JOIN); +$productCollection->join('categories', 'id_category', PrestaShopCollection::LEFT_OUTER_JOIN); +``` + +### Using where with join + +One of the interest of joining other ObjectModel entities to your collection, is the possibility to filter on the external entity with `where()`. + +```php +$productCollection = (new PrestaShopCollection('Product')) + ->join('manufacturer') + ->where('manufacturer.name', '=', 'Manufacturer AAA'); +``` + ## Ordering a Collection (order by) To order your collection, use the `orderBy()` method. @@ -167,8 +180,8 @@ public function orderBy($field, $order = 'asc') Ordering can be done in ascending or descending, with `asc` or `desc` `$order` parameter. ```php -$productCollection = new PrestaShopCollection('Product'); -$productCollection->orderBy('reference', 'desc'); +$productCollection = (new PrestaShopCollection('Product')) + ->orderBy('reference', 'desc'); ``` ## Grouping (group by) @@ -180,8 +193,8 @@ public function groupBy($field) ``` ```php -$productCollection = new PrestaShopCollection('Product'); -$productCollection->groupBy('id_supplier'); +$productCollection = (new PrestaShopCollection('Product')) + ->groupBy('id_supplier'); ``` ## Paginating a Collection (offset / limit) @@ -198,8 +211,8 @@ public function setPageSize($page_size) To use this feature, first, set the $page_size: ```php -$productCollection = new PrestaShopCollection('Product'); -$productCollection->setPageSize(100); // will get only 100 items +$productCollection = (new PrestaShopCollection('Product')) + ->setPageSize(100); // will get only 100 items ``` If only `$page_size` is set, the collection will return the first `$page_size` items. @@ -207,9 +220,9 @@ If only `$page_size` is set, the collection will return the first `$page_size` i To do a pagination, and get the page 2 of the collection, use the following example: ```php -$productCollection = new PrestaShopCollection('Product'); -$productCollection->setPageSize(100); // will get only 100 items -$productCollection->setPageNumber(2); // but from page 2, equivalent to offset=(pageNumber - 1) * page_size. +$productCollection = (new PrestaShopCollection('Product')) + ->setPageSize(100) // will get only 100 items + ->setPageNumber(2); // but from page 2, equivalent to offset=(pageNumber - 1) * page_size. ``` - Getting the page: `1` of a collection with a page_size of: `100` is the `PrestaShopCollection` equivalent of this `SQL` statement: From 1bd8698767ae0582ef7c88f2408031ea7b2955d9 Mon Sep 17 00:00:00 2001 From: Thomas Nares Date: Wed, 19 Apr 2023 10:32:40 +0200 Subject: [PATCH 285/310] Add known issue when paginating --- .../components/database/prestashopcollection.md | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/development/components/database/prestashopcollection.md b/development/components/database/prestashopcollection.md index 5e64d9dc10..469dd96bd9 100644 --- a/development/components/database/prestashopcollection.md +++ b/development/components/database/prestashopcollection.md @@ -58,6 +58,7 @@ When your collection is created, you may need to get its content. Several method - `getFirst()`: gets first item of the Collection - `getLast()`: gets last item of the Collection +- or simply access items via index, or iterate with `foreach` ```php $productCollection = new PrestaShopCollection('Product'); @@ -65,7 +66,7 @@ $productCollection = new PrestaShopCollection('Product'); $firstProduct = $productCollection->getFirst(); $lastProduct = $productCollection->getLast(); -// you can access items in the collection by offset, like a regular array (the class implements ArrayAccess). Index starts at 0 +// you can access items in the collection by index, like a regular array (the class implements ArrayAccess). Index starts at 0 $thirdProduct = $productCollection[2]; // The collection is also iterable (the class implements Iterator): @@ -177,7 +178,7 @@ To order your collection, use the `orderBy()` method. public function orderBy($field, $order = 'asc') ``` -Ordering can be done in ascending or descending, with `asc` or `desc` `$order` parameter. +Ordering can be done in ascending or descending direction, with `asc` or `desc` `$order` parameter. ```php $productCollection = (new PrestaShopCollection('Product')) @@ -232,4 +233,8 @@ $productCollection = (new PrestaShopCollection('Product')) `LIMIT 100 OFFSET 100` or `LIMIT 100,100` - Getting the page: `3` of a collection with a page_size of: `100` is the `PrestaShopCollection` equivalent of this `SQL` statement: - `LIMIT 100 OFFSET 200` or `LIMIT 200,100` \ No newline at end of file + `LIMIT 100 OFFSET 200` or `LIMIT 200,100` + +{{% notice info %}} +Known issue: When not using `$id_lang`, and using pagination (`setPageSize()`, `setPageNumber()`), pagination will be broken. Please use a Lang Context if the entity is multi-lang enabled. +{{% /notice %}} \ No newline at end of file From d886d28a71c4866f91b56d6d09148bad16adba68 Mon Sep 17 00:00:00 2001 From: Krystian Podemski Date: Wed, 19 Apr 2023 12:17:05 +0200 Subject: [PATCH 286/310] minor improvements --- modules/sample-modules/extend-product-page.md | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/modules/sample-modules/extend-product-page.md b/modules/sample-modules/extend-product-page.md index 002ad9ac7d..3f2d3ee8d0 100644 --- a/modules/sample-modules/extend-product-page.md +++ b/modules/sample-modules/extend-product-page.md @@ -5,7 +5,7 @@ weight: 3 # Extending the new product page form {{< minver v="8.1.0" >}} -The new Back Office product page introduced in {{< minver v="8.1.0" >}} removed several hooks previously available: +The new Back Office product page introduced in {{< minver v="8.1.0" >}} removed several hooks which were previously available on the page. Complete list of removed hooks: - `displayAdminProductsCombinationBottom` - `displayAdminProductsSeoStepBottom` @@ -32,7 +32,7 @@ Finally, we will discover how to add a new tab to the product page, which is pos ## Add a custom field, before {{< minver v="8.1.0" >}} -A custom field, before {{< minver v="8.1.0" >}}, was added by hooking to one of the `displayAdminProducts` hook. +A custom field, before {{< minver v="8.1.0" >}}, was added by hooking to one of the `displayAdminProducts` hooks. For example, to add a custom field, in the `SEO` tab, you had to create a module with this content: @@ -88,13 +88,13 @@ class DemoOldHooks extends Module Before {{< minver v="8.1.0" >}}, that would produce: -![custom field in SEO tab in older versions of PrestaShop](../img/old-product-form/seo-custom-field.png) +![Custom field in SEO tab in older versions of PrestaShop](../img/old-product-form/seo-custom-field.png) -From {{< minver v="8.1.0" >}}, this field won't be displayed since this hook (`displayAdminProductsSeoStepBottom`) is no longer available. +From {{< minver v="8.1.0" >}}, this field won't be displayed as a hook (`displayAdminProductsSeoStepBottom`) is no longer available. ## Add a custom field, from {{< minver v="8.1.0" >}} -To do exactly the same, from {{< minver v="8.1.0" >}}, we will implement `actionProductFormBuilderModifier` hook and modify the Product FormBuilder. +To do exactly the same, from {{< minver v="8.1.0" >}}, we will implement `actionProductFormBuilderModifier` hook and modify product's FormBuilder. First, create a module, with a `composer.json` file, [as instructed here]({{< relref "/8/modules/concepts/composer" >}}). @@ -208,19 +208,19 @@ final class ProductFormModifier } ``` -This module uses a Form Builder Modifier (`FormBuilderModifier`), and adds a `TextType` field to the `SEO` tab form builder from the `ProductForm Builder`, after the existing `tags` form element. +This module uses a Form Builder Modifier (`FormBuilderModifier`), and adds a `TextType` field to the `SEO` tab form, after the existing `tags` form element. -This Form Builder Modifier is hooked to the `actionProductFormBuilderModifier` hook. +`FormBuilderModifier` is hooked to the `actionProductFormBuilderModifier`. -This produces this form: +These changes produces the below's: -![custom field in SEO tab in newer versions of PrestaShop](../img/new-product-form/seo-custom-field.png) +![Custom field in SEO tab in newer versions of PrestaShop](../img/new-product-form/seo-custom-field.png) {{% notice note %}} This new way of adding custom fields to the product page allows you for more precise positioning. You can now position your fields/forms exactly where you want. {{% /notice %}} -## Cheatsheet for old hooks / new hooks +## Cheatsheet for old/new hooks / new hooks ### Hook: actionProductFormBuilderModifier @@ -318,7 +318,7 @@ class CombinationFormModifier This example will add a `TextType` input on each `Combination` of a `Product`. A complete working example and implementation is available in our [example-module repository](https://github.com/PrestaShop/example-modules/tree/master/demoproductform). -## Add a custom Tab to Product Page +## Add a custom tab to the product page {{< minver v="8.1.0" >}} introduced a new feature: custom tabs on the product page. @@ -573,4 +573,4 @@ A complete working example and implementation is available in our [example-modul ## Handle data modified by FormBuilderModifier -You need to implement the corresponding [`actionAfterCreateFormHandler`]({{< relref "/8/modules/concepts/hooks/list-of-hooks/actionAfterCreateFormHandler" >}}) or [`actionAfterUpdateFormHandler`]({{< relref "/8/modules/concepts/hooks/list-of-hooks/actionAfterUpdateFormHandler" >}}) hook, as shown in our [example-module repository](https://github.com/PrestaShop/example-modules/tree/master/demoproductform). \ No newline at end of file +You need to implement the corresponding [`actionAfterCreateFormHandler`]({{< relref "/8/modules/concepts/hooks/list-of-hooks/actionAfterCreateFormHandler" >}}) or [`actionAfterUpdateFormHandler`]({{< relref "/8/modules/concepts/hooks/list-of-hooks/actionAfterUpdateFormHandler" >}}) hook, as shown in our [example-module repository](https://github.com/PrestaShop/example-modules/tree/master/demoproductform). From f3bdcd34f3419d0f1ef584dfc1fa92e6a2ee6c5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?fabien=20Verni=C3=A8res?= <106905008+fabienVernieres@users.noreply.github.com> Date: Wed, 19 Apr 2023 17:20:29 +0200 Subject: [PATCH 287/310] Bad relativePath --- modules/creation/displaying-content-in-front-office.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/creation/displaying-content-in-front-office.md b/modules/creation/displaying-content-in-front-office.md index 75479654b2..e9adc7414a 100644 --- a/modules/creation/displaying-content-in-front-office.md +++ b/modules/creation/displaying-content-in-front-office.md @@ -64,7 +64,7 @@ Add the following to your mymodule.php file: { $this->context->controller->registerStylesheet( 'mymodule-style', - $this->_path.'views/css/mymodule.css', + 'modules/' . $this->name .'/views/css/mymodule.css', [ 'media' => 'all', 'priority' => 1000, @@ -73,7 +73,7 @@ Add the following to your mymodule.php file: $this->context->controller->registerJavascript( 'mymodule-javascript', - $this->_path.'views/js/mymodule.js', + 'modules/' . $this->name .'/views/js/mymodule.js', [ 'position' => 'bottom', 'priority' => 1000, From 2bd6bd9cc2b746a17a31997ffc26911bbab5d6eb Mon Sep 17 00:00:00 2001 From: Krystian Podemski Date: Wed, 19 Apr 2023 20:39:12 +0200 Subject: [PATCH 288/310] Apply suggestions from code review --- modules/creation/displaying-content-in-front-office.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/creation/displaying-content-in-front-office.md b/modules/creation/displaying-content-in-front-office.md index e9adc7414a..02b545c9ec 100644 --- a/modules/creation/displaying-content-in-front-office.md +++ b/modules/creation/displaying-content-in-front-office.md @@ -64,7 +64,7 @@ Add the following to your mymodule.php file: { $this->context->controller->registerStylesheet( 'mymodule-style', - 'modules/' . $this->name .'/views/css/mymodule.css', + 'modules/' . $this->name . '/views/css/mymodule.css', [ 'media' => 'all', 'priority' => 1000, @@ -73,7 +73,7 @@ Add the following to your mymodule.php file: $this->context->controller->registerJavascript( 'mymodule-javascript', - 'modules/' . $this->name .'/views/js/mymodule.js', + 'modules/' . $this->name . '/views/js/mymodule.js', [ 'position' => 'bottom', 'priority' => 1000, From 4afe64482704369ae53c6c7d9d85ad546e66387b Mon Sep 17 00:00:00 2001 From: Krystian Podemski Date: Thu, 20 Apr 2023 10:32:23 +0200 Subject: [PATCH 289/310] Example implementation of hookActionModifyFrontendSitemap --- .../actionModifyFrontendSitemap.md | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/modules/concepts/hooks/list-of-hooks/actionModifyFrontendSitemap.md b/modules/concepts/hooks/list-of-hooks/actionModifyFrontendSitemap.md index dfb53b92f2..ba6c134860 100644 --- a/modules/concepts/hooks/list-of-hooks/actionModifyFrontendSitemap.md +++ b/modules/concepts/hooks/list-of-hooks/actionModifyFrontendSitemap.md @@ -42,4 +42,22 @@ Hook::exec( null, true ); -``` \ No newline at end of file +``` + +## Example implementation + +```php +public function hookActionModifyFrontendSitemap($params) +{ + $customUrls = [ + [ + 'id' => 'custom-url-1', + 'label' => 'Custom URL', + 'url' => 'https://prestashop-project.org', + ] + ]; + + $params['urls']['pages']['links'] = array_merge($params['urls']['pages']['links'], $customUrls); // add custom urls to pages group + unset($params['urls']['categories']); // hide categories +} +``` From 7fea63c88b211857dc6b776168b15ff7c8de24a6 Mon Sep 17 00:00:00 2001 From: Krystian Podemski Date: Thu, 20 Apr 2023 10:33:16 +0200 Subject: [PATCH 290/310] set hasExample flag --- .../concepts/hooks/list-of-hooks/actionModifyFrontendSitemap.md | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/concepts/hooks/list-of-hooks/actionModifyFrontendSitemap.md b/modules/concepts/hooks/list-of-hooks/actionModifyFrontendSitemap.md index ba6c134860..cf42620d86 100644 --- a/modules/concepts/hooks/list-of-hooks/actionModifyFrontendSitemap.md +++ b/modules/concepts/hooks/list-of-hooks/actionModifyFrontendSitemap.md @@ -9,6 +9,7 @@ locations: - front office type: action hookAliases: +hasExample: true --- # Hook actionModifyFrontendSitemap {{< minver v="8.1" >}} From 9a7642f38cb859194495c00c51b2549c340b50c6 Mon Sep 17 00:00:00 2001 From: Krystian Podemski Date: Thu, 20 Apr 2023 10:35:33 +0200 Subject: [PATCH 291/310] change autoupgrade module URL --- basics/keeping-up-to-date/upgrade-module/upgrade-cli.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/basics/keeping-up-to-date/upgrade-module/upgrade-cli.md b/basics/keeping-up-to-date/upgrade-module/upgrade-cli.md index 6c338df96d..42cab0291b 100644 --- a/basics/keeping-up-to-date/upgrade-module/upgrade-cli.md +++ b/basics/keeping-up-to-date/upgrade-module/upgrade-cli.md @@ -77,7 +77,7 @@ To upgrade your PrestaShop store to the latest version using the command line in 1. Download the latest version of the autoupgrade module and place it in the /modules directory: -`curl -L https://github.com/PrestaShop/autoupgrade/releases/download/v4.15.0/autoupgrade.zip -o modules/autoupgrade.zip && unzip modules/autoupgrade.zip` +`curl -L https://github.com/PrestaShop/autoupgrade/releases/latest/download/autoupgrade.zip -o modules/autoupgrade.zip && unzip modules/autoupgrade.zip` 2. Install the new version of the autoupgrade module: From 327dab098c3ed53b381f6c075128ea33f282c498 Mon Sep 17 00:00:00 2001 From: Thomas NARES Date: Mon, 24 Apr 2023 08:41:34 +0200 Subject: [PATCH 292/310] Apply suggestions from code review Co-authored-by: Krystian Podemski --- .../database/prestashopcollection.md | 44 +++++++++---------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/development/components/database/prestashopcollection.md b/development/components/database/prestashopcollection.md index 469dd96bd9..73302ca13e 100644 --- a/development/components/database/prestashopcollection.md +++ b/development/components/database/prestashopcollection.md @@ -6,7 +6,7 @@ title: PrestaShopCollection class ## Introduction -The PrestaShopCollection component is a Collection of ObjectModel objects. It implements common useful `php` interfaces: +The PrestaShopCollection component is a Collection of ObjectModel objects. It implements common useful `PHP` interfaces: - `Iterator`: allows for `foreach` loop on the Collection - `ArrayAccess`: allows for offset/index access on the Collection @@ -22,8 +22,8 @@ $productCollection = (new PrestaShopCollection('Product')) ->orderBy('reference', 'desc') ->setPageSize(100); -if(count($productCollection) > 0){ - foreach($productCollection as $product){ +if (count($productCollection) > 0) { + foreach ($productCollection as $product) { // do something with your product } } @@ -31,7 +31,7 @@ if(count($productCollection) > 0){ ## Create a PrestaShopCollection -To create a PrestaShopCollection, simply instanciate a PrestaShopCollection with the ObjectModel type as constructor parameter. +To create a PrestaShopCollection, simply instantiate a PrestaShopCollection with the ObjectModel type as a constructor parameter. ```php use PrestaShopCollection; @@ -39,26 +39,26 @@ use PrestaShopCollection; $productCollection = new PrestaShopCollection('Product'); ``` -A second parameter can be used, to set the id of the lang to use (`$id_lang`), set at null by default. +A second parameter is available to set the ID of the language to use (`$id_lang`). It is `null` by default. ```php use PrestaShopCollection; -$idLang=1; +$idLang = 1; $productCollection = new PrestaShopCollection('Product', $idLang); ``` {{% notice note %}} -Using `$id_lang` parameter will allow to set a Lang Context when querying / filtering multilang fields. If not set, multilang fields will be returned as `array` in the Collection. +Using `$id_lang` parameter will allow setting a Context language when querying/filtering multi-lang fields. If not set, multi-lang fields will be returned as an `array` in the Collection. {{% /notice %}} ## Get results, count results When your collection is created, you may need to get its content. Several methods are available to retrieve its content: -- `getFirst()`: gets first item of the Collection -- `getLast()`: gets last item of the Collection -- or simply access items via index, or iterate with `foreach` +- `getFirst()`: gets the first item of the Collection +- `getLast()`: gets the last item of the Collection +- you can also access items via their index key, or iterate with `foreach` ```php $productCollection = new PrestaShopCollection('Product'); @@ -66,11 +66,11 @@ $productCollection = new PrestaShopCollection('Product'); $firstProduct = $productCollection->getFirst(); $lastProduct = $productCollection->getLast(); -// you can access items in the collection by index, like a regular array (the class implements ArrayAccess). Index starts at 0 +// you can access items in the collection by index, like in a regular array (this class implements ArrayAccess). The index starts at 0 $thirdProduct = $productCollection[2]; // The collection is also iterable (the class implements Iterator): -foreach($productCollection as $product){ +foreach ($productCollection as $product) { } @@ -121,9 +121,9 @@ $productCollection = new PrestaShopCollection('Product'); $productCollection->where('reference', 'LIKE', 'REF-%'); // find products with reference beginning by "REF-" ``` -### Having method +### `Having` method -Another method is available, `having()`, which calls `where()` with the parameter `$method` set to `having`. +There is also `having()` method available, which calls `where()` with the parameter `$method` set to `having`. ```php public function having($field, $operator, $value) @@ -160,7 +160,7 @@ $productCollection->join('categories', 'id_category', PrestaShopCollection::INNE $productCollection->join('categories', 'id_category', PrestaShopCollection::LEFT_OUTER_JOIN); ``` -### Using where with join +### Using `where` with `join` One of the interest of joining other ObjectModel entities to your collection, is the possibility to filter on the external entity with `where()`. @@ -178,7 +178,7 @@ To order your collection, use the `orderBy()` method. public function orderBy($field, $order = 'asc') ``` -Ordering can be done in ascending or descending direction, with `asc` or `desc` `$order` parameter. +Ordering can be done in ascending or descending directions, with `asc` or `desc` in the `$order` parameter. ```php $productCollection = (new PrestaShopCollection('Product')) @@ -187,7 +187,7 @@ $productCollection = (new PrestaShopCollection('Product')) ## Grouping (group by) -To group your collection items on a field, use the `groupBy()` method. +If you want to organize your collection items based on a specific field, you can make use of the `groupBy()` method. ```php public function groupBy($field) @@ -200,25 +200,25 @@ $productCollection = (new PrestaShopCollection('Product')) ## Paginating a Collection (offset / limit) -When fetching large quantities of items, you may need to paginate your collection, with SQL `OFFSET / LIMIT` equivalent mecanismes. +If you need to retrieve a large number of items, it may be necessary to use pagination techniques such as SQL's `OFFSET/LIMIT`. This will help you manage your collection more efficiently. -To do so, use those two methods: +To do so, use these two methods: ```php public function setPageNumber($page_number) public function setPageSize($page_size) ``` -To use this feature, first, set the $page_size: +First, set the $page_size: ```php $productCollection = (new PrestaShopCollection('Product')) ->setPageSize(100); // will get only 100 items ``` -If only `$page_size` is set, the collection will return the first `$page_size` items. +If `$page_size` is set, the collection will return the first `$page_size` items. -To do a pagination, and get the page 2 of the collection, use the following example: +If you need to paginate and access the second page of a collection, you can use the following example: ```php $productCollection = (new PrestaShopCollection('Product')) From 5cb5eb5d24ca0ec8d181b9e1f2e99d4a264f0d70 Mon Sep 17 00:00:00 2001 From: Krystian Podemski Date: Mon, 24 Apr 2023 09:14:43 +0200 Subject: [PATCH 293/310] Update development/components/database/prestashopcollection.md Co-authored-by: Thomas NARES --- development/components/database/prestashopcollection.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/development/components/database/prestashopcollection.md b/development/components/database/prestashopcollection.md index 73302ca13e..2aaca34249 100644 --- a/development/components/database/prestashopcollection.md +++ b/development/components/database/prestashopcollection.md @@ -236,5 +236,6 @@ $productCollection = (new PrestaShopCollection('Product')) `LIMIT 100 OFFSET 200` or `LIMIT 200,100` {{% notice info %}} -Known issue: When not using `$id_lang`, and using pagination (`setPageSize()`, `setPageNumber()`), pagination will be broken. Please use a Lang Context if the entity is multi-lang enabled. +Known issue: If the entity has multi-lang attributes, when not using `$id_lang` in the `PrestaShopCollection` constructor, and using pagination (`setPageSize()`, `setPageNumber()`), pagination will be broken. +Please set an `$id_lang` in the constructor to use pagination features for entities with multi-lang attributes. {{% /notice %}} \ No newline at end of file From 706ececea3730d8cc9342bc267ce506d683fab28 Mon Sep 17 00:00:00 2001 From: Krystian Podemski Date: Mon, 24 Apr 2023 09:44:52 +0200 Subject: [PATCH 294/310] bump hugo version to v0.85 --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 5efd0aa503..61d7741338 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -20,7 +20,7 @@ jobs: - name: Setup Hugo uses: peaceiris/actions-hugo@v2 with: - hugo-version: '0.82.0' + hugo-version: '0.85.0' extended: true - name: Find version from branch name (pull request) From b7da2d01c70a401e3c0bc0b54d26af93e18d14e9 Mon Sep 17 00:00:00 2001 From: Thomas Nares Date: Tue, 25 Apr 2023 17:50:31 +0200 Subject: [PATCH 295/310] Add flags to feature pages on homepage --- basics/_index.md | 2 ++ basics/deployment/_index.md | 1 + basics/installation/_index.md | 1 + basics/installation/localhost.md | 1 + basics/installation/system-requirements.md | 1 + basics/introduction.md | 1 + basics/keeping-up-to-date/_index.md | 1 + contribute/_index.md | 2 ++ contribute/contribute-by-testing-pull-requests.md | 1 + contribute/contribute-pull-requests/_index.md | 1 + contribute/contribute-reporting-issues.md | 1 + contribute/contribution-guidelines/_index.md | 1 + contribute/contribution-process/_index.md | 1 + contribute/documentation/_index.md | 1 + development/_index.md | 2 ++ development/architecture/_index.md | 1 + development/components/_index.md | 1 + development/components/hook/subscribing-to-hook.md | 1 + development/configuration/_index.md | 1 + development/database/_index.md | 1 + faq/_index.md | 2 ++ faq/i-need-help.md | 1 + faq/product.md | 1 + faq/tips-and-tricks/_index.md | 1 + faq/upgrade.md | 1 + modules/_index.md | 2 ++ modules/concepts/_index.md | 1 + modules/concepts/hooks/list-of-hooks/_index.md | 1 + modules/core-updates/_index.md | 1 + modules/creation/_index.md | 1 + modules/sample-modules/_index.md | 1 + scale/_index.md | 2 ++ scale/benchmark/_index.md | 1 + scale/optimizations.md | 1 + scale/taking-care.md | 1 + scale/webservers/_index.md | 1 + testing/_index.md | 1 + themes/_index.md | 2 ++ themes/distribution/_index.md | 1 + themes/getting-started/_index.md | 1 + themes/reference/_index.md | 1 + webservice/_index.md | 2 ++ webservice/cheat-sheet.md | 1 + webservice/getting-started.md | 1 + webservice/reference.md | 1 + webservice/tutorials/_index.md | 1 + 46 files changed, 54 insertions(+) diff --git a/basics/_index.md b/basics/_index.md index e64fdcef06..b00090abf0 100755 --- a/basics/_index.md +++ b/basics/_index.md @@ -3,6 +3,8 @@ title: Basics weight: 1 pre: "1. " chapter: true +featured: true +icon: fa-play --- ### Chapter 1 diff --git a/basics/deployment/_index.md b/basics/deployment/_index.md index c8bcba8b23..3fd4446641 100644 --- a/basics/deployment/_index.md +++ b/basics/deployment/_index.md @@ -1,6 +1,7 @@ --- title: Deployment weight: 40 +featured: true --- # Deployment diff --git a/basics/installation/_index.md b/basics/installation/_index.md index 787d82a696..9b34a2981f 100644 --- a/basics/installation/_index.md +++ b/basics/installation/_index.md @@ -1,6 +1,7 @@ --- title: Installation weight: 20 +featured: true --- # Installation diff --git a/basics/installation/localhost.md b/basics/installation/localhost.md index d3dd0334d5..dab8bd3ccc 100644 --- a/basics/installation/localhost.md +++ b/basics/installation/localhost.md @@ -2,6 +2,7 @@ title: Installing a local environment menuTitle: Development environment weight: 15 +mostViewedPage: true --- # Installing PrestaShop for development diff --git a/basics/installation/system-requirements.md b/basics/installation/system-requirements.md index 7a2178f40e..cbaf9a4a82 100644 --- a/basics/installation/system-requirements.md +++ b/basics/installation/system-requirements.md @@ -2,6 +2,7 @@ title: System requirements for PrestaShop 8 menuTitle: System requirements weight: 10 +mostViewedPage: true ---
+
flowchart TB - A(Cart)-->|Associate to customer|B(Cart associated) - B-->|Select shipping and invoice addresses|C(Cart addressed) - C-->|Select shipping method and carrier|D(Cart shipping configured) - D-->|Select payment method|E(Cart payment configured) + A(Cart)-->|checkout-personal-information-step|B(Cart associated) + B-->|checkout-addresses-step|C(Cart addressed) + C-->|checkout-delivery-step|D(Cart shipping configured) + D-->|checkout-payment-step|E(Cart payment configured) E-->|Submit order|F(Order)
+{{% notice note %}} +Please note that if a cart contains only Virtual products, there is no `checkout-addresses-step` and `checkout-delivery-step`. It goes directly from `checkout-personal-information-step` to `checkout-payment-step`. +{{% /notice %}} -1. **Associate to customer** : details like name, email, birthday etc. In FO you can either fill this information manually as - guest (and optionally create new customer account) or login with existing customer. +1. **Associate to customer** (checkout-personal-information-step): details like name, email, birthday etc. In FO you can either fill + this information manually as guest (and optionally create new customer account) or login with existing customer. In BO order creation you will be asked to select an existing customer before you can modify the existing cart or create a new one. -2. **Select shipping and invoice addresses** : provide the shipping and invoice addresses information. Shipping (a.k.a. delivery) address is where the - ordered products should be sent while the invoice address is where the invoice is sent. In FO, you can provide one - address to be used as both - shipping and invoice. In BO, you must select shipping and invoice addresses (the same - address can also be selected for both - shipping and invoices). -3. **Select shipping method and carrier** : after this step is complete you will need to select available carriers - (carriers are searched by delivery address and can be modified by shop admin in Improve -> Shipping -> Carriers page). Note - carrier will not be available if selected country or zone is disabled (in BO International -> Locations) or carrier shipping and locations settings are not configured. -3. **Select payment method** : choose how to pay for the order. Shop admin can configure payment methods in BO Payment -> Payment methods. +2. **Select shipping and invoice addresses** (checkout-addresses-step): provide the shipping and invoice addresses information. + Shipping (a.k.a. delivery) address is where the ordered products should be sent while the invoice address is where the invoice is sent. + In FO, you can provide one address to be used as both - shipping and invoice. In BO, you must select shipping and invoice addresses + (the same address can also be selected for both - shipping and invoices). +3. **Select shipping method and carrier** (checkout-delivery-step): after this step is complete you will need to select available carriers + (carriers are searched by delivery address and can be modified by shop admin in Improve -> Shipping -> Carriers page). + Note - carrier will not be available if selected country or zone is disabled (in BO International -> Locations) or carrier shipping + and locations settings are not configured. +3. **Select payment method** (checkout-payment-step): choose how to pay for the order. Shop admin can configure payment methods in + BO Payment -> Payment methods. All payments are handled by payment modules. Prestashop comes with 2 payment modules by default: * ps_checkpayment - allows check payments. @@ -75,30 +80,41 @@ flowchart TB {{% notice note %}} Payment restrictions for currency, country, group and carrier can be configured in BO `Improve -> Payment -> Preferences`. {{% /notice %}} - -4. **Submit Order** : Once the order is submitted, a unique order reference is generated and certain records from a cart and related +4. **Submit Order**: Once the order is submitted, a unique order reference is generated and certain records from a cart and related entities are added into following database tables: - * orders - * order_history - * order_detail - * order_carrier - * order_cart_rule (if any discounts were applied) - * order_detail_tax (if any taxes are applied) + * `orders` + * `order_history` + * `order_detail` + * `order_carrier` + * `order_cart_rule` (if any discounts were applied) + * `order_detail_tax` (if any taxes are applied) + +{{% notice note %}} +At this step, some important data is duplicated (in `order_detail`) to ensure product data will remain available in the order even if the product is deleted afterwards. Price information is also duplicated, to ensure the order amount will remain immutable. +{{% /notice %}} 5. After order is successfully created, an email with the order information is sent to the customer. {{% notice note %}} - Email sending settings can be found in BO `Configure -> Advanced parameters -> E-mail`. Email translations and templates in `Improve -> International -> Translations`. When order is being created in BO, email with the link to a prefilled cart can be sent before creating the order (so the customer can finish up the checkout process). To do that click `More actions -> Send pre-filled order to the customer by email` in summary block. +{{% /notice %}} + +{{% notice note %}} +**Dive more in PrestaShop's Checkout process:** +Learn how it works under the hood by looking at: +- [classes/checkout/CheckoutSession.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/checkout/CheckoutSession.php) +- [classes/checkout/CheckoutProcess.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/checkout/CheckoutProcess.php) +- [classes/checkout/CheckoutStepInterface.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/checkout/CheckoutStepInterface.php) {{% /notice %}} -#### Order status + +## Order status When creating order from the FO, the initial order status will differ depending on selected payment method. For example, if "Payment by check" is selected, then order will be created with the "Awaiting check payment" status, or if "Bank From 7d37d65bd7c6848a749b39c62af1a3a297b061ed Mon Sep 17 00:00:00 2001 From: Pablo Borowicz Date: Fri, 25 Nov 2022 16:43:57 -0300 Subject: [PATCH 144/310] Move articles to .org --- contribute/_index.md | 4 +- .../contribute-by-testing-pull-requests.md | 100 +---------------- contribute/contribute-reporting-issues.md | 67 +---------- .../how-issues-are-sorted.md | 104 +----------------- contribute/img/github-create-account.png | Bin 37993 -> 0 bytes contribute/img/github-issue-editor.png | Bin 60683 -> 0 bytes contribute/img/github-new-issue.png | Bin 151311 -> 0 bytes contribute/img/github-select-issue-type.png | Bin 15204 -> 0 bytes contribute/img/vagrant/build-failed.png | Bin 28850 -> 0 bytes .../img/vagrant/invalid-php-version.png | Bin 48676 -> 0 bytes contribute/img/vagrant/run-script.png | Bin 61188 -> 0 bytes .../img/vagrant/script-ended-successful.png | Bin 200327 -> 0 bytes 12 files changed, 18 insertions(+), 257 deletions(-) delete mode 100644 contribute/img/github-create-account.png delete mode 100644 contribute/img/github-issue-editor.png delete mode 100644 contribute/img/github-new-issue.png delete mode 100644 contribute/img/github-select-issue-type.png delete mode 100644 contribute/img/vagrant/build-failed.png delete mode 100644 contribute/img/vagrant/invalid-php-version.png delete mode 100644 contribute/img/vagrant/run-script.png delete mode 100644 contribute/img/vagrant/script-ended-successful.png diff --git a/contribute/_index.md b/contribute/_index.md index 422c232d86..1b8630fdb6 100644 --- a/contribute/_index.md +++ b/contribute/_index.md @@ -9,6 +9,8 @@ chapter: true # Contribute -PrestaShop is a community project, made by hundreds of developers collaborating around the world. You can get involved too! +PrestaShop is a community project, made by hundreds of people collaborating around the world. You can get involved too! + +- [How to get involved in the project](https://prestashop-project.org/get-involved/) {{% children %}} diff --git a/contribute/contribute-by-testing-pull-requests.md b/contribute/contribute-by-testing-pull-requests.md index 8fed715ad5..3bd2ce3a01 100644 --- a/contribute/contribute-by-testing-pull-requests.md +++ b/contribute/contribute-by-testing-pull-requests.md @@ -1,97 +1,7 @@ --- -title: How to test Pull Requests and branches -menuTitle: Test Pull Requests and branches -weight: 50 +# this page is redirected so it has no content +layout: redirect +redirect: https://www.prestashop-project.org/maintainers-guide/test-pr-and-branches/ +_build: + list: never --- - -# How to test Pull Requests - -Tests determine the quality of a software. This process involves evaluating information that is related to a shop. - -To make testing easier, we provide a [Vagrant](https://www.vagrantup.com/) configuration designed for testing branches and pull requests. - -## What is installed - -- Debian 10 Buster -- Git -- Apache 2.4 -- Multiple PHP versions (7.1, 7.2, 7.3, 7.4) -- MariaDB 10 -- NodeJS - -## Requires - -First of all you need two tools to run this project: - -- [Vagrant](https://www.vagrantup.com/downloads.html) -- [VirtualBox](https://www.virtualbox.org/wiki/Downloads) - -If you're using Windows, we recommend you to download [Git bash](https://git-scm.com/downloads) and execute all commands under this shell. - -## Why Vagrant - -We use Vagrant because of its flexibility and portability. -With it, you can control every aspect of the machine, and help us by having a similar environment to reproduce issues. - -## Getting started - -The process is pretty simple. - -First, you must clone the repository [https://github.com/PrestaShop/vagrant](https://github.com/PrestaShop/vagrant). - -Second, execute the script `run.sh` (or `run.bat` if you're under Windows) and follow instructions. - -Most of the time, there is a prompt asking for a network interface, remember it's the communication between the virtual machine and the network card. - -{{< figure src="../img/vagrant/run-script.png" alt="Running the run.sh script" >}} - -The first installation will take a while, because it needs to download the vagrant box, installs all needed packages and configures the system to make it compatible with PrestaShop. -{{< figure src="../img/vagrant/script-ended-successful.png" alt="Script running successfuly" >}} - -Then, visit [http://192.168.42.42/prestashop](http://192.168.42.42/prestashop). - -phpMyAdmin is also available at [http://192.168.42.42/phpmyadmin](http://192.168.42.42/phpmyadmin). - -### Environments - -#### Available PHP versions - -- 7.1 -- 7.2 -- 7.3 -- 7.4 - -{{% notice tip %}} -Be aware that some PrestaShop versions are not compatible with all the above environments. See [System requirements]({{< relref "/8/basics/installation/system-requirements" >}}) to find out which version is compatible with which PHP version. -{{% /notice %}} - - -#### PrestaShop - -- Username: `demo@prestashop.com` -- Password: `prestashop_demo` - -#### MySQL - -phpMyAdmin is available at [http://192.168.42.42/phpmyadmin](http://192.168.42.42/phpmyadmin). - -- MySQL Host: `127.0.0.1` -- Database name: `prestashop` -- Username: `prestashop` -- Password: `prestashop` -- Port: `3306` - -#### SSH - -You can login into the virtual machine with `vagrant ssh` - - -### Troubleshooting - -If something went wrong during the installation, the error is displayed explaining which command is failing. - -* Invalid branch name: -{{< figure src="../img/vagrant/build-failed.png" alt="Invalid git branch name" >}} - -* Invalid PHP version: -{{< figure src="../img/vagrant/invalid-php-version.png" alt="Invalid PHP version" >}} diff --git a/contribute/contribute-reporting-issues.md b/contribute/contribute-reporting-issues.md index 29c818fe4b..b5ab60b6b7 100644 --- a/contribute/contribute-reporting-issues.md +++ b/contribute/contribute-reporting-issues.md @@ -1,64 +1,7 @@ --- -title: How to use GitHub to report an issue -weight: 10 -menuTitle: Reporting issues +# this page is redirected so it has no content +layout: redirect +redirect: https://www.prestashop-project.org/get-involved/report-issues/ +_build: + list: never --- - -# How to use GitHub to report an issue - -PrestaShop uses GitHub to track bugs and issues. This is the best place to report the bugs you are witnessing on your PrestaShop shop. - -{{% notice tip %}} -You need a free GitHub account to collaborate. If you don't have one yet, you can [create it here](https://github.com/join). -{{% /notice %}} - -## Creating an issue - -To create your first issue, go to the [list of issues](https://github.com/PrestaShop/PrestaShop/issues) and click on the "New issue" button on the right. Or just [click here](https://github.com/PrestaShop/PrestaShop/issues/new/choose). - -![Issue or Feature request](../img/github-new-issue.png) - - Choose between a "Bug report", or a "Feature request", and click on "Get started" - -![Issue or Feature request](../img/github-select-issue-type.png) - -A text editor appears: - -![Issue or Feature request](../img/github-issue-editor.png) - -To fill the required information, just use the text editor. You can use the "preview" tab to see how your issue will be published. - -There are five main sections: - -1. **Describe the bug** – a clear and concise description of what went wrong. -2. **Expected behavior** – describe what you expected to happen instead. -3. **Steps to Reproduce** – describe the different steps and information to reproduce the issue. -4. **Screenshots** – add screenshots in this section. -5. **Additional information** – like your version of PHP and MySQL, as well as any other relevant server configuration. - -Click the "Submit new issue" button when you are done. - - -## Best practices for writing an issue - -When writing a bug report, please use these guidelines: - -- Make sure you can reproduce your bug every time. -- Make sure your software is up to date. -- Ideally, test the latest [nightly build development version](https://nightly.prestashop.com/) to see whether your bug has already been fixed. -- Search in GitHub issues to see whether your bug has already been reported. -- Write a clear summary. Describe the observed result what you expected to happen instead. -- Write precise steps to reproduce. Be specific and verbose: do not fear to give details on how you did reproduce the bug. - -These are inspired by [Mozilla's own guidelines](https://developer.mozilla.org/en-US/docs/Mozilla/QA/Bug_writing_guidelines). - -{{% notice tip %}} -GitHub provides very good documentation about how to write [issues](https://guides.github.com/features/issues/) with its [flavoured Markdown](https://github.github.com/gfm/). It is possible to [highlight code syntax](https://help.github.com/articles/creating-and-highlighting-code-blocks/), [add pictures](https://help.github.com/articles/file-attachments-on-issues-and-pull-requests/), or even to [link issues and pull requests](https://help.github.com/articles/autolinked-references-and-urls/). -{{% /notice %}} - -## What happens after you submit your issue - -If your issue can be reproduced using a clean install, it is likely that the problem effectively is due to a software defect. -In that case, the bug will receive a severity classification, and be added to the backlog so that it can be fixed in a future release. - -To find out more, read [How issues are sorted]({{< relref "contribution-process/how-issues-are-sorted.md" >}}). diff --git a/contribute/contribution-process/how-issues-are-sorted.md b/contribute/contribution-process/how-issues-are-sorted.md index f328a3ebe1..29611a977c 100644 --- a/contribute/contribution-process/how-issues-are-sorted.md +++ b/contribute/contribution-process/how-issues-are-sorted.md @@ -1,101 +1,7 @@ --- -title: How issues are sorted -weight: 1 +# this page is redirected so it has no content +layout: redirect +redirect: https://www.prestashop-project.org/get-involved/report-issues/how-issues-are-sorted/ +_build: + list: never --- - -# How issues are sorted - -## What happens to the issue you have reported - -PrestaShop Quality Assurance team (aka QA) uses a transparent definition for the criteria used to qualify issues' severity, and how they should be applied through labels on github issues. - -Please note that severity is to be distinguished from priority. Indeed, severity is used to measure the negative impact that a bug has on a system, a feature, a component or on the project development. It is usually defined by the QA team. As for the priority, it is used to organize all the tasks (bugs, improvements, features, technical tasks) that have to be done in order to meet the project's deadlines. - - -## Issue Severity Criteria - -When a new issue is created, the first step is to understand what the problem is and then reproduce it. Once that work is done, the second step is to define the severity of that bug. - -Four severity levels are used: Critical, Major, Minor and Trivial. - -### Critical - -The bug affects critical functionality or critical data and there is no workaround (no way to avoid it). -A critical issue affects a very large percentage of users (> 60%) and matches at least one of the following: - -- It can lead to data loss, introduce a security vulnerability or break the automatic end to end tests -- It prevents the essential shop operations or puts your business at great risk - -Examples: - -- Difficulty accessing the front office or back office (significant slowdown, error during installation or update, fatal error) -- Difficulty to globally manage categories, products or customers -- Difficulty to globally place and manage orders - -A critical issue should result in a patch version that should be released as soon as possible. [PrestaShop 1.7.2.5](https://build.prestashop-project.org/news/prestashop-1-7-2-5-maintenance-release/) is a good example: this patch release fixes two vulnerabilities affecting the Back Office. - - -### Major - -The bug affects major functionality or major data and there is a workaround, but it is not obvious or can be difficult to put in practice. - -A major issue affects a large percentage of users (> 30%) and matches at least one of the following: - -- It impacts law compliance -- It has a strong impact on the usability of the front-office / back-office or blocks another project -- It is an important problem but not necessarily blocking the main activity of the seller - -Examples: - -- Being unable to add, configure or delete a theme or a module -- Difficulty in operating a module properly -- Impacts the price the customer pays - -### Minor - -The bug affects minor functionality or non-critical data and there is a reasonable workaround, even if it can be annoying when using your shop. - - -Examples: - -- A tolerable slowdown -- A display problem that prevents users from doing something non-critical (eg: can’t click on an element that can be accessible in another way) -- An error message displayed in your back-office that can be dismissed -- Cloning a product doesn't copy all of it's data -- Inaccurate statistics - - -### Trivial - -The bug doesn’t affect any functionality or data. It does not impact productivity or efficiency. It is only an inconvenience without functional impact and it does not even need a workaround. - -Examples: - -- Cosmetic issues -- Wrong translation in a specific language: that can be solved on [Crowdin](https://crowdin.com/project/prestashop-official) -- Missing confirmation message after an action -- A link opened in the same tab instead of a new tab - - -## Issue Prioritization - -Assessing severity helps to prioritize issues but it is not the only criterion at stake. Given two equally severe issues, how to choose one over the other ? - -Prioritization is done by representatives of the Development team, the Product Management team, and the Quality Assurance team. - -Together, during regular meetings, they look at the new confirmed issues and they sort them. - -In order to make sure that a given bug does not damage PrestaShop's image nor it affects the confidence merchants can have in PrestaShop, they take special care and strive to make every version of PrestaShop better than the one before. Since no one wants to introduce new bugs while fixing other bugs, regressions (new bugs created accidentally when fixing or improving an existing feature) are usually prioritized higher than older bugs. By doing this, the overall software stability is ever increasing. - -Then the issue's technical complexity is also studied : that is, whether the bug is easy or complex to fix. - -Sometimes a smaller bug will be prioritize over a bigger one. This is because a complex bug may require big technical changes which are not suitable until a later version. This may be because a would require applying backwards-incompatible changes (which are bad for module developers), or because it can be better addressed as a part of a larger project – there is no use fixing a bug if the whole feature is due to be revamped in the near future. -Also sometimes some bugs will be prioritized just because of the “opportunity cost” of fixing them together, as it is usually easier to fix several bugs within the same component. For instance, during the migration of a BO page to Symfony, the bugs of this page are prioritized higher in order to fix them all at once. - -Last criterion used is the business impact as of course. - -In the end, handling bugs requires two points of view: micro and macro. Severity analyzes the issue on its own, while Priority analyzes the issue in the context of the whole project. - ---- - -_(This article was originally published on our blog: [Introducing A New Bug Severity Classification](https://build.prestashop-project.org/news/severity-classification/))_ diff --git a/contribute/img/github-create-account.png b/contribute/img/github-create-account.png deleted file mode 100644 index 4987741a9f6d7310ae9a893e988455acf27889fd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 37993 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

nnTF#VRy25Pe zo&S8?ly(s(9Fwb|J0fC!jgBXwth<}CHht7pzEuh*l_Qo4>DN)JG34>{s8GW3n?FnS z?%wN+mCuGzEDKHJ`1KN{gBX?tF_ z>{7oIC}kz#C7P&X%hCxR#L}njh5jYF&2%1 zzj`NV>0A|m_nhg^pj0Ks;8Mjb5b8(`L4V?=Z<-7|Q|2q&8PQBP#1>ya zCDC~`DLb3$)vA%_os5{4eeCNTtO~{f@j(KtQ`#Iu)wNa&anv zJ%izI^Pqi-Ygamv9#I(2X*ZZ}Z{zY=<&WtrkulZh2s?ldXP#2JY(snN2^uxaUMeGF zC;O8+ug%shLCSZUT!0(GMev1RF5HHr;DW->-R&G@9w$T-f5&o6V>JI z3{dNk*$fN*tN^U*$==ew6IXqm>{}@F7YhT2HO2_ zL?#QR1fb&_7C|cm@~^}L4XiK4JZmEK2@SO8b-ANarfSoFTWMtDu1%K5D7>w;0I=!_ zBDl+L65H}01NA4AGTNLeG*ijrrQo>dc{@~BDGsdg{<36LD5zuVatXLrHMV)`d36Y0*0d5s$WJlOL1g4J0uoV+wza#+FSB08kUJr z6gc~#y*0Pc?&$eq0fg5G;{(7S17qv>SZbTfN)ZXILmS=aVqa zGMH>8SeBavTVi^|JX*4H1%Gt635T=$$3w@?Tf)VuO#gLW|80-z zw*Z!#FPO%pBvCY+I&dGE(>m^le)1VTzH#?gj2Qi47ez2WfY2emSzUlMAyi2iT#!I+ z$$u$KIivyT-2sv4g2|Jg1QB!vA^w1Xj|31VB?^cC^TPjj?sZE+#6sy?g5HwqYQ?a!x4yYoYQkSzE?Sd452#}itz!nu<(8z_&nXI*7~PE-bS!Q zLywa5b~rVlJ%W)e%O37}C`Xa_Xw6-im+t(ew#y$#{c2bN*ZP=iqy7G1MZx7 zyPlEeT!5b-J$Ea=t2L+q0L%oyrj{Laj$tFR8ChYh!XgWAHWkfLe+E1<<_LUTLL5Ix zv2Vv6lGl_%MOmhY@?3$fK&5k0kJf?)Y@O(_0WfvwX92&jkPP{ETUMrbjFm@qyqNMZ z7d0gs3Vx7og0BT@v?9?;Xbk^tLzsafA2YjnKd4<)6%c;THDD^3HI8A`66jcZRJD($>G zmU2K3$DRZONZ46fx`RYE8DC#ZjE3@}xi@yS>9oF<6ukB@|OJz){(-8gRc zN8(~?DZlP8zZy00Ziaj!6albe<2U7f*f;22|NZA06#fx98A@tpgjPP+BxOtn}kdJZ{jTKkiRv=F6imM8mNs| z*%0v95qG$Ztd9U#0jYlsx0qMro)spHcfrvi3}j`apUk7qQU|9&Yx4=BZB*hbBUF=j zc2}4BzZr-oq<<2WxH^eTp#k`moW!}B`Sh!C0w!@WKu`nWDBrM?X1#$mRPS(J zG@<``T~t<063&N&c6Sh`=}FQf2-l}X&fKJbx>jt6WRSM~$mk>RkQ~rvK|t?IK?z0$ zP~2H1%BmuFR%2J0Am@;$w;=wpI5ztT=)BiBaItf|EA9*-*KANGp;7R^j0a{?l)Lxd zXPUX*aLcW>l7Ht=UP_t$-a3syoSx(SVa(O^!6B#mMRT;d9J_OFB?M|&FXroyH;rxO zh=xhbOvy#}?=t4hrehUMDsTsDr~rJ*9A-e(!%uqvsRkiDAer4N5#^Xir-Hmx-7%06n~_cMAgcmN0R1a0M2O-1Z%Vtj zZ!2^OEx#H0%R^jK1`KsfGV_FhKW=k%xbUM%78JR;6p^bFn=!lR{`8yx$$q7;m`iH5@wo*(P%%}w1@-L*2rko>0 zh#PttnDo9}to^5obNUxq%>Q0b{del<|JGCg^&o9|0bcIlRG)xY3OuVb)f%JsHPGy* z$KA$<(GsJy_zp`=eEU`53Y0}u+6OWm-gim4 zb$61{%;{Clxj$?Wwk}&)G5M8}Rd-+X8wg8K74T+H@ew&^&+2L2GsTc=QUI;g_N_Mk ziS2c*s)SaITN+$3?_2R@QM%nX&OtN|G5$(Jqd^WDo4Zznz$d?6eP}5l9!!(vdzKQ( zdoa>hOQ8B~WVvIz?iYME@P>e`#~WF5(OsB0`1MoJTh8_mshXEZ9 zS);kbF}%LlQ3tdV^DHHWAL~$WsC0ncF`*oMOr)IkEXzhI z^`N5U?F|PyF#f#F!=gH92?!p9_;%$8(W*BT)Be@4Qy-aI`{eH_n+!U8i42;5TAD~c z8)37+p(P5-tS6`3ih5yK@I`gI?x#;CW`)k6JD!Z3A!h^d?}uMr6R<@~JLRZn#++^C z)b5rnd#2sDptW9eDZgse!*y6|dWWoo#9t;&rl)1^y~>TuV4pD}_eUH7m_J}|2R@(x z0aV^AjqRPD`jeBfjpW6hEJY=Xb5y#~Ei78;-ZI4{egd`F&oNPLEn;E!Ja1oVLe0vd z^C-G6v%K01CjBaujsKi;fW1vt_`|< z^>$j%N9jZJ-}asR36D>O!44~bA|mEQ9vRgc+bu)|Y{rRC?pEI?d4- zHpWbh@b<}yh9%oBS)-~qaSiISuC!j6$X4PrEF{(cMRXevuK1qO>NQ>a`Z47@0pNzo z{yyt`Ix2MOUh5lI8JX>^-&&s(`|4kvRyQz#U-WAYjR{zaUI3kqLx%jMMO|uE6a1x) z`ZhE18$#}rn}@8+bQ?wG%=&MHi0AsyZwP)xT-aQc40%D{5bx<#v+jzPph~?X5X0L` z$SqIh+%!$LA__l1N?Y(&#c`>M{}zgYi*|EkW_MGpha&JBHHeX0b-8t}wWts84r>nm zLrx5^T&I=zmhkdm7VceXh+N(8Tit?lrKS_)-V&Bv6;Z?CkC3FR@PmZoi4n0Uk@-|s zSD`<8)B+}z?^SLBox=};^f~m>2+KF-SZZm@$14yjL-8bxfW%2{aKn$EIqmhiJ4!hn z@zH%pVo!-n8rPYhKjhHA-v)c)CFDm4uv+^fBd@ z7KHWrSDb20y>i?qtj3MtW0{ZiOOw%AY8@7@#dau=RszLxM&=7gK5q3l_!!Ei%t6Xg zGR=Xq#bGrOWE~mWNl3f)Ly(u5?-(`Zri+1yc+fZv-K zdrObx{1Wb?OZUE7!U?9x9B?BIYZft=zbu=QIGoz3V^uskhd&OaA36` zrgXmphR?A2p^&i&127U*Py1sm9KuL7b9goKEc3PS=~O*1G1GfQ_D9#nomVV76qP6J zPYMA4s6acP1RLQzxV|zQ;k7EzX1$r}o2>MIBRx5qdvD2?rv%k@i zt}>{~{qzi94smWt)nwa6rf~^2{@L2Tf(@uTu{z^8gseX5eBAbj9XqM{{Xlqr9jFC# zfY00l!j&V}Rbtv*T=&*R1T|nXZZ1i?v}B5#0$2UabTGg63HAF2fSWZJu;C8p&;&{! zFrWRDsJoHR1{K>)dl<7m~14Nw0mBkLna1R%G z1Rd=@b&rG3q^}AMwB-?vE~#oTWB=mR^SZ@}`mT`lQ8HvzQv*8jKVh;%XCFCmJatY4 z1OfQpT{cAPcWK)0|7ggOnBx4hj7V7r-1tJ%A_8Q2tML@;&sXY6!n%I?re(F^NCV%m z$dfYZn$If4ktU<5%$4T2o(6&dn33mC5qW3pG>uNz@`5{Z>n}w)fS@c`kw@eb9VR)N zuITlfLl&dc%jKMk9#>^6p=YHK29WnjV!7O~JPAk0Q>5)D)g?7GIU1)~Xn+en znD2q|W*?8J40ol@`BcbnS@m{>!)$Osb~N)XT5bKXnRu{w+TyGTAQ-Xo5Hd_|_ox}j zF*OTT&rJ7qKYXrXM*>h`ipOyb_Oq%fJ%&psotO~N>Mu;1q2|!6V2C7t({kZ z$IP@=>@0+MNVOv5MVHlT@@RkGo3AY!0uX^1=hwH-4IX08uldn0<;-+a;D?nX$>VBg zY#+g5A`n|{e*H%*|J97ZpYEHT#-K=${dc!}Yvw-=Qf}gh^EK`SZK4Nx=?8eVR*2NF ze>l9+`Ek^G;|+QeUijkC3_A1c7Ig~W2`yN}%QcKZu7usQsM-3&_abcU`A%4eU;(%$*H)`N>~U@ISO2Mc+#%W$2LR?|eeye6-BbQmhjCv$AiI3@ zCoTKeQN!3>=SZ9EEzmZHIe_2!eX{>ngMnu7S!8+{;J#i9mPe%0EL|_~>#Bc$eH2G~ z&KbR1VSROwwd?{u&7Tp18!vA%hU&zw+K`8c}*VmCYfzqd+=C;Ja!hE_0`e4TwYFVCFC^? zUxi84^%m4p50LfT?SQSP&)ng1i>k^nN%1&isuh$9($g)zDeTkpXbc&-V9c2-+~1h?CDUS;Qw|g>kod~*FZZ%g`(<)knd z7BVmMS!EnwMZpi5i>78$qcv+xL|8Y~v1IyepG4z1`;~jB`dSbi0 z!#tF1vLDWMo0I^xnP9=2(7qnTdSF@ z*nIvy>(yOfP==o)`#!76r3MR_XM8g>*)F=RVwqm;v~;W*199vgJBfR#w_ro-eYwyE z{iNvZpwT_Q3gZHBxfi{Ecc$p{pXbT8Y&>lsLUO+ z?msCVA5gAQ;pw;%d!sOa!+Uv2CHY`=X^I#KE#lOU1P86C{a2MXrRw%QB3qx(%e<-+ z_NcA|>Dhbx={fZcW1{@!0k!%XdYZ#J;7v?|0b!1hR|SVlhUwKfGfi>`=hSZre-rs1 z+&2C{!f*c#m-~OWcm4y`{ZA;~|CD?3xfDYuh# z#3KDa5WoMjr2bd&!T+z^Y1IG0{!Cx=tvTGZAJjtj(C{_vonmee4xj6y>`sZA@w8JuB|lWktWM(SuK5?kKb|=W;+bQg<9regRkS7_zgnHeKYX8T zoc=vCu|Ev;jc>KjOQgo+UF9y19g71jTC+0XrCriIlLuShF5J66fob-3(_>a^r?`7A zh7dm-jZl60lDj!z23`|@!~&+hX20x@P8LhvR}nc;oGmq72M-!Xrqx``648Cmoz52gFLv}EFq~sTbSGf)qZ`iXjcF`a4Hq9!JHXGu+7a~ zae$VUyJs=m`hfrVF6|eSg{&4sHV*)-EKP;OwKZ1!#K5Ikch3KzEBs&^awo%Urlq}G zr@)2=jzW*usd$o`BmF+<@O*K0enwRQy(hnN?}qPuyn2Sr4i@{-_;xOBR3g~XV=UqK z*vgkaskLXv_4qk;7rU1JeNk=%kqpsZEk%*3D+j{dl{jrXb zvfonjc8w!2&~!V3NsW#@X@va~i_{Mb}@fs?kw5P7jqfDo9Nr=?>g?}ngT{V7V# z&NO2UYtII_N?()s59~`YF!A??&aw?}>U3?)HASPwwPhLpfOpfLK{4Dn z#;fZD9Q7q)owx8;dB7wlFlg-SKm3?)mD0pHGyUY_)9*n#Ywnzg1e@L>wJFovFt(?O zx{qo`7STx~2+>go$uQey!izI-U;&I(=lr?Zb$AboP#i=^TkoN1Q;1 z%sLW*-nNIWeE>ifuSNOivkh>cLwL15K@G8QCotC06e|;qiNlDA_AWr&tkY(pU%k{# zBJiv4@JV|xftVT8gk+7w*ml~aK|Ec5_JSnmiBySp^W75U@~c_eUZLOWVDvcSdit!z zo0L6MhfLModM%pz{_{ zYiM=1{bt7Evs99%_Fpe=$M*ZUvkt%{b^sstl&&*IJEn_=yOx>?}b@Z8qBC4 zis1Ln%5$GQ*`q4gt0UB3!Sdx^iPhWou&bE8=e0wkLy5S}%Oxc(LPheEoU>6*=l06+ z2Z8+Z&*7^!f#3de*@o{Mk0YUKQzxvCt#Lc=7{3Jr1Fix(#*$jZLqt=|2bNu6jg>!r zxHKb`OW2yg;~KSINhskGRQtMppK^V4!sYi({N79V`f)X@<~%V}#`=b+AMdD@tFnBi zR6@t-dTDi=hUc9w@)DoRWv5#!#Wl&UPh7Co{K^K@2hW%wP8&KNC`EYIz@;IE?g$HR zUUGrW`lO;Lc5Y;K?ffwM?t&$NKFl)mfe@@+Ns8d-;$W0g>+ijj(j6K)P0L4bZ+`(+ zS$>fnzA+>XmRU>oD$Om)rQ)%;GVW;?t0cY2G959mJK2Xm%q#hq-C@tOsWko@!W?jJ z`$J}FBv!m~e1Yf_3Q@yDy8J{xxcyOcqv>dWb-G1(spX3Y!$sM7!;k)2F`LkK$67TP z_2Lc*Ecn7@kEYVPiZLjqX7j7bE_Us%0i^T9y;E~Lx~s)@TzX;mjv^unNE}gA_1<5(oVPKxoX&+V9&ODanrdx$c`g$INnM1CYJ!ZqpL1qR+DF(9kA}^>9StmG6?l<)hX=T z(KsE(1@E)oZ3u1C5+ouJCA^vTcmO4>^-fj5R9JYkdQLk+&Wy|9xKdh)AP00UrG&5Z zV{~(*YC8}G6cq7ZG3~^73F_E2(xEZ?GH`TKd;*q6Xo=+&;jWRs2E1TX$% zsibJGv5HosD{2{ZWv}DZ(esmFAD#rEuX4bCZZN7L{GJ4hQzANLm0Ny&6SH|eA zU9IuDw(@+-BT>j7EqA-?dD6(rvP8J?2aEHemeW!EU4_|-0;ynpxct^KdIbjg+nb*$ z&EdaZI(6*cv(!KNT@)UzB0~rZcaC>17&U^uIbB^Uf0o#$b7mj`m|V78?1zS)n*49J zT$#c4lGj+5xwCnCBabl>T5xGqunK-XiOcqN25|-5`P<*q-a$jwUxO{Jo*h+-vV5kP zc;c}8VJljPBmRat=+$d4J0m4?gbTyKtj{ukDcRDa=0Ecll3&R_Fh$+NAE~Cz`_j)6(l5q~tb7_lk|eOQyZF3?1T7>lNW239+n@29 zJw9iZP^?k$b?{|y9rA4|SaR-Z1~;YorDIY$8=Eh`X$Iy?u+pFuv6{7%MkqGOxa|DO zE8SqAtGa;GbF{SIIKh1HfzWfOq$$i)x)ZM=6elz!Za0bj8twxU<~8jQ$>=cYP*k;ZtR}CM9hr?AOIfxoA&jkEKr%Q_3FVbx__W z{KD+|^dk3w)#FZ%k7xOo}+q6J5!Zjye~d6cnwDg4j*e(uCvYUc$J+ z*eG1nu0xwVDpE$mK{7ij_H+Xk;cESikB9tTY5Q{{)ZZq@=DSi>=ptDW0S>T;0F#OQ zxjO=@&!#Ig@pEfKV+Oz`_RISqG)k#J5vcjL)gXs+RKTR;stc)x(80J~$QQzQnsx2Z#6H!I@uP54HdhZKNIF z54>J&)jf?{ZdI9fNehYL8p_VLEsAr0I&uPh?j*G{0v)ZxD6pSKf$BY*{V@#=3SZWa zX}5ptIu}{eBAg%MawQxRHY`n~!(~qm8sa?b_joQaMZOMn`D`r;yszd*wU?P6~ z8sBC1(i^cH{cGoQb?UC!)Z*u~5#xs14dc!~ll*4E}W9CJztt)lxQRH_DSxGf>UfjH-JmDp4@Zgl@lPk78&AJd1Sn(wlY%O z3`@Q;msI^Cq5XuNXv#?lSvoDz8=V~uQ2p%SyDL#8p{4(VRicXw7!)V_vo~S6nstmb z3X47vV=)>Q@3T9r;>o;$!ZJgcG`OtoYF;aGy0Of@P5~#>XyIs;B8a+E?Rk4c8&f3p z@TC%N@y{muvhU}RAj4ym26CDFD_tWjyq5Cng|b%l>?qu169gVo`gp%r+u zXX75H%q_KeFM|=Nn7T4aO;wVaWfOon(g-U)cp(Nd(TzIZWQTjR$9#z~#AXu?Yfqv$ zKEmr1cqQ~{&~+SqL{08k)>2TW$+LT`8ljR2p&;Y5mE-$O9&q$ItUHwB_H@%=?1JEpI0||f zjcwRCl~W>2n_k`|Q{fllS0sSLFu-klKTA+(Q_L_m{gzGG^MrRdEJX@?zn%mZ+4gwq zLMJ{`N9OcnHrFr04{rDO>^U(0WA(di9#n{e8dP|MG4b`?x@Ax+mbrb2v*GfhKNxCL z&YtG^1oI*EY##_ zo52l1qZxaL z{e|Mda%&_O20ZaFtgfCo}on{Ahx z-{YXoX}X}xxj^dRD^_;t#0*@J+e+b-32sC)vG%mM=`j>JZ*xa<8U-0-**L574yqmeDC}pS!Mk=~Ah~jE0~19o_^^q_p-2gw_sw(4>zKtVo|M)n0}Y zaBf7&Y2<1@NI|4H9#*9lt!4X;D-ng1PQS{Rkph8j&g?k$NJ0&58RT6u<)}i8v;8_`MK`Zdv zOUg$rE#>5dxRn2V6Y&YYx~J?Nm})5doPx&JlcANOrCvI(Jt2daLE?->s zjm=JiUFaLxb1sSZ6`9j`;v{L)=M+{(Q!S6`ki4)!nN^~+#|Bjzdg(BfC3zF}HPOXG3FOI)>4bu^k#=p3iagh*DK^dofet?UB=eea zr2x%or*qLm53ZxD-&bS?;GQ!038G>1$X#=jS2tucFG)tw8To!bv1|SA)$&X*FzrmC z-6`+b`+G6BQ`vX2%DWtS4LgN|%9G(^aQSl~(c|~5@+fbcr}lyuuiKj5lDhqP0Rzh$ zEL;SMtlmWVwt%|CCa)i_Q@g`KR%Co!a6GG{?*B${hy;VWaDTJ6F>6I(+DCkUr}7IE z$ws<`kk%r-elpP-QJY8|%~qqeJ)6pMMBEjl>Ahq_&B?m<4wF{H%b3)6526DMU``6> zW3NSWH{9Hu%DdHBt%upw=sCNNgT~C+k;R`?BgetL?91v-h?yZq#U){WE*59R>1>@V zW+B;~Ik+8K*vW(uj>=irYtJ;K$Hw@BH})>;d_hVg9wzP>x6wSJ@RQF}=tVKD9`pb{ zY!LIply%C)43(G~7DB{BX53=eb5c;JZ{7%n2)SAA!YRttQ&eLAp42iv_NcWJz&}Jl z*L4#-cJ+YjR{co2&)^6q^cE_EzP_tOv)1h;5&N~{Qix77(`~A^fiGpCo`bB(IiADa z!!BxxcA;IaYXgxn<(Eu=Z)*o%K4CX-7U<^X8INXm>OvwLo9I7g;o{a>&BOlT9#!K~ zXxlPNBl^84V<)8v;xr+^e|1&I)8Q*zZcZgYyU;A0ta^yc+wLGN<7=n{PdDnEhX*=p zI4V4&d+cx0U=wqdkuvUl9)X}Y7A^iSfW7Sx?!4{#b5Kg5>!vGXc-!?(&rc%?qd z>3q{5{BGcq!Z$pR(_F8O?}Qr>rPyOV(ol-`w-?56xwY4$86e}z>aOAA z?NJ$Di;D#}xf>APh_$q&jEhgkM1S{s`&efn@#TR0W}RgI`bp)TM(RmkRmZ&8RW7aL z*UD`#_vswYYeL~2{8?lNal%2;4F}!XdaKE-hRKUe=u7F9S*11beGSKrV_=i$3FQIl zSq-G`yqg1W>7}9bXh7`RROY-?ekXpDdf`gf^n3NepER`_pV@yXR?|yqS(3b6efX>1 z$lSFX+{AqBkPDb*t6hM{_J((84Y%%6a~E8F$#MUMX8GO!bMxt6FYP^VT|S+5P>$(7 z$vd6V58OG!OuN5tw_CrTt4EHknxZC8zW1|w zuk?d|=4f~^yI)oD?Jf{L%74#3s(VJ@%y{9^doZna)&n zjmZo;zPi0;E-i;H_O>{I|H6V-Q#{X#KLa)lmGv$!*3c4#|BfZDM|6OzcCId*L)8AV zp3kNKI48WvGfhP0e`NK#*J=R@_g{xKnvdvNvoeeirp@~Dl(``=)_x8f( zlxcgKtFI&R1nM2@Erc2q#W9AP(1o~n>*rk7 zKw9ev|G{W!e$(KEAoC>ugSVt=h$|t_S@Bw_xTLjFm>1%Za&MWES|JY0d23!jT_td9 znM!$r#A!Z@`Ii;CwPZ$Q6lG-KF?+41=C4V#1|yx8YkBy`hOq&F)$1%WRI~fgo{yv0Sr@ z5?UQ>&D_9n`c38^KT_sdjxYraMZI+Dq-7i;IP(nK8|U`O8#NBnsnRCkkt#*UX5zpFLRyzi1M9_; z!b=Gvdahyu?w*q;xbZ}ptoLMD*XG10$LOWlb}h|Ux{3+5B3jQMJk|5F_MO17tQW#R z2n$3(J3rw=H#1Q@@mr?Y%eD!tUN>~tJ+ll@&cmQo*lilPJ0mUcam|A}UUuywZ1yM( ztBJf(N;vTh)w1q7KAXqrz3Pd^YJT|VijZExjO4x)$p^(!_y-#j&;CYZ;FpCQ0ndZCTMnH?<#Xn>NK zZvcL6Wi@G=V*Ag&jB=wkMAy%m1yXv;u*pH$`SqX2q`YdZyul1 zk;}ZB3S1=kCvD4(9fqg$tG9{SOk8WiJ@SsWntdAOM}$L)_q}=0&+>V3Yi@Jl_)|Z( zS1f*i=$z6~&?}h!E=VG+%*IppFz^T!Vm7cLR4mp4J=&YLPcLIx_AKjhRWx+XOjfqRG5I41J*RYj`kP9s~<%LMN#4cvj zyJm9)0kYfNek4?1bOs(Df}`f}wFuJk4hPqA3h}0AH(WI&8lk{M5>lGv@suAvoStoj zR%d?mC!=QiQ@F}b#e92Ep%z{?xx3Qm#@_JB#!h`Ggsj?pr}!m&hISMYGCULg9;fp& zFp|Tkrrw=NstnhdPj|Nujk>DkbZ1=Prb&Gvjat|cGL|9KAdT;z(8#2*=D=pN)||jP z{H;Ch?ofWxD|dL%sB_KO%Q@_&&Sjrx@ltUUu0!eqtezSGKKZYzZ;ofXq|BuD&J>H` z;qL~khyaV3Wmc0M)jhRVvdYTt0~VQ#U!yH_nl9MuiXE+GNAWDsRN>Z`mUD5l}xmF&t2R?{}?=?J$_y%8W{ zHg0W-1!?3YABok%v=QImMP)XFlCgAh1`5_}+n*GdIf|O|dk2<}3lpQYZ*>7z} z>3?^R*6D6dFzwh9y4a1X7ySo5^qofBfGk*o420{rZJeW>wo#6_JH(TA1SrbarJFBN z%#0OWy+$b1aRFln;rmSLYQ7(iXw^90tdS}u?IdEssh*scUgW-oM-Xt4up>oHm&|?VdhkW8jVrPGuk^0BhJsT0p-G>;iF*N@Z=+ zlSEEKGX}gRh?E^$I|DPJdvEii)*3ft^l|w^l#%2^B=z@}R8tfCcQpV@AZnA*vr4nT zxxD*C|)%ui2ROr$MldLy_uC5)T|&0Hc-|K z)W)XJ8mUo~K*Wr-!itwJ0B{lL$dNTd1MCqcPs*a9f2yN$6jYaQpzeWc>o~i-S!^19 zd0xJPcYMV9rDGI^CUL7Ya*8?$L@TW(v*G|iXit-#skM$vQF*5oTIP`e2l2cpTBm}? zaE{HW@0qDU6rD7xL{sD%VdQoYCm?wdS^s>LUXh#n7w(%R6u_YZ*_Jl;^K|pH5^}5? zSZT;WxD)Dkm>yEWD83WJ@CtPdse=vfDW{`D9M`g?q7WPaE^W>R0WLyahqa`9YQ--m zZ@=nqhB0Ci(jtyA(o&owKi_#oN>%yH9 z{rfDW>r5Q4;Tl*#(X*}o5|@%QqW~I*yFajJ&fW=htA(+$+4f|mn4vsvwd%3S4pbQt zicW|}F_FhtcFpVNc`M#546jZMx9y1-mRVa7utT2~tX2nPJDOj+{?<8Fhn?g~)zo0# z;7m&ZVkPqDsH4lin{Omadn~7T$oXpa7whmZbZbxvy@(#rhK{AQ9C9cJ+~ADoh%!ozh)GQRmf*vTjdl6C zb-)mr`PD2(NVu+;;5Z0wy|vw5BVpiuaKMv(do|bT4lhEZ9L|T0>!3k<>J_qIjMLL|;^x~J@9b(vcQI*(D!`gs$;YwMU8hDT%fhP1hLhS)Mnuz-rq&6yBElM>!~-SMfD#C~bF zZsE9(peX2NFE446RiJ2`H^oM}H|1ce<|>QT_`V=cKC%b9R;ZoN<+~BOs<#3C)qx0*4i zzuMRGjMe1d*_aGKQ%rcDT;vLu{KqLXRQrZ)7iD1K03|E1GhRkh1nO%v&Dwj398{y z%QN*w(Js~h-16{MR8Gahu6y)LH#C~{Eq!eMkK%~2K0mNTsX654(XZDhc_`;~MQAJ+ z^4wMEIlwY-H@U~>@-aSBH*5*Akhdo}TkKQufA#qQ3c9yKf)DDuuCTgmQ)fJM0I~9J z2)D#|Ot|%Bd>nEV!WAE$UJbhUIff8y`{c6EFbAfFTN7gw~?F{55uPh1NhH( zjb8_#+qw5YGgoW}>QVFbd`Wwl&VsXSH3wa8MtF(vjXf5X zgE)|cI=oV)T7Z1(@UjMECp^EN)+ljxr~vd~jI7o*=`?@L(>!1@Hu0NTmX+LHfZ%=o zFP2Hm0e!*T&Rg8I$e_QCOe@2uQ0rOG0Yrsv{U;xBM9hosPYZZ354Jh24&{z|lMkpZ zrX%1m{JTYZWNLr%+TWsz!@dL0==xBq5#iu}1%EVLfoT>>o+~DLZ}gg2A#@m47AnTH=Wx}LuduCS07B`IXGY``kWB^M69vP`F;^$ z4=${rah2v$NVx`FU||q-d-_hoq_FS`FD-5Tx4ebYf+UZX8#o*Y9-uh9~Z7~GRe3vJ+cwG zYVoGV^mPM7WbA(aEhk@0yt-MCp+%5iV5OI-#Cl{4_XSo`=z4a@=w|l{Na67|W+@g< zN*AW1vvjC0Lvp)C%_&AgOm0%i*faj^!#`E2|Fs(QAB_CJ%zlz1tM`0!XQ`VL9K%c+ z4co`TbEo;VhN)sj7_DUejep_ue{)6umq7Z@C9(hT>u077{;pf6Lai3*XSLgvoS?(A zrN~bI2bFmqcQ2|Sn1%N14~BRAe4Sba*5!*&bVi2gxpAtP_$Z69n9=vLNgx?N}8JD2_d?V5+m zaQ+6{o-->yupcKa6|t|~eI1nvg;5&Ywc@CO$1eaZJdbDE#i<>?ky%9>bqcqWUy}oM zu}E+bT@aFm{O?S^k^1Y1QTcaNM*r;MMP4s8cIu|ET+9u+s0werr^NRa#XcE1`D&97 z_^`-eMflBiXkl@AD1|>1bXj4DDqV(!s0x|U9@Hats0s_goQrDU_U;OO5h1U2mFj!< z5RChsxJJhz?vZs+V-FjmufLM1;(w9rq#$02kI)YnGVK1KHMkJO1ZaMyV8!e}0&8&@ z?k#F&FB&8sO^#(=my1O?0ot-6e)yYMj2Cy}+2?0X_Y$EJ!&qZ0CUs92f=M6cqZA-K3 zDuV7*_L~6!_J3Eu*L@eeuka%?<FaM|64XUaq;>*@AMItBl&zAefWE0MXDkZ*QO^dQBHBF8F zEur*wZ}k!K3)V4jtsOM*vr7=S1m^+_8!q>2^;vNy)tYgSq=0IqB^81@NnUO*ix!uuF_Y?$>G|4G=RM!IDLvNcw$q#7mQa4mJHS35?cy!z6w!1J z71uo0C(f~w@;<%*+qIv{2Vi!BP-+P43Or_WNn!qsqr<`VHtju^0WR0|C~r4xC(X-R zQmx@NzajE{eH~c<*R5mkFi#G3Pwg^Q;%DiKh2M3N+EuF~4x6)f*UM@{Wot<4mFEG9 zSKrCxyPu6|6_pPOrL5qMukdLg2$jALQLmi7ZYqls8i^9} zC#2*OaA?NCi8pUa%C%;00}6$>Dg6bxmkc_ZNZv~RhVS%v&X4R^ytHyZHb?*y<9J_8 z2`D_~^4$IDw5Fw0AEq2lcv1bupddWe-*r{^#~Xed@u_N}wo#GOQ`@&!Gm7~2&Yq;+ za2=mQKrwfv;3p!z^2u9k3=@?}S04NxyVRPpyDLFK;Zs|VkFizY#`ctyxugEj!k-Hs zOgbIMCtnt7IHufaBPx65oLE?3hbINF;V6t`GNV0WhB-lGtHMxG2*uX!!G>6#LGEXcO-7tYVzWrOu|nv{blL@3*5(;J=| z$kd^Qu$2J28mv0iU~4Tr)OwbItjnOiVe)v2gF)bm#9TOVyJP|_3;4zTSp|qm$fOun z`c*a;K3T1YOfpn8E)L5jJaw)#2P9!Vsx&#!DxwB`G+A?Vw>JwoGPMHAbshUm>*hnv z{ivTZJ`hdlGG%HLr4Nx^`TI2Q_Vei2YN!n>qrgO!{ypeP*GG$SpY0isE;F6+KBZnI@7l|*CpV3!Tszx>#5x_x`IjvR zkwq}RW~sM*f*CIm&ceX6wjF!@_I+qptYB&BiA!xs%Y7Ek7Wr+f&Z(As9oiwWsAykK z8G!1;)+Q-V?N<4myxv1 z6n=6EBqYm!Ifo!KQ{SIY zhY386=~g$$FAA|<55WqV&Kl@h(~tQc$42L&)-HCd&F;$IXMPR=vKJGCO=W`wz5r?%9bL>V`hm*xRI0zWpLNs*@wwOdBA zeCSHW3!hA+J#YQ|*|ka12Q}(6dvFNbDJhnU%~^bvq5sl?oAoVPSvft|LVf+;=^7Xz z-=W`+HxDv(Hn~O#UDE;zyA>g#ImX$hssw^ocArwD62sV>Qy(-_jVbY{G(4$T;cvJ0 z&B0#n)}m66IiGL2FO*&h0T@6c&FHshV|#Zq3Z?Vc_L{lZiRnDhIg_miVsh?ZT!OZb z?3yH4K<``3GOdyFM;GeHc`R7vHb|OA!w42Xmz;RMwTZyABRKHIf8>U5qNzl!+kXHl4fA zPl@RyF)Q26>AWuABT`4zs~mMO(% zr85Cn+vUQEU8yNpnMSXT7`UO=!~gy z>*IKn&KnS4Nc3mQt$WpTOZZ_hX)+y5(%8$NHsV;9gZ1Aqn8-e+_r=V{4iNn;xpz8t zqNhQ+{R%_-mu!5^$}~vx*9a&2cbM6VEk83GksF?Fag&d_@<;K`OYEk4n4pl`581;G z+n(rdm5TK~GDL(p685V=@)K!1vw^#PQ@VfKvDfR|jTra$zmYx@2R6RG-nxU^=1HU9 zC{S0j`0oAWrB08^k^<_MS)g5JFF!70C9^9^iZ}~%;k%HZswJ808*-vOpD!pF0}P)+ zGK7Z>!TcPko^o&=qu*s7>TO!4x!|WGm>HJnD|=5_bU4%VK$PdBl1R)$QH0KpB0}dv zFGUgmuBG60e6S9+caB7lq>dy183$LD=GfXs+h8pFbMEM_8XD1UfcP&X$r|{riOq3A z&2rqNknV`Z=z)e0{@X@18}%SZR1mu(df2Db778fy4NBaHl%Zpn723+#$$7aCc`03GVJ1++}d*cD~=; z-EZ&ychA{#IndNpcUM*$M?=+n$9YAX3lPgj;2pkzPLC$n>rf%k03vJ^6`ljSXkA4 zZhz5B_rv*v&@tC*Hq*EIt|hp#Zm@E7dVCzTy7e(7W^`U^V%3Ng@E@j)5y zmsnZeb%_5JT(DG;2NFGC!Uu1f3^yU`MwaUX%x&WLW3#@t60Or^vhqbggF%>|F5 z?tmU_;MC^{vdD7vNED8(A-AL@75K=`*+2awPHpwR?_UPG0@GSYoY`Ac>x2i{gW{|H)m;PW@c%b zIhESNhFIM%!|}a6SXG%)xZtmn&okHRS{N9Z_+ZQp%#fH5|L2xuU1bvpVRZ~ za{}*un-rY^{f?w9c%k_?9xik~EA1Zcz`@4mCC)!^&J+R7tE;W`JwG4q%1tL97Fauu zfd(V15f?PLBi#PEABkT7%%{zLzv6+CvV(OWnA`#X{nn#O`u+Kx44I8sd%EXIFzJx| z#pdQFm7n70I$$ID-4Sh3%tH^JD@&!RoBOlA_csEJAF69>@n3xtWc+ZK$rHNx>d6y( zAvRdLhJ4<%L9=&5{d(vS=IzR~7I6Q2CR?A4fdQ?+9mnTy?;!ZVDy)jx)hJsf()bHM zkI$38+?yVbsbZEbc&z<=K|=62~kJ43upv#rJwnClxP)R9y^J0qi$ZL-ME zNWhr@x?3|dYjWf+{E;H&idq3J5w)m!Y8b_ia z37x$Devb-lVM{m4q(Td@wSu>2Ds{&?mOkQn(~rNn$E8c!gR~9(oajEFw=$b_2WV)>?M`7~AmFVTw`;{3D{)gS2p~`*Kt?)2? zM5wm$SplhtaMxUXlR@}mK)S-4pCjG#5mP8n+{+IZ&L49JQ{DdjX}NtU(E+BQ*XVrT zk+4T8!sJuQ_IS=krmdr6=ftCCFm3y=9eZzz)N-%ys=&D(Ddb$R$7$U^YcVKveKXOU z!lvwIV)ygnvh|2So-tVFVQ0(0w*JS^tiR#F;NW1mpo?hdE!zIlt;cfW6K$p^e&&b2#ia4q0zZ>so#$UtF|Dig<)Td|~btkzDE? zyUv@rk-AVQWy|KYX=YVydz{pRU)vjIrwb9l+S#Oxp+>rR`Xu7;-}I0Ln#0(PwH156 zokZj;PGFc&`9<+xhGh(Xv~qH_vf6vG+|qmnHG6EyIp+RdhI$6I9<-2(rHp}LwhIUzx{KN6VW#yc)i;~^&;RYOK zGk~iw**eXqk*V&izpsqT?smN|o(_qw`EI@gaes48mdRAqymU881z7rmD}{~aXZjpR zi=CqLcRF2xC8tZC#>cDKB9n@ky)o5^xHgMc+KWUIs&4Yj*VtO$TMA@w(QHqW`fe* zp>Ku)m9O)(=_()@ww|f<5gP!3=8jh`04XfhPeB}>xOpCCl$8p&9*?Z#D51BfRUZDl zTHEOwkeh#nhQGbeTzF*Fc`>*bCV1F1I4?+=xz4et(Lvw038&r36Sz zJe>xwd1%_a%prHp=6-Zpr0=nB<;w7pDb?lSd>OyXoS(k}U|SOy^gn@@h!2s_7P9*xZ4xZ^7RbQFh9dO9JEL^9$2eKqod7uPN`2= z#24LYo7FDkdPM(ooNM0q`UFd~{Z?^_)>UdfE0TYV1px>Zl-U>3Ju`V=@u;7>~~T(ek`v^Pqrr-`d->j?j57 z^QkbNDzk;QuvmlB@tre3#zG;UU+T7>Khi!%cK0&|ez_V%VCo1hAudvxi>QbdJcRmF zEeM1RZO+#t^9bzfsY_~kJO*#d@l+mn&npdkXVcfu&4>WyWS*nSmlzd8q$$z=u>-Opf;V>@{1yK)^2DU zf)1#vzEFjENlA&8P9^m**;ke3={YIK^R@zZ|Ya%D1$+CAVA3G<~GMU&Y>pK3ujUH~Tf!&H6(k zrv0qUZ~4({bQ{lBE*AduJ{^`xBjC1gmC3U1Jh<)e=va3w^DDCYN|9%IBQ<#zn?o_( zuLT4oY`-td7D+hrVy25>-VFz~vBZarRpw2;=2c?L)%sr^mlqsp7IyveJn@FG8<{Y> z2Iw~Z1s|s06s%z3ydmo<#_?86yK>wTs2*cdy&tN0%LLL}`yC?AmpwZpA@aN ztb0FyH~M>c?iNmbQ`vLJnc(>#M2AB{m=yOX(m?ndlFEh#2bkTZZ@IZt;Npm><;|Jj zIUrJ#HOtIl*RNB|<>cgoP-`9#vTMLD!@O$`huSC*M3Fp0nOW@{T?mnDGIW8(M8xWz zHV9wPdYf%^ML=PHcF1p^N7<)Zrgl4(86#$zxInPc>G;>q@7OTL-^q2#sl1CU+v~>~ zlL6_8;pZ3J`j3mT3jFe5zB;=*g!39wN*yZtn^XzDGvSqmhmj$gZx8K(C(B%^@EQtd zWbA3QUH1ASQNGFDDs=@xVX*m7{!n@g^V|wW`x%J>7jHBB*l~Tu4pqCAZN5Q^Zz7XH zgb!Ee#Duf0d;ZF>ejo#gm3`~I5@7gR?p>80mLF*pptd$P0zTquXC6DtcinE}Z$Yfp zh6~Zwqg)7of&ZTC)7EspZQ6_Yvv6L$p5< zkU-!xTSW=ohFt}B2fZcXJOh+g9xCW`xNt4>Fv2qz$$qvIfq%UkX^tN`L3m&aKPK9n zYh;xoq|JaJeEcW8rImmU^|dmS92&Z74#ueysy@97Kndu~ z2`nv5!JqSRD)Qh8a(&3SZ9jIxORn0&?Sf|!9iHLEKfWMoUlV;S@D!)tHI3EZ%(V&Z z-XXDWnB7c`_%VvO&ppLqw0>N#Dzl2j^3mtLh-bl$6qw>M^q#gqi7*KTo@HXQ^-j@g8!<+Ki2ojb7MeLM({3KPu&tbZe?EQs{nb0%kv;LX`8*!42uSm-e)IVn z5s(Co;iOZ6!n=Ap(&TQve% z#v6eJw@@Vk#2ojtg~!FT0nd<8K1bPfowwHcIW-IiY$rb7gyihY@$`KV&Im<&)J%)ogX0SM^1Nl`n$O;)`0!) z!CKKdjBj%Pj{FFcS`>-&Mf9mIvF`hW96E=9heo98KFiGc2mWeI4h?bbYv)&sDo;X>~l6KmWG(o8k zVh1$j7k4M~X5g#m5mle@#GNh{Nc^?~QET+ktMb>DWn7ssMyDs27bZ@a9v-}|ThK70 z-LJxRuI9YN1J6y7-=e?aB?c0E;-cGHSTNT_S^CauPeXeU>SU@wongOgdj~3s?R2UD zm-oy_XS9>o)f{9rAF*N8%Jn|;_ZM>}L$J!EY> zGr$V`7Hjw8&IeFe9ul*gaFV?*LXJ+G$(I<3<~e1)xpr)bbL94c0c*n!9q7?d$L{k% z9F+ih*E=tc6O^iskoNQ9#q7M`AGXSixrIl)(eb@5u6EUE@N)a~+Y35*dUT?eWO>{K z+yuj5)mtaJ07JgSa2(8Nm!8V&AS&A#ij)dfM=p&A<$kW&6+69q*rUp!lL!$B*%)SY z(u`YjKgxYD<5V_b2FuaFF|MIJnAoma9p_p~s@=*?hDc(JN)44ELfPpa&49?x!#2Uk zZ?_)yr*loLYpZg{Zyokn%N=2Tb7=Com6pf0{5Y~odS8&6u@RuiQfhCHcAt0h8a>?A z+d}_}Adn`d&gTRO2tb)iWHx*)juVpefC(om;K9c|-bKZ^{k>`3wU7!KVlS*7Y!Lvm zsfsf91$#!Z^vFGOkVH_lP+G%Hyok(@KO}Wu0(ygxO$=_jIqt0N&mtRV<#c&4+C@sK z!jTv{7#vo1=A1K}XmDyN)oakuYJnP41+zWBSBGG32T>`r z5slyeDOKw<)AzAyuXP{=Ki)$j&^5x}qIANYubyhea* zs7ek;@}>>9;Chp3!?R$}ujQ^(jCZp1R71WorQd43ioq+AYxMY4XQw%wN@?jZFkSL$ z@e(IJlJ18oI=7Q6gQCl53zlVyp(y<{L+Z4i(J0+1Ywz^N!9y3bcKfV3_88 z;-F!krvcX|o(Rn~ZrAnUDUF4AKkS|lR$vB-`*#PuCOVM77zHo`%a(#Y)`~>#&~6N4 z9D{pyO5BC(;S^o2VK3K~p@^;&x`XBHrko5Y5G7rB&vq(i*_PkU+t(e<@mvm$goTrI zQsmS>bRx?1jd25`p?7vJ2NghWq(MOsD-fpvVZ1?VVYxp7pCKar@+ZxY{&;$ZJNW!r zdnu)RaK=YqQe!|%UN%<&22YKR-XR%iOjn`aZTBpp)tN0M?#tTmeW22O>Q$%V+ZxNn zPj<-Zt?R?>Y&5Xn;>t^re2MdZ^z@KvM51QdfW5514iE1}Wcnxt7utWP)NRggz@GY0 zy0W!$G2Ar5>fE0wopTH`2;^!0dX&;C5T6Xs?EgR&qy$8i@Q3(>)PT_)y|Yb@#o5%P zxl4*xE&hbm^0U13$0Hz-PDe-My0iXam|3{91q3V3vUixf3#<-SqI^}H=0(0YS~qR4 zL36b%_wPy-3_RD-T`eZ=>>|>yHr;(rlF!5C zrB&L1Q0Z*AvTb!t#%-JHl=o3~?l}PyeNL8GUzwX42Sg8J?iIh(!of^Oj8TF$PWbkQ zGMLQ$2Aqp7?_d%PnJ_5!I1+M2KZ@u1SejoO&zWM2b6(uDl z5IB!+G`|E|Q+KhzFLnAn`svU-+F&i5eXLd{c1f0MvwyI4kE7OEwnU~zRPoCUK#i(ytj~YT0k3an=Z-&ua zjoWe-r{V3GIn{`@_lgxyhe8{d5UY&|Xo=JChTRD_3>j6?XG^#4!8XPheBajcnxI7_ z={LVw`7R!)dmqS_b#V=sPs-$q$g-xfpmoSz=7GjK5`ot!hpx{V&q;P{+s}L%i=v0o zK6-W?%gC*6rL&OzMv18Jrvkvs*Rr1V8TSag4Kjo39m7q6=06XJCndChG1HBkPOmYPz2-2H7f+tJ|Ev-L&`>eI zBC5cjDVLm_3r29o`?G!k7E8xv%}-Cl>jTjHKf)8k>zj=C?dg?`FvP0Jsoh9YvW#8`v(gd2VL=k@}kN+1ceI5`H@Xy=X2UT?*P`&+U1%ELXta4($`Un2S z?ZvE%Wwsxd18({C_3Kx@diLtSi12?Sf6x@*iW`CQ!|Kk-ib>l>(bYyR){S7 zU=LP}Znn>}(Jjs=r<7orK&g>%Blnh%oeG>qN0-VqC71h9tyiO_HfuqE%~&-DbBQ^( zf!DOsxtFRtyK%~BK=Cv>kgHQS?aizONrZ~{mq8h-Fz)vB{hhCrW$T*c zmf`fHu4bG>I*r%Y+g;i=N80?1cOVouDJGp$G&63`J&i(sfUCcnn9b*mm7?426ffNr zl7C;fIH5MHG~NW2;0s6oSyL!$=$>-&CGSt%LN(7?cRkRV3~SO?N)xp5uZyj6`y^Yj z!lA(@(U%4FS2-ESei7#2=6Hdsr8YHF`(&)Scl!)_(b zkG@`OA*lsU&It5-2=89JT3Jr)i3?VHttb|A9YKiRTSaDcdVL)4K@7SN-v1HjQPki^-l&NY4X^KUILJfN%?Ek*RW_9I zy(sISwaXJKXXd8JYBO#cu3>n6vg&Pd()Bz^Wb!Z|L#kIfQSL$4Soo~%nVF}N>yt8C zS(&*d*#|JVaaYZ0ZSNqf%8@8wE}20}hU{$qBy%4k`KYEOX0Lpsnow1-?!1J8L8$lA zWrLQ~%7pDdED}*a--}M(7YvHT17YEQZV9q2e)A^6TU(u_j9_qS+Cc_*mw_BqP-oR` zb;eO-K+w>*rV!}%S~r$^GFeh1DY3{gxIbyP3j@8y=sFm%T=7h<$R9ynzBkr5q%!Nf zq=uFa7Ax{12|b-UA`O+4yBJKkx8*O>rs$*Hb-z061?oz5#AEk#R=F{ptp;0TH|G^x z&VK@D3sh&tc~@dQ+lN4k6NiQPIcZv4o1v)aTJ=L|M+Y-goGY8s;PrJ1=H{e-G`mie zfv$fsO+|5(+#WgY@MC=d1(2HW*7SX!A4g$dTU`ou#Kb@^z{+DEq)PB4+>bX3d}Bu>DLdZz}M;9o^B z=IScjcK8ngZHtcD)tH5jg1TgeM%|4Zr)AXjJ+9)J3=k+|CPa-!jnHoJbc)}uL?A9& zi++45nwu1#bgbW`uU2UCq*ffgA{-JYjXHf1;h#HJU9v$t0We`-0l;MSSOIOl%wXT# zO~US^buNG@>5EbeMUJ9ev1qxFAIMm1N_e+GQ2W2t0wfhGsn@a^isq<)Y-Tg25_=fm zSDTMj?%xOxnOpc#5+7JrXirQkD0{s-vmkAnRoKi-YN67Uwx#3;tk4amzWuWmJ-m?C zh9;s7F$2?VHQmoSGLNsveI{uw0;H=0DMjQkJ&|?YHjrdm_XjIOsPK@{ENb0D*;CM6TIG3Tg=1Z zqML_;HRkFE<;Jx~D9;CWU=FLDHu>|+Od0B{BozlfLVTpsxIiyr^&+@kNZ>u0iPB$> z55aMJL-i>I;5l2<@eb#JQjdQZFZ_#B{Fkr)-&}DV)fGAyZ!8g6ZTGmfFCfUy2@`iZ zuwtL&!!Un&!^;DMMWQChN4aU{u+`=lVi}9WhM8>l`AhhxEM)grB7|yA+SE{T!_HkD zT`$w#*OFJsj@FXvNyXhxPS)QHyNSu6(HYbjgi@PK#udMc&X%TH;?Z%^&IL3dR@jypwk`3%k6khg^!D&7o*b zYwD|)9Cq^W-rQAhM}0DI+ZrW0e?H+%gH$AmPyx+R)}!7)&st(PQ_g+>}#qxEjh8Z|8|8NI37*J03>LUlNnUS<_qG7$-l zQB9@jH3^km0e^*qRUBq_V>1*n$_@hAbOwsOlr{0Jk0S+%Q|}C7zb2##LdnMV%e-lu zxf*`A9smYUCXHIvAV1a5Oi4!Z#1pMbr089mIkIwd5)vq;lS``Wv`lFUJ#W&q_@;5J zTLOVd>Jhf=JCzBnrFuqS$M2jPg}6lcl7^Z~iov7UX|-%thEU6pu$ivyZK8fQmGxbG za}3SPP2tXedMFIf?*|aNJwCPxjka^|!4>j%@)0)QS_k{}`Gv>@ofIHe`9CG~;wo!n zA_sO}W4^N$G(Ol2%BJ+*JlD#^-4 zi$W!_!`yQ}+@<^jA9rvtgfX8USNx-ci+y9T+{Qj-(A<5&E{YW<^LXw-#Y4iTe^6r0 z-bDEl6{*%x+YfCE>4!Jd5ehG#k=hw=Vc}MjIqG-tj;7&KVF!3x*`7~ix2##Uy|0)F z_mlr$LX^U3xhU_}eFr$aSXUTa7_%sWmwvo6&8~VZjB@9Go#st;U>&wNKuvPP?;_K5 z*k~4h7h=}UwaMoaK_oKV!(~00F5g8QZWFLJQ!5i$ z>%_UW-W7i@+#8UtV`H2CfZvz@tHUd4FghaMLJtYUAU zUq@{N#ahNqi_gc4To$p7xisXBZ}sx%bvexMa4(~WnxCFly({7^jJj+)@R0HMfu=4l zKF_M!s|F|E9Y-BV`)t6<>Zw%GcRu9MI6e1)?n^`xV!n@2TxfQf3-s^M3UovXA57fI zr!>8*6urqE)~{>Pc0SP2ipD2iKiEHHr~F8sQJ>M|RGvZYFy+EAGIL`vUqB^8as>Yc zmdRfFpF+ZX%RRyZ&F#8eaX+Jy^xK7DK~#r#k_X&oHKtD8FLL@IlJPCPktt2C0Y#tk zsP)nD{~YcMP~_G(e*UKNM?JZjR#`P#=@$q@8|nH+UN`+cr*CoD<;)I>+XVib$7D;I zJzF7tgPO)T2EC{QeRN`z?PNTXv?WgCx=AUW76H#bO*g8ouTei(#T1Y#S@~wXY_+G_ zJ{cTUG_S#mVhan;|3=D-(5@GQgT=~qN5$u--y5fn|Bvx9!ll32)3Q(>>wQ#IA`#X^ z&ZdE1+K#iLIft{`FBc6XaQMbf)w3pOs!v|Whkjn8keA))Wb5_?V(@yh|H_Fir^st! z%!m9`L6rtU;o{;LNb{vh8mmU;qpBKZtk_cm3G^2uAF}tO^!W5#RdY!W$q%$)B}50; zW**SWy7>vs_f6%W_Gg$~Rq)VkjgXzqdzA_!mx^SFDhx+#{fmIHAj1-jZc4w#bZ88O ziXIKJGwe_gZ_kXp*q`H$Es}*Sk?&cY#^)ea$6`)V3|)Gb`WP_uEOI+Ab1|Op2}Jv) zZ1+wk5ZTUmpJYmhXSD?7AQDPSWa`)(y3CFiV_{=zD(_<*73T*#h_!2hRG`<+bZMzc zXDf79WwWHTab$7R?fSENOc-R$}_YxyY}R7JtNW7%Be>zOZ8E)RS4K{0va*{U+e7tLG0HDCH^ z#}l;~U`C*5P{gB%a2?Vtq+ktAXLlT_VnjEx+v?BJ^!kT2bv9U0D*LKBm#%i5Uo;xs z7v_t6fHu?GCZAQ*N~P^x(#Nn4iyb}~sT>zQRhIM6@|lk>fY72n-x|Y^=*hJp*C+55>RwxriybFcl+=#X-TtV zCWK$0JsrnjK^H^DNlkt#G*|VQ&VwkO6F?+kH4+!bZho>2KS(WJP*^@4NuEfmF(GqI-O?7Vad>s zfGbj$UuabiSr+TdW|#CaO}^zM-q#1$jhE3KQsqj3Tw(Pqg!$2x zc~^wa%xt=uVm3M=xLMGHMVo57r+Ojvhi?)fkV|AVr+5q{QM2MvBX+^&-`l<#i3j1Z9dXT3F6fy0__-jpKbD(NcN75 zjitbCiheuhDI548z3U-b+ml=@K~Atq6TklLZ{#s$oq%mm&S^__PjTzc(`PbEOpN`~ zy>B3@6nsTL*qjotAdntU&woG<5Dzn{+E&S=XgR<#xKEPCT6NpKPZe2%z|Lp0=F?y=>rn4YojVFxv9XbgnS^{-oUbNltuS;eT(-zZ+R zqju+=2*|-&MASypVm@igpA6+y2@a6UB>c}QlKmQ9wKfCGvj~d772L7i8nB+FX_dN6 z>Ms~V+I!?=q^&?FHngkc=x3xc_n1|gL5zA9MZ}(I&NK}{To`!a!9(#28G6*kTy1Pr zFb~Qy-jS{8-sbKK-{^26Sxhe$`I`z0p%lrx1WAbGQiW_zNVKHbLFju)if1LoQa0X7 zR38TAHtZU3T-NcL^b0Kyz40ni*xM_d2bTpL!S5Jt1$~7DIq7%eDk*(z`rNnTicTFI zv3A(|DCJGYeO*4(%SD1fdMcN{6+Ta{)yrCZP5i8G5kI%Apyn#MSD&BaEL?1LY~o;Y zlC8lxI|FNoI8EnQ@4>)>&gkVRr;f3wYwkMat4O`o$fs`Y*)*ubf@Aq{yM5G& z4vnHYW7UF;ClsZK6)WfMRxIHc5UP_Ed*0a7I-fh~Hq~S^_C*M(D%)X|&jd>5sd6GP zgJMey%XN>Exob;YE9kpXH_5%{(feM{Ts){dczx3hEzt}BB+c!x9}oBa@%`d&H<8!9N|n#BHd9V1DbA#Wpj!mT0Ki zq&_`JQ-p(rFBO*XQ#{9dlY;Z$$Y{-^J+3Yuvzxg|aQxY7C#tc3CY<|rEfoV#%3CD% zh`pZ&3zd*==Dh5BgUdy%8v=7_Y9bVySz2BC+(Ax7wEaT;R#iXmt ze9_cBZUZE=I*XNNowiC?nZRPjg;vcn>Dgy7Ee{X13qCJb*?}tw5IRd~sMDHm(vWb> zWRI6a@sg@tfy7r)PjM}upK@9PLbky_A!ocq?G^ME$*P`oM-e^+QT^4KJ0K89Osqs6 z!{t7sbbQCfdOo5-n*lZ-S=_4WvzPj^A3Kn85<%RYcJWm3w|}zBDJ_gIIdk9k@Y5kR zO*`){AO5Ya^UXeMt<&{Nw|Q+#Y57VtDO{0% z;#CRe*$;9T7UWMNIE|F2T*5xanaU+axhuN4B!QZ>)XVl~?mUwMF}0Ax8KtesKsn0o zTBmT1VI7oY>G9eGgQ|CpfthFf+Lfot)#Rp5hC|*Jg}c9EFhgHzn_}W^u6h*CHrD=9 zmnoJs$x-W@KZ^Lp5d7w6ji}UHt1sK6piD}w@$exls6t_kgZ^D`Or(%dvD<6=gIdi= z4v&JDju~t9QJqD#2ea&YADPM~aiNlL+hg<>YdLx2m5ntC{sT(t&SPs?p_!Us_g9N^ zwcvPNbiI@T1G3>3{-x`J?=kh~`XteF-D)b!4{w<&cjYw8792k9;XPV-%FZ|o+41F8 z*tBSd|B)i)n{0k8Qhz0{aBy+>tS@Gu7^5ltavc&+;JWWKt)-_$nYDtE7RMT1ZUfVt z9denik?Wc^=&t5q!pBgERrbL&e=#(r0*Wj zK0VxY`nqymdFM^{S)ysE6O|V8YBut@_-ZKH-M2K=oEgqd1kl@*sbdoOWRynObtW%nCX_w0ql=GJRauIQ2GkxipEg(R4r=?8#ARlXJ-&5Tr`@Q3ysb|DTQ=S{(yF}>nDcy$id>W zZ{vC#SL-xrRDmnw!lY3OvLINqAsj)Kbs8MhyE5uIarw3*n|+nV@*dltp}Wt}qvcw` zMalj~B}M7Rmz{m11t--2F(cyS+-i-cZZ)#{dQmY-OA8m@ zCP`<~g`z9y_kPJvQq$=qm1ii^y?5#Ygcqlo0J}J2t=F9;rjVA)$xScum!WgZ=~}MW zZpe}xyX-)?l+ZwU%Hf>o%j);6*~J2?B_mFRSt`D2S!4Q&{W4=QZ{o7YcY@u^EEtph z!J_vxQvI}JQcdI?j&Fhh$+~xqP!nC~1&-u}ZX>V#WL$?}{ zNyX$C-Cw84obofU`!8@yJq8_yZmp9jti zsw>PC`EvHK-UEhe-trq%AY-Bq?wORqJW6T)&NS0l@X=={!Hmeyw7p+TRwd zKRxEct++gNbv;!awO8XJhhsYJB_7vZ*u=o=wcbv;+I^c48rr6S4mNL}eeQmFpP8xH zY1@gM?A(BZ5mtDIsr*#odt`JMSU!gZO^T7o6ek;ef{c+ax1UH*d_bQdPil^kg`zp> zg>od%QMbDjcwypP>t>?*Ov~3?ih052WR6>Oyvlv|hTiAz^U;PX)h`~7O7y5nGyi07 zoLn)Cmf4|8QVvC?)|0}zS);>Hs_7ORw}}?Jo+I0WjfNdo(N4%Q54>hXi`VWrLRFN< z+w@1@o15;{cpqT!B~XxI24_bHpQ;sc4WLkDh<-kMmU!i3vq%TfF-d9!F``1FBcFq} z?!qg4ML-#&gGXYfO@_Z+KO{yQsS@=))C-!dlJk}Bv6jsrtwVp}B_=F!j!xPQPCk6CC}6w6*UTu~YeByLEMnN_*7xVwcU;`$j1XxzCyf7t{d`O!A=Ml)4mi+ zcLWiX!}$77YUXUpcZ{{YgdB1SHA!#K6oq;xm3LaI#U7v6DZU?FiFD4IhYSdV8}{ZM zJ+x7tt{kD4hPTyu?kdEKU!o1|;}oDR<)m3FLExGEmJw)MB8FM?BPS(z+vW1QIDN!K zCqq=K`7m#BU?JXp+p7|hc#qD}f8kU4y((#s%t&jet=Qzg5H&Qnbd;rik+Mt=fI(I@ ztmWkOY79pwTzJjuv;6LA>jaLx6?D1siiePDMxTe@g(v>h5(E1&wQL@Pd02S4Wjr=FH@E22-4Y+^J(>&4OY`#lnUs_i9E|)19U`d_d!qe} z;=aK)Ae%4seV(V6&3kz$*RNhQG+IRO(b+kRo}P9O96yLdi^X<2F-=~rl9yEr@5*9G z)xo2B-12wVa~3r1=P*`2?)BsKHUdB6cYo6Ul51e+{h5k115V2cYLIg3LqU-0$OaAD z2gU`)k~{nGyW?)tu;ERiX&Y>{&H&y>Ns~}wOiklOC9V53>m*SV&n*-Nt2%Bn3$?Sc z){g~|>1Byc9nv4yC5tR#CJCt*v?wtHYzLBQ#jl_8m%nHFQ(IsKKwQ6K0?Qt&7Ozv% zIkalpJ(ym} z^$8lQa|A$q-AOGr4WX-iU%5YF#W140(B@Xl3oe&Li3;1%Vqp?yE z@c0a?rq2|_&3D1cH?cuhxCSIT5ygZ)`!(k^m2=tw&i-_E?pWQY?DK!g#ddk${wGvqc)Hl zP)~)vQ%zNw<-Y(0xD1?Zb=Nb>{CBwwuW{D|$7cCH`%Vd~CAy5S2L)Mc?9wg!bP8mI zKpvmmVoE1wU46}&g;8nFxpAwm&M+H$wM}zd$W!c#wm!a_4NAY(`AF$T&)HG zp71eIk75ASh$)@ubKqf3-;JH>Bw$Ep9Pg1k|5e=*!5uBhq#whRV#0xa=SsMtE;=jcOe5^b9{zGx7DR7<|Bj7JUTiofkGBIQ+|t7yJ%; zUtmodH7YkM6nqK|3`_96c4~>iw5w`bBJ=`RrjVXd z&n|CmxSK|ClVyKuj+po>QCyvGw%e8}WHGcQX2t#edP3p7%Z~XBU+vX_!k7elNQhUv zeh&t^!&qy5Cwlae_)7@AVg?|bzMoxj5_&`Q^dJyjfqBZ;IZGm-7*Ck15N7*dh*ti; zE`vemvVhdA2Ee1%L^0SXXi*~a4VQ_N$i0uADOiD$2{H5fl>lN39Cm-!=_^l&uB5l+ zR)MV7Fry;NZX^sZbd`P(^yrb@h)_Q1m401L2CCE-d_11XzMH#tErrfKog-#Fc+_!c zkbmc38f?8OJEu~qPzu7)`)%$L1G#4t2mp6TbjTGYSN=u+3SANh;l3}ionskkh3F{fV9X?840mS;MfeTk~lf+$dvKF4-!5$!9e*YfzO^ z#=zJjNU>f0Gji4&;tfiHT1;Bbjj31y6g!olD-M&NII%ju+z zo<8P0X%I>q+Kb|%Vrm)zdu}#XKl9^S__aV?0Ir1wX>R{=Hkp7i-)Z~$FZu5xn(`xS zeXI$xi8P)>(VuniYG2ku(^h^oX?-hw`HdGSjX;CnuGeZO#}EZok5%aNBX_D7OBbxV zTcy=)dRQG~gbf%asZT4$rRmAI>c=KzTQd$MF{!H&saArbGtnHrA{F7MEw$JCQ z<;_XxTE_L6>6^5N*nqQDE$eIRFxlgCZ5T8b_ivnxDn1oigPLt>3e5KA{IzZD)W80$ ztt9|~8b`8K>o{y7nj6SThnB{#XzBh|j-1Js#ZM9g`Jk?rOS!Y#?p^u1w(!XOw<+-d zDBt;4$wyiJlbT3sdF5+o9N6}{#`;tAmB?tsPZp>GrYpw+Y2sOQ zITzh0byv&vMaUQ)SK*;OA^~;(&F~ufklY#3a3heBftN#yiUl|t1wr$If6D&w@35|P# zJ3FCqcXxMp3rT>+y>STc5ZooW6C4_MZ`|z_+2`Ev+o5ZuzsF$1yz0k_^q93XDzJ=I|*0yc9j^nYP6?RjVOC8DDzXeut|O;Xc3 zFrS<4HSR?+0K`&XU4KxmOyJikdXg<u!~Pg#V=_QiLq^7>46%chk>X;04Rk}Y zL1lmTRPGi-pAf^6cf$yU67!qIn-VRFimyHH3>0$|sl-*|pjI1YQkpWq2l;-SSXggdZ+M|Za6riYl z3^Z~JESX$THQirzPMFA*K=D^6=Vm1yYTiSuD)@3iO$n#x)+YpnLJ#va*mg4) zCrvPC;*u#bv7;eQ{>V65=ZhS}m)-(9ZU^=Kc~R&2smekdjoNB|YFgU9yB>0w^g~#> zIWP;=t{rSwR~Kc<#kfHq;~Vhla!%4Q4q>g}oK^rq!dA}JVyi}n=| zr)q1OxaS!^FgCG^=E^W_SC%lpXjWc7n06PhSgriXWDz$WO0M^Vo60*tnxH_Y&x+7a z%z`MzkbcCN!x@^rC z_Iw)^|9~XFm{d%Im)qwvOPqbRA2zD{!9I1aMsjJ7tCn>X6$O78 zzC9myoPbhH;4z7Fnw?3pQP9KH6L*S-)ZBumwp!_Gy9g?rcPi8E)Qs*Pn?bhhpy777@_3*<7O`8`!?`WiK(}EDyPE%&ZG#RH+i&OC8u)ZBT`6i^}^PkmpJNj9-zUdY&hh6xbg8sdRJMR_)b7fWIlBj!%1T4)w0c+tn9~jFey8zqdTyNzmyn zK43p*7?>PLVAOaLu9J8}OmHvg%#&w43Zr%jd(vEeLhyVkJv0$oHQiM(OX5OZhXnlV$ zv}r{!e4b@m)*{Lz4G*``xM#g6R4MK`$ew@>mCYxg(XxSk&dZ+T3_H%TG~QXg@L2yL z5*Su-hN^w41o|>?^CS$#4Pu&8TD_1?yIp^+CZkYb*?8RX!=pHp40Ln&D%z_)o11El zB+jVjhyWf_T}D8r5^kSU9%YR~gVZp*=j|KHb#~+XrC37xLe)w8E{iue`$k>G2?GUZ zFijS8?6u(HrJy}!g2@5X_j($8pr-5$oq#zz=-(VH&i7iwoVt#6hPs$9`U*0?sy1{o zqDM~gZ<8;^OfaI4r1UOwUG}^RgLs}d|FH-!Kx=@Zo(xs*pb`{Ml&USZ=t?9)qS^1tR4J8;yw`~JBi zjo-1&-eg~=AfY*m42N%|o2S${Mu?O9I(hf*NeRpk0il^q#>5^>NK&RCDs^a_G58^J zZhcw1A}iDwnu{b+Di>stFaFvPayh!{Ub|}Hn%3GA*b&)}-PsHuRZWH5vh*Jhh;3e{sEHiN@QH3r&z#-By=DT7X{!7NdKf!Wh~6mVzAbq;^YQ_)MPhCo-s&(zc`6m^nB4_ z2wjJWqNk>11|BrR2WS<0A&__@lQuqgvt+T`@3d?Yq${zZoz+^QDI2%SD3N=9TTkoM zp9^M*h01Bw!?9>2>kKCXnfUX5QmWs_Kak3PgSquLQ}9k3RCtRmYwQ{G z5F8go^?*C}84D%G-;7K?{V+fCrC-8#6#vd#Z?*hwQ;;FEKkiJEprX+fQK%e7Bs0&o ze%;{5j*=1I_Bb1{YMOIXFY{M|9aFI~T{vj*;r>FU_YxGR+NmpOnhZf35Ya2?pWsic zuomCK-?oKUdmx^_N?z8AQv!@t%QANmbaXw)Gx8xRPUuZ;@Fo4kijIcUr~E_+Hq*vR zjD_{&X}$Hfj(JP5_rOypy_gZaBCE=V zJBNUG^@IxNTtQlzIZN0N8+~i^TwWM~U#Mv?FZ~AJn}-G|cOi+rF;>&Aa%D>A1y#iN zjNL2{=E}`C_}N*AA~?)!M?ok+b!jX2LcN=@licSXrA$}TUXe``FCUzGWH2$XYk0Um zBvK^W*LtFgK+kXQut|j@wic8p3mVBejlH5nkJ3XgrVLX+k|?^9TAaHdh~v~J=#t6^k$dwB6%7dqA%dWc}r5yWsp*Vds(^VpO8@w@_{ISi0ai! zpaJg8SEi2VdS}&2C9tdMB~vG>QYG?o&grH02EUA5XAZHNA}sApQVfV;a$iW6dI!!*QY%-f-j}OlYEiU+<|l z4prUxe5-g7T`(y@M0K4q;(11r;%5d(g@)L{RU(8mim8YhRUOhCex zK%ZiRstKDv-^B+-`H}3Gywb7%1KOJqa4=7W-fK|6i1mVAEn4YKr2X*BGIf%hXNT*m z^3C!>|2B^M@l^A-zIe8w@jDWVZGx(J%ag@l)o2j`;QU0&T+M+PjaZ_LNV+5+ld3_r zrk`$!Kmf6NUKktD%B%m<+jh`quE8*T)~}6y6^$6dQzNyl38#cW&{^#=38&;tC*|Q{ z*CpC*aZ_-$|G;WhQ5?ha!uqQN?x^!b$b5q`jS?^7mw>ZPPM@%oxMBPx9!bz(e92rC zMU69C415+7rvy~Gm3g*Ebm?ZZ7)L6?GYrKsq!2b+k20BGAsl8Yq3K=$`{_O$|Ln&f zzHxiLx$=_1RU|0-T<7@smU09R;0G&}PU0)KF&1#+c>^lFtoipV3fl^=cNSV4_xELM z+{Qm@j1wZFhU+(fqMl@4#IUCl z?DeSxK|knCWMWR5eW*Fn)*D$)UUhw2u@f8aBPKS4*u5fn5Hmrs>e?c*C3D-HzVmRx4V(6GY;LtD)yR5psi`&9eo% z_q!TfE_2DN+GeE=`b}fy<~UCfTvJ#5EIh}{XqefAG8KEgs*by&q%E$l*4#k8i{9R z4eriLw@IgbrRaAt2e9K*>Q~Dhnw*!Ncq$cjz<2bD>i%1f^Y*#g0 zs0xX+lyDdrT*jCO zi+OpF-jFE&g^~n;HF!Bx!&1`tk}TATS9=yClA9T9jF)&iX1)e4cvUsU3RetxS$YEV z+V`#!BPG*2-uPy5b(4rIESxc6nBZJm)j7d)_;iqi=Tv*R6117iWC>5?7xcoFG zH7Ny$VT|!cRB#nS9S!sj$X~qR9Ga?5Og=#|)h=Buh513i5-uJO-w1pz5SFfjafW{G z>hu^ylR>pOYde}gGHM{_wV^2!*k7#uwnhtu+aXK z1%|N-3&MHssj?;N(5j=jUbQph7G6OGS`lzom>B9QGKpJ-K`&2~nwQi~lOVA^hO~2x z8HpX``VkBYQM`VGSB4)N1&MF9eH%&3?b+l(0L1T_VDUG27HCa1w|qpFs`6MCUNu<@ z)Flo1lO9?|uO#B5h}w>QQ~cqhn>NNoqWFpbX%WT&$U z85axzY=cz>Bgsn7LBztU`Zskp&fbpe*!&Zi2&v5|E(Z%*7BeLGTXW|M6Y9a**S*06 z9M*F`^q%4$y|l<6g-7ICW>CDAIyx0&+}*?=sdlxm zFxc_teE%%iYOy&5qUm#Oo}&0eAH8`LdFg6tht6kTs+}ROn}J(I+Hp?5J>y8P7U8f6 z2BAc7C4PUMiBgT}-xm_jR~b0gF^(5zipPrd2n}3>ReKsfDLyQg`}Vf#+uL*^geAAn zz32ce@Nd1u{|^WLCy~d08ScN4f&7;<{(AeL4qWDR!1o5Er=q9^*sja%0wJRKG?P|H z?pMA(cCnKImgDnrHJ)!%tW~7fBNVQous)vn(qLd)=!yaSyKvujW1`TAfpu0SB0Pm0E-(yKNO(!+CqAIU$n4Al$`ff&9%Yv*8`#ZnuI zY><^b<}4vdTwsi}Q=t=#-z=Obfr)eZZY4ieVWprWt*Q)R`C$3y&D=p7THd%P$0CN}*4fw>f>PAol zfF+l%&eo_zaKqxbo>?Chn*XG+BNQx(N^)=|yXd?oe9})dsjUDs1r_d`5x)%DIkReS0N<4@Nqq96b_u9ptxuU?VNaS z-f1)_U#JMQ2Vr#E)Gl)IVE5MzhTimxV`-(RiG!|Tj`MD{IW!_&1!kd5JjekH`0ER% z_4q^Fj8lqX*OMtfj~2M?YDbA>^|ny;{3L7up|SHDDT%DiW!+f5ypCT)8Heh_Q^a(K zT3a-zhRt%10>!totIso$(a1or!_{3srH{}-L^IKJ9Ef^7JGVlMtOg*ufsoR|D^T-N z&u8nJj^LU~(ky zDpn{NNXXSYjI#Npo~1AX0tp@*M4WmPX-KQ)bl|!816R|QltuMp7JX@I>cEGRI7a#= zVVaU`S{fh)kq94-RNFZF+bpiVMeO(Lbyqt%NMC1UNh((aBMK2^Rtju8T4}>@wf)Nm^C_CO7 z_yQlZURXm*iFjdD!X(d&zmf*2oSkp-Y>}CrY#bKuS{#lo>inUcHSeDQt&g8wkFeal z`blmkaq%Kgd<%-fS(AB26s3(`wW+%$NG5@v7?Hd=JD>DE?|GXke>BXz;V^jAs$A~G2ne3xd~_s*o%wEEXLaoju5!+j zT#&_jH~}?Qpb>@MLb^XxW5G`kvGlzJ;pVX2J)y{CSWa{A)qY*dP(mmAivWkPRiy#4 zeXWwUb?bn!rrMJJe&3Un(C9 z*&2y>RkGTWuf|q>p<6gCKw^_a^YO@Gu46R{{^fEV6)gJb>DTueZZNgQ3Y+sq&CCZi zA?W4*#qD17csx38<}G(Ob^9S2QhF-$v9?w*OEn?-(8k!V;)bz1XhgVL@X*oyBemiD^9l7=7p%CY1OgRJt~8#6PtzCUX#;;D(>nJe38%ze`U@ zDX}RJ4fN;Knz_t`-V-=GrsZokRG^cHJ$d{h$4`TCv9ZDt1z=hU zoDZGf_1xJgjL=TGnZ+l-{FPVH=gI8(%(Nnb(Jv7W?@kpdMGV2jddl?|swpGaAC)LY zO3ufpN__T-_!=2z-b;bW!`N^r_kUR-O;D{9bb&#MB(B5x4XUZtbkZ#>G==p(?%sk? z?^RPUTLg1afOFWxYO~gF2>*$9ZlU5+fJ%!?jlG?P)3is;&Uj@-Of2j*@#mrdbs=%S`qRQ(5(8sz#)D45hP+n`+!#E7i_#v%Af{I@VK6XpHof z1SibCPk4fG_%saXr`pRW9pUyXV-h=zsNpjmJme}b%x~4?v7OUq?w$}h>|8v3t|69a z%BgA;yNO%x!}1H7S?gBxy_4NX>`V$J^hQY&50Ah)2$Kg@Ndx|7@N{C5N0CBHMPS!V zJT?@tE!y63LW;Ys=%IVr?RPDF1pNcZu_Wd$1!$F8`v>$WM~>JrMb4S6Q#rdski?wm zZp`tJii+=zaTq)9C0e^ZoBN>w(yG`cKZgh?)!;{+xER>o&8z5jmuK`{94f@ z#phv4n-em94(j!#NXo*}|KtKVDN&8sj@VHpV#-4l@iwH``) zV|WRhIDU8Jxll$rO#Ag6)b|79Lwo8FjC%1`Ti7I*Na21DkG9TXvqZ|na;r(pcERfl zRK==ri7c@o=xhko?_?d9E$|OJx#JriXGbDH2f#nhYjn|TqZM1k0T}bhSD3Pn(v5@? zu#Db4nK*qh4paP`7~O6II2PfzJF#i|1NnrBK1V}6K!c1wq>+OOkLKJJfJhI9&7#6K zMH&J;s3<_78KgiPtY_um5Zc{PT;s;>J&J$AiZMUc*!E2pUKyx_CG_Cx8zKvmpL(Bi z)s&_)%VjDStc0->O>#Cc$?&VnFtT${@p6K|o$(&^oj;;nm_aegE!;WBu21khBu{EG ztzYwK;^w>qG3FRD+3b^O)$%E%cym%n5)c#t8PN9tLW;%AKkMqrW#e})YOnKA0E)UdD z`A0w!R-m|zRCqi-w6HtmG(1Af0}>-XDl8A;$f&lr_i<7jvW{it*`<6P5~wH{ws4Gr zUKhdvtgdq9-kR##T{Ced+D}d+)>BvCX=nXO4aU2saKUDu#2>H${cO1%IA3Y&W(Du}N-XF&WytzdE4*=--H4tE-;55(#}dDYF-i0j*s#i*fq!jxWzu&y6*q;ma%G51e$pe5)IyPEPJ2qE`B5W*mG@xEu?%VxsGa*+-x zFOsSPvla@~2aprTGx0(F5&fIChGxTyr8pnHfGtRPdbzCiNc*ipX(}Kw+ktCJf>l9+ z0~Kf52IA|tWIQa>V3x7~hwUNDYNEUWFNGK-#W56g^0_1E)_7tHNjZYgec1#M=23^V^ zkZ^ifUx8d?#H3kb#^DkL>F2*`JGRPTtW#L>rghnjk;kY()<^ppb zTz8*j?3NPa)Mhfr6)78ZB)h0;nr~=_>GP39$Qg$jqGa^3C-n?Fc$F)7i%#*`pnu_s z<+7AIE)wN~bR28ZkhKp=IIo{V>Gj?gD#})ux9z56zH|Xx54O=1thT2%?|as?W8K*) z=}B9wsD8{XTjo0I0c+h?`?mG)Y0dEY9w2G6bbTF77SjCz=G42V7BvlKa z@D2}h?OkAd?4hFdmtJtIrk@&sKN{Bg^|{(qSE2DVB4yHtbqd-^atETRUOB(Kr=Z}X zA`C`rQc#WyS-s;-HPO77db_8?_yWP-bD=ZWgs9@=sMm&0gt1#64^Zt%cI&Ga8jM^z zq~5UT{1Dck%R^;C!XjQKo;^o5Fxn=}S?+&u`6wRQG5z^0sKO(%cG7YV50GAF z<2`{`pUWcLh}aCE0YZ;_c_Ut`v0d1>vrm$$uVJt)#FV6{gwNu_?j-tcbE$|lD=G{e zSKLy*`~owH_$M>D>JWP+G7Ma!k&IgdDWbLQwDLwKBO5Uh zj%+Gydc_g7nb4o-QrRn5+2C~%u7ns=mRx&Ps5HN)Vs@!0uJ>u9kR~A5y~)~Y`aow8 z1fpaS$9Hcq{zW-dOFwVKP%|ArVC#=4BcnKHSpcsYEaj<;Aj9SVbGvTFZG?HhJe-v^ z406&=s(HHbUPfooGesm3MKFp|eXw&M!R05obF{GN_eFugSUUSAA`NV19(aVf2_{S@=lMN%b|?pdY+kTZDZCTg5hc}g8Kpwmdb zO}M4aWuOgV+}P@G?0CM3n<&o((x2iLDVzad%MWU^=kA^aRx7NLTsC{W9^QS+6ciF* zPscrI^@*nDh!Ka$;l>838iWz*Q0uGsy!KnZ-W|7C| zu0Jhs>wJH97iYHFiwC{#{&a#nU$+zFnGJ~NA@KgCnRocj%5%d!YuaJi#UnMg56mG2 z&WwKiGjYhHh}{45K#{-x*6KpcM1GThI<8PHLc3diKDBPL1H`@0w;dbo#b>*$KVXr9og z!?r57+4;`mU~Ac`*WV1lax_j9{v%27vW@Z^dlnFoM@++#_l4}!7gxu}$qsn6FLPN_ z`0z7h_{7zEKWvjL#T)ldXh)HYfs`53e5{T0Ze<%3yuR<7`lU)A#c6y1_d02*lvX#=a!kQXiCZf4B|-Ijimxw3MKVP53Ik_Ctbv>0 zkhA%ulr`zZJ#cxtQ=-=7Jx8;-{qi3Vh47!B)DA?_9B%6AFx^1%#8$`LQA66P12kyb z+|#50pB5MN_sCE|YaJl!beY}}EQKr)HR};z%7Pxrd+mBbr5)JAa_Q_B3nBmb#>gC{ zMOC{*uD>Zvjbo(1_ahcqETKrdvFwZ7%X~9WbFSK09pX1J+l+^Z)1vmiA&O^aqoHddp^p&O&=Y{4yRK$Zg)S7SzWZBJn zNDl`a$Mw+<-V_sts7k&|PBhU>13VxaMR&~C%VI)lV6N5+7VTFCI4EDMUoP~di{|kW zZ`^M!G1*&i-w1b0W;X4wn>C=KxjoHjzk^)S6UpavIepn^fNk@;(=uC$2v?CD$(&&$U5R9!$*{IT8jG!d_R3 z;-w&t#+^@6K|2`Sxsz96NW0dL*CQ!Z&nESpkB2uLdr`n z#J5W1&1#PVoijB+C^LGVFNWN=3(GVLgcN$TA6M+?c}S^tsILh^J~AO^7zN4&U8J zJJyCZJQ6XB;qd8_#W%Iz8mB2#^o3(jq-T4d;v1XQWk-``WLI%2{N{}DO#7s2ki&$Hz$N@Ap(cIZsg_+G{64?Y(QSk!!Hof#jzzzV@NZcgTS@acv+P<=d z^I5h%e-R**hyF--JX#6Vttdn{U zQ599+4MoK{XB^JVC7x(8aZOS!48Pe(6r}nFfu4`Pah_2RD-nFI^=R;}8-@v|S4@X^ z*jZbkcOPp%&* z3a`0rloa4?04eMr{e5&#E{*hqlzp|1jC? zBzV%R(v&9u^QLSiu5BeWiN(w9sI%P~l)-SF_oJ5M^`{O1zkSOg+vDaPZR)bnfanP0 zrm*uCPX>esKW~z0b8_zpT+8Dnm82%s8&%ISYgi|2mhQGq3$=gW_pN(rWH0vGqmX-3 z*Wn?4f?sc^)T8Mz1K0L4G=8wqS|>WWM-5hRL#4SAQk8q(7>$Hh?_(1HNMG!uSz1`@4#62cjYyxM{?%uoc3fe)ZGDhto2dir!b&G5 zn^oiXyR^)f71^K5oj(2=+8_+!As^ngWDi{wWsk~}wvqQ~b*t06H##1L?aeeBhAJ96 z>Nq~a3Wj;%&=SCKt;eqXVeB&28)MW?*cU^VAGBD-7S41-&*XHT07aghj)z7#=V{5} zr1GR3*V?eBIA}gxM%mq`6iS2}^$x?6Qb@Gw)<3oY*ds~h|1U#ltD%0P;FQiiU((2( z`HrvXl1Rfx%esJHvF4Gbsmr7!qIgbQO z&WOl;0n1Ik786w!4~YZLq9wq7e%x-zybTmtuB|tvYa9^C!~Gr^-rf6Tqg!i1J^~GFXG`FAmTc zc%91Ldk640yWgU^S$VOkHJrlUrSLapja@?){o!>$R8y&tJ0Gd;Xm@-+M4|VCl*v25 zTEkRRzIhoc`pDR2+>H_igBK$8=c`W{r##gZ>KFk)_ur_z#klVO!A|{+*4k?{1dRf0 zTVOYm`}j9gVx3l>0Mw}Qa00C6na58wEY$c;IDL&BGjc6~y*iogrgI-vHMbJP&LgMC z1x>DRf&H>dcC4fDS9nefc!9sMm>B3+-W;q$ah0r!dlRk!eP~rY6E9&U=PpoxS8gP6 zZY{LZ6-ga2xipSz*UgDA&jnuH)FdAmk8+BN0L`%3cJriC3b; zI+x9i7rErn=F8bjastBYScvJ6;|zxD?P$lr3z-*4CW|}q+SN6AlfGp5GZFzeJ|65) z(!V34swgu3_(3CbH@$y9I0-~~u8b?4jlK2XE_E8u@vM@jZdR^>%uVi-0T1k<0~qMv1x2FGkL>`YrTI83F^#mQX~d;`uX|aVthr`U&@B_ zd1aNbiscJ3gBE(xBGJ(!Jx)hCqc5G6%wLr%2CTDUi_`}249e>&zOks8rT_(WcD?X( zkS_G%H;)8n2gUx05qheoD>xG>|;zm+wF?~8h#akT=1_k;77e@=ouHcwz~ya zz0ZCJU}3T6+PL~pKgICN#ZyQbLRi^IBWC&6C$e%2JlPAQJH!e#GN46FqpX{ z_!kp7D%_vxg^lH51&7!8KYRaWj3S*5*oKu(GF@E%<+h*&QCUvwIgBY+yL~naL?knX{JeRF5R|>@xIn zn3$SfUDbAUT~m`Bru{q&o;n8vtlwdw)j>}*+|t_1YN4~+i82DW65{sKoY=u`xkZe4 z-8blE=p(d0=U6rl$IMmzC{?#>-GSY-^)6H6$g%A zT30Kf&1z=!!*pgmzh;b*VS&j*v{;d0%92lijJ%AB4I8_uu;32p>K<7Aiqo%CSpB16 zEK?06We+kjD}<-n2C_`1UY|%?ufI)^nI{0aH3CMCLy)1e^JDfKXi>~kz(l0X909p@ z5ucI$P%ULcAm!;j&JLi+6qPrWBGxk?Sk z6UTc4Z*R9=7nYipzDng&i8wzANhGCQHWW#4_J)1J!vax_ek%Z=QxGfjF%qgAzi<+{ zP}w8^qJ)C-D~2l#e{^+KeybGR|5ATAw;fZZ-a>DM_0v%q?KuEW@JAu|1$i`_ng0`02RI@1|4GbWHH~#7B5QEpXN#k7 zvFvPWJ?D3RaCS7aUQCI;_zPIu;VtYEtKIMH?)qMBQLv?15vZit!ib_gE{S5l9My-Y z3^lp^GS~u2?RM_KI^Hlr{gFIo1CxrnWX^wlVcC$evOM;K?)?b@1-(L3aE+#AQWI}8 zU|+ojPUa0r9bJPMdX!FPam(XZZKn(2MMb(OHwt`h6DHwvSvEcVRBij8YJ5%%Ly2=` zXEDY=eN1~2-j~1Uu%KqtzM|@&H;Ou6E$b!UtS6c5Gdhz`G8zov^vZk)92E3JX6w!TE7DG zE!3bl|E3USzDq1lL!VRWyF9;-*#SNELH4)$REsI@V>gf0bWA7@t3cZ5f2}SB(MtY% z_k@P%3!S7A9y0SpX<`}IZ6DHdwD9*cxf%rypK24*j|KOo&wQ&3?^3c!Q-{7pNl*1D zjU!(Jd3I|J2^0C|3}(Bgo?7zCNMD6stk!()#q%D*b}JhqPl^o_u}&>aYk=M|H^$%} z+Zc_WzIHqDA+{T{XWHO+)N%1`QvG*popI$b1%DjHy|aq*@FDv7oQn+#vQFYs>DOy_ zTvDS)x26}i2Wy|2m-HPR+P;!~QcMaI#g1`f{YZd;-GkUf;x)8yktaD$9a~VFDHXsr z1n-Y7ECMVn!mj(ug|_I}riK67a}|U2@G^}4-3z7N3v@R>#4+2=t1v;Ez7i*+h+T={ zx$&}|q~LW={zdFK>JMRRi-rcCrmJ_GYPq6oJ~m(f$qF~^O~khggFp-khZ$zrx(CC{ zM8CZ28^`yy^VQ6RdJt7u>#LMJPQ7T|7|)i}a>!}ngRR(bInbN-+)JH#E}`oBxjLZ* zzZD82T_|*T^U>0OZ^P8_9NQauMHO`fG^8~5Ev7~3st%ceqPi8esF79e7pWU8i@=~X zdfmmBXZaGTMygzq0T9D-irrpAi5#BEMl`1xT42r}B~<)eD{<4Kce|;6KDif`k@?zu zV+v`t8^J!4RMO|(tUKz7C|O)2W%Potvq{KagZi%=k_Ec2JpL*I0Icwf*A*QMyfTlJ z5wU~OV%p#IV=Yy=zqlW}%E|vgP)L4P5^iXIi2(C9@4Eh^=A2MIYZIWLBAb*c-eAW> zNBj++ytQf4%|s)oBg(xnnQ}x84NvHP$pmdtw$gLS6{+ZW_U|Bii6PD3uw0q?|FASv zE*fymXq=@VfSmu_fmJw@Ttr-<@H^Q6{IlDb5iTP{woB}JEvVMfzR;O$8Gi%H z09Oi#oPd{q`S1Vz!2h^{#bH-cXA=|WdMK}6$w*wN#09bVimHd$5Cg) z*y@5?l2iK!C%pDUzgy51RXokNW z2UkOXpT?lWZ{nf^w-uONij{@{7px&X$83*0^|od%>en4G(b3At`<)(6>pt^`6{r$64nb>_ zj;LkC6d{+j;6J$l{M+%#j%Ln&4q(>52r0@57?|k9IWqK|vr$7_FWiY1E2@oR~}h(Za4KU4w78lYbUhtf5&rHzXnAN?6KOW9~%D;K4evGI!`swzQ}3y zs~@Jt73(zw^gIGS^}lp1ZU#3L14?R~zndH@PNVLInm)YLYh>gQ!zmb}z;RZ`*#y{2 zlegpR9{-8|67}upPVyxYw^bfLO^sa#&P)i=)_%=@wqskwJELId${)DeK-w2uEOqpxO=!hxSwyC{h`RRVM z_0B~5=P%*w29oF9CVMbSlY6^efeP?k@WbIv_~LG@{`J8_?$m|AgLU+6x4?Za$%8A4 zAb3H;sgxw?cC$SfU;O-qE5C)!L#a1SnZUJ8OY>>ko==*(LKJcK6&jN}<2u$wIi5`# zZU1a%gZI2EyrmE$^C1EK25sH(e)vJvxtvyj>~N9a%9{C(n)Krx+KLbS`Vw{;?mgj} zlmGsz+voDIqi6Asmqymu&BQ0*0!QjV$*8;Oa>9puW*L_Hw)bwfVk4cTg~O+mps=YE9p!RP8o;LXV5-JMM4Sk(Pl z8pnfafAE7h*){M849@^y_9FqvR$*zgddsxH-IxISNXvYJ2G!dl)l=3I+Yn~n5C}D| z`7$D)nf4A8%I~?1Xw+9{;pwxvE+d6wakD^{!21p!S`Y+IJyLfMmDiL|l7A=I5l5Ux zR$=Ll;QLR`X2~{oJ8eBP2p6MUr4Ky5Z2{U-*xj>?IU=g+s9JhV!b29U@P$mnjyd>xl|ucd$50}K>%J4^|1htM}n zbhAtxe6I>_aiHM~+gBO|xC3<-XOK*VdQwLLVg-2}5j3)&XmeqRtW!5-ZX3ieQN?NX zU7A`6GcsDV>*&ORYR%beJ0Xc1+s(mFfT=b(CzAGP$Q?27;&uF};@nFa~O3FD(?bC5WX`c6Bw+r?1P-)~cthxxIzDOnt zD^KVa3E{A=B7rw0d#C4ezCi~#tKJdK!Qm77ykR3H5*yiRj?0gf1A04J3PkqJm8L{g zL0Cy**}Bb=BJ~}v+#9u_wAEX#p+%31Vz23Cqge4em3Rv4Ww+mz{*o&*{EX}hH&sP{ zihVkZeSBU#!O5fEss-x4-@H`=JB=uVzK^%c)@JB`(>nA=6VhYI-psZW@>PyiFzg2{Fv zlS(Z%=Y6sCe^VQG>r{8rZK_U(UONZ(@7wWMCnob}8xL+HQ_}K5n`RW}S(Y)hs_*+S z+p%Jai{I(v;sq*48^H!6bh&1KF`Ht}TifZ+fyxX1M15SU_xI*#52iJ{1IO~XMSLI;oFXx@JVj%x0Q<^vA#knnO>=Ux(AW3#B; zG7Z#)1AESLODDyi(_t^u4FV@DAqqAEzy9}rhW~U%u#y;AC%0CD(fv=NLVz+kU;V3A z{3LoId^-AV;ur%)=BFu)|(hzluv#CKg`13~*AdjxNcj+Gi4r0Aa7Y z$*>#cs`~|_Ct1b&LgkkSSRcE&kT8%5R>#0}Y`D9K`&p~Kny;9?r zZQGt3_tw>Mtav6PsEZ(zO^vFrUk+Z{R~~Pjel6o2;%;TxGV?JgnBo!f92kP+-khyj z>WVwRlipzI384I(+athB_Ock^P}0316X#r^LEEhSX78Z69N?oiSw^lgvlB~(jlF1U zv=Wh5KKmg70wtP4f|=Np`=llgLdK|YsuMRidA5TU8Z~Mt3VVO5y$o$-TW3XZ$mVtGrPtvwDYF54db@aUBXzYMp{OOe__ABV zPcbfxJS3Q*1IJDd7b$qrUUF>H3x8COW*(i~c38tnBWaX!f+b)ZQR6)e9*S%JEe_{l z)#g>{=Srb&7N94caQ&kqV!yG%Tl4c0GU4CVm_JRURsTEt$~EB6ir8P z088+VoGn0}`f+XT&|3Z+q2BwTUZ@$aU&GNBw>eojuvuwCk!Z&L6+5$@lkzxEUgcup zpp)jzIJnY=#ezmU@Z1Tf;fet!3*u<%(8T<*>?G!}p5GMlhLeGH*7i(T3GZN+SS#;6 zmi^8`%vOT8Z?kvsB%#I56z>b-5A}>;td>ZKVl;g^I15Z>sq-eE9m;D$J-QjNQ<;=feL*N$;S>$|fD^ptbIw6RJNb zLB9so=u_XOD1r|9C^M~kb#NG+ae@U6Saz>?4$6TQ|TZ92S`pVG(=SDa?HBKxT z6Z@(@c;1+Sz?AIOoqHS7vj3>U(Wg(f_XC^Rg*oSYbb~j_S*&)@jnsT@2g>&F7{jcj z7qay^>TjVA>DRaUoF(L>&A&Lk<_qcKJmAy~vRaJ_)G|6P!vmd0`8NkAR$9#iEJPGg32cggX)!R#1?*AtI+?yzsW<67zh3y7 z$m=r!)qe$3cib3Qj^#BIZoxUt;KXmq!Dw^ANiF2Ada!a{g@<4~N5~rnR1W1{b6{cJ zQ%nT&YgiFR$6ud1;e|SXxCwrJF*FgI(gb_pZK)z>(As#TW4og{QevAyY3AYg8Uahl zLYYXpp@>i3-TXnnfRW<<^T3;arDUqibHiM4gS}F0AYFM0qQ1kBA{IOurE?d#vxn7E zBXzDPY>4jG!c3Yq*Ljt8_5V=zmQi(d+qP)o79hb17J@qjcL>3Ph2ZY)?iMV#ySuxy zut4zO?(VX1m$&lmeO|l!oO@rp@6W7Ot<{<}*R<-R_c7+6MsFRaFsVqwPPZr?MH)|_ zY}Xk}Ug8Cc%TNf2l6J6PjDnLYKQYv4q5u^;8p_*4a8eGk8KZ0KrK397Syh0y<;Kf` z0rl&jF)0-pqeBM{CFVMpjB+j~a^+%AL4l&0vAczOcFG#U&rLY#JPFS@AVw=m73Q4B z^0pw{tab*wobkebMfFAoneNC%9d&0)rl6(d7*9U2TDXg#xYFf5sr)jjS%+Vbx3J+B80HqR-|mo=@BXGSFB3)jy1+>B_iFA_J4#7w zdAR-}^Evu_fcyJeDKyp0c$;M&5-YO@I|@^aPj!baK3^lZ3AD8tNcCU7d%b)X#v+Vb zQ(d)iCN%uLkJdMq*}U0)^2a1AJ!DH#2LC{x?7|`Np_Z~o{!>K4^@j@=iU!>8i3OZB zd37jbSor}$y{VP5dN=tcpghznp;L*`A$|pylVw8kZ#d2LMzvw zg1p-|-~dUy*EJLJ4@9_DvXSVv)qA%0xy8DqPTO7i@>#X+ zd8;iHk`OmT#JiHx&@}k>F!k5H3DUZn_CGPlGQsV7m#w;_IdDN+m~n~kclt~mn!BR| zwKdsg2q+P|c|I`mFDLZ7ATPG|qSHzpxi5?NPGe(F5})(pxL&l}K)>dX2!B%}XYt6x zhH1-2EkW9l)kF*4Yc%yMb4tra6;e{r6c4nKMZ`M0t3;XHY@^=llcG?s`aS)DN??qJ zi`(u7FLw=R#>)J|Ni!j1Fc>2x74#}cjMbG;SMW(#TD|;Mk#UZOp7dOf*i#Gz5aMDA zMX`6dw%wfEi<)!5p|U}IyXfF%9fpyJw9_v;EUe*CjseY46u@gX{S#PFpC zb!sNQRl`#6SXdxKy?}y-F{x)m7F89rH{K{A4Bjl`l`pye`bTx0X8l}i&sqlcM=EAQ z-_JhvddGsQvfv`$mAcv)bE020TlNb#vce&5+#yhwfVzEKCbEw5e zw3uJY(JpNwP@f}j(`9(znr7EMHH2(2XpE>l0-A>J5~FmM&CdQS3;^- zcr+WLQ-yWfNx}zo8MCTjvKB`3OAl31@t?Hqo9UvM&VG)n?v<1dR1vUs?4O!4|AF3s z|NSLQlTVAtkU|uBqcx*uRpFiwlK-?m@VIYlCiGPOEOW@^EJ8+`a{v8p_@3r&ng2Tc z?*J6)4@90?Cy3hP7rL3K-(*)AvAiOTZGVWoO5wc5wJ#z*^^_D|ir1wXS$!>NQ>)xM zi_r2Tvt3W_gAvG*8IFI$1-#|UG{gHyC9|^%%KipZ^?KN<3DqWnpukLqxcC9Wo1&w% ze&lYybw#OYri>dh%cv_^<8DTZV4@@W&V9)g7h2k{g9h^N1NO-_U{jSmQfkzNt~T&j``CE4fq4 zO`3Erqqnr{Ev~Ncuz?6%(OuLDR#;=dRvjA;TTF=nW-9l4v@}+`Cc*u_z(D zg)N!7@yfhcZhbFKJ1IvtftOV+9WhzLJk+Z1%w z4}g%ZTadmyUBYd1cjY;1VJlB;{|+)dHPARdp@^mF=g-b?q_((Q+5-hN^EJ|p!B#J5 zAz|2fe(oGO`>c?}B`L0*-tBUD~Mm%--=+s!#?Gdfq@=X%S_1= z?2P#4%pTxXja$@0kV2DMb~dKz8#F3aOAPurPri~% zMu*;`8?b*~ zGGQikx2#8>cOIpHI0Ghp`JM&g!{(3E<4R!lyon+R>(v_~j7!sqEv+Ki8b)#x`;#m3NRhWQ?KVk{tKYnm!jBC4 z&iG{we(u}}BQp+aZ#9@v2XA*8Qhi}UzHs`ezSN2!kf3R;j#XfE;h~wik*`J-mm0)j zCFMV<-bG+4vBPsFys+$~kVJ2@T0V_3Ice}6wBtr%8KL!-c>UK*iHGKzX`GV`@lYA^ zk2!~5aXn3BW)w1ZCoP&DjC0x=X>l5)tR8mT_I88pbIngM8p@*Z9-tchhEYdZ___De zoEN&RHl3|blrU#qT3N-N_{_Bj3G#+Fg>N#e1~x2LXgW zqbd3y%Aw^jY=vnQ9Nq+vP#E>!ZgVz3t@$B*ElB-j9K52O;-sqYd`f5w-t7}7j`EPB zJaJcNNGPGnBq}nQ7M|NPQ5yG*ita`7KpAp=5HXOc>UFI26{lr%!A2yrh=H;>)Xn1j zo;fzcTjg+us?p%IR>KNzDLX7R)a6V-K~5=QPI;)v3H#*X6CBcF?)B&J6f+c6vym{9 zNK{85m19!9)^fKM*`AA={qMRIyAu}WQN%nXDu1&|F_J_z_2ezaeLtHyGFrPFUVG}H z3j+CXP z6^iHvJ|dCwmc(PJi9;ae>q@ppW=&oZ4y7yhDJvH9f?A7Z0&k}e0T8?b2+PCfJ(b7I znnTWNQ8S|$I)yXIxU#*NaEGgCi%z@q>t^}%r}}fTLZYGJ*X@eX!tQ`JvDF{8b5LW^ z{M|6?p2}istShC(YiUZQ7_QB=C-d3Xrm+@yRu%^G_SO~3COiZa4GEn(j)73)94B6# zp>KYk<-2DdeSvk*u;ZH4^mq&u}!`Ix}=$zk*QJjtwgC-Jw&q~_l8i&?8p?1O3&vr2O}h+n&nW++AUB!aBm@WbTfFgYCv(Mg`-*l@x@e*OIjbbhgxK!$axOAg`+ zc}UM1iP?uNn&}mjwvEr=Zcmp$CC?5Wd#cSfb3Ps7ZS#@Z*c4zC@mx(kW@!?V@^8iV zaGt1PDk9H1L(Bg@Y*~~p_zuSi2sOK+5U{?uev>(COWdIdAShz{yuKyT*=dP}s+lz2 z?k2A=Qqg7e@_~hJ%U|izG^3%5*BFfBLl7z%4oXiacz$r!y-bHms>CwF)?(3IASd(+ zNQ(1En|ecmD8YrX_xVN>gCdaNVlu?)aWe0vJctDvobcELYxibvr2qBLS?*_8egx-@ z+UbPQ6MTm@45S;Zv4t|6qfg|M9A^;W_2q+|$0CCKrDD9u*^+Sg?LlRP$WSIW%FSE8 zs(t3Y^umsmlvYQTT%Hq1>texB8v6~FE$*n~ zr>|RyJ1!iEZ|zyl#W+X);oxRauERN9g3~1zXN%W=UJm1bA2(i=PrH$7t8B+oQ_9oXM^F%LXo=O*{5BdRgEePjut?QJd~Xen10Y$-#5RhQ^{K z3NR}BNy$yK5dqpdtmc&v#Bp1_8Rj>P6JT*M>9llHp;aA6O6eAKviQCaZXGRIq0mR_ zbj_0bl{EBSbEe*Cf9<5Q>6GB$jnAKtM72oQ$l##;SeT?DKEa)USzfOOI;1Yts4$wy zq0x9(Lug=0>v!d9vu;%4$=hab&WYgnyFbreHBCb13nEs93-by*6&x_@Y9q*kAnn{x zvL*)*Rf;O}o4^|H;0Tk(?^L6<>qN5HQTfG?a&JsT+^zfCZo!Z)6{sQk9gL5_)!2kU z7;z&r4n0S~W23@#Ygg8j?onIkBOu02kG>wmwUU!H`%^rMIK|_XHYV_zi7Xqdt?rOW~E`5ar5L!$UN{T!g=Q4KVhT^ zaakH&)yY`DF(7GfG#)AMk%jBey%z*S3-1?AF4&O(9Zwg-zjSU6%c`J#H;)MXzrcBA zc4x79KwreZch08k!$ExhQCu}WgJp7Jv5f$CR>Su8VM0y!9iKq({xK{)T!6Ry{)JUY z?|K_4?=&$AOb*G~*wH59XGGEf?@z9Fu%rQRKX>BcX@7uR5qnVnmU^y!kdpKb)88_H zxlIUCz74|tTXvs8|NX)L^@IPe_djdgfcsnTf7bZ__rZU)^xti~B0y%^?=BX-4<$yQ zE_k4vW^UKXFA2xx4I_(!9L!2KoOwX(p}lmwF>5ekEiYODd|24rO`6c1Pc1+6WQA!b zd3rY?8gn`k=oP7@QS-aqrSEZqZI|I36GECwmp;~@$CxE3vKOx-Bn~E&pHWa861$bF zvmW&`X+!z~Px~rWfMUU-QE3>!V*h(B5zYzwKbOU$TH z<~tvC^&Vck*@OlLE;$PlXq+IgAAE=QOG+d#U06FOfsmin;pc)6wM)vGxB#A#=tUvs zCn7$#lyPjyquQ}D#Aqc;tt77)z4!K8abFoNXdnobf#7TWybokpp1*9s(VQV~H?n=L z(zYarh9RV>c0jeA{hDSdBZIs_FF%J>RLWrSkq;N)JOSINmTComjn_RU_}P~D$t)U; zG;FU`-aim`(W49V-i?QQUO{lfk6$h2TcqD=K>dNaLtHw^dOu7om|yCHg?S>Uq!TeI zqvf$6WHh}?&wdP(8Gb$OZi4;F-Ln%bbl!4ns9x0z#gh`dnL2u`9b^C}BXG}d&ZK0iVY=Aa4_w(;l{k7uhuLTF6!t6$LvE}8JzoDWE8Tr2AlatzMa)jwasa|I-*ydHDOCW#cr^n#c>%SLRx<^H)aifu z0#t$KM{Fj7Fk0+5OADU@_ET(r7IBApi5T2+l#U>vYvGFj2c;P%vUQo(08IW-b8wb) znp|-x4BXX%`o@k^9s*%Jal%YQsS*a*gVL4zK%z$5Q~_aYh?)v7Zeu5R|H*|8m$MRw zh&l7nP--3vc%_2Cf0B<;*nsJBq{W3|iv?_QZSBD;`Zy>T9@|wKVmT@mq&4KC?Gf0y zOjxw6@6;jdP5g@A+0&%-UWE}!uP_5~f!U{Zrw~X^+-3?zAt)dkVkzFvR)k1tQ`Xk8 zbciuz!!j{~}Q%VIXyQFEBt{CO8C>?_CWP)%{JEQpQHT z_VXA=Xv@pz&GcP8X5xqIf{;xKcqE}kR9>ipc^HY>0&)jm+2zYoU3yO(JO;G zJD@`=No+s$^1CgnZ4FfNA-Gp*4rh)907_Fgd1yTyK4<&(yJ$t@>>14i3M#Y{?i7Xa z+~;nxzXn6<`rmrpn%$91I1Cva$|{<-W3b}5BD;FdwP+~#XYYO~*iaVl=H{7Q%7l#t zlYE3N&@}Vx{7)ta33$^_MajTE6fw4I8%T=M-fW&ai&jL4xO%JUQEaXfL{eyr0GlWg((prYYy`XxQeDWljF{W{AZNqu&jO6^+(W=?u$c z>c%_ep3cOjmJPG(M=q9&QdjhvQQAd>A$bk*Kg+(G4z6phfUpNqQLm=>L zBEXgC2&P)ACaNqN@Plnk8_RY{{@Zz0b$40E4N4bwWL!ld)Br#w7_$;GRM+sH#E0Oa z6q+&+C7h}59gjl}F<=VeIQ(7vLSnHHiG&2MwEx~m&`|?I$mww39C~dlW$hOF`e}Z^ z2C-BGRi8-LQ3^-%Fu(wsW7XMou~QyVP2-^!pGwkaxmkOLDT6IqdHr-1K0wA~We#)t z>kfbAc#cJE=Ha0PaS|QgIyBIG;AY>*Zi0&sxngrWBVU$Qqyg^ZaD1Mx%H^_rCJ zg_3N086Y-@- z4CMWwhMUP-C?h>-N3@f-c&^vC%K z59Mk83E5z+O2{TUKE~AcO)*IdY2pEf;7cE?qnMli)^5qf= zU`r@iEK)%Jm!YSmt0~nyIp1yDeizl5qdXWA_GLd9?g(-`TrxaT1uKC>%1Q|`2>LT( zPSKvvSw%)@Ds4)GifeN8*dG2%;X@lXV?bZ5I$S>;k1vf6Q=YU~6Nd`9(aif@`|nuq z{*y-SFV6r*l^ig*}{KhfELEUQNGs*kWw{#`p`*e0T_DE4&ql&Lfz}VL6 zC!vKJ;gxanIp)RLzTE9)^$OV{kN3D}%iTC<1#SdUv(%=oEuY9*zMRxEUmHZAKe+=xa@8P;#_YN}(&jyHcOUA6Q9tPb8wr_Qqo6VeMgZ%ZY}ND8?HxGF?| zwx;L~iaHb^xWe=;88N@R;c1J{lY+nrHiCnkOv=-bz`)+0@5rj(zJm;mPVQ*rBXG8p zq=WWStD@tD4Pfc4;gQqsUt+!F{sYQEfXn~Hd=Ml5KQJGR`Qjm` zSE|EYmMR~edk;&=Zm@OYUoiCMdN?z6cS_?Q(R6Cr%S6m-fi5Sa6YXP&%jK}?9sb;x z%f`1&PV90v9@mmK(zsRSrYHBwhG9#8l}Yd?Uh-W>l@N2^Xx5 zgqS&>2XbJ<(TKQWlZe40Y^T~8nk6s78j4EfHaw(Ls1NTSt`?O%-j`(0@H(H2$*TUg zpi}GQYnOctD@JOR`+WhdPOTI+3fLsw>#MM_$9%+{vS~9r8cIXtwOCj%hjadmaRtMB zqw3UtU^F+k)JD+6e4|QBQKK<}7`7y=tQAfqoC-N4#^T&i0K^x-KMz%sN124_qUnBN zE}-31_(}m??N}%_!9_lPQ}Wv9`--ZI+#QvIP~JbtYU_ug8U$GtvqK-h|BH*f%W%E& zP=5g9Q2$M41r)FEk06SvoQnsU;b0?e;Ko<@JbI}Rh%!GvvcgGDxz+Xqs#p!PzD|Cw zmQJFrEfz`_D*=C41ZE|@NX~HCG1(TLVw#wprj)Xpe0q|Q z6mu_l4{$-r|4M&|$k~wket}GvhD95+&BJvr6GnY_*e%v?}`*XscR zFaq3|{c*-dSW^ICskgt`)ZPrE487ApIx3|VYbQNh<(_~2DKmJyIW<2q-HKG}S(7GM zD27N&ZLv#t?r#^?p)ff{EbU3(x_Y(tA5FFIKApF#BTC4ku#WmJ`zD*lgcX&+sHrGQ zc>D&dt`F`lqCCZMAP5`9d_g(nV2^gzL`&*%36UOId8I-}1|aNU><39eSE64uEp7{j z@R(b(gPK+qv0f7u5OO2O#yV9ymKdP5=U~X%dVP#`f?IL%#~3YB$n%72D-mFsV9buE zgNpAZ(b{EPO~j(#z9fR)a<0G`LW$zU*Je;{W7HIa{w6DB@TIhLvrt=skp>wfMrJP! z575n@!RRAX{la2wZ#e&$+x&r31)Zu=xnlMmAunT+6&Nc%IVldW>$GM=7!3(g@AsiD z0>Ot9m>-%*Ms*lKSD({qswnY|vH1_oYUhUPldhZG+104wL-pp5CR?p&S`OOCl~9Zv zfWmWo^WowqPxxOWm%oMNU=`&p{U7No6Br;GD{Z(A+;Jmk>(<95QqWx3F;_cL)<{P^ zaX?99ikR}4Xt6VTuMNkCi$3O?eFg*zxLD5rPgP51inRAqD}57$2T7z9t+-9X*QU>J zSE%d94}9aRJQooAUnHPtlSO6?YF!H>D_UI`i28M4XFsWU+Kz(E{?onuUGymFM~Tw5 zKR?sc=qwy_VdW+*A?X6C8Rt|H+kAVqdufJsn3^zK-C;-3P;Ua4bp&Mv^vIy?awqg%6G;BwXdipi1}Lem)AvW_G%-HeVM%-4 z$zA>v_W*DeSk528h(zEyAH>ze;F^Fb&hMaQm0>R2d@sVDg#zDYYsdotwQ|uSt?;fw zUzO?-xpZK1718aZ329Kvn8a?NmPT8?Xcd>lN*rF!B@w4(IDDEha1Dl)v$vra{Aj1w z3!yU-pCnC|n@bOJzc&AI-GXB%F^3`|_mGi0bq{O(oO^-3p^Na>cp`sE(kbiRSc<8S zEo{EgtmIF!sHzwltcW&Cq1#!wms#ItbrI=9FoL7IcYKC38oM<+id3>_k9&>Hc-u}r zFc)HK#pAcN4bc*{`PbM(yuR0 zyTT76$IL z3&w$cWwn{vcrPb)j;xQuYCgIe&T6a`-zQMnui19if5Ux{gx(jEe8$H9Z!G>-T|6RS zr;aV2X{nB!mc6rW_p_GF!UO|2e_ElA%#+$7xC=#RUxH*MR*lA{UeoQAFw?yPaWs>QCXRn|1h$g$(B8qN_ z%WQ~B%T@aCg_nrNp#ZXqxXUk$LD^FB3KVrW$mp0C_k2BTidjwFf#a&*!*qNhwA6kQ zt~Nlk9GyfgHeDz_axbFT7~f>?BlZ?S_i$1xq|%C{JoVP&)s4Vne%P7n?mG}K{*!a2 znOC6w`w4y$q3lc*(!(=YWD7;fyKGN(k~V=B_+EV|AzT~P(8f$>cT)OWi^8g{7xYrw zYZQ%wd;{T6nReJsL|;iA7b+=lYTK4gwJl@t_+3zibum;CB8SuwY<0Dxv^`Jo#} z_AmSwwRI{BP&t|HLq7@H##5q`5(lgOA&b!+_v!-yyw>tv^pG`*?EmRiQ$5o})r zoAcxFk8qRMwe0E9U6TF2jHCrkhUQIN+V2#`d)n+@nR%Ds;#)@lMN_EWfBH$dIj|=WVt*q1`k*C@m4x#((>lUu#J( z0!=h-o&@{LCG%Q38Dyw8PhVXh*CL0Qzri&hKE#tF!62Z3;NLe)@R>C%xFO>{(Xy^{>HeKwgof)10-tit^(lBCrxC{fspMcGPZl zN_3TMS&WYdqhd4B$iw&+wwQ`2W~W^`HmOZWQrP!UBnQQJMaQ>Qyz|rV-1kgryq`~W ztMgo0?(KMY?r}5?v@=CA57k-?8+VXq?h@nGegfxin2i1%1g0g8*cw9!3jBwF3Zw0* zwBTr#<2-ITh~#2i&rW1;i;TX|oOGm{xMq ztsjkZrQLz?Mh7y-`^Vj^a5SXfYK)Z{&(V-qc4F&hhml9w758BGzs9XrnLr}s{iN2A zovVqNb2lNR;_sI9y7p3^uIyqny|DC%GOP%aESof}{gJwNZY|wAoA2NM9poIHR+59w zpOtox=?6=o*x9y)K{GwgEr)Bf&RdD2=LZ(8Bmu|6C>2+)Wqzr;3>C2I!K?>d&){0v zrS*)c)i*@A&>?koyqz9Dx)!QbxUx}(n_U2KQQGW&aD({Z_(OuB5I-shyUoKe$9`u} zU0PaLaFBeQzk1H~Sk5e?EiE-*H$2PPwxz=G?H^N}g0%gvBAizQ-q52Eor8{rQ_rmRH6KAp~X=0LFNQ@@jf-TRk-}|8&2!k z+@H)ZhgU6~g6r$YG#BV-ms=2t7iC8Yjw=8~nm3%P_AhyW4FSAPkggi2CBIZ&vz zGW@n`A=!zmjk^9(er6|(Hpx_kuUC_?3ekn*oY%UFV-@)KEMi9-uz65xyn=OYZg>-}-)Cy(+DGElK-IqimIUv6 zRQrhu^0Ff`Q%;h(}13rae!+sFC)!bvr}e{*#QC( zXqE}jto{4G$-svxMN)bH8`tgntrc(yADtH2Tm30Wd#;ABrJmI*N}#ll`ykoGuFZ2g z(GdV@fvgIpMyMov0;-;ZvD~Xw@65iBuK_8^CQB@N1Pb=VxnOoURsHB7H&Bnp|Tm=R(Frg ztNz(^g4SJ3U4P}6jow$^57Yq~KH1x;7S&05TEEP!1BBdMw;D^0QOR}_ z@!i8@mP8=-`#5Dq^aST|sqZ>@Od;&BTQF_k?R;`_n}L~sG?Zb7R$IQm_89!cBE>l0 zX5p_ew(oZ#Ga}1{J0qE#<2?Mm&aK*rT- z523Lj_W5CYkI5~M#P|9S(Job$`O5xQn19jG|5=nnr2q2w3zt+}wC_P^t3uC~uKc>nT0YsHO?js0%-i2ova*y>}*#L;dG(23D}>i(_l z$>INpZucM6{g-&QB_S>S`(LkzOEnVgyeZH8pNzR+}|;0$jj z9-;w!V;PY6u5r#cQMYme(53}8Ko=tL_%bLSrM_eh-38&dj!*h-B?UaMep-W&fU$7A zUng0fchMboC_tv$F8*nNT~x|bW``XCkE(11DO;6t! zwRI(PNV42k@oBpEuEr~lr~PHtiXC`MKigb$+##9qlK2%Bfc^Ep{~*oK@nMOU9f*cy zNn|ztNuCF)=zsypCBuybwJ$(myqOFesPzRC$=WK(+y0#Cb~ zLi_I2jn(#tdzTxEo9t!SEJ1Y*P1^r)XcQ!O>)ZlC5?RCf$}5ivaJoBo8tyf@EJ5kU zC+s-nSv^vMUA&i8(SSTLH35?)!G&`x5Ii6jQR_ZBTPSz2+8zmdj|!-2Xhbv~WVQLI z;m28(AWrR!i~(TRp;6SWTYY* ziHv3h-EO`6U4XOY{fWHt%#*mbODhj?6DlCwZFF{M@*igG=Ta+UUSmUoDdI+V;p2ZTkxp5Kc0zS400mX;X3qN$1sd zXGfSQy0#sm(L};`M+{Jg6Ikf6)Y@F^o*=CGpaYnFQ4M$toD0sEv$t!4umI?MODxi} z(B`7=1Tw+U0cXsX*5_o|x#n1?tZ}~7ZCQhe%b=c*`I`&e?i4w$GQ`$i%IHbkAFTVwp5EHk3-8Zi zYVW6^S^ZS+c>Gb?Z(tQ0UVl*qvFAsECmoL1qCmd_rqu)n%QRMcn8L zVJZGm+D!$K{`5l%Dih+fEso&n?ot{#!woAeXPJ5DdB$T~N!7{$v&?rQq6|5&j#eg+ zBYygv30&vEq&Is(PvrGcd5e4%EK`=Q!8J^yZPSh6uQ>$_=c=ZPkrl_(FwFpGD8AvBA z`0w~0HV=N(jm$0aUel-HuIzSPiWk)YE=DtOR1}kqvWX0Ge1i59792o!r`^HX&2th~ zhB9WxZX40T<7XFGyVuLSG+FH#m(SLz#v7l!XGnX~mt7$F4aCNA<%qeLJll!NDR~0L zM}3~*aC{%?@<_0K?CP}8(+63*amSoCt}-wcodV5*Q!9_Gv^}ki74vzU+Ibit;i9wG zP=tUl$Y-hj0A-Bm{4~#l{*5M=y6bLOn!84(>RA_C#-8Ov`pNQwXGsQb0^z0pFmMm2 zG$kH9#N<_>x4<1jwfuzj!(r`NYi^dOJTq%UOzWPC*ZD|uRB#ww({XT-es*s6x0k?b za6y}=$W)FA%3dcCYX&Odq9IE{-FBtKYYUsHz-z8(W85bLCNfu32Zp;J;rROh%NHQD zx3)H?ynG%ea>u2U%WHkRplT74P}pH}-_J;ORFZ4r9Qm;foY zh*Qb#LNC$K10&DNf@?gEN@LYxp})7BM{@eEdCCk&6IP^Ok3m(}V{I3py~)=B=Nf2V zu*QowYssN^*lx_p<*ddF*RPuUqx`ZcHkGPJ^X6Ah?e;6yqp)-G%iE(&nQ}yw-R=>D z_w9jl$t#R17=ZQjk+P+{M;tt*Y>m@Fo5%28FZ5hY;fmSj<>^Ziraoqe?6RdGns196 zr}tbt>rimxP2T2eZJ6sz3KV)t`(B5ytIIEkHLY)1EhU}3?i}Y@k3W%&=RSakN>Pw0 zzAI4;-?;59#K>oEg$T^x{^G2lK~v?meeKM`NiR5gd}v0D7f&8+b~Jp@K-c4Zo1l;k7gNNB7~dRR+DrYWVm-Q&AlP^_X|hJ3t6* zy!!?03GfQ61FQul!)0=w%yleA=_2ipsL+ScOt{maY4^ zhalYu{f#q&OKmw@(P{se`BV6KFH7cDP6a(p(RFXgp%epp`q~QKmTS@L*^lwDktlb& zZ34*(_5B?-^>x;s(w0LMNKE`Njd8>L=%m^GDR$kfj%9q;X5e}R{yT;2irp^BoiH#Z zF;}&TPdeVAtS3E;>Fe=;0FrCP0C%-XzvsjD-n)=}qahd-c0bfm3<5i&iboFvxE{FQGsEJ56O;>mKAJ`fP7`(Ra<-&xv~~xOy|m ztHBy|tj#}sXn!gYqL9v9W_^<$1FagYYcUSB-AxpyC1mEUV^)uk~eehlK&>`5;QjaXyq86ZL7_X8Q-+nZga2o2N;AK!wS!qlPk%Pq1|hCo3U#AtvX7lUJHH^)n}Dj z-pvF_kP8*#9v!OI^~+vhi;usW-BRSSHtFn>#^Qp9Or^r{E-^Y85`$!FZJMehJ!ie{tV< zQJ8zA*F)tZyza!XKMHjpx{yKAh*SCVEo+p4QyWwM`F3}@7fiI!?jC7%=_eAq1h@z? zEqlqb8tgQZAvE@e@(8XzPOL3$SX*txFj?VHnhxanj9*v%M5%mc(aaZ=xMs+ht7x{r$_(3DGWmA6cOy3${d=&ex~b$)-eu|>(Gs)nj| zKNwlZAAd3nBUV)|zbT7t-F>asXsue#1l_rOS>yc9`q^Kn(db=cCrTE-==Dy4MOWs= zAV}Ngo&zXm)M-7Bov-O1?0h*a(%CnGeQY;`gY7rdTbI%zW3-f4>npxE8oOb@{O5HyttA_TS__4Ndz+Q?5fh`AR zA>JrD2AI0+2P3-Y0WZUfsfANi6shORoG%r%PN_qBD=H=6qeprHtyX~vswZ|1C}pOR zH#ja?!)mhE7;>A{{pvJ=&z}VitOtf0>8szrK0Ku`d3qh#L(WtS1G9?j!U1`(-U5xU zF?f_5!%5F;o|yokLG`M#VZSo7x=@{dxbrCyuFGAUYob=m$%M-d{JBsa02KZ4YVqsqbg0V7jD!>4t03P#zL0x9(P?ouh}&{`&FQp ziOfLh{;C~sV)uNwO|-ef6lvUbuHwJ4NlsU3)3Su>IusT6__k&l969Xt+UUi)eT`f0 z%l>kG@2wE5Do7+Il?D;J7La|7INkV$M|({^q4-{RZ?il&k9@dfwCE1E9orMHDW_~{ zY0K`+JM;zVXt(L}8f>HmZ6arG6}Kyv?R(jOIa!gG}ex(liY zyb(#U46Xt;viQS#QSfy=D4#oH!pI(WJGGQcu3L_n2x5scQcGVS=u<6EuQTReookzg z7trEYzBFp16Z$&KP|bg9?88-!@cM-;gx*zKTf@fp1wa9Uh}tX^Pck6+;?_!zy!S7tk0`n zlgQH3dmO()0rh2U^cnV9m@V19`?#j@ ztbUugs02YA1XHEqsQvKLG3kK`8y~Jx(b`ACwDf{2P=gEP@s&$j*G$cfO2Ffe(17ZK zCPi6h=|aP$%JqX~b=azGwBNi%7wU+&k45bT;3;Q;v zJYBV*hX=fDXCaC*flQ}+_uzt)fb+%-_hbM#_H{A1DwrW5Ddo;>^4w?;Y^zh{84gSRhPA_}{CgP+wFf^%`kh!2JrJ-D4qLdh z(Nv&i9~t)iv7OF}&{7F&sI51jt0(waQ7LY<0Erx2ohX?DOrVY2=kOv?9gBH{t2z`_ zwJAU_$_B@j)jVC@^_Wsy?bQBnAZ8(DcUa_ZDbA3f^>sN?UnV2Nvf5MA?wL!*Pd{z% zrpmLfq~o2zB~42;Kt)j9r-7(zwhx1C(b-oX08)1yVk1>v&tN_~5opk%fH>z&@N7QK ztSOnPHgfPJdLop z&wHsLAP)-QQF<2C?5?fRH(Q)`Xa4==#6{7aAP2Pzb-by}1|}R1Xr3z6TUeZjyk^-9 z3{*n{UXQ2|2^FX;UpRuYZiAbwy#*)MUS7M`d1d+s1*Zsx>RC1-oyB`tij!1%aH8j zwT7l^p-M5wXN*F07ws$0C+X0%qk7ocY)~p-YBN<`4&T02>vK~7d@Ye(W*D+AyIik zP9hf6cD}r{s86pqr~Kt5bZZ26=&=dW8Of;RW{63);zA#=tAF->Hx2HXbs!uy<5$ut zn^Cv1vQy{n;3?uN+ElPiNHI4t*C;_75ayr8Z$Pk;52ke$h9Y1R5`}Fc{~aLpaiQfH zc2)2UjauEJ=0!j*OMt}?+&;TFxVl!}aDzs%qm2Dj0sF$wYSI=Cn7Wu$zGuE+3IDry z?*4lBJOMt+-%=0@TRC`nB}W=$u`R9dMigr9O08G#LlZ(|K54ZMGQvlB3nlXo*zNXf z$EE~u0_2f4f-bbg9i4SSW2ZFBbH88mvt@JR$ddDTJ3*$h`RC34sJ(&V_vwn1;DEw#vKii6 zZRQ^<-xRK_p1VZ$v#$fQ^I=;XT}`|=QFg-~T{7Ar9)KTX`)aXyrI=WNzSLYB^I!)D zD6k#UP~x*_5zld#CQm&m|GBXR_X|FDSNh^>C$5ZhVcteRM-U?Q)1^JxWpZP($D^Rdmh-@TACIOqGoVX}_%el3o=Cft~I z4I%W`y}TB!YK@Qm?V?2zpY6L=Zsy-Qnedv+&6rx7{p_ftNS$kR;;dVz{GbobW(TKZ z*IMLs!lA&5(xuw*RC~~CwVM_+2|K08_~=X!nd}ZlDBfZ1b&BbQee@oes=fr(EkYI$ zS32Km*i#dL;)E`Ael*%;Z0h*d7ZGZHqF!NKv0lzJwRiLYzwL&ryO8MI{}z)Ho?+7V z0U3b79kY-r6qGK=XIa5>wwnhKQfW0Z zIQ3Izee0qw4V4264Sep>$7Al`U}hGh3Vx4v!Z=mi<*fMZ<+H*}MTzz-3kn{4ZO9wR z_Hpw0MB4oP*iBYp41jL#`jpBX}b$6E7S3CscX?z7(QeZvG%v2@X># z3S4dE&%;cNC%ve?Ygv)-w%?og)1%i0kJgMEJs}KEpJcgD_4_p7 zT^knhH__y!{rqLUDo-de3|_SKG@Z?+r;HC%{C=+uu*613tK!<(S#Je_p(EbMO2#t7 ztLVw`!39HE0&&4bS#P*kW>S?^#g6V88bZzRXk+=TkpApwi2@r&-0XvfkT{k^CiCr8 z4h$ZZL+$u*!c=c+icL1~2bFjegZYciud1Idz~2(kth#L?tjNjj_3nsXUb0G1D-mCu zaVXPOx3p|U+)Fr3B%eRyPGn-8b4pAm0UjRrKS`)1FVSxZ$@fWkbse8AL*zjP?mpI!y8u^n?~Zo+t0*_M752 z_agfE&mia4f-kRkzo()`vD-UjX!#y1{AW-kODhta4}*l4-o?5z{wZrtsG|RIlJJ8z z+_oexnrj_PdvlwmpwtL3HoS(*Hnc$i9MN(kd2vp^@EitJ^quwA@w<*VFoJw3Hu>+i zyIR8$pvG@fnJ3_FnRY~<=8wztEDzs$!c1HCk@xz&Z>a%fTNWQ*{UW@QqBn~b;JjQC zo%6q!e_7Do&FeflhZX*4oc=-N0{OrL2(0K0JXqL*j?A z!)wI^8oMvN?|-(h-u;koxZcf?d5kHY7SF$w*vM?9h^B146r@WrLgn4#A=$flITVQp zI;u>06c}(6uHw-T?)tG4oOg1W;DRq{P}zgtCE(LB=&7y+Nd8jya$KnP>f}1GTKHJr zASEb}o6jKRtxp#k*mKEVuiIN8`d^3-m{7_H(?o2pB;xT2b3!7rfW^JXO8Eh|w0LL2 zl3t>Zoi4RR@5<%{!#pW_enZosdo=@57N3Ace3L(c{K^KqaY|B;a2uD+*bQku4za3!;9`z$l@IUXDORH>smhYw29#8P2mmN{}-5R;I?ncqoDcr%6AO4(Tezrb7gBD9(rS}>2VHwBmb~41)zVq&qBiCcs}MYsS=<#^I?lC-t$ZeV`!HH=q;+_f3sT>%Pvmn*!wjq9-H&%4w$cyk!_ zGh~uy{pC&yO_;%XNS?uiLU>kv5x;NeO`SK@l6i2^^|w8P?f8wG2=kz3W|d@S)}v}C z|L+z$R<@B7fv{JSk=|=}li2lH&8{W~QR`k9w989U8yyu=0#$xT!QE^A5>;eR?jb&8 zVjG=8hcq#MQPH}YnZka%d>9ya>%G3%XjL-qE2E3Hp{jUZ0mTknmpfNYWVCL8tE(qc z-|<3EBp}ypBRG9e5Y8R&tL4HJ^y$;jYoqB&jm$>J0rz(l0aG-yCheGA*b?D;;&SlW zE74G8&B&%BH>wohoIX2u^b;8U!OVvhFt&JN%uJ|5?3eoUh2fG@Z(csY{`Hhl51|Zy zy9WY8w)K^v{nu;rLZ03}yEyPr*48~Rtz>RFSUv(rj;*S4$6Y{Msy(3A=+dmisk4WO z=ttD7$*8btj_2<_-!FcUR%xv%<9Jrdl>8<EfIe_&>c9Pfx6>Xlj<)@&jvpq zI+zxGUwIg0DD2F4Xq5s5}|Fe-DLdPpiqgy-_JrwdMPnD?Tg;r-&)~y$*P@t@Ziv)Y0|B1AALZy0{&Mjz%N@zS3NVmLFbowF1dyk z~IB{!+^trG<#C7C9h37x<=f8$5)jtg=@-K`1{~N*IB2)uVTsq~)8}rjX zC_Rq}zo}NFo@ShtkM!UKqx#?JoZzA=@VxJf3F+2+cNatnfrfst+P(JYc0D_jBztj} zNzv6#it4;IfJ{|tRDD!DJVcd09?4F3i|Lz#4DmK1Swk_**(TCL7EF%cpVFaqMNL}> zSo~R=6I|yr(O;x~-D3EE-eC-)F>UXz@r zt84!REi+EfkJLK@xS#@|uZ8sG=4i1w^f|C7WM1PkiZeVsAA22KfCoV18TkIv%t5@%QD?2Nb z1Sk*k0@zbuYQbD!KpSbddYosPw_5UMV;Rq`QpiB(S4^hps;bgrNJ9_7GU<-cF#V?* zT|?ilOmkiDl=>C>7zXWCHiV1)iy;wT2hdtUdmPh`t;U^SRm#wD%O8yeS4*)eKL{h5E@SJ47|H{FbJ{`X^4cF+=cnjLS}Ex} zm9I7ATc+fxMDw9_(pbl#zU2&r^V%?fb(4M0f;|cHQp`%q5~*@X+Eal$@{kaeD>4l+a%gA zNb}RzS(B3)^y?8O9(S{|_vccM{;(g5$+|vu*%@YdrMRjpS)vj;=xvka4rK)Xb~+~v zJ7eU&bSV^f~{fz@(bbBZ#PH0k}yn&6!L`a`#~$pD%Ace>v-*!5esu?}$bTE(1@ zlxD(bHgOhnIboHJ&8UO$%45r`;Mp%8)$*Ijj_Mkb-*<+d>9vLkzQ-lO5H5$IP7roG z_-o+IFpqK!4q}Tp;Hr*8j1hx|v zB`gUcUJ;?mz*dg&jdi$?uiNH1EmxwVV1cE8O4^8(6LCVly-zF!4)Y~5IgOW)M|8fr zSql-oPq2(4L6azLot&oRa|0WW7!0)p$DgA0@=zs|+r*M(CA#{yI+hg6o`|!4kGpPn z7^Y?Meh&334VP45&Sb%4(EjK%MP7Fa4Zs?LM|#vTn|!67CL zrG#SCUxJfds|28RWRUB@vX~csjDt6wC~xXz*yCUcFtf{5p(=8xCfan+}S*e2qBOhLhuRzG1y4)Lb` zN?jY{#!Pd{^4J=F43X3DIUk)8q zf2J4Gz6Firya|$%`?3OU(l8j%Pgr=pYGd&@`tv732%&{#rJ-biFg2)UC{KWD-Us*7?Ed$LI%64Gx(Zdc>W#*0!~9Ax zTX>#~EZ>bdh7|F#oL(J50GRm>GI9HT(FN||O%uWgEC=;{Zq;vNaNx%T7>OMNs9c+m zF>3zaaSfn=f=}};mShR%AMbVx^A7RXB1^uFVFtY2@T<_e9PTI{$Xsfu6n;NdsR+%< z_oU6%j99eZvcxQ+cD0h9XoJx7!yBr;Fv>kFs?d&KTIYG}x|i`LxkmPOp`n)bjlHVl z`s=ys)6~NK(fC$#F8vdO&a~B7lw>l;h?0h4D9uOjF^*{=_sww&Hf`sF8@3TIp{Iw* z^cT!uduQ6xj*9jZwcPlElaVa&WSUx3STMut-(&hJq|Ar=E7_2p{uL}OzwAu&j{(fl&1!ic{ zB(X2-WWuMTl=wH!?QgDPzhF@;@e)C#qSXf(Vu^wSK}4Wu-d>gQ*5OivB5NGaCwF|w zEI!-jX0NM1>7A!u%l4Vy=-wCtq_Nb}_-`*wAIv0U)Ek^X=L?F*d_%x~C>=3s(U&a- zp2%>0q{NXLGddsgFsz%DbiL6;)2zyPFLcvV#q!;MzaOw~ZpBctiU9$gctBf)gc{&H zmjNvI*ViiMs#W!&>WiI-(gKE*fb%hfIB*!Be=~m?tzQ;^UL3uJCNwuN6gWZ&%on;N zPe?qJuEm3vCqbt#Z>_(>i^jwxK4>3ea?Y&mZdGn>I~V~!gq{q_)<^2}SyzaN60Rr9 zc=I@>uj8qr0eA{{xOI0l-JdZo^vgm$O_!=RhSMyo-l3juy!eWlAc=avwUFa*1nJ6` zxRtn~nG1yn3?HuYj%p~!Q-;E^eZx2UHETpfjeCC*rz5YVv{>G_T))#R?eiWJ!++Fe zh)iK=EMk=hr@1>U_Nf`y@GNH7EI`&rYSWW9zsr62_?A|T5mHl$#$Hemte9c?v*=qd zmJ)U9ILZ*2Kub|hM*9LA2*~8)y>&iCS|yL9NoN#)C3+g!Wwvf3x+!ZM$$&1D3Q|ltHi1=Oc9vDrN)&21F zE%1C79k4JOTVH^6MY^+cgx#v#ff17(Z;P2Za=q5(P)e^+?UQaDi@Bm*IcokQSE);_ zviC;s{xi_aMU!eMD*y%5H_&#lY=^^QgA^E_6WK?htr6{R8Fj1l_otITCg^G5EE>!6 zF!C?|tV@2tXtPtb_RW6a%fk5Mmp(@%^zOMDd>^KEvV*3`%Z(B!8yqzlfLu1@PI7V3 z=tt9`xsd^k#e8>vZS-=hvS_f33DOf5%%p!t;0^@J+<3XE{Rd3)Pc`~14SiP-A}?bn zR*L*8aHy$}!kGK@*jD!o89+1LK)AobW_XRwGu5i0Y|t|sAtb7|%L<51d^pOJ z2vQ=V99%E3)O`m{!Pa2f6oBZ@W=|v)7+T=vp-e`JiJ9WVKm1v644;` z5U(QYGbO9RiN$yOmBXIi@N$VwCwha4vEe5g(3Ok&GKjA!WxGybr zoRAhxl!qr)F;m}D3-z>ZuRxhwPZ*A}u201?T?b1s9%@nB9hGd3qT*}*KKz&}T#0B2 z%C_U>3CR;{oBPXfuH#h~VAqWe-*jy8wFslw*Y(^_84VwPxQ28c^XCh;flpYa;iYuDcHPSEqux53Qmj1+N&t0DbPgP^qHAVZ*H!Y6&CHo15@^2pE;d^|HMN2axk~JtU>nh{J%d^3uyjO9B7}6C5B>V$U0T8 zi|iI^T9C)ud3kz9@OR~*S;~a9f(v96j<`cl)_Hl{Tnilcdb#g{eEMY1_7H zy2Z6tdy?W#haBT@uG}Ff zTM*rActODnvqa)0ryNa3H_=N&G)jP`A;J>iOQTtqf4>s`%h(s40z-BtQq>78!M!sE&((X&NbPT)33C^ zkK!R)yoY!|B(@!ICx2?27J+Hy_Cc&SO<8q}0uMQEw`D>UbFvGXUc%za?+3qSn7+jG zCK{Bq9h0DccgWBM0tBD=F3Q#h$cYR&cWLg|ls$m#Ye*1!2AK;jNaEPn8jrmu;rj7SI0;UE;Da3UydPPckwvd!}vK`F} zoy_o&-Nha`R!%2;ZthN^#-n~D@=bmH&qXmsmZrP+RafX?=`WZCMcg92kL#7AWrpj5 z&Is|c>YR&y>p5x=V%*`GITxrnU;+gN)llaep4GH?B?){KWUg7mZ}L`2)+XNinxYNt_g%At@$YZcAQG)71g57KzWU&Ar7iR$X#DLZVGOyXYzf1#*=wxE=7-i zm086`fXxO7znjbuO-Nv-2)(pVxavPGHYyzwJw-X%g>db?45QIeokFBRvi24kiFco5 z!-vc6xzE?FTHq#E?^O~bB9!~uU%vDSAxww(z|NXhV|0E$c`B{g#H6|2lEH))5UY1N z95paKXk0HIhK=ZYe^n>?;pUKcjNrSdyV5=^N!bmJ1qtrPXyH=U{xu1EXp;0WKrT2I z4j)6J)lzUv-s}u%*I@WohA+U#iYNtWHS;Nf{xt#jqGoPgAOG2?B8_ z&hvClN{8>7-XuvJAlxS)zHz61lG*Q-_FU`3Hch|GYz%9l?B>XKCs-QJD3Xqo0m3*>lj zI3~zidQC3x++@E&v5n{P4P{f$N-r6*%skr*4~B`>&@cdUtxNEu#s>Y>3_f==^zOiv zCDnO|$j+?~Ad91>e^nVCu)bc&uFc8nk9cr)|3Tf~-S%!heNdtetKVG-IuM7+;M-o^ zbW?I3ju(fiz~b>;ev`l3c2aa`dBe|c;#YFP6O$dUVPoG(*KJT{u}RvtlYUNdLw??s z*R;aMnExl^C8f^uC_-I&gW-LLCP>j@nd@AojA-rkb3~L-(l(R=4WM#$xHJu%P^KwQnm#Um2W46iA-Ky``s=R=rBIk1gX?t9 zk!iZtsr9H}wN*ZEV<$c~c5v3DcifrbQLF?RY7aeM3{_t-V?6&Ac9lac$%!?!TN|A9 z6p$`DY=~`qksC__oG&l6WCqRtf%v>U{51bcJ3jeWoUf9)&^J?FL=^r(DZSeG{@I26 z!`%K?gXAxA8AJY#!P0>n(%IWHrx&)F=~NK?2YeglH7$8o1U?Rjn|Bsa_3cs^sBa|U z%5OIFgi4Wp`vW7!k{>1JPJe7^mI2%Jz^H!ZF^vezpH!KV{q4jH^APXg8~;cP-@3ki zxCsjl4NA)$^sh_Y|An0Xp8%$mi1Fd2c=4kH@LzQgqkicN$t-tbr0lAU9q$u9Gn9Hs z*7~P?cC&q~$7rp@!T9vFdr0>Qtr4x!E6`B%(@@kZXV0TP5r*?L!DGSTA3EEhEBpsf kM47++Pkb~c>7F<)$NuKjbX*oyX9ZA{SCcD~HU0Yk0JE{sYybcN diff --git a/contribute/img/github-new-issue.png b/contribute/img/github-new-issue.png deleted file mode 100644 index 97176ca80d77f29f878d7bb1b1eb2a25e60b6795..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 151311 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 z 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

4{K5u~oye1mcG-M9KoTvG$Y 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 diff --git a/contribute/img/vagrant/build-failed.png b/contribute/img/vagrant/build-failed.png deleted file mode 100644 index 4f9ac79c81ea499ae066a03b73d6c6826b5b2bb9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 28850 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 RM+h$|{G%#c@B|$2{{Vo_XdVCn diff --git a/contribute/img/vagrant/invalid-php-version.png b/contribute/img/vagrant/invalid-php-version.png deleted file mode 100644 index e7662dfe290b3319aa6624d7b950ea52bfc6bdfd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 48676 zcmd431yEew)~<`Y)3}EaG`MS^gS!*Fg9L}*t_>tu2q9>2cXw-=;2s=;bO;WC;LdIG z?fvb&|8wrHTes>|ovNmqT2wFAnrqB4pZSjQ_InLAd0Z??ECd7uTt$VKS_lZpl?Vuk zK^REzBYmmJ5%4!m7ll`D2nhJ^9)A!?2MXW^=@ArPO6z!k+0XF#0+?yI?3!7wL4p4$BgeIm2=djf^%^H*|}pM*NK+kV9i57Fpr36*uek>X%lR-+pN8==Ib6;T= zNydR@^vq^PqJz0%M6Y|mM!?7GHr8U7fi>HFle1qP?>b#L4l~nb$3Y^!Eu?O?vwTrU zL47D7={UE0RM-TZDQA(<<9yX(IEdIGtz7}4_4Sx(>a8(h-8%Sa^?4~RtFuda>Eyjz z^Q@0e_GxkFkCv!!jMw2pS5>s18h@r9Gn)A|SsV!I9LPJcz=w3&c6Vi?Ow;YTvGm#c z+Rr*aN8zps^e?NU7o&z5t#hH2u=e4Ao!EMs;S3x%@8ejHX?_g{ih8J{y~)a8&gz$JUo7fN}3f? z&dW+E>epLQ6W2kJ?%Hijt3RFH!nooq53Zix{$6E=ZdB$!sqdWia!(HQZac~7);~r#kO0!H&oAYeb0F} z6{P3iv0ranJ3i-oFY36He;k&sYslu$$gaP4=Wb{z<{A1@8sDsKN6nTpEaCU4Em&x?88 zLat2wJNfl)on?14J8Y>A#PADr6StR0{iyNFSPE=jQoPTke`{Ws`4M=c))~{6!raoh z|EujM-ov6k+j#(~WK&+%-Up2kj5hwfp`ROF-L#{$d<^ z%BFAU&gR{pHewBJ=EM`=Q?%;%`~?FE1Ec(K+sMUL*LvfT2$_AVYJI?725Q+3RmQJl z=S(um`i5LvBeS~m#md(vAfT*?r^zc*Xr%ybcJ7MZFK5kg^|wT;D4rewBawO{S}sv` z6HEW2-J)FEk50%gD~aD+c%5s5XTa@^sR zOf|3{$*UaWF%$emlrSC(;X0MrgZgCHHQE}Hf#Da^LPvx)u|R`kCNlppnpW+T>#}5e zFF_aXh2BF_bZPDA?Zy4Q@?z&1JI)5K^Cs$$`tPfeDXk^a@WoSci%Lr#D@8oV zNqm1or*C~*a%?hXWdR>G`9V(toj?b=&cT2wjY_G&gbl z4R}adxL$U(mHT^Ra@`UO&S#f?(#IU^oNul(pCuP&y;!qc#0Bwvx9+FrjLvJDQj{vc zkLNrmwvux-g~6&%HZYLW19@R8|Ge%!sn2|CkhUYW(#UMf=)roso!vh~#jzhN(hqsO zv&Jjn@~h;XUzgg_jqT-;V8H5|H!)R$I)i~7-xT8xW~XWuoD~)@m!bd>p(tXFkBf}= zGt``F+N(D~2W_Wn4+UOwu_9Ldvr6Y>oJl4Ts7R@crSQZUkhjMmDn&jp)G)T=CV*zB zO}&^aUufFgJ*i>+y=geirz{uIrjLKQbSmhe@K8<}QFX~~;dwnS-#P`+Z1Zu*i}j?% zgg5L;A6gS!4ylq1B6d9Cw=!JA-o%AxHa*@1(knh|=yaCEN~ZCeVB=in)(#8}SO2`# zcp>0e*08sJ=Pb7J5?q6`=K@KZ)RR(5==K5)yKBfjDH7ptU(`ClrS=h>od+(1( znNgH6UxZ9jBwVBZU>9h!1oiH77jRv=k@V^Ku{}0`t;EkdF%*~8`7J3qes)b|CBnz> z=V*}i zI(zoF@J!IL_d}y_{o?L<<gTlAI>X-WCKqb<;A+vtM*)qyiK;| zg?t0`&3pwZ7L0w1x?nADo(%Uaoyu+5ZkfQaEnT`V{A0(;L~VS$jhf*JCvTH9ES33u zcgy&P@_1u$ovQk3aLG>1Co_rajUJ8YvCiAd&KJ*~i{2b#2N+2TOK6mGCpLNd@Ngm6 zrn1BD?}08bo2}B8pXZW<@#EeRQ*lp2@5rZ z$cTzJG7|i@m8FOxNis@L^u92vQm!cq=CS{1HfH&OR0# zpfa503;p}<-!AENqajYfGw{PZz_ z!XM4`dzJXdU*NA@)_-v>05cr5n~}KNZqW9xzu`1I0c7HIy=Q)4@x~85vOC+&z>~&+ z(v|9~5h>_=vL^||fa1O}F@fOcVCZ$z^kvH9ykU=6IC`oRI3tYFqf&bTB>0w*zu%0m z2jrW|bYO|-ohEMj6$QHdU7>X!;tJn5VOOFjF&U9@#`UXEZM7je;FC~4A^k3RT4HPV+t!P2B>N%HEB8e4s(SRa+nmBEs>#)$McmY#9-3o!)o7b9DB97>Vm|I* zWItvh3CS}SvkVoZFZm3!DGec9L{X>=oT@*(`)){G?+Tp z=&Gq#!qHW4`eg|EfN8&*Pjnee5OD-(dpl9_gRK*MXLJT$dao#UaOB-0k%Jthh%%UY zGM-GlSP>`0c6oBAh85s(xWFFAti;8lSyBQC2Y{$BWGMPe@|6v zPkSum@tISoM1~Zq4GKx9f1oL8u-DILkAxT-psX*){$$-f)>~_+rcDB3oOj!Evx@?M zW@`m?`Y@aGRw)}RJ&(l;??P5yFUP=0FP}shF_V)-h#ODvcVY6kUaZ3tP1WNy!!fKM z_Nip2>g%amGjkzOgK!w&+0IIEl7OsH-jLD~>r=gA51Bv5=AL;`;i1Ka^xM$|o2K`^le!A&aH|ISK z-2y#5{XiH5xTpJ$5)?i*6m<^d`EI%B##bIL5nQVc@GwE^0+Z!1i=!pWxG|nMv49T^ zY;&FFdgD>Opgk_gI68tuHJr|iBON60bcA{kU3&IBBITP zn)o+u3cQxbNniJA8VvR7HmXL8gGRedC-M_T!JJ)iBtzy@yR$+UxKTSpcnz?X*IFsH zmd!;0&{N7v+3w|Pgq295OM=aw4j!MC@YlkK?4V5T5Vtko0VH~4U#OT|Lb}@fiZUiJ zh$*q#^Rj}_K)=X@*&K^H(xaM`(@is*5+8Le*n%6oRi-PY=;+l1of0TL*4uLSFsS?4 zyv_ct^VGzd&778Jc{q`U`6U}m*i7Mc-=uSksvwgDg0umWRLJB}X3fLH8h+o`FdO~^pw6;1Oim(PT?`ag0iIpxZwDAOP`N6O9L&zktVB0h0LTms=aEXVX?sD?0d zTDmo-9>mk4jiEl2q;P~Pry&|K-TH{#8(j}R!Aq_58v^C#dC-HOtQV#8D2N$$TThLT zPKZ7mU-ZT@Mqt>+gq#s@ThF%cC(gGf^{8DY^W3g-JPTvm^*j)ikdR7x*DxXu@CN(} zU+vZ;M{({RmD36`zzH+=KgBf#E8w&e1)|gSsH^He43eL5fge1cTgi)*3(_{ahtYrG zEuiI@(Y0x3BZECiGn|H1nS*!svw?&-k+erh-_g5VzA^Bsi;mVa*E-Hx(s4vC<)KPU zdsMzn_K;{tLI+`wxF?k6qXgo5^}K$iBm=+YdzkC@rysZbvS{)w(E40KO|>JK69jz_ zz2e}a>~PgF06+OAxwH%INC=|Zs3HJ8qwWjrDF-+mM$?Q*3dPhewJ7>J>jC%`I_4sR z6WVWX;GVJK8-h7r63~Wb^*~eRHsibvq0sbcEpk*! zW0D6X|C=?|6hveTq#-N=6f(#M^W0+=NffKe3#k@@I3M(1t4E2k5x@4nsnQe;Sj$t2 zeDRO81DMo@5O~!&6Zu-H2<$ zzIR#mL9a^1WpnDNJX0Jnj4{mg+eW;ysp`Y+W9Dh9GKg}hqhMSvQi(6P$esvHR#IA# zSf=>zql^T9+17iSWiKFVFO(>T7Jcr8bM7%wzW#U$Kv01-X1 zF4Un%QPD_Q!Tm5tmJl!VIM#X-BxmxhqZC}_*UwtULh+6$`9pWO2NU^GGlQSlAWRX} zy!$H2Qtrt>xCs&ArhEo%;wD+C^h^b%U|;lf<<23U%(9+<2*lAxK|_TAcb335Cs z@DBGFs~ZRF;iKHg@Oe6-Y7|q(#4>l(-t*&3UX@y-=o#v8)u;)|$r_K1eNd3|Rf9-2 zJ4y!W%Hu9{OmBB(ZWARZ$qhjb>ZL6q|AV8@=+rAcglmnKC33aK77?F?j0zurhoe7{)n_Zp|{0O=nh2Ej@p!ONc?yey3>oOL?}6UC!S9V zo!BuJnN5(b1YVsjyj1o21YfZ=ZXN~4UE24)S6YA2O@vqfZvj$)h2s$o;o6$Eoh*y^ zg2BZcQ{I{cM&E<%0-H)CJqmG+xr^g7)00J5r1>o!;#g$%Zys*^b_{j-LkeVR?-Bcu zP)g?xW4{zwBExJRcvm}pd6RHm-0Z4pqGA671BO)e3dL1t!iG##R6g6+YY@ir7E-5a^barI!%5^?+RJ z5M~3aY2+Z!tFcUjqm8F^Zz%9%L4faAS&-<7ZZ@L~dwr#1zp7D^7b5;?b^^N$Ir&`` z0ys%fvcB=LBNlP2vNd*ZJkJ+zU3EqG6a%@K!O1zyDxq#`UK%JT6}7s*Sr{~@HJdc2 zh!!EjmvlDRMnw9q&^zwbI1}aFT}0LI6$mHtQ|D%DYTNd@))`_VBVj=@-R|V%cOMPJ zfF+}QA^uayB`+naHR{=A#I`}L$)k~P))Wm;A(Ybf$`W z0g4wggyrBTIkxMUg$ zFW@HO^wLaTT&RAFAkW(7sr!vium?>nZ$8f`;FhJ4Q&uBK!;~TXlTV}p1=dZ^tp_7s z9DgYiWt)xu=$SqTeEb9morOOos5{_9piYpun)8xdbPe{KJu*HR*RjxqqDD8yrLzqJA3d?0folA_ zGnTjM*K2|wAn0m79I1BxB{zfH=DBHZ;p?JxEexjpeTD2(=9ITIoFN>|Bg@kHE`s66 zEcpNr-308iHPdt*F;{Z{M|iZ!bO8n%V2C{*u&GNvRKv~)kRfpLoUBaS;}ZKJA;OYx z7oP}*9ztv^#1QCG#=`2>n6$^bx%mudc>$GBlqtTClvv>%gw8Df!~kHDZUR&T>qIXS zrL{2EgwRl$$9SXlMZ?ld&ZCYBl!FA*=)iGvaTT|}MEj82Q=UFxS$~UoDHNYi(es1$wTl`Rn?gW0YWHn_Ph2jim__{=$$dB%t znw=qq!=|`}s!C;;0~Wf50_!eslTAU1JoO-7YaqpGl%mHJ>t;4o(?^*#+=nE>bzdo) z@D|-P&SxlV~_@K`dXhX6*MU^99`J$wD#F`tcGQut9 z?TvY8LnY~5Zd=R1dWH)YLy#lx8WX3i6B*#I=(f2wxuJWqtu9M>fhq$_ynH z6wyA;T%%qmWy9ZuAQWxtxc&?KQg(=5+ZNxcZR#HBJsCT5(r9AGzwVwF9(H%9>h+nr zV{M4Y2MndR@$w#w+@SpjnZP$b+Y~Km< zOk4FcAjtWRpfjp(bBymlA8`rp4CZ1p)nXNtCk1oayqFcxSf)&)GtYV`2`CALYD85| zuPNH#_q@hivOG@~GR~w<0AfAq;ho1mh{>|mF#pb$5lnNW?#-8pB(RM`3{zg;Vse>R zsBmqXBs!OkhC||*mMM19JWJ$jmI!^A<2Gt~29DL66~l0=wkP5UOXlzQa@$*C(`cSi zA(73d;L?0{#@*>V@HU#qXPTMi){HYj^IMZye}iDyreUEbjz32fS|I;^>1!G2?rl1M zGvz(LDc?Cxs3s?x-pp4&>l3|fDtHnYisdH9azNW58CnuarwmVA)VPDubGT`SGo{t+ z=H~wO><5z zG>tOOHdv$PIQ9Gm|AQw}yH5n%!wU5jS4`8RlM%Uzu;^)8fyDEcPg!vaxSgL%PgYuU z6Wmk238DQiH%c`@>=ewgjoFb`r1Oll;TRVN8VDJNc}|so-nA)q+4uHAb_#Qvz_`bz zWXe?$_)Y7J^?|6VM9PVnEIi(7B<@``5$~GV49nC~>ZnmjT%6;=XY4iQ6bzaiM0fDV zUx`g_f&!jeyRE!yaw*6RWje#3dH~IouJq`g_!6K>ZIj(>sG3hhBD5U~VB&-S9oIrd ze_SbH!Hh70m~e)=gyPhn#uau!5S+W+!tq}T^w4r7f~gO@sAMgT?u|>??Ve((l!m1K zf{;Jh_WdQxa;I?eP&$6tnurZv8%$(MTq-;VuzA*Z;*wEwS6-u;A@Be=phWRo4_aSJ zUt&o?-h$YqV5~xQys!;?ffcv?+1(Bp-PBXux*q)X?hei!;<#fWZ|D&YA%?{+6>_c` z@Ca9xc$?nGQV5< zxW`ziUU47PW_R9lu-ng{_BacbdrPaQ4GU}r@Pe4dk?V~AEth9+58W^zn+jT)+PCAT z!n54k!O!?3?;aA?SJE;B9D@V4hQI(r0U&d>>+J@dlA$7Jis2n$S6>DQav z7+u)Uw^MHeOdqear`~zY#vhkdhq^>qOfb%fV!WNiLxZMQ(>aBl!0vR)Eak*YJ++3H zpTVAf$N#i5ucg2I!@*HM_Q_-Edu0Jj4CW(@-WfVs%{aq`*+BP}N}9k9e-U0nZ!>+~ zL=dWB0#JTsW?}eIlVIfCQa)BqJ3R)WrH%ms5ioXqk8DittD{!9fhhqPqvVy!A8is& z)LL<1=pTN?VE&5K_0L`a8HoZtF!WQbN013G)=C(CyJ3fK5s)DCy#aT#AaRw?!4Z(a z>76zkUFgJ+eE}DAYSORo1p%$LQm^1b`f<`UaZ}0Yh|3Vcp5W(q&eOKn-8cq_d>x!E zBzshtQt~s@oO_f;2hkRvTcdFMD{s^PzYuI4(~-YHWHCvOi?J~l5T?ljW|(2$jnu%P zTYQrO;xKrg500C_y|-TEL--Y}I6?PI;iF!h6XP@iqj~=C$!QgGyu9+--d5Fb1gpiG zl@Y5Db{7ei5VPJc8y#o>;|fxlo2p`=g?>pH6@W5m8CJcc&4~3Y?0_4|DMa@O$@ph( z<>I)v4Nl&g-X)4D7*B6u*SKw$&*QM61&Jk6UAsa~;%VY3nQBD0)|60|Xiwe|OL=J3 zn#eq2@2@DO&SM#<4}~xEsW5sVx-9o9n-NLV+n4@%l`c}{AtDIv=y#y%wv_S&?*PUt z)YvxP9TYbG6% z8;CF_@-&6$bwFO40jbRbYusF7-;r_(wlav#_*X8cJiKymg)6jDCa4oMk3+Q|^ZEl` zD(9}2@hAzL#aws~38c3w>F>^v?MUP3K2!>E{0WEj&h1^gbvSIcjV+F-M)KNWX{DTcATo+#J`i zy%MELSXU2IJZf@_n?pDqTRCjIBk6y`uEJXXFYL-O?hq%hboYh*OPaM~GFeNt6NOInO}I$nxDxg6xV(GG{7=G-wSW^Y!^XUsV&AU@ z5#=Vr)nXZ%v)F<7nT$dSWED>;>=RXW5$2vto8R8*tZ@dU+unDz?S(HLmPE%|0fEKU z5qTG-xB}#QGJJlzW$|ymZ*hc~@{~A<_WI`wvpKUCa92S!;!H64Lmwc+JRj!Zn`Eqg z8PM5BEh!)jFhVjGyjk6Q`3i9<_8?+{Z4o9YV?PkAWtBQ=4lu^uBL9FNiaFbAcp81) z_{72jsl5PTj3)*&t45KG+;Ab#pv3Y!5#=Qav~o}n-Kj)f@2xcXj1zKJy=Y>K^`SJ5 z5>BjN7XJ`yA}ZVMk;Oa`GE4+s>44ENpBdBQ*&issQ?)~lR*@1i$~b;qKz+kLIN!k| z^0d$KtI&S2TPLBdewwYiW!ty?Hq{RmAEZ6&FXO${Se@QIpEx-yL#75-t(UNeLh(sv zHT5n$~-s+p>J!i4`RXT}s+ z*W~|{=oabAF#b!=Ecwau9W?{yN{;fOn|t0N-;mO->yr;j`vxG58Ox*XIGZlU!z3+F z-bcH~*xYh4b$!IQfo?1`2QIauVXsw-G11_o_gW1aX%Mj&2qrS!y+)&YBD`|%)A#Kk z_xu)PD7T-{jR9wsQmPEhxLK0>J5!5V6R-`t-e}=`jP9IxEvi!D`jEjfHvJ9q5wH{Y zGyrR9ra)3_KhcX0Sw|YgBCBtA^t3(_#Dgx&doxTG)w=tf^&QTzIafVjV4-x#+kQ_Z zPlyz3)EjF$n@$mI6JCq9{gV_D9>N21}o5cF^TGaP#X9@r~b?o+HubBTY5mi84(qW(<|4Hj!d z&UKHp!DcR&GQS1WOIedR`KW?pJJtrD=Wq9iB4NJdAdi@*bzR_>AK{hY74T9vwq*~? z01wk0MMQT)JZj4X*)!44g*|%PxT-l6F(FBX(`On867<-C2xMR1RYj@^62I?^aGIEA z8(gw?`^}3WCxe&|^s+%pk9qnCaTQD~i!(TAa$T}N(VSKFiV^w2kqqdZkxLeZ(O>`E zZXP#XAX1yL`r2<7;bI?nxdJyHRU*gh)L%nvI-(TwheRj9iLn!wuy{!I5G>P-`7HT-JoYUt$`d!VWAbG1 zd$vujj88ZvX91Wuj6zhA%p*wNG@-AyfwF4yz&lC-eZh)&0`crh3X zk9K3Nn*a+Qm0-dns(EB$P!2Y$a}mH9Rn#+TL!f|K4hlSyABZ?Bw2w9PX`ovKF&9*p zk@3535q(w(zkz8DfHRJ8MqD+MuN7*vO&Q>c4oOyj1)t)mmi5GN-EjcEkwbD$-Upj) z?-Bitv8G)`X$EkNrDQo5HNb2U&~OcSHVA)0nvn|4&QGTnragR4fMO+!Q=F&*?%PaJ z@RP(FXi1Xj5sbNT+;f%8GNeH;Qt;8WDh6Nmy;>9eK_&1K4ppgR&pc+HkIj0{plk8L zCDUChVi0ZO%b*w?0)kbzlB&S^4|w(B4UMM+94eSt7^-O%N4|4@EU6==(lcO`60$O&Kecj{oXkgEbFi5Mi*NQYyqSvgpcPlF`e~fB)29hhoV=+n8*R>cp9i<`6$r+w=!~%fE?~e8b;3Xwyg5Mx)%*PHyU>s4)uNlKf5+?b2S1RI%?v?GwU6qlXno%blgaTe@d@;^k`e!l;$D653I!jW}*?>as_ zLHw*+Vy<*V)C*F2SDld9w6`xNGA*dZ$F?8FbA-qdQM2|z z?Ev*5c;kpu+-6aVG?bh6TMV;U6{RAsIm<{e$q}hILYm^Pt~LWP%!m1`Hs%=H99(m! z;7;pIcRv=E&9eqeSOTGOgza!oOmptz76?|MAFHZQ5uMe`!ZGC_J90-(oGvqj8AO6$ zzxFl-p(2M71=dteKpSS(^W?Ijghd%BqO^=HTTK*Y?o#h0Btu{biLOQ|l%f3zIo?*s zZ3v?`euc}v@XEBJJtL8-UyZVL)RRe<`h{-`=XotnReGPVM{#gp;q*lg7lIJfPw$7W zf8I45Yj-r`HXU)gz%A8)Lg)tPE+slwk2;9QA1?fh*y4w@RAcl3TkZctp#>I3w*uy@ z!jG|7zl?}|9nzRLW1k7MnS%?CRR#dERRsr&SNf{Pwd1b;Nw|aM{~}!fzG^9s53EOe zhTlCm0$KLtt-Sw0X^9C3?65evvVVnjnE{99qNQYjES z$W`C)>FZ`RUulA0Jh`6+gtiZG3X*ow*>mtMrMV37?o8~F*%zB^S-jtPEti~`yWI| z(Y+tJ`?yb70Qsb_?`kPvCgod)el>yDjS%6L(k^Pu-aeXn<|9#@kS9e*qr?w$P@-l$ z>t`D4DP*AU?E#H)|LJI5$5vD9QF{SSU> zdTM#~AbHaTQ=L5hZDQfur(`j%a*16ZQb7T?o2z~K5OmcX>uipDh4S6QrQ3YIV2=3n2I|E2Y!va6&D z!8zH5t&ZXrYb8XN0GzJk%rl3^CU5+tDB;N*Bj+%P`4+nmS}`#)U&RgApyF`&W6^rW z)@aB)4@xaD$|GlfC%&@w4=Ou;z#*fxVnwYF9eq|ZIthGBINP^>MczohyogK*75mN4 zV7i}J1)T4=5&qhTn4fHK#5E4~f|2isysu`@4C(u$$kGxYcjC7Q)-gtW4RX~WHp<>& z*F+aCZr6NY!4Acn+CmlrX4;}boj$#dlWr7y9E0l~En%A~JCbvFLjYI`0#2!s8*ZJR zvl81N(Xu-+q#RP!XSzR?;MC$~`=j$lOiud!CnY}?{S$G*^y8Xe zI+ddf3lt^fxsbU>48v=$Xgw-q&dR_8FW#!qrnTqlp}%vT^l4ASYGx`6Tq9Boa;OWa zYuckm{s!c|Z$zPf8_QGpeMSda8Wt-=$;b-uvKaW(mAtXlbXX;fIY$Dgj`vtJT_}*q z!_`GQJCgn5R_n-{eT4@-JZ)Xfv5}6d{{@f%k}jpn0Va*wD|a*PSnx^Sss)Q2+~;y; z*(Lh%1ob0`Vn5uoZ=9cn``3vY1n-i$okBeX-VN~nsNnYr(Nu5AP=%KAJlXTWZ+1Go zGCt1@UguFq<&c|(H|3Byc=9G@_}G&q9Yh@=ID|31FO~%rKU3=dBlfm7!o-d&nu#mp zPADp&_{3_)aVEsXPp7}`A$%K7dfJs7;DYGjk$m+i&wlmsR9YL9*33?4|5)H71T|-= z_8~3O=oHAO0!BE3x@=WN;gz!g$;7*RwHg0pVx@4pXK);zPWbs|H|uTQh0X z1i=jYavK9Tn=!_{$RFrU?z-mMynGg;F2?F%LgB(V5)!Xlx`8N$S{Xq-5ON4qpL%N1 z_E*HtXkneOX}A|a@!^|WxVo!@0ncO;CmsXgt3ZUPT;?Am;acQ)WZiEupzNGj{z$Zu zO*tqlAtHs*qeR|41~MQ)j`yjD0@$Ju`w5J~o~PR10NzMZ*@!C2U*&hsdt1g<{mD_r zrQPOn$Ge{}DuP(TeL8-N8^3XovUkvV(=8+0hSqI5mDjYpKAQJ;Bf`w`ZaSg0jMSz2 zmnj{NyNUD-ngXI<^O#@L;o;n`#8i~L8Vqw`0E38c2kN)mRt>JXWqxMD#0WzF2(bl~ z9yKenP<6a0BpQjKZ|xi0M6{t&GJ@qosV09*#@?eD_m2v=uXLWbF-;2AMNdIIrWlMO zWh0lf*W*x*2GYVkJlh}bXi61{$q`Rr zFG>YUqNhpF<4x5hF)v~*MboEsn}m&)nC3sGwLn8%^mqw3r4>)Tl)~$9cB~#d#4sI4 zqk2uMl5Xgvi=_e1dTsD}-<$%8(S^?yG)2rg1@}ex%zb@T_1N5i(U4_Gh}GX)zzv8< zBXzw{`B}&L3F7<-gf>!EVUHLW8ODuu-h+JfL>z-kyF&MQe!8s~f?M~f(&9z8AUR?` z%*h*(Hkiv!LG}-{YrR~?4#&dx2f(#>_%W*00?EEqHNQEN_J{jeY zRH*+K=nL;DsIu&bWxWVe2wUI@tL-o+uMc75rn$G?r?bBn_p)5h9l|8SU88MAJqB@& zgwDm_=j!>CN)pzZ$7pqMOhI56>wGb~oyONda_mpWLH^=0kIF^$l1ZR!o2ii1R1Oj) zl@!V5Xyg+MxEtr|0XN22n8}g)dR{FJOdth)4k`vOKd%A3hvHkwenp7Sqdy1+sAw$@ zd&Y##9*OwVv6&0ra)DJSA|T5X2&CO87O`ydB^Y-gJ_nbg_Y^d|>&ZlLxgFlR@+oa@ z^Ht5-C&fz$0QD-zYQYJ_^$Ax;>27OY0AhwCXX!+n*V5LYYCI?4|#N&Mp>f3jIgKQBd^nI;2LbCEOg65q_%` zj0y&1rO#G^VVW)iUo6Dm>HA-?UY&;hF3kG89!bT~SJ5$E#4EVe-076@=HBvwQQicxrzM8*P z(+*AtmO#1`g!P2BHTbp^K3IzMaKDJt?E(*_oc!USN1Cx1A|;f39*g7%P+vWmnlL!& zW{yYjU<~qT~1*LGD75Re_0^Ec;uUhzWjS>Zd8ZhdC#U~8eJ9PQN!!74-s5BNc_!T z6Ai8QtF2-#6&0FTTf_^L9g3I2c_J@Cmy7k$ zjpOde#%emH(&saDcu?LsQ61?pG*hcbSCn*dL%wz8QMwD2dx!%$sz_nJR1bGEX)Qh3 zHS}fCH}`q0jvQA0FrLZZzkFGOY2#6)g0WwJodYtjGgY(s<1S~H=zhazurZv>eWua0 z_eZ1|1?i^fcO#HvqQ>Jb=e%!QsQLG9JZ)qf416G-FB8T@rdOhNL;jP<|z2mX8t?5l(&Rp=S5a+ zLrUF#R_*3zL)3wCkKHRiPTbG+o`@O0ehalg$eg)Ovl1$0SHm;Ji@P4MBV~BgZ4Rz4 z4c*TRgr?*6r-ev#_g8-&OpO)&A9BP#m(n5?devgNVaJ4iil*8S;j=xXyGq*cS@5Mv zK1tWfJ`irVbR1_MgBi9_1u&m)4+olQzSVM`8eR=>UrZ<({;+@K)W7Ily!c^W<1whG zraOl9^EM5eLwEbT2j5&Qx&-Fn3wNa-rZZ|h#IZR6UbKKRKHaFcMf z>64>S{%Qj=a1Ivo;#t|VGTL4=-fbZfiQ0g-K@YumcaS7}nXJ3Lkt3J%%uclnlv&lX z`BsQyag7*x=YAyw{`r%t=+fo zwBE%x@w-TDOY1Ts4gQZjXlT73ejl?RUI^K5iM30#pMRbh1d5&u>P%bBeYSmddS`N7 z^iY23yI?zInN@Xm>#_JvaRXhbtX}6*POozIW~Y9@b06h>C~c=_#~rR~1KhupbOBsS z4rinkC0EK@r@6=Wz4XY)D3jS+#R)f2c~i}oc#ZQ{4rUa{acPshpPjqbe<-;f!0QN* zdT62X7t_n^G|XBZoja2cfg3rO?#YM7<|-*ESR_j2bHQ*Q>|SBGp~?EAS#)31Y7^!wsLU}nwl8EC7XuF*&*L0l2)}2`*+=aVLtHdrLXJs(e z{JAj*89S51d0M7z^J6{GDByDwI#vk=g^1ybRp_kYUn!Lv+ngyKA|k zw%hcraD2xKo5k6=@{Yzb1N}!+l!<;)a<#o`^O?u}kSR;^te5|X%D6BRR3!Ku$tAS< z*aFqfPivg4Z04%=Rq9>wfR!6pn9x0Rj-P!(_mBq)*q6~PjNN=l77$gx83TsY5<4{F zb6xzi7l6%mTOd3KPU(+1Xf1X+rmucyXQ`9FKIoIFDHQH5u1(-mq(QsvS|+$ZUe@rz zgj+GqI_Nr&o^@G-i0Ofa;P$ZNU|P;C2-$U}2drI9V5z-|;b#xA*ZPs;KuL ztX1d5HJcr|9x^{b+rnT`+WvKd?PBCkb2sjv9!F8=1Zkt_(tp#o#4%dN(KnOFxtBG- zLbLexDLiqZcVYKU0t0v2He`4l?Wd^dB>dcxOJd3MvrN`{bQ&mD2Ng_&9>h&s}o_5A?{G5gJvKf zZhEDy5oTp@JYKW zsDV#0Qj-7{+zs6EO;ol0DR#PdbV~(q1SfBIz(WX1cp4%HIql$64t*^`cmyxCaT@!M zI1;PTeuMjt3#{G-=2Yz+K^FDDB+C~UI#XXhVXIq=@boBYJ6^NCgIgi@_Wa?qD8nn9 zE578w0OsPnwjgv~iJvuJ6m&Re>nDXvw^Dd`vmf(&CW39DN?&xaX4%(}bO)DJ3}o~X zsu6Ggmoa!epB^yF_^@9Uki4?fbvjneQxww&H?hz3)(%&{pw~7!lj*H-c9(d$g^v8H zWmY7hvhRg`6#V-a2Bxuvgeiw&ZajUsopt#URK@Pfc2CW4?Q;u)3mqHwNf#qh-;PVM za)Fk99El`@msa<^aKe{wBAAjutr@rnyRQ2~2hlxbXD5y+Bz6H6hv^@nR{b>fQNuzb ziCN|_?Twa$0J!NEzCejB(-?@B+-`HyFavuzy?^}Q=9O*#u!_!`;mQ*5=yZIoxiHbm z>7kDVpFE-~zq;0ZgH{SUNyf#vzU>=iD>a5X3xT_qA<1sQfJ`;}$zCsa{eejh+;NGM zQ+hEob}{J|TLod$Hz(!r{vUW9C24wuWTlnc*d;@%sUs;#HZmmegz-#OHYeKYx6t8F zY|Dg?c^UBh=+Ug*Ug@^~Q0MjQx2DdU^@p+jXCd(}*k~BZ7{#&xKy0#U)dZy8z&nwR58%S3hJ7=SMp9sDNph~~s1a)J}zKD;e7it+~dXcbv zbyuU3GCKApBV&2rY2f4zMY7Iq^UKMXEg$R6RK7Q33yy%#+Y47ef4WUNc0Sws@}2|V zneTYf#*uUKPUOqYbBQX|12wo?SLV6so==6NDBp)e0Yj7GH(N{73ng8W?sA@|Yx?*O zK3wySMW#BrH&m1G_i3Zm+BJ9i5*ban^HjD2!BQZ1>3L_lv7!6y*g;Vn_0x)hjp5vF z-hizrjngkg!o?Ru=(piyJFip+h6*mzeU~z?$3EA5g*%tY!;$BI6a%eHu(V$Xiq9SB zne_(tY_u}$B4uoQe_lDWHZ!GC9nY;!&xG5oGgCy8a&JZ4+eY~}nocVYWl#UubHRV? zx%ryh4|UZ*`& z{Nnj8wEcd6SGy0+5;W{UpYWnj=l(>C$EHW$J_f2<^w+LsegHODuPt^yoi4Z7PL~=U zvKyHV?{455*J*;8bu0fm$4^T;7%q`WH6&VSc`{x6s(Q(>GlA#+Q)FyxL3i4FLO|5< zET{7>DxQPj1o^3DBcbJ1l=-N;bEaFvLBSh=zEJ>yfP+7y_lien=GL|U!s73$m8bMklq`Nx>MGz?g>7l!0KpJLH zQfZV%I;9(C#-Kr^dqlcM0crRyyzl#Yo`1aGde`@@#ag&zSX{f#eO$*rf9LK?C?s_g zk9Y*+=0G%nt&}d zn|$m}pyXd=raezsnO|)8L?IRVq7TdE>ULHPzwj|1tOu#1NhmXq*tdPDf@d%d}0-Z;he5MiP}R`3qlHWa>pZ=j2OC^{JSV2>G#w_x0w19yfD?+LbSIb$%d;p;jD9gDbc{Br z*G2dJN-=qOa$k;-k~A^QwUu?K&sGM&_CwNLtJOj}hV8vL6VGzaEQLa1M+ z^p)v>0JAcIeylE;EXRSVFk(po7H^lR}#dTPZ*rJG+WeAi^A$aM%#Djy5rY36s zvzQ@Z>PF!(89FudDSjaah45!WL)NLRgXf1ExhAFl(8to0i?CyGY)7t~n)xEA6Eq1I zAwVcVDAw-ZAy+6LAC%n3;oI_iIcTQIrivN_J7rU2vcyTyNBPviz#VrOF-A+6&I=gb>vm2hsv_jWzjDR43&8T=qGQZ= zBIEL#0?`5+BpGuW0HP~-m&P4n%uHxYTn&cWJEFHw;ZM7@!Ue1p)DF9R0eTlLQw3u~6EnVNPl)n9;bnv-q3&s-ORWUt z@H+}9CwnPd+Y|3gX5n^$4Vk72mr0EY_Em5@@efcnWj2eE-cqEzRu)xQgUj@NxOef- zkZ!w~AzR(ltMno~zOQ*GJC*wpr)(RMn7m3-yHtUcau-8I_rvFdO_32rSj z`CMN|T?^yi=>)Nv9Tuo7l0~;vFZB*b3=X~O!XxuL60x}?9Ak8c<|&g+xj2Pla$1#b zUfcw}C{~gJPtwNbc(W?l?wbFt4U9p4e2?%%0U1{l#3<^qF(GCv3v$mnYPhb5I9%_b z^sT}}PMKc&L4eT}-pUmJN!3aoImR6B((92}<>!>T(Vh<1K8cyRToT#BFdg5WwF`V6 zDn{p%7087qn8)n_>{>>P7>~Cas#e0pG2E}oAYg>>2Izz&7)P<*;POGkRFCAvqMra~ zg;m;VeK8r%^1FLSE}G_D!%tQb7tDt+I9fWs$&87Z3n~mG(O@h^<$X$Kk<*qLtmo`> zO9LR?C{tF^pt5bo1MY456H&%!ezZxInYcl(ATU;Z`WiQ(M$YW_TlQPX3maa7pExGQ%GVa4bWH$CH_RZ1#+dM6nI3|rju-_i7{D3OcjoaGBh+;BhC_Cp zKtvvG=?KW!a{USC@*I8=+?Dn=wT>b3+*2T!xrAr*yQ&V|>4iQaLyH<+#}K$zF>w9!tg z`27I$F5kDU+ApYCSgTt;MxBpQ%BcBC@NN+BTQz@x1JjHo`7oY3l-eC;@rrDvp#0wE z6CwJVNHebRZLo9ISK?_9b^&f<^vl;j_hfErI}j~J_!QOGM(z0*5eab?*XP*v&k<8< z{Gi?-n^F-tjEN8uMTr=}F(HhJ>WMGVR#aA8@ln=&u;O0x4aL?{f#f{Kj1a*Y zVyQ5Z5T4y9-5@{S^p&_Ij4TEv4xv==UHJMb+)4aq1PWf~YL8~*V}ufgawS}pth-6! z+AL#9;bERM#9=W<#GpvZ!X*oaC}#yCjE3&Xts#=jlxuwQc{>RLg@{U?CFe#x$fu%5 z4%uq4z9$RfG<%pS;)r|8iYFLXbU7hEg1lP&)@hkMQ4KFsza~ymPVA~65 zQmx46Rx*v@U1*t$k8(Tso=I(&oER1&>j0;lgfu?6w-ZsGp0-;BoXnf31Dvk+cP3iw zCFnCD=}GvPcMCV>q>4;`^aOz2Du_&=L_5$sUyRdx8|rgRVvVV!crQ;3o+0EGfO4#m8y1`{D>4B>4C zcuPLk@2P^$o4{BK7ug0YqhZ7{II=mnh?Nr?;NO$zyM5F ziqo7h&F==&HGiuC>|1@o>{Pd-&mPn(bW`1kM!dxMf6P*Pu74Ft z7I9*fTK$oaK@J34;yj&&WxqeGnwlPe;ib@K#y~sL&OC*(`@vL2 zrQATO&kA=1Ln?B6Z|l*$MXCwH5+ypmNV>7X(>{Y)UV0Cj7%EFW5mu_ixHu~+If5>* zt+iSRO%U?=2>wuFcAdsU;e~v%i-~#%u6fWms~1`$uP_|)Y?7c}YwcbMR>biwvV5~e zILG6bEvGWxUrs#QMyAR9k>dU7oSUJv9uY4yMbbERtJ}|vX&Ki=KRdF zMyVX}R!|%#w7C&A{xK6B{>9L<;~6ty132gA?IKJ{t>PavwU-(BM z!r<5C*vtEM#EX&7`Oi6(F-nxuPrZNOik1V}ZZmbjZt|Qju6%OqAkVo5RC#xbuZQ;2 zn>n)kcW#AJ{9b^VB(#w})0KPX9x;Q)9Et?Lj{6|P{ixc4jOv-i!+YCMXrVc{T}g4U z!Ik2I{th$^qY4&-@)`uqY0qNRL}4^S9jpk4>iGCe9<~!b0^_D42&Qm(bbfeKhKk6M zDMo%o-?@GgzPqQ6g9)1@abnbs?J=MKMBO< zeygFTVa|=p3>zQiHvM)y5p1fc6%^6jO>rAoUdUdq%+T8Ez=>W?Nj4BN^I1p8Yw;1v}Yuy)gc)+YpmScp-upL(EJ0# zdyPR#1~w~}R3-gPj7q*K_%;j1v5JBj)_(6;U#F_oGlK|8xRfK&%ox#PjOoz3%mTF7 zy6F9%x4Fd&&>zXeF<+5J_c6Gl?kigyUgyX(Xd~XM9 z(>pGD4Zk0016^sa|HI|NQ=bXly27JT5ir}?W7m^C6qw<^3!Qe#+#EhGqEZZHF zd()2i;P}ju5dl3V zjjmelqd=S3TFmLR-cCa95ADkQ4d-H~s@9k%tLTD`I8-Rj^}o~zG37G~_}p{}Lh>ZS zpDriaBK~5;3N+*kz`3PnAQUH(b#Ubugi8|^eFNvF8$J96j%_msDT=gQ3MnouJlD<} zp1I-0R6XBrjINb*^i5D1BCIg*;5?2_9QPsy~O|g37!hx4v3%q2hRPWH*V+l z1r(Z-m2d?Gad{Gm~3H90@1m-k=mL(Lov>-}2R z0ps7bqM9e082LOsSxm~49c}bOuX4&z*IjEf#wj2EgbzqqFD75qh|g^6EGXkWddET~ zF{H@JVJst#r0Ny0%Suwcl}TV)Kz}Eyne;))sw`aOfTDtYz{;^|ZQK*bJtlVy*lbmW zX1$5tKOMg^-g=4-5~;aCb1TX5knf}h<2NN@w@cn?I_IqE5qOB(L8i0LF|QWc8;d8^ zB!XO9f_l>6x=a{gYX!O>brdkU1-5^wU;4duQHlyomwy?9Sgdhf1RZ)Z9GPVxW~fN> z`-%+>0ycisxG+0n&j_)3J7C-qTOaqS0O(vP!W%jl3QR+NXEawfSy7SpoWblMgMc7u zISa{a@VyJWKo@)QRef%Xa>m^-3DZ#>T;*dH?S5;R;Bq=YLV`@sv3fl z11MAoCd+oXI#hi?W1af(z?+|Y`erJ3Qc5tk^hfe8U&G_pa#2EyYM(3KKx%>Z`L0Yi zm&{|Z@aG?eT9(BpL`V2ma+Gr+7$%zj}dl6pT;u%-G>GiyhR4Qu&@9|tO$ zVcYC#=NZgy^WBvfeb@<-R2A%t`8hV8e8@>lVx%lU)q5l)Zs>&P3XK@UGC|yT^w2QJ z|2RhG4ZIAx8~pYgTL9yX(v0DoOy3JUcNMUJA*8rqt{X(d;G(Q|I;kpMbdiPT{9xLP zdm~u#tqE_8@)ga9+Qyji)Je;=1e{TCdoRbRf_nMWb$MSt{KM$ty2BJ+;a?L5_H*e! z?kvqk6n$``Pn`Rp=Funq;6d~=Oli+REW4nN`aoWx5}Ua<-Yl+>h~yFdnQIBhFNqB6$SPGRqZWiSMrXZbN#Lv*v|GWEgR__n$aj5?-B#to1l zkmVBTl>TmgnSu-YNl26~?(1%xPetdc5MyrSWF1j%ef)tw*P{Xp4>=N}w{uV4FuWW( zEp?pooMyPDSz4S|SEg%>Bow0Vj->mkWko0Gj8eoRSyLe&;9D?w`OtBDda+9GmI=HT zPUeB2U(M`n%tr$?74W`G3>S9ap`)GYH;M~I`~5Je%0q^>eyT4)BKr6gqXJSjfEf>> z^l~-TH-t;Il7-@*){S@%>J#n%aCOf1F5jld2<(@wrt;&C1VPcUW}qV;oy=eEeG%*Y z__e}4Fsmtx?4YxO+8^<445Sc4SjV=&N|=?@nsApOE2VJCOREiIrR8IEXv#=-0IMk6s`q%=D3OtNh)8KVGk z8Xx(DQh=vZWIzlp%_zjMmb3e9(@q3Xr^GEgbf6Z5SSxdLE5XaH$V>pfrLa+sxyH_? zm?wFLb{z+QaZeHXAi0&wyPN@VoMcOppHX#o!$gwo3jn4d^!oWD9;OaM^AJ9bP>AfE zCI`5nRm*m}NFKK*`6pod;O9m>zY&T@HRdE)XEY!h)u$rgtynA~xv$4;#rT@4PRDQE ziN*)t3nqO6C*=w-GT4IBB##`7F_$Rwo{*#>f;*7TZI88pCm;$yI&)z!GtpwPeJ6&l z0Hv2`GEe=EqSk&^9ZS$RBXzl6_S6j7-svP}!N`SzJ&Vk_vVZ#rcGQaxZG(gG9&QLx z-0ro`q?(8l!MGwFT;^|`st=>Yu>#pefnl~)sKv>PJ*A8>ix92Du~#aHd)JXq zWvIj*?`dwO^}HAl3GRTIxJR9Qn)%KkV+Oiz-g!o}Fua$I_6ue2B-uw&^(FGK%t}&z zXjU>U`p{V_7L^B|tD~}4BBSy9c!+%MKkK>D<*Y^$Fswx6 z*JVu)dLYx9@a^;{nGPQt&p=g_X17B2xmrkGfY*mHju-t~& zp@mdikE7X1Z>U?CC7juuhPI)<8NmzmPUZ6FF)D!wT-^d#^&HoQC+Om%_m3o0p1^Fe z0#l7>O!4pkMZR*4C3HCpOF4UjPdqZ?3}uCH12q_su8uf1;NWrLF8~hZ<$t1%iLZq6X{AaN6$5hnaA?s~sNM^5+~liB+eh*>%q>b#`P)!!XHn`y z=5FFT74^4Nr8^fyxk*7?xsRT6dxD@74v&z;&~HM9Qurpw+XoKfu97Wpm0}*o%>7rn z+O0sq{%k9nmT}XqcZEXwdHy#LL-; zgbmD8j|cd0qNv-(x0;@&GU%Uy z=^fFxGznw8%0^RR8uTjQ8@DpDn1)m9zuJ`t)z8G7PPOZXf|GfpMQG_O zrNtQ|<_b6u!%=ARc-XLgMRnot&w90yQ#R1GewBq96tzCr|OT-s|G7>W~WdG6-QveAY`%2@(a(`9s_Ao8gpGYTR-> z6v8t9=vC-Fo5s1aOLE99pn@ly+B1)6rZb1s+25E7H#>t^ZAS0*Xk6zzt8D;W-0SyT zB7mE;_SLUj8&~f5RWLQhrOlIUbqZW7H__ine_X9Q;~9-xkpPKtddyHO_9u z!z%C6fR=+Y=_|#sn-NNmnEYVY#+G+AQPvyyZD=MbNuG0=jXj}P8$=t}{5#2=Ardr# zs$fPcRf$9BTHO~dJwUlF5(5Qh(uMeb@v=%nT)b zqE%169%0-eD~tK1Wc+|%N@ll)p!894 zBl+J9)2h2of+KY22<9<4+-fk5oE_az>5Y6}gwWSWwB(6NQf39|e5paz(cJ#mBY(h!0fWU_KAJjfe=vH{0PREV|PY*WU@spqUA=2h7d%6%pL%oi`lxQ*5tHIT&9 z=mpT>trzdk)p>FrZ&g@kSMNF#ymP3k15Q^<5OQU8L;ld^=xKaA7#aaJy@eDTJZ zSLVeU#|aQ3t@~YoSG0WVCQ z!jcQw+%I)h3Zh}Zqw!J7#)NrD{W|OceO^5ibjj)X+@SoZYFH*-^|B;DobQrWu3|Vy zI^?BEBFHdW?`>&|0;0lZ-T_QIPrxuVjw?iN5xos&xri}G0gq!KV+tFeAbazd`&GNhE#Ns`{r1lZp^4FAlkY;vXhj33^BfU^B7PVbOzCh_&sw`{c7k52K9QxJ zPAd*^n63~*I`aQT(xUcN2r`-O2(;naBk_fZV9#cu4Ta-dM@p|(-Aw8in{Olu(P4w! z3mSMWO4pdM*BL^4CkCk5gN5cb#vy|XE{B{zi@8kIJ`VZOq#{6EP>R>}=J=S7M5Dcw znV8Tqs&q90@o`)%PbVxB@2{OEkWw>uMp-*r(mC;QZ;bceA&vF71fQJ+k(9yg)5il) zL4b)Huv0(vE8)X?{;|m->xve-3*tpsu@H7pYnjWxJ>0EA`9CM@Alr_S)$tm7Sg*bD z{=3wN0^xIMQG`X?dh;372wrar%`UcGD(FF%-foQc-@5h`X2USozV$slBt0b^n(?4l zg)5>&2-ENxUV{Z0W-HAv6eWbynGVTP$5+w&){3za>bilukL0)48`6QiIoPa*;HCq` zRjdhmG5TQE5S-ae4Uii5_*()EM#wuyBa)s-#dcnPMqx8T?7J8NZ@y?iNP;-k%6&*+ z)ItQ_U<|$}mUQ}BQT&h_MLX5$^CY6jnDkuu;#-q8z}i*^HlelKoL_7&>@AnUp_uEa zw*quT*SHB_39-oc{@Co!(&5I^qSbQr=|~l0oKe~M=Ik0Xxn@b6<+*TaL*posR{BLe zrh%dlo?%{|8om+2`}do-h9k4klC9+4C~JVV)q*`m+c<(Uda*QHB?!}zkiMurbi`^& zQD1RcB@D}$FhKgesO~Vxc{qyB6C{)rMpG z^&4-nY$s_Yia-wg0iVVSa7GDwfU<$~FN80*p&55zkBqT3m$zgn7i@1I!k+n=X+pB+ zL1odqXx?cX4sNPq9S>N(qfsWQ5SPgEi~bn2Fh(WHM+&UqT_!)kJ;hW8S^T<@u*EvH40;SzD`wP6KS3xm4l9&$VP1G&SyJIm~wXH6bj8S-7r_E4?l6oK> z5%iLz*Jg@Fyt$Jhg7L`wxRoy|2ThiVBdM(E({tlrf3nRimgHI_-EZ~$TN1~X4n6X@ ztbTLtV+Kie6UfJQZT>OKI73Zi|9Ct%$tuoiGIR`QF}{@W=XdsCdBo=2=hvj9cMV6x zczf_X;JVY;`Y6pQri5_jk_bG-m!QBUC|1lD3bvIVsj`;>V+T29yo}L;-^+Q2NC$sK zye%N7&r%F{mg+!xf= zbn8Q;gAeR<{R2)Wd0Q!lKlflT%jcdX};$ODcTKc(@$(@8kN$ z)it-uvdj15mCHvT+Rx^T+>Ka>VH$)}dZLISLtSB?j~{*uh~TTknV0R231ZAM(y8W& z_H*GvAKkB4{MPurZWatT`^N#6>8&6EQIb2*18`$b@{~;Q&y=dTsJDO+eknI)*JT~E zYx?c+Q(mbC6U!T+xHm>v^7%GhK8fuE5--BusJe&G{u<`ou&ej`Ft(&4I&hs<)$opTYQ@#I>LF^YP@tJgy>P7LIMw6F~;fWaq36d3D=q#QJHN z`mP4b(y2%yG#+vI@O!G&cZ>0eW^?dfgj*duT@x48gjtqXj9N@@V2$4i2XHSz6z_7k z6#LUt@Yk1v?_KWv&{OXOMzi_ek>MoDYN`5Z-0%dkGd{gMV>Ey8^dSoI4x#x2S` zTjeD2m771EKkPDHdXtLFyPR4ahZKP?P=R6iKp|ZVmfUCbrrEE2e^47y=~F)8qN%0N zb0Gw1m#>;ZpFlnTAI#gmk6dWn!-(7d8jA`*g~b9P(paDtr;5+CK9)wyvf2O_rfi6i~X z`(?lrH*G(oD0O=ecS8o=91j{>|c=@Vs_ zY1}99bNfHXP(dqBgE2%mo~@Q~*^OsQL`2Eed3#Z=g4hI(lL@kf$3yIwf=Td@J>MBi zthZwp#h68nzB0+ag!lmarEkr+@hLSe_PR2G1mc)KrTcuSoD3PA2Ow#8=Sif|o%j3_ z;!XvUL%npUXulP?PMG4ZEGwKa{XojZ%}yY~aOj7icT?eUdp`mOifddjetcZn0wgf^ z-XI{n|D!hqas7O~$emNt0ju+m?iKp>SpK`SaRFl)kCblGO+>Z+NAaelr3_1>Qh9x5 zi+fE|^woKG@7ZGghfk{-`7h0T_AtZ?XvLOByT`k)Gw=Qwv;y##K(@*4=!WESAu^uj zfX(##Wk7)pAbY^!*6h}5oMz3db%3!|rLr_Mcgg}7+o>06K$hng+l|ECVm!4dV7Y4u z5LRVLeHes)*|G%@tpD6RIHuJ9LI=_=yeO}}g% zDPz=BYyO;nK_QqT_pEci(R+Al9#S6=^~<38!C!aD#FmHIKm{Xpg$6`kcQ_yh+qJOs zkeCf%i;@vsDO^$nWSZ=_SJYF`^Xc^mQU9SBvXYes-SLg;b*LWm#y?rxU-}El|fkx!K2~by!+KW zfkebH66kxKt^z!Bz_kp4p46R$Z9*7}QJ;s*0^m$K1n0|n=^xoA4E?P|e50SB6!YoV z5c@2S(pK#Am3IJSxr%Yj+EI&W zS_2i24L3s1TBvI)b4>)d5a@~x^C!>HuNEY+k1YSnOY`PR$!zSw;XKgMUgV-@n>h;& za&(z)gNzKWHa44l#-SB4hZ3d5RUPs};UmewGQ{DfU`Apu7T6n2<*2vI4?Nl8>)1oE zy-^atAAo}QyrJCTy!=nFoP*JtC%ij;{C}<#BREPtj7GE|x9jK=fnoiSEJiwjs`aE& zfMxLgtcm;|!X~jna~j)yHVr=orJCumr(0&E{G0&(kId1yBv-(*5)UTj%qIw!wPNWc zqDJ2tis_)dg)K!I7S4ti9)j)P=a9$$Y{g#{5x1}k@?oPzH_OuP;VO3SnArc-d2CL! zcVA;ygX2yc=$qfpJha(i;h^IPtiq&gE>iD zTzSa<^p98NGhe6D<$RO$htC)B1Wd=+_|EW6x1Q5g9<~xbWXXHl-p3j=YK;p+K+cdj9Sy* zWY84!u~mz3d1EdV+|ml*RAT5$d?U?{L55%rxObEO9jPPuP}SC$@OeSpsVGq_iU{L> zKQ%ogo%?fYnqREi|I{hRT6IBSNce-z<6Wq3nIy-*&QMbeJTsZn+rtlr+9@fD*lgdL zcjkZ<4cN0?ZjL$U2?3`FmT=<~2>>Mj4f-GTf0Z3KwwT;b8e72p0}-%1U$(QI-*HM| z%->#fja@3_MoAcwG$Gio$F;E9`9f+Y`I>a+$G;ik87>9YsfSGBwL52;s zx3_ z5pj>5I3E>DwT?X)BV^GVP46=+2o1_>4u%}RYooaBq(B@~nlHW+S;~r!DXWWDZH1); zt+j&LOFQR(WOL`v>I zN&Jzo{DC|$pl^XMdY*q<7nu)hfhxK;BR-~dbDzVXPy81{<7;c?EZvzlI!^`>6ISgX zcmYKQGxe0O|8R+Erq|3Z`(@^FZE3$snzJ0Fx+7V_Hp-vz$^Jsi`( zLrP0@=jGhl7nyNim|O&fR?S|Jp-0ClnwJ82P@#7mm<4b3X z|CQC!SI$b(P@c8P6B8&Bg;k~y`3?;I`R^H|m2!@smbC*P5? z>HcJTIaAYk@Tqm+joa|&qn`fRgZFbn2FE^|53gTh`;~OJvm7L_-gFYltFr*p5tnLc zg@zodwtUBAbZpSJQisCXo;co7Ev}!++dD!2xy?3Nb2=xH3?ZM7>CYuO9*3yE`1(HW zWdPw{ob&#}C$)7Y-vC%9hBu@=k7+Qn>8yYD_g6vMok78`JV|t>G%$%SzjpoR^PFz& z%MjFVfoOfi8%)Y>#&)x9mnEZ7x8fWrTUSfUSvf)4L~)lcxFFriv845??*y-X7->|g zLrhDL@Q33B76q%p$mO1Euaf7j`e9w?Iaf`hl`R6k3@W>zXo2p9o*nryfYb+F@~lw?K=|9{2;enn)q_yYFN<9I}2QZFp+es2CjzXxhfH)vR(hR+#ZHU zqS-Op1E1P7S;(v2J(W8AvQ(k^w8k5{2}uk6p}B(gH!5&zAT=qy>Q+m73QhQq2PO3Z zsyIEdg|-yoKcqVT)vzese(^Fdcn6CIZ|Q^T2gJcAg8B@K$5N48P`R=GqaC=d>1!KD#^@n@x1y(`Tq z*AELh|GIpYp#BthdmV?DcZA)KY3tlM#PORcyaGh(E};-6>AOhs{`}gXkIe1F2>k(* z&ER9iXuQ0ODs*A{=E_zW@HFlFlz2kZ)CA@-h?eJmeKI<&2N+AaWU3ul1zRaQ7Pn@p z3H<0F?foFNK;+w?h>Dcpv)N6vxkWPntuXbj3C;wPVtBi!j0;T$%bwk#eLrJk9(5ZRX~A-GrM3 zKz?_~O}juv>qsb`d++`l>YQawQ=X-}lyyWd@9)$4OCm3job zZ1|rb-1JbD%QgC1dg+^B`*6S)H;ND^>EXuM%Zj`CQ;t17ubY37O*{x-P=A$seC9*6 zlQh0SDqMXF=n{mg;5@m$uHnrMt3fVBn2xiXmQ69&&eONDh#bE>8}z8G4jX>z`qngj zZ@nU>zDhP`q)#BMIcW4jVv@Yq=GdbNuiNs5Pd&RA3mYcwUe%s6T@`<;NDOu&ADk)V z#PiZ`tJc*Hb%WgcbBiiY1|UdCpL%_N^?GT~SL@w*ze^F*k^{yBr*!w|NpPs=Tp{Gl zR~$4lr5IX%)~C&O(Gd9FFmT5gNB60+;fm;I3GQ*{1hHxbHEn%--KcVcoTPnGgy;y& zX;xdddkV;?lWQ6*3L5_9r-%|*yl9^7uT9v}f4Q~=Dc&E~wb?f@LhLNj{-pBSBnX2` zHfA1xD*b5LJj5-l$wHcPAA8{A%fFsz&ItW6m_Iuc4q%g;cB40uRo`xtGI5G47kYyn z;=oA&mE7s4TXy1X2|qP46aZ#MRqeQBI-VeKB;Ve#=W$I# zM>sk2;@l6!rPsA=10io;PpP~3yxbc_&3kMHx;Y1!+*!Qs{N>rGi`%!Xz~I_1TPpIh zOC=-Pmq$PhFT(E$vKo92Zes>s ze|N=&)w@n=0+zScGB$zA1BL6Ucgwe)Zs;g~t~{)fJO?n)pxe-e!yUQZZ6>@Ao)W!z zsx5Ov9ATPEXBPMK0y@=SatBjV|Iu?KuMUUq{yde1XP1~sC}N@Tx;`KQN3 zJ~i`9seSf5Y=Y3{T79LVep+yB>cYb>3DvFq#MUTJ1PBYe#&iR`aygCbDP!r!kwCC= zp_fg^Jq~94r8aWAE<~g3+2=9Iu=KQv%xa=27l+((cVtgw#{4d`nD|_V{&SHg_Ie++ zGTjENmbqYnHsmB@V9<=R%uLw<0%x`P;y4lGv}?ZbM!zdt-v~AQ&E}%qy7QdosPhm_ zP3f)Q@hUMH*S$-#7vHOo!*Ug95Fw)-hB58LhevIrORdF*@0W~^x3a*rAP4OKhD*|k zeix5bf&2-E$-Tg6sT^G8sn`f&H{SJrum9d4Wc>d(_RO2IzGmNYD?SPvaJl zw*OEv@kL=%fFRRuYA{Mz?g|A9St)bj#Uc({cen ztlhi~ceagfypWC%V12 zF6}s&cFVVVZ*&s4GWTr5V}ix!zEY=OAg||GZG%D{^Q?$sA=;<*3!u3q_u;f`lCHbd z+TOoNpwY3SANvQwOT1A0-HAr$zKWJLpw-(tK86)f3jH%SfrS9<-F}-3-Rb5))eu#e zD@Hl5z9J7U_QMhqGTT+}OOJZRz_znEGVQ6{CGG9&xGEqh0~@w=Y(eYn^!J(PImzQR z#-`S}b$4oXrOshD8P1!#v%Ek-iu*x9&<^5Xew_m?TS-qX_k~87cVtT|yKO#h#+h^| z1oawF*wzb*ZkFo*Dw2{mgn71#x1aG{ha8o&smE#0t{&SxHKLun z{k&7hFi&QIE$vMJboYFVW^v2(V0|m(nl$IzV?cmi13~(8JuQOwP1SkZuZSw0SHBbu znCEPM&^Q6$I++_`#oSY`UM?n6x;sTq3t_)pY_4HC9fL=2bXqT0&#p#QI7#V2!sCA2 zRXg{!io~|_cP&Q|4=R7nIvXjx@^h@b)2$y=HfS1wFG0uO;b^+{fa+^~T&R_Pyd1Y-}XtP`B553%^CXlSm4yTj0JGlG;5-0+4*kw@PSH9vti3dRg0YE zdHpz^m4ENw156)qd zZh#ma$KA|QF8sd~SPJXO+6};+(LiM6B&99jAq}?QdB(uAW6|<>u3gALrdfoWW@7|9 z__+cxAkQnF)IWdhXmoen&PwI6`<%YVtcB@8&qPcM!$hf6>h89?d`<>huF%sGXHrS;;CO|M?>OhQALvTdZ9A~uW_dk$Rwlwt#=Mf ziC)|YuD<&Cb=hcJ^(nP07l|PgK#PAJNh_$GjH!6?YofG3a8Pv|{w(W}o2wx>$p zDKOt8{SGOH%x`(A*zqPA9E8#=5vq~ z)KOfm2YYpINGz$fsQF6&5c|gSyRv4jOa1&Zp)oD2Ord>FDDtp#D$mp^>|L(o@#B)^ z?*5mzXx0^7Ft8<>gkIn7YsEUYam2&?Q>;v&cMLs_!KmU zYS*>qh1zCV_(ihGZg1Us0*%(_Z4;YI*%<#a`&@6ca6CeyS&-CR$kNSX?au`+#q`7^D!N2 zGXW{)R?3t#Q&8#pYs!*#-Mn_S=}UG{lw6|=P-S9?`RriM8A`KV>8v1Z5Q{R%c);xqEmDHV-?tOfDT?Wk(`hHn#Y?QkGLDhKhkEXSg z?r-J7Pgoh`PGN6So!EvFSK;n0CnH^-j3BSOFE&L5DX6R=x~Zbh4*KlU=2i<&S*xM5#Y5NqO&#GdU%tc|u zo+vXCZkp?r_d%RKqZCD9>G}Ob*8RtYD?+y{MZDBSi$(@B*QK0=)T125_6n`hAj;zx zlxh?KcA~vq3;Ri$U`zJ^zlA**(frb}s#ZW=g?`Ujj{d~D;glZjdk>qBx1hz%M&cnw zCI@??Nz*+)^<^c+j+?%{PIw&B@tz`0$8G7MuBHTRcf#|BIKM2@LP9~n=Z`)`R~23} z9nb*Fi+4==h%ye{ay=Q-N4f)~&4tMcddH#0nuS}f`y?zl@_zU)Gs5N;9bR>DN=S+Y z?tb|lU~%%J_tUoM!7gveZ}g|fF_P66t?0ctsN(#yz&zRQ>*n1c?-ls<^w;K2p)mE( ztNmZtuo@ndlk*GS zpq4HB{*S)FQ%vd4s{%!vWP&b#UU0l^PCD~mv2YN-+(aVc^ye%GJ)Qgqc-H6Sey^m- zGJg~Mon5jP+D5j%nwRyJ`&aVz5%hYY(a!tnx6InwE!xWcT@x-yh<)g1Rr>XXC5wv# zyGOL#fESUb&!eR~Sl@1ndM>!i@P=V2lq0Dnw?9cPzu@~zgx*|bd-rSB;xx;)+OE-( zPr+T>Q_Dx6=a$Y@74m+Re^)oq^9y0ShcK!CGL3(A2tFp2?>_T9Z$206{Qa=|BseNn zs6x{qHgzOjFSS0Zy6h0obU)Pi_&$_eR_7(HJ*AhslP|bdT{b zZG2QEuYWIj`yx@-i(egdva9G-2pFnQ61bx=uv_|fy@OZ6`F$S0Jvp?LIJ`D+SKh|+ zVMqsg!}hYDqX6{;jWPHAD$={2=xT4q_pmd5(rdPV)&w>(H zGi}4)uANpN)P8gXT7Cs6gTdfm(>lQox`82Bc6Y5;-aE|r(CqC4ubbWnsVex0xxOgbV;&xR@ z$>WQ?*hc2nw`Wp2u}_mQFXt%|@?;BNi|769SZIX-{U#q`GuMefxo1P5erK!>shkiJ z^CP{>6tbH8+lYCX*Ku!s?E2fUbB0-q=e`qP@!eAxjxX092$-H;&8xJv@zfag4|zz4 z1oYw#dkhVcF)g6a;(wPs_BP%Bf?nIX*vYFM0BeQ;YpikAy=|?#jqExzY|m(yxl^w% z8Oh_?5P$@h<-$QuT1VbjDM$>A%yM}2?AiHeW~u?)ykz7dfqsxdn~NwQ^vUZ+~pAF`n8)0QnE&Ud=#IO@hvN>mCW~E-+ zaIYYC2I&4BIedG^2D$xn+b-VpIRDj_@!hVKJ4-G{yE5RSr|+CbzR59vqJDJU-14ii z{2UXxBV&cx!rhDJ-5f$NhH?1lLk2xouG#iUZSQDE)49z6zP9FKCu@S39K9iv{epma z)cI;_g<&GAxx#nCm%;7CcHrY%P#B1@#ztPgitgfDjgN*oe#6D=NC7rciDF?Xb$K^l zGdWnLr+>?DW!k4<($UPpYre3iHnZ=LA$DSJwxc!+E%D;s9h|1Bp>ICvFoc{6Soz2 z)^{wLqL=l^^)10V@9jjww)*@9${g?;4A=ZQ4m)}tLAHmWY|7EA^a}8z^yXq#DXgs5 zkc@w=#ccWHsFMi4S+QkMs*oO1VWq%%zyY=;yY+gjgs~j%ID=1>OCI^UgERIb)^`ZU zEQyZs93E6LU{+Xw#PzDmq$6<>E1ers9G~&6c!hIvU;$Qj6_F8T?}H=ggyu|V8F>&g zPovE2*N=T0LkPmMDYH#-l+>~rERyxvtJ%)fc;+t{?`Pnp72AOeE##wCDa;Zc#A~3R zj5o_-?D5;5J2=BQG1tKzchZ85bAWhn+)MLmM{2&eId4J|@?<3%4?|Dq#Yi^L`%JM$ zySnCUGW6GOVy682yV;$nwt?zFj2}M!ePw@UX~t7F+C3AkN7h_#Z?&Rf(pI2$T&a8B z1#7Xz)Oz|m&PCs<24<6O`A`cBaf+{zqcTk%H~n%ln}G86|Ke0*5=gvT>EHz%jNxZH z;LT4pos6uIj*|ci*w!$S{9K2%FENgqUwK)8&hYgd+ZD9ou^Vev#57Hd#;8@5v1RxH)eBgzSa;VUYy+O zg&RYw4JTZDuO-~5Zo-B35k$A7v;1+M{8K}I+j62#O*U-^FMeh)=8TX?F{d(=>p1RbpFLdQ&uRm9OS#=~V9NgeVL@2^hyyoo z5fB~naZyBV0CJtJ`^Y`ziMYCZjO z#t`bmF*1o!QxtPMeLOMO{$V5QOmiVIhapw8-{z@fTE$K844oH^rsYSysPZOy!)vR; zUvVvyqZeAh_5=0P{F5%S#Le#c>cW8kn8355hs16y=YlPSgPTM(Jc6@E$GYa>84QNk z67{ie3-nQqdC-QJc4DvD4(vu(3Oar8%asDl&eQ z3w`Kh0W4(inSHbG<^XYV{byd^(y&NPO$d3dT=~leA_jkV=%n%`#CGJ_@TGYZYBzkZ zjd@$Zg11`WQAv%zuDY!nsoIT=#D1cYSuq$%ShmFOWpUMaFapq%=+8E zFfvV+W0SjZC;TF>N5y;Ud!BGI;VxIgl_Y#oaS#mKjpWV1`og{Z1}F$}7mhHP8J_vM z|8a*p^&zTk!d)tNWwwhq(s$LFt(=?3L#PFSOv{%3L3d|IfEWYmX>_EWALv#lJK4M; zd$UX?mS1-6{k$>zNKt*y|4ukxl*TjWSv5Ck29)tJaLE)RHr>+ppiN@6zvE_EYADB> z&OJ^h8zw+~Iu#laNY`9csHlkO#MVS_(F4D&TLeXa%IF(ptU={--Yy+&GE9#OrhzaZ zzc@^k4IJ(i_LARlldFEw(lWNqe1i^P9QK^^F&YfziNDCYTP*}Uz@ur}F~i>p*c3H! zx~R5y#*m18S;(Pjx11EaU;cM)Rsc!={gSN!)jnVR&wKxqxM`CG19bwp%3p12Eb4xB zYbUU0Kz;G~H9T4VQ28X6{VnGCM*7tiiiww!mdl+ibzufFOtG6{P(7S*;YqJ#71|6= zDk0q#(MI6#j$24F?(Oat2I$&#bG8aovfzd#e0nS0X*0GkiYQ5AQ^~m2S!`sm@vrK+ zJJUAzwss%-b+0sj9njd1uK<^&)rIru1(IXs2uz(-K{;c=V|Jj9OQKoqF4~yA{X}=z zlCd$nA&p_#!+yNwrHI*TyZoF5aXDSBP4aFL&l0h#wDv|wHNEcTgofp0gee_o(-{90 z9;j!GXTqe|cPgsPjW6QyaSL_N!TmSx_)5g^3r5t|C9D;DQSQ*o)v4#P;POI7%9fMo z$I@>)E_Q+k7&{5Z9r2sRM^85wpHN$+$wHe-`BRJkU`V6(jg4*7kp6OGZ;6!;dNrpm zs$nczYPr*66E|DUMuv zm2V^_QF@i&WFfs!evR2uvR_2{d+4M;xB5g|61=cSmmykCvHbe({o``>vinXG9uGaI zvK$CH{h#>-0%UpAOJD+b3Bol`{BoR1V1o}OB9z0XOJ%J+xoUI!^j|im)2JSbi)>PABYgK@_*IZ`oY` zD^eQs0GZmm!PrHWqW3-B80wj6NoZpImsBh?aq1!3lE?$iV;CR)`GQ3apD;8!ozeG! zJK_XKl3%75wY5Xnw=Q&~+-2U3#~}x=d{YLALXR8mc%b|Ilw1^fJ;D9rG0SbdZm*V#NcZlrMiF5JeJkXUm(>FUK71*?-NxV%NDlpU?y67dgh2<>q=CrCj6T&aJSI<2M&bfq zZ8Y|FjrJ2IABej?j5HZC!zZRy)He~a(znO81}E`7iblM(VL$XO;tS>4v?ApYOmVNv zTP|$^B5;$-MI|RgDtxm~ci(t{?%jqPs^~1U1^Vj@)+BE*z2JKmJj+avS*kE*9UK7b z$h4K!BQFPfyL%<&?)~q-Jz9SGj~v$dkDANP`2A(C540qg%gh>N${m9G9!1$ntF56Q zeCJ7~l^xI0+8;+*3t*fLZ=y3$2eYhwMcJ7=eG8xavUukBTV0O>pglMm71cZ?E|htC zm%#KQE(Nz*%625H4)faW@~;FXx#3?^(iwT0h;|bqR{dyF$CmiN1T$uucg*?3HFfPM zmu{ZNZPYj9?uka8Mzt(8OX`TH+NFHyk<_6D%C&FRf0b*=Oc^)2NGL~LaKoBA|3tKS zxk~@V0?9RJkr`m6xT((Q04m7T%G8^SAH2 zR|d@NN~vwA1y8|Qh+oTl{)HVEr6(>os8O8sO~^fcRcp|3vk3r$sA}OnztA9{JnUWj zUha)I7tH&%Tuz;&FM2Ic^OhAo)73#qUsXUQr_x-jXu3%hnd5@pVi@+=Q-eJY*{JDp z7JIDd;<`fT_apRMG`$4*I zu&-?=UbhsXAsN5Mz{NK&cVx$m^=lr=ZOP~`k^amMep@K67s{55#?zrjvrb-MsPVQd zMi69=vg%;PBq~Q`ZW+PL4p#Ke(B;-xLVc;ENYD~GQaBIv=OsDHLW-{7+hV~V6OT7? z7r967m;*5rsemC1Zt2!Y$IS8AY#|Wx$OvzV_?CsoQ7U14mSi+l0fG@+l4$%NhT@?u zvv>Mtlj%`LiGvs1BlpYvjpc*s_LrX5;D#aKv;ou!_->;jTUNKRxw}j|b{#{Vam$9e zLktRyjj4@*gm7O7Ge-W6k4smFHn_Jg zPEqiV7Yw9==wo2>WHTo`V!@~JU@-V@a#uBvHTj55L*Wa0y&Vova=Yt+nR51nJb@6d zsTAk{f=I8#SVMd7pbN5(lVL(q*-c30jmoxbLFcKW0&sbaqANO-%uxnPRk`ZmJt6Ko{l>c2YDp; zKQj*zh*#H!&<-ixI5%lVkEMSWt9w@qyx~5#C7u5G6dc&8^10>L+0HCAiwTPk3}qZ; zCsn+{VH|$1DZ0M!w?E@sB==JUnY}m5$SDnsj%8D4x;S^&=)bTe3*8a2ad%9J1*89j z^;~vmo6+=Gdl{ z=05jA)8-xlC>9I|01wsd?nGU=!j!7?_)qQsA2wz;|G-8x3#TEn@9v)Dp$mO2oRDgk zv;0EVOuL>`{Q*wZy11MVOY@N3O(j(*H$i8Jb7()3ob9<1`Hmx|q3hO6br1ZvE&OvV zZKkz;|3ryL%QxTP0hm4?p6YIOY)a1}ZnE#FX8{%49jwtqG z67@|OIkRR4miDY)7)LVGqp{xg2ZvBW!Ln_imE5slkbH{qhnipU;%|ECdXQxN+`fr1 zjDN^Aqw*Vi&Utdsr-di?opp@S;6e?d=)x*RJ$vfn5!_gjBNGV!*|Dp7E&a$O^dSW;l z+Up^xCDaYMkt5#?c-xTe6BkLEU6Pr(_lv9#SGY@EAVE1VHhdneT<$|krUbo;$^1foH|&%h^<{o`&G8I|cL_qq(|WNQXEr(k6=UivRP`hkXY6EBd|OD3XZ6ch~B zd-;pj3Oe%P%wxntCDMYJimAzTgD!I}p3i2fRAWyd$wgG|8Ec$pd5?=0ckxt)ed~P= zJoyOal$98ezIO4e$Ja9Nb&8B5C7;MFDm^*W3D} zIKmC1%2!$2Pu+(RMezcXuI_ByG^fMH-I&Xy!3~OFUI#zhf%9R~zsy`!%76{fFyDzT+vZ2;-Au0Jd_^^Dxm8$EeyO_{WiC$A> z{}T|gb!PLXuk4_*ds=0!M9c$8x#E|<3rkdY-XmcR+8-~>-gc*Jqg5lm8&``f$;i#@ zyO@WNV>P3&%5-6m^cfuI)-$762f)Lw(H~AAI z?Xbz|n7uGe)q>-Z&C2EsDy(*AW(>NiCjzY}bmhF)lQVH~qTYq5U!!_-eXY!qELeTv zx8vR0NtO2qKGHUoOe})IcEZ|2Nk07(hp`n-UK&H9OAL&ku4FDi{IV!BKHnf)a_~!$ zHg=~Rc`0`ClK6}kb7q`wI7o5&*5|ExV|$6Q;xFkKPG+8jwrkB@6e7Zr9X)IC>v0kR zq+Qw2$0WzU^>?^@$R zkq1H+E0oS#asVfF*@)tJ#%=AoT_BF+D^!VgOM6Jk@wJau0bP3wlY;_<2iN@#_6|tF zp+Q>p&xvr(BC4l}=8YzUV%_jp+-_dgAN8)Y4$jaYQZcK7ETz<8vckzZEMQ zS0%BCaE|~d!8cQN{1QeS>>4^{dXOL;tA#B>J|BxI>Q?x4Uive`UA^)6eMrpZvhV;7 zhs{TjaG2U3keNg@ye9s-)_Wd1Qol4ZI(4jU&APOcdzuiq8~aYvyj_=XB*)Km&rK-F zhCHXC`47;;d zmn!vv58&)2T8S>Vmuey_06mm(CqJzFE)29kPo=%8XA$lWjtq zI8!z5)R&^LPjQVson%GYB9TQNaa27Pk|#7e`h20CFb4I?H(8aO6J8|;4AzzLok)fc zkwWRx(NzI@1Y&BpsBH+fV5rd%q~@_sg((+>ZcOCZI*D7}Lx~(~F>7eD7#Inx#`G_R z`nvEGj0LCMJoV-i*{(`n_YM0Mip03eVs`?c4eZX$?4#+`J}J!3fM$<{ zfy-k{C*AGGn(=o|Z=9y4@L*Sk(o9D#7l9w}B3KO6-|0Vfokm$)3plq&mxXb7zoytT z_q27mnkSUNaj@`f%@PYY)!YohVD~uQK4&h&BWnag<$#t4JK@}92S48H>bn%H+*CKM z@A-F7cU^C;EH)$|0!2McXGZzG>`BPo|`uW#kbln`M zA2bp54ZxfWxf!bHx)URoc$+_^*|)8e;qy3=rYqm1{-8n^-orCRVNr|wP?eR&I@#0Y zB!beeQilU_&5Q<^zxGRm5@U4jk-D{ZVF~q0n!JQgt&4BllZw~}qiIHT${>G8SohT# z)Nqd~2dH)hzHvooeGfpsrdT*<`qrta-kz6c66?xsYOA7}$j~E^i@2@~^=M_TRW2k1 z{4dSu7h#9#KRMSaS**22Dj0m;S#K>(@2QojT0SWgkBHi?Jhgo~<&_YzJylpK7=3Fr zlHZxVbDKmtY`6#@t+LH`#nT0@f;}J(+07h=3aF5;ar=OubmH zOohicOT=rzK{TLgye^GGy<+l{s3xhbhkofUc zf2z*beAnp**f0e-F7S}&>(&S!9g!@iu<1>G?CeVgiG$gs#>Wg2ZhZnHB-7j^IY^a) zF~AQ_=vlmQAwkociEO<=z{)N)cy{6A+~Uiev{~Tl5J+!0qC63JfWK`E&2W6LX+r!& zZ-#GtPUJk@X-A_!RL2Re^H~3-flU>g8B`qSYBN;$ygR-(+bY<=5NSng$9R`%Izymv zn==h2Anz$651ef9C8}#8Z}B+P_2B`*%K@nLPs0tfMBN|SRI;4WqOwg&)%jPR`+at^ zN9n80H(Py4)6~u&_ITSBf#A6ng^D$IOq#ICr1h6&05YC+$ z`JxzUUkM%eSCso3h|$ouK3Pc(lsdJ%dNk(Ul?O|%e2Y}gZAuwVA@52XR8xTcDHc!$ zC6O)sV>qbMcJ`0=0>_SFZ>h{iH^%TDrHO}Ckj<`o)_QR!%wzxEWEXRxLUVYdrAw;PS!Cz6rw-DanK3#AfTkZD_7EUAjj;>k^vHS1Ib%1dEwNAKXHGC0M^o-5!c?|<%1?;j8Z*o@@UwHtRX_0_LZ&dhAF zTH-ZxnVIBVKtXz4_Z+w$;Mv%>WZ#NbvG7w5r3B*r(SP_B|1Yn2s3;VLbN9RdLj41+ z0$T}Vog=~^y5zyeP+;j3N0qex$9~Fo?z_5`RjSzu!{eK$<5ROE0upb{BmJ3J!84p6 z!pNU0R@f+OEMS2R%b6CUY!0p(2_#u#?&#pYqtk$aUGoQ+O;JhV0&UwF{6>-CjA|yv zM>09NQKn2Whx>)h*u-E3kv1iRJ)l~s#Iz=^e02AFuY27f!iv3R3v1jzCQ1)1JDf|> z2yiyGyPnqZKiFjt*`cm=VG4e~r>|xWnx4Jpmyx~fqd>(JnXDq$2mLR8q9TzgJQfw5 zjH(9DB3PUZOo648Ew85@YWiod-}+dXkACk?q>F}PyHe=`44w3WV z1A10(6AT1;BB1@iep9Tr)mRP)Aybvp)7 zPxzh{k%8^fIYm>@t(=BqNjo21?n!-3l}4UFHI&GBz24y@A=FmM%}qF&BJ@1FM?~A3 z1D;{w8hi4geAC>O(^J8OYOFvK4_vt6XHugF+2%?`##~s~99NLujYG6~qzA@1wRVal zG=EI-Ct*QI;b@p!Elp&LM=P|{W*UnJf9GMxSO1n}AyN{tacVwwqJSj->on7$Iu@8` z=ByE!h1jNY-(EpIDh%TGDt;fu+O;xbxq^{pOm#4jX|SoPa6+>NRjj z2~|7IJ=!unX&#<2ddDvW;R=d{mOVM22>nm0a1#xwc;&O}B}f!E!ZoJP&>b9OVPY*S z!>|-!X0wsN>=X9ioWV^;D0Bs^vsix1Xcw~U$xxP8sz$xPG0K%vOC6xDH`9Dcb%a}% z(<6~&(7Wf_u$qQfCB=I;wEMY;bTUD8Ivozwc5Z&pl~ z!+CdFlvCYbp=^CVRejs1K68~}j9-SYPeIXxeQS1LVMJ);{K1+nu(?HjA(gzLw^yM< zredAUD%jk`jXocJktv9^P+S&FY9ahUbt!CE{F;FD{%$zAath|=q_K5Cyui1T^*$Pv zc6--a6g>{|p`_m4H6fP3GgjaoGzHOachu@5P4E7qsrVdQCEq{6gl2T^E~sZLoh?BK zq|%MuH7`C843zSZ%_JOOGs`GEQGgH^)Y*VWycNI3GFnV#x*O;k1?vI)@9#bA`) zLhs&^6|#mHqL#OLa^gUty2@QX?X%H2)#zMpxSq+(la(t}hxSWePCt;DN6WUfoCFAf zqWz=Hl3E8KaU_oy`3XN^uWDIp%Tx{fz`pBOKTX$F9Z0{cBZMzDqhk*NE7zR-8&DIn zp!&K$M10zY<72L|f>P8fw!U#WAcBR1Uvl%a0Wc2;FcACrk9-p#_9IGA$|tcSn`^uF z{Q*B+_mBx;Vlz#+L}MoF=^Ku`-Nz1s??Yq0jY&>+s~LA*$#bUD6gE4Yy)^57PGU=I zF0y+KNf3OdY9Hkw5%g57$SLpg$sk_j8#^z_%U+tvej+jd54XKM z{rweJcP;gEcJabQEbDotiJ9il$m)yOevNVXmj2s!*0*Z}v`MX7)FNjZFJmR>u za|JhGtSypxffe*?TN$%uNIaFD-p_A}+LtU*5rwQKX+MmuiW|YfGxLmtb$-h#HTHhE zt-6Ub=UbeqJewX*60QrTo9q~obWe*{;G*lG?pb_==sK9YQ3IJCmSJc&RqU_Sj3;H2 zVc?q3g9Ez0#J*QOrSBnG2`h>l_!#a?MMFcaQuOw{^S~CY`6kW?Y-eH;yri98H0hQ5 z#HlQHrG!=ik`upfpYwc)#p9h5-j{j)q>D#q3*0avmiJOK=~hdRQ}}eEu`aSVyIz-^ z)xJPi&cpL>Dg4)S73cp{;5*{P1JOIu9TZ^LS>y9RO+ryg36d0eZRThE*96}_5Xu6b z{x)L`@Yq{s>S5%$2?KOr98VM3gtbSr7Y!VNXfIgAIB-!7-|^|%%lkN@B>hGI+U`wj zYxL=y$}>B|(YR1?Q7*`f_;`U*D;JG38W>!rQsbNFq~6|vfFYgEo>CWMUQkSIWc)_a z>b~TCi8N21v$0TlyEotPFhDGX#UB(V zPsf_S$LLg6!O4OTq0%MkU&ucSA)a?^Zi0)J8T>JFaKiQ-Km8X5Txs$U#HCfI9z}BN z0cN3iR_FY6FnEA>i92yyq-vC%aQYkbEOX*Zxx>WcwML^ToM@&Mg&b4^ODBglGx)rP zOj(HgN2udIj^ERkWq_BJZ?@)t9Qj+{_M~KW=rnebSPN#Hg+tH}ArM;kU79^2U)oM4 zrT+2f-Q+hT=GPj(kS1`b-C$$C41magpfKcm(e$3?V6EkduhRg|yl zFM+Xdwr_y<_pCquGS+pqM?FfPJg=eDhd@$5TKmVdc1P$c-`_BmxOaeVycUl zp=bIr+} zqaJ*vSA2v%qoghDerVA}TJGU+g;S3;r;$)%?a{A+VfhiYt_)3M#4`xmzH%C>6)Zr@H{&b9Vt+uYC$DEy$K1C|_kB9LfzjKv)d)-_DqLBBa&23QV+@?k zjE*%U!vXDVn<6U*qp^&w!QASrGY^}(Yez_^D=l|D@3IM5$^HlE{|S_UHPO02&}gPF zA#JgZzDgsbR6^xOj)f@1(F|@@wtBA^I#5+A>Bj4w=0Xwm7rR6{Qf8~NxQ1jPAsyrk zJVrP_f8+Mvn z@}${hHYd(1=ZWPuInHx-2)!y3{=Mzqzx{OlZ%g#->}1ld-p1YYeR2u9JsmGUy5YDx z!XVgkW7?ImCu7a4(_kR7R#h?etCt0$8$6l?iv>wVLm|CXc_0bBOCt*6t)t@9B`_Rk z0)?CRV4bZsW^Y9C!1xp^!W#I8YFq%FwA*FYc<3S|XRb`WeV4gg;Nqvb?(D58l93i0 zo|-S%geI8QR^A;Ee8pvat<>ha90KTf#(1h`T1yN($B7xI`S{VGCBiY4LBsaZe>5~M zAHM}~-?l{xt7H60``E=Y))M}1@o;S++9rmuZgZs-zu62*QM#OH}oKr?x+Ai zAjy9+E7g1Z)Jb?P8H8NxT@w6>-dx#f(I9&Sow(-YTejmSeKj~95&C=sa4Krta1Tw;F z<-u;s$07d4aWV?G;!`nXRw(kFzj9_3@c97XUAzKyKZOCd;4jP6_3--)oWEZt5z^IJ)Ehy zs|sHqcsBeHH+FA0*dr{e>U-*VVd2w#(8v7~u@p7s@P1>5Mnn05k3V`f zb@Z#A3t3rt5OVKoT=Jl2A1luv{hU?ur6JEXQJe>UVnw~Q=DaaKh~Q1NfmOYK@}6;* z2P!M(4AUXiH)xC?1JsnGtQ2L_RLlr>Z)HI6dUB(K#p944&v>8|7UI%A^!`jL$y;;( zwC~bAe<>48>=jnex}y;GFH5gMMp^I>9Z3?^t2i^3FeXVHeP@^DzYrGRZ2XK^o8{?$ zS+(h>zZ0k??Fqn_+W*bX5Tv6O>G@lZ&1cjObXcJE1Kf(??E@R>$pO}4en)Hs(B-+j z##$`gbo>H#>GUjj>WzkYdr7|k@veQYYq2$vz0#&Qmzr59hhR&-{EyqLsr~EsnEGC} zu!diAY30R(Bsc5oz^cGg74J=bOP#+{wj@B!vqHYEcMi14i#DXfp`AX72rn+toFF{(X)X61EO9(!vFvP diff --git a/contribute/img/vagrant/run-script.png b/contribute/img/vagrant/run-script.png deleted file mode 100644 index f7ef557a721fd534bb29b7c01de65ed3ab5e7866..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 61188 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%0Ao3`LC1F;XBFOMTpuz% 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 X>FW(G6n-+*ST-u3+hU6(P$ From 9decfbf65cbce39a2874bf9ab18e51353be905d3 Mon Sep 17 00:00:00 2001 From: Thomas Nares Date: Sat, 26 Nov 2022 20:56:52 +0100 Subject: [PATCH 145/310] Change diagram to mermaid to better searchability and maintainability --- .../architecture/legacy/legacy-controllers.md | 39 ++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/development/architecture/legacy/legacy-controllers.md b/development/architecture/legacy/legacy-controllers.md index 80856f0475..dabd5ebbda 100644 --- a/development/architecture/legacy/legacy-controllers.md +++ b/development/architecture/legacy/legacy-controllers.md @@ -1,5 +1,6 @@ --- title: Legacy Controllers +useMermaid: true --- # Legacy Controllers @@ -10,4 +11,40 @@ Legacy controllers are based on PrestaShop's custom framework and go a long way Legacy controllers work best when a Controller performs a single action, for example, render a page. The process has been divided in several methods, which simplifies customization via method override. -{{< figure src="../img/legacy-controller-flow.png" title="Execution flow of legacy controllers" >}} +

+%%{ init: { 'flowchart': { 'curve': 'stepAfter' } } }%% +graph TB + A(("Controller::run()")) --> B("init()
Initializes the controller") + B:::importantStep --> C{"checkAccess()
Check if the controller
is available for the
current user/viistor
"} + C:::decision -- false --> D("initCursedPage()
Assigns Smarty variables when access is forbidden") + D --> E("smartyOutputContent()
Display page content") + E:::importantStep + C -- true --> G("setMedia()
Sets controller CSS and JS files") + G:::notAlwaysRun --> H("postProcess()
Used to process user input") + H:::importantStep --> I{"has redirect_after"} + I:::decision -- true --> J("redirect()
Redirects to redirect_after after
the process if there is no error
") + I -- false --> K("initHeader()
Assigns Smarty variables
for the page header
") + J --> K + K:::notAlwaysRun --> L{"viewAccess()
Check if the current user/visiter
has valid view permissions
"} + L:::decision -- false --> M("Add access denied error message
Added to errors property") + L -- true --> N("initContent()
Assigns Smarty variables
for the page main content
") + M --> O("initFooter()
Assigns Smarty variables for the page footer") + N:::importantStep --> O + O:::notAlwaysRun --> P{"is ajax"} + P:::decision -- false --> Q("display()
Displays page content") + P -- true --> R("displayAjax{action}()
Displays page content
for ajax requests
") + Q:::importantStep + R:::importantStep + subgraph Legend + direction LR + S:::notAlwaysRun + S("Not always Run") + T:::importantStep + T("Important step") + end + classDef notAlwaysRun fill:#fff0c4; + classDef importantStep fill:#c7e6ce; + classDef decision fill:#e2d0e5; + classDef default fill:#FFFFFF; + style Legend fill:#FFFFFF,stroke:#CCCCCC,stroke-width:1px; +
\ No newline at end of file From 7d3464640cd74de5fbc92d1f425ef7778f48a098 Mon Sep 17 00:00:00 2001 From: Thomas Nares Date: Sat, 26 Nov 2022 20:57:58 +0100 Subject: [PATCH 146/310] Remove un-necessary asset --- .../legacy/img/legacy-controller-flow.png | Bin 273810 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 development/architecture/legacy/img/legacy-controller-flow.png diff --git a/development/architecture/legacy/img/legacy-controller-flow.png b/development/architecture/legacy/img/legacy-controller-flow.png deleted file mode 100644 index 8f38134cb48bfe524515ad64bfcf572ae47cb5d2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 273810 zcmdqJby$_{*Dbmb<28WS02B!okOoCUN-RJ?LP-HZDJ2AHX?zVtRFo7EQRyz}R6(Rg zKssfibeGf~kG{XXzweyuoPC}D&b8McUI>fD^W68m=Nxm4F&`gQWjU&C4BJQ~5|#Y9 zvlmIE&Hg0PUrm2)z;{?rn>`|t4v^%}o>IT{aJBN+ZHM*f zH_}^~h6Z1Z(TXY)3gH#blo>HKNsQ@gs(Ke@(Pb-YC$Hu?&SU7a|KRW`svOEswojSr zCW2H_^X#sXcIMdi&a7F~9jlj|soC+P)ouAiePpIK?=Jjp;$>l2(fH>pQWDiwi9cVK z4*#7^`RB_d>i_?J^9iNjMqJ%VXM6F>Vy>jt&A#Oy0ybFgX>?t z%GN^}CKS4I*-U?acE#bZ4vIftYI>*rpYct`TWrJ~SzWfVv9Yzam6!MF^jD7E{?}hO zZEX6+yG>*x)8D;QKM@-l8Cg=|NtNeFic_|y^S!r)2+7yy#lw~TqpAvp+1S}PZQ2yS zZDFE^W#`T}@xBs2+p{bV9y}-;dEvx8{ZthNg#@)&>YSpO_>~2EF9*Y?y!d^uj?(UK z{f-BBD8IXoi@3VFIyo)8aHu7zD((E=#LzJ%5-H)1zrX*=ikr%ERvvYHEt&5jT>t2dgCGI_Hc($k5o#j?91wDPpi%B;cX31Rp zp|9c&!vkdUrp=qFnI*N87#F&ndcu#}d}wYKK6Y$os)EI{_x2Vc@BWgnU%wtYbf~P| zH}hKk+Hhj(6J{xH`LB1k?v7CouX?;;{LQ0Bk7j<vaA+fyB<0-(&iTA7PtK-&V_(`RQf8TDx?CdPP zft$_H*XZ`O`l7mzAC10$dK@m{^lh}{d)+H3*Z#7ta&mI={)I(F9oaWr$ShR7%3=<~O#_ty^n5x|H%bgjJnE&_-EyqDMn}0{EOD^2n_vSX z+@^gJR?2aGBgr|qfGyOF*G0l)VzS#Tsi~;KC7m-wc4(=pPJX13ezae-&R8(s(fQV` z!ntp{DpGUmxDVkUAs5xuDxNTnjE(V~Ff}oenyEQfPZML~^I;-m-~FUDgG$zZjieU;N(c$jvav}YJV5fI${>-h-0=?x;PHrl zcBB2>(6~XjQ;$1`(*Z%jjNDvpHL{~ly5T*y{J1#Iqxp@7>4l5^zP3wAmomqP`O<_X z97mr{G+5T4Kj%EUcSl}cp71L3o0wfa|5WL@+1h3difTXf^J`I03Pk*v zHO82=tNA{7@OPfIiB7Rw-r$4v>6sY`oBq2iN+F&yS<>x3K0cf8oNDxHUs;;TD*DnL zEaOX;tec~3H@mJ~;!zY6T{7C1DW|qtf*rX{xka5mx@Ba2@jH!@V%%C83yFpy?K17E z9~X&~q~_@87;(b=-4eCQa6@E8yjpBkyWJKs35n{*%fEh^XNp|Wc=+()CqEVemw_KY z=$V-KlNh|>brOE>J__P%9PW|G=01% z9>O6koTZVdiHJ^EO<)=0)6L$vWs9$6=R>OfBBRv;B}r*j5%+iO+eJ$o&9%l-7cMbsQIF)@pl z6phObP4Q~v^*%QzPWq#1nVGDX*T~tHZHG$wshPx^8XMItorb>3)TM?Vw=u+hE0w5~ zUcQ>HE$hd;+NdI}F>QP}V2EXXQSQQpXBm^TLyhjgW*eG{%qsj?JO`f1aeFpBKWdbH zqa%h(b2~Nlx4`%!#9cyqioCqMpVa*Gm_wx3?S@vk!pD_WRlind>Vw?Z<~yv*8I2A1 zwc+dp1_n+}-V|f9UYaKF=1{h5e;4m|?&{UPl*FRY zt$T_W7Z(c)3zfsgk%m&VQuTN4+)1l4pe`R88Y;cE_&u0US5Q#!Z1ANPT(iT-;P>y5 zmanIoin);93!EnC>?Y;?oA9eR_5AvU$NBl|dV1DzR%`0(dvdHJ;#BqYIzcbZ_{w{M9EAN(ZC0=H%0xjOf=A+lV~xBPARLh?3Vx@tv%q9`dM#WlrU zC@(LM@c0#P8avyhrh>fM9Iqyq`9t7FNA~Jmi$S^L`r4|Uon7^#3!lo%krbLz4GfAo zgDWV!7`!R!NTiMolWID$^f%;Q9zMQi{r5GY$AX&YCwc@XevReya6f=7tZ~+pf`WqPen$G4 zw=ep>zoM!%pnflJ>|3fqs@bBzv1@he-CwKh7x7-29Xs4+#gA$Qy4~{d@K9G*_hXh~ zcAsrPMDpuqpZC~iE8$Y)F*8^@ZG6wrkjrFK^X{hk1alh2rv|Uei-f~!tBR^ha!N~2 zl6y9*o_SERUZt1lxGRUd=7yGzPJ60>v<9n7(FuNjX|ER^^dwzbfT+?>jN1fs4-S!$)4N5ZK^zoM~hBCpLe=&bZo4vt4pS{ z)>x2=@wjSgi$!enNJow}unN{;N0nWY6@>wifyc<-MGbjeaVl`Bo(KVJ;zy%M$xVFomoKPNO}eHZobc_ z&zvF4qJ%t_HM(-;_26bw?hSsu+%)rMZVe0FY|E`%w?32Jyk(1ZSH4E*89tBwY8Nk- z^)?D}L=qpeqNau#*<#>XgdDGOVks)7-_xw|*L~zphhg=l9;R#8eoTF@2&)~WIk9;1 z(hVGO_vLxMnFx-)aHsAIYt$oizp!5S@837~%rG|LPff=~7P~J$9K%Nx&(ui(hS3`A zA(h@gl0$3)0L6vzH2qZThPN`Is|)k|JiURi*sz6 zT<6v3&<_gh%ho0GIs zU)i4e)Zw5@3X~J8^!l5L$$fowA#q!nkeQ(SFMEx?`LT|2n$HLvje`5sOuv8*61PR% z>i0Q#=6)ce*ONuWvh_8$8**&c``mP+iUf~q-;#Bm=7u$t0z4Z==CEdsbN~n!)D{Gg zCH9M2sndQcE4$8WuOc~hSLE_e(v?U8+*`^66-+Fd{vwa%nY5n^*<_%G+%k9X!ptq1x0zg?w5 z6sqC-R#xKzB`a^+=RRx~xbCTKFCIR>PW~)->{xxcL@alq%iM5f0Eb5SQHI9}ykY^B z_JcM1u)0G4`eW@`8uw6dafJ~v;|ANdZF}c)i&gf~mrs8?h=vdXkt{FDtS{_G z+ZgF$jgrt%oUVQa5OrF)NWTPE?7VajL0cCg?b(`kwLh}qx};72+2#2$jmJvQj~o;c z(L7;{9{^dmILe0V{^;+2>#h|@wNG#W1;XCJfp!yCNnO9!PZ|l=u?ZEt#X+kjgQwBX+Gx}jcOcL z%k@n^P(M{`&G$7hnAYGP^e$m%TB%7_6koo4Syg?h;7xzOA$g#`{={;Ud1Vv25xu2X z0Z*U4rs|Mdoo%f017h>fsjjZ$N!5#5u6-q?n|Ct7c5u41wDj}mb0(`#pFTxBud>Ox zT;LcKDt+;Gb%;Q9V~xE3yKD8Y07&TR=oI`1e*TQB;lcJIShrG9CFg$p$Iq`m#K7ay zpcxY*W4H4UCZ+WD1dT*1>zWjQnh_w-7vH%v04jh^xYu`X$bGZz?PXE6;&v<)09#eQ zM@x|NJ3l{_bLT!cM9K-fTE%nFjx@zL){1xlAqh%cI!r@D!@|Py!I7j&Meqi#yX535 zu&`B;47+#jQczIf-j~D8$@%&7=cm%Zi`p9RySgqfy;4(EeQox=KK@A{OV;DgKx79A z2?-uQbXWfrcDl`x6yw#X8jAw0cQ&FXFUJw|(b3U47Qs2(U!L@R zbzF4J)3S~d75>anTC|Ia>GI&TFgK13YUa%Rye9jXXnhX4P>l=Z13jv!2HZ2A0?Mx> zhsfk;t`u=JYt89F219?5t`z*vQa;MDKyTraXF}U7*GkrxOVG5L30&>UcbG0T^=BIc zfN~i5Ru%XVNzj5ie<9F9!v5!%zWYZdZWt#UCS5O{PT)fAb>>TApLK`6VO@YVM@y<-O(N(K0q3K+E@T_m8ek?e7aOUAhF+ zX!4}3Bz|WW&b2HNutw@LwMFyo7QnDtwHKXmi|BSLSyoq8blzR>8y;?db7qTJq9MLd z#Ij()7=T07!b`z`#qoD(X-AfJpd&4CnKNJgH5b&9!#lIaF!2PO_x3p!icVQ{x@dB;~Eke z^O3$%^^0`o!pzdO2kXKU&3Xk;WOq#lMCVx9&dtpxG?^1kd61=hY{G{aahL$?G5gj!}tVW?>Pi-|d7mderEXPXtv_MBRevcc5>{;ArFJM8)R$=F3 zdV70u3-`Uf@nN~NcG(bUu@gHJ;3N9i`(S;rI{ZF9!n+wS7LU91ah!d zl9n!!V|G5^8Re!Iv)G@#IFqR1`Kuv z9uCqv=skwA7jr)JkP3}7+De7{W9rWQAH8Yn>*~haGJm`fwg{w|q7z0EJK$_*RT#jFkon9crd*iO%H zZ)X>hU<`WV5*3!~qEa*PpcCCsoM#5BB6<+**l_1$wu48GOwO-q{|23|GTw!q?O&7NK_H)i9 zFADW4$lw_z=?eLG=23}N4nOhhXQa<=4sO@tUh%OkH}qDv+rlCudIGuB0#8MVrZh6L z6`?WB$)LMyTXZ3^VJ{tBOv^}szyG^XJ?}6|E9lxAW0Xd| zygB3Hu?F5I>yj;+En8|^Upl^Db0e|aY~}rD*Bo9P3qg;oU*)suF0+)&j(vh`fFP+Y zEP!myS_T>#f4{E^Q#w}oX1uE)al;FLHm2h@Un2_xMr_@&LlU@7=`z6fuddAUArdK< zmY^R)-yaS_)Fs|OOC(4W{;O}^S#^n%|GCp1Ut7&e6Jhx^N?uH(DKptZPVdBIDJ7sv zBjbW}x5x4r1?A@J51Vh8Uvms$tL*4l{t@B%ZO^(Nj>M@a`dw)sMb($~$3-;`RXvK+ zOxi{>(&x<*yj|3~J1M`rsY!i_z3s}82RqA1<8k1M7^X?};je6_WeL~ltikQ;x-Fy6I@5$OzIaRf_ zV?g{ona@1eW+D)+tfpH?%{0V0PIeg#y@q~hd11o9bbWbl1khN>{->%&-km!iMSI*b zZ}y$8-RZBrvwyPh4VeR<|(4&6l_4X(G@Tu@9c*zD$RKMdkf0@4@}@wWIK?K zv#onl+%0Imk;Q+Z_ttunqY;xfH0RVeh z?r3GP6s7U|)5$}D%W^0Vqw)L@{kK>k1avW=~Y}pHT zI5;>)QXy|%#?sQVS&)&UbB~HjJzA~qrh^lOGs^1fff-RI)xl^-Tht59z>5)SgvS#| zZhh%T1drI!pS8m+sS(^XJ4vcVL(et$k* zuU@^XpimX97=k?+?Cn)8a2x|^5~mqeBm*h~a0(0zH8nNPgNF8PA#__{2Ju}P85z*b zsC{z_3#ls`=tTp=!`)HL9zELe%$;uU-dmYGiQPpt~t$l|TOd{p{G?U-%XJJWwvF{5wRkW$JKXzGl=GuUysah9RtMp+|T~%LO-d-wx zlxSNAg$u_`Q$JKz#+N(1kjhbNKJB33(PH+{dO!9gA$i0lq`73gF5K?((}T9H;{`_a6%IU^OLboP+Q7#5D>rXVM*dGi- z8L_LEij~rnsJ!gFeeL>;b5_N$eLkA@1BVWs4%*BA;L#{}H?UDkmyps@Zfql6S^Z21 z9gB80yOwUa0W<)?f$Ris35xxqaPHh+R8(ZyH=8r=TZRt|46w>Qc`4z(3 zA>5px0qR4@p;`mvpPnA?r|Rn4nV|me-M!06Pe@3JlQXU+=}eQhaR){A6GHOx z0!7)KpuzKueb2sqdAOITs3?F;Ux{NLD~mu`HX*9V+WIX#t*lb^t_j%Pyvcd&ljyZN z#%4r4 z{-s#Ja|El)q%|RudJV^TuCD>aC9lW~&HVy&Tms`h4_&JMk4UOYMa6PLlAWCldNOtK zE4Y00R3L{yhY3Ny$_;t`TZ}xJm+-z*8=698WhJO;X{T{LGqd}A`IZ{VfPMD#Mm3o7UDcj3$b`c0eOXSk!w z(Xp}C9oc;R{Nt_ZMzWC&#)9O5fph)?h}o7As?BE*r;wruc6e;8)__n%uV`q?(~-Q) zulIeprx?uJmSLjEE|BcHFb>V83FjlRjq-Jj5xYXE7ka+#LehKBt}W*#GyM%BCj{yPn|0jSh=o-%Ij*4P$H`W}PQZ-nYr zs)@E^{EatrzTHuYgSbSj(m*GLFkR}Z*I57Z_EvFX@mmv6ZhL&v({=Di+Y6jhWA>hW zTxubGrC@PwLw4O0j=xA=d@iUW6UsGERuM6e8O1KD?Z6uMQXe9Mp(E36X&P{#lWZlR zo6RdOuA{c&^$XU0Z!azX#|xmlCGE1CCxmPCW2BBogouPxbhzfplciu-h093^V*hi^ zcKB}sBX~Ysd~UpAlucgTZmu7QOf`Wf)f$jg3i75TB}g=EylZup7@_z0xo7 zSat3003l{=ZLM_FYuM+M@(Mpa2yF@xUNA#hju&X%FZxS`Xf_WmncKLlJwMRnFfBT}rGla~8ik$8b z5nAM9U0of+THm)Jd-Urs3`xzqc`j`Db8>zsXS|j4$H`!Mzo4K%*uGgIpNM&NYa%w& z_PG>w|6i|X$DQ|As4i#uTM@t8yr0M=ma>S4|J(KaMMIPGziv>e;^G&C$U`I?;GmwF zx|rx_XIEE?hZO26gwW2`%|OyEBTfannBxCoBR?IG_&3@K2Sn?09KxYk5kgoi_z>i0Kanby7t$I;_= zk~nan7yUZ1N{nsd|8=jV0ytEPm)(mwI5y!I&3S+C%d4M1fBtyoI&S6YI`H`!abOLJ z>v7ul`+78RV7haxdoKTULsKz7-j#@x%6jB8^}o?e*e);m=Trt#!|&rYI57b>viljUTz7Zkt?|4cxG=>UVjXj} zh(D^zCYFS%5XzA$% zw9{VW1%(n!@X@13UvPW26*|v=lY{p1%6TwU_A!Ime2>x4&=6oSs`gJbMiB6llU>ue z5$1nV2?=#bsdXHDFB5c}^XK=leE4|AX(kvHgzXL%1h~3Sgm#8 z)F;FU`D$#?v**uqJ=fO?3nk_KC8eYw^S2f{+mUV1n1h|z-SMM7LPbR-giSuRMJr|s z=u9nE*{AevL4hk`BTU#LCVo!3#?%fthz-QL716_{0Am4`A8pFfFLFs>rlX@9wink( zwYueK^O{Y5Zn(Me$pL;YuATHF=*_|WS&9Iq2neL6rG05@yX0C?6%ZC?AreORIE)uN z`;dJ;KF6o-oWDAdwN93KJOlC@oo_VIArxB8`Ob!hbZ|A(L3Dfe92XadPM+bvO5s)D z_uISV#ZY$TNX_%3-+eeR?RB9ga&g52(!MynZb9HExhH{IHBW(b$kidzXkcHkt_ecr5beHo#y`pr zv_Y+CPhd4pY)6TwXTt{o0IaNxGnx|^a^N`W>+7?bAHB5mQ$kG}A6@l>ovgSOcKNS_ z{_Dq_oUnqL?Nh)2;0aL%ykt{T6X+qUwhS2!JKPC&An3>6y!B8pjf{-S+YjIzxWi>~ zHUvhYY>=uc${hj75)PxS4cCRLx}LHPp-nR=c5?<_1oGk)1SRw(+%!H99uOuA?%b`U zZ(aj8i0~06Wc)KUQbG`MY$_vVAMbM3rG@lq)|?O|V#*=^^&u^fPPS$IV`q(S=ud}O zS*tDI8w)ysSBBmS5gKj4>sF$3hQOp(41P6l6IuI8KqZ^<>_W-<<+5pRXUA}5j(@KE zvmq6ncjn*Oq+8^Y<)%0`I{LM-u_MbO_Hmn!wr-fnjkBK&H@yrGFRw!qc=-IXNh^*+ z(isB-gFF}X0&Ma+`Sw8KN*YHcY({XfHFR`zD%DUMe&;5JvrbGZj3<>eLHu64I9{7HgQ!gDMa^nS4XvNHj?3A)YMi`Q#Y+wvx$mo8GqWh<9=c$}u(}$nz+PwlVl-q2B9K1oD=^(k+z-IM7eY{^ZnBG_YGO`Ga7WucP`avy& z47-9HsgzuW+kl-2AHPsw_5PntD7$nO@J(stT_WY4A!-`RkPj3oF?8xSec*WQkp@CV z-y5d8L4`G327sTLnNb^`o1b3;Ut2bhuAcRSuB{qQa=}&Osz)%k1Gqs|QFQ?)duAIW%pu=&tzl(7 zNDdXXel@*STwMIgeoq?1_A+oW5GZ$lyn;>#-Sto8Bh(hqAbNSWCgA@4+2%%C>LEXDyJn3833DHs2@r;; zlmdcOL9E7TqsYsLMSjhXNf>{A3i@!2pB-sYvD-=OJX0&0wY^32wtgzT z*nJa7VVsG3N#pDUK1NMbeas;I3oJNm$|~FpVrYH$o=z;>kLx;QI-66ns#JGE%^bSp z^FID#$1)4wB#GLi{^Fb=*`k^f)d9c>X*a@i&DrG1+|<-gR;lm({TWcDW@bchw6op+ zIX~K_)a?DGC{b&ez7l-f>{>&J(NxPos6v6*2349_qhl)!#Dzwaa*7$?ke6lkPo zpQff-BOi5puCId7&@jD~bUrV4BdLk=-;<|@NPGAB4a#n6$(jp_fb*TB?(Xj8lPa`g zDKMHat5L8?|e0a4i(zI%sCstYXr`Dqu7=a zr$&0(VZvI7s~)Ux*Nkluk|+HEon zE1S0UyU=0*Cd$^3!&P9*67$gok)o`ud{1tj{lI~f=f!f62^)ywf;4`Vc^--7oT8#G zIyZdy+5DG``bi(!z(NV%>@8hfyp`GJHre|g$?D(2)k z_-HJM3THXmnr?XB#?&$_;uN5`v`2?QDJQ*s&lMwAGS;1nFaggN`2^5hHI_ zI4cHWKfoV4YydXvIvj+9Kf@$kPo6x9Y%3)xN!a*qO&Nmv!G+WD>3pVzB6gN!zqYaj zfa{!8Zn$&mEPfg#zgtO;o1K&MoO;*^cNbaN`)=pl+*VvCia3<1NX?`_1lLm}t65YF z1^=i=ZCl|_6xqAu5Cxb&dz5R0AH9ISUY5BA8gZF$cx^gij5XBN*L6fCgdDhvWXQ8O zZ|KJl4w22&jEiV-fJm_sYs)?B^K)}SuC~Y?=nOR_cfYg^+Db#?2SDd@1A4ZY7{~(X zO(xV=n(M5tT@%I5h%sLi3`M&rW|Eb z7@7~z49o+BwECT8{qK9XZ{NnH29HRHiQzB#G@EUqV%W2LcR+Y}ve}#flstM4SnLRc zR!)u+$Q0m=)FeB&*l^My>sUNl6TmTXzWVU#)4z!?v_kkV58OyUU7j4V3Y$}44t6h) z1#lL{$Zhg=t1=k%FK_OEj13FxfSOTqz2VS>V(jfRN3BgDT~Nw*Rg_m$c;CARHW!`A zep^Mu<7tx3S2kT$Bc+-C=e`aF4uY9`QKqDcyScZWzKR7h@xT}%6h}o}r%wX7|8RFJ zjL(UnFZB9<{yc86+w5Jy1~QpE)>WXTVRdbxMe!wJ-jY0gSk@9G zs;={6Xul;7Y9X{V`&iA73WBUdFg#EJ=?_EQvxL*Cs$Xy@WrE)-Xlo-QR|F2-Hu1mX zQnlrvEAaQg=hwt(NBJfsq+D%hOY2R3-ObG!mg-`2G^BCH%e2AbAX7yY3QH$brM;>W z`zJodUlWpX(w?!NsB?ypgnT-N*XXF5yF1n9J0T$amu+75Gh6w?rF37yLPl`1(jxWQy1<7%@yg#^sB|z_@8tOgt^bwNI)9Cz6 zGxN}GRaSC=_y$Z3ikMC{MC!s$LhTA-8!BENXPu4tP_q1oNjypQ!Lyh$_tM=l)fmMP zeqnS;Nj5esi&Irep}qxvo(mMZ6$dU6Nv*W@ncVIYACNgcsF3D_fQ z)p-kazTv@ka0J)Q(U;N?3<}y(h05C6)j9DCOYq%aNPYxT`0>AlZrmQ{E)966u72F? zJf=e`4KMZIL-e`lm8g16rwSnQ%QvYde-HlTv}DZm zbde>*dyBP|_JN}LH*Mn{|F@$*iWiB$8n+XQW)4`HN>Fb-J;b1Zq&>+i=wIeq_PE>P zB$Ntv`G=1ljW)*m6&1M)=MJNJhWSg;e*kfS=D5w;h=Z^>qtj(%Vp?5Y6_%iQ{psqT zxe|u=m6h^(F$fdo*hJ=#LKq?kTWY~iWHx?MegUZ(GTUHnnA6WM2U%IqWU`RV8UHNz zl|+1)Og##kLkoXjU3e4hMrxZ$!t{UAWtuat*lB&&_!oJcv4o1hO-Z>jH8+U8d_9N= zL4JU$0Mnj$cpb7JHWmsU$^(?M1z;d5}ev1&>pAunIL4L5PY%xT+(ZnZ7x(lL!?G(g~eFsPEK zRsa6|K}?ol@xk~8v&G|12>*BoFBjL*uv$?`vrytJ?%IXa3nK+QR{zo>d4$?ngv!*`mWPS}yBOi6IyQwb z?sgE~6(P+~REV z=vZK1j|}gMF!C#gTcovB+ONx{3s(6c@0tkd^|osfm@S#swJwV0UBIXXsxF%NvI_LD zk}%Nuv#q*y5q9q&*iRaeL`ANDIoTY6CBcGfH7c25#Q~V7E6^ceNA^Dc^!)jAcyeY( z+Zv4_Q43xDa2Gvy{FBFz9(5MG7o5}Rz<3b08i`B80lE%U4r1ackBy59x#gUH6nyxQ z&H(x2sV@Oq!hIVkTrFW1ibfn;n~#pLxen$VQ1i{r&2#k}$FGzUN(n8dli;T~oDG!- zPS|`9AtswpS5bg`E4X1E%rS4Sx-Nui2q6)XY&4w-B1G1?O}Qnwxz_x_f5}L~A(AyS z&?_#MgZO6) z^j*iY;3}PJ0Cm^ZC3XDxEdV1Zg0x2qqOvX(x&IbHSLQ!9q&Xl#!k#(u-@$Ut>8G(jl-)qShR%BDIhr55j_G#{fD~(Dre#DsXP^jyH$R9{DNf(RB6KgeBlBS z5(A&45h+Mp@{N-Qp8!EDz9n(M%L2h9wQ%|&C!?^rI_O6Tmln`7{$)Z~|2q>R;Ma=Q z#mZS;8_@@W_neAKPp(a*UM_0CZ+SnA4&Cy?wJRoQ(+@Qr|3h#9;X;42?99E8+T!~x zbH9ish%1BjUoG85uH;DQQ4T0LU%sfy`-4gTg5irLTaVQ_EkJRoaVW+QKcHWqfn!AT zmHHDc!n^}f9DOYpml+|J6U~{K%Qn)Vk;dk4xUpTkc5xTy-@Uu>#`FeK(@A)h<@}hL z5F#M6K{XPjT+bauf0B0kAt9lro*qvCjEUmq6i!iw$L-7S(5wU69Tgzj1maRI6r;QO zUg4+cudb)J(jdp;^8rd!$wId)2p7z}U2je6Ls>2c*OESx)uPXX5sNUT^XK8r`}Ui= zfJ?UxO#xwIM9OkbvH%N)d6I5`+@n`}z(TOeW2ez5f`z#Ut|l?j0(~jrqwF_99Hvm0s4jAgtI zBVS~>p&6_RAc7un!!~g5{{3tmv+{D8vwLM~A#%X%m}A!XsjI69{5o;5-Yg!Rj)bG; z$-^q(SU~sv3=G5LErM9@-Jw+v5A2<#e1*8lWqU!Wnpb`U-L#?70b>^mlVX&S80!!^beZpYCL{}T`_$JQTOI|xFFClQK+3;I}y zzWYwN<^J?xbmHOV4a^}L8>s$A*?X=!+{-9dj$Qsu zCjqHuWMotg36iw8YeJBG-EMB%1=6Viof(XSoFPl_VY|U)hq=N%3=9fburhJls*c|N z{zDt|L9v8<*ZW5j3MZ^1S!#9h8=MiYwEID49|}7U_%wzrw~Io;Bs=^;ybQF7x=WbF z@FqT4!crs*eLDEn64VSqj>6qI*F5!&9J`+hh^aee+S=Kb?*wze1cx2mUH{y<6h z$jAtJ>W)8q>_ZMjfyl!`1)c!)bD>K0X%BKv~&YxZ@#Qp#)bK?AUw;Ga(6CaFPIV zUJ_%VCnfD8bT##BhC)w2Cj@M%In2f;2?x%h?JCUt8zI^taSfR8SaG5O*DbHFSFt1p z$=&x}+8L6i-Gm11IILJ6?of>coTF;qh|7B}9$ z<=VAtE!j78kIF8hJif@J@Nyum11BB6#j3E_I1u)ld^vaXL^M2J zzJ7T|X4#EjkGkjTG1xuCJ1}3tpInaygWWdSa-vnG$58dmW>=<--Q`K909~7 z=5E~+gdH_7sG7*d6UM!LI>w5gq|LFpasx>$dwROg4*bvt%@H!c!0yIE__bYpY2(Zwz@i7y%^{9EeCkO z#Wp2ssX*)gc8`!$nmeB!JcH9}V)OXWoiiSNSMTzYI`vIVZ&kJ#8x9ID$=!m?0kSQj z3Q99*nCa}8bcH3*FK4sHpUlHXiYa~@qy?Hm6G4i6v0CuWb? zmV!sJfI(NU9&ik``;QmkO;J%1_aufQqfx4x)$hPAW_ZH@*0$*kCW=xQLW}n@R~Fmx z%{F}H+0G2oO;=*dwE0!JVW_Z0a4Vf}X_c70f%{yLNFP52c+vO2)d@XD*0^7|!vg*{ z^Py(=3nLqDwJ-asj2fsdQJXh@IeRE<`a1|a7@Rn> zft9Ny2Vy$YfSYJ`#=MmFEN-*Zyqu(+1%Icnrypptfu*5=hB7o{ySLZD(#)k66DRmL zQ7ksEz>IA1@g_J&HRW3&p`l!UOdg}@73vg9q_opSgB7<{#kfP)^dPC1&SB^)IWe^u zR^L(F9Kn~sxA9M#S1^@XA9SJPhesEP|{_25AF}pkiOo=Aq zUlFqD=_m-eTV!DEJjXE{9iWm5*i#uEfAU;k?g3cz58yw z@8I^=n{6?CM4#L;LT(7ReHiT6cLBa+!7Tw*V@)ZSbsauqRpcJ+eZ&0{gfmp~ps^AA ze3&Ud`#30Isc@i>W;N&@Dq|khK!UTmzTO(1g=w%D0^!P908ls@RlZ`JuKr*S89pU4 zjwCQ$8}98rFn$Mgj$3M#Wc=X8wOxDm*w6mFaOeH&Hdf?NCJDzRpb6Vbj57yz1=k?;ZQzhMQxgvI0OxM#k*d2GX~4v8z48Xl8$firK{oHW&eE zAk@E$QRW_O-qsZKZgj=TY3Unvu7IYR<3f^NUIrv`!}2>{zI;J%zW?zjltJ7*K}+s4 z)mggss}b|GH15wxr74^*q&;JXbiQa9L-gAbs}0~TXlZS zp~4d+E!|U5QGo{WrKa`k!hqoT+}uUfI53hzVYRqNkksfU!6Y~7TcUy1)C>mjD>uBb zNfsZB3iIs63+@j|fbv$~l0p;it*oq|A|iY-nU{Pi^RTq^I@(;rtcS!HjPob+B=a5v z(l;1EK%xAVV3R>48;Mg%J6wAlg3P)b8)t5BVg9nGN9acIOVvUDvxjU{)EqmMbq=HC zYqkVs&3HnEZAsSEQsecJJ)PP($`$q(*Zq6R!AQhj!wPw`e0KR1X$}Oza8l`@Ux3N)f`WDn#2X}< z#uPr^f|~d5-vB3pN$`Y18_wj+O|sn2gIZ}>nU@qeFdG$E6R0Rge{4o@T5+0h*ZR}0 zyLVaq6#Qp%P8<|zG~#(3V4pQ=;hfhrNvNDWwkzf&az2wqI5C zV%o@PwtKv*09kLqx$B{2z*7Ca?Q^2(^DOV&y7oIxkE|>l?s_>EE-Z0-`2K&j(RpQc z*qVO7uQoEHFpXzlI89Hc-k6-bK0xjt8y^@N=#2`{W}|irmdV&dM?bj7^x9ywfuOQCjG_O?garT)f*3ItMzGe9Dza8DrKWY$or2f#Q;k;YkOESCC?qrFD zm_1VIau*i3%rSI-<;JaBkxwKKsVn|ZHzlE$CN-qkbfGRM~^=lo}9SMRKiuOFb<)=cx?{C|nNovyBbxSQwCCL{E4$Bow8TQ>4I4fMaK zq<2*GpB?RyeQM`D?ERmm3ujXK8{SId9u=O;)liGDy}RoDK=v6d0t(Na_<8QhfqC-k z_y>VhnvZ2@J#Q((=pIlV#& zQRfFgHgtT=t2~4MsR`Cwie*0g{ei#TK3Dj*DQpvYsUskN@wow;g=*>GPqxd?dm_%5 zh`!V@P`y}6iRb8)^1%vAN~0^Nv#RE)EJ)3M-&0+B<~HB-f?y{yu$F($$fyYO0pid9 zey~GUYe>G9f7BIsPL++>iYpYp(x&)XuO{J!)xKwUi7UjGKVQQ6sri<$!3mR_PSd%8 zcF)*NAmZNi{k`y~ZC$=b9Q1218@)197LmRfKsfml9uW(`9c8>0`eItu%3+X`lKxvN*!zqjOH=30Jr~pE6crxpV(kYw4D`3*4V$nR6(c!zDjWpCjBwT947R^zOa`^<^!F>|47UCE>;IsSECqOeW|`h* z8C}kcz=YP=Fv=t_(h77vwo7UXH!wDh<_5%-87A3+KB-^4 zc=78$o3;~Ug%+LlR2t(;81lIe0~pkg`%J z1*Qn~dmP?_mgbApM%;h^w=g)W5RVQUJ$GU^F8=+}ujOSqS=nz<9LJ=k2_g!B1-xf? zqp#KwFT}u%K@MY3=~f^d`B4G40^?!@HEOY`%p*fug~a=y!n({Si&N;PR1FYt}$*v2RlD`cM7)Lin`kestqd)#!p{lM9hS!LT34nb5y?R|9 zR&loVPH-+L#P?R4e+_Vk01Z6E84V@4Z?<2A|C&e`9&B{| zdfciU1}&E$@w>Pv+;;%N2fpNr=B4v(HlLfGw%uza@Y^R-1e(HF@Dgt@0CjuGi{RkH zTa`f>zLZvcSi*hWOl)WJ>({-Y@&MyzCnv9C;tfJUc=v_ubvS3xd!Q-&10Vw>&hsp| zDJm+mXDgmRKRY!==ooOa!6yQHBgnsTm`~q@DKK>ey*zHy4?+MK7St7fX#VB(?U_=j zfAHhHeS0XZ7KTzXqs!pn;EP(*JVUr2plsvakXx*}3-kD$Gj)=Iii1;O=N&Lsgj03< zcB+q)Gcy5#A2Cmc_(=xK`pbX3r(_)@2v!7sRA8=otKyi?h)}yoSoMwzdW`@>L?}IB$+^DIXgf8$W)$X}9i7mse}b!~HJb z)#aA6bDL%M?CyQ^cD7wooo7z(-~5fbN$!SVL308*d0ksa&vtEeDI%ipr7uit`X{BpIQ4r{N1V@6gY-p&Tgj4>W+_#)71hPxCN()haB9j zU~(!eFNYXojh0+1KTS)#2aiQqU9L9mLqrzBi3M+9pq(Xb3K&CVXKv=Uv()l`@d5)D z6W~VJ*w|pk{!u3}v19Aj(Bn35_2(7era%$_KCgTZjSI1`+DGHb$+=iUy9)M<0Tb~% zccx?0@g@;S+@Q!IW1&6}#xFc%;Nmczz%V;M4^NplnGd}Ss0}_|-t+SEQ!_J=1=`>S z-G#>iy?smA9A~LMVvP7U9ytb5njDFXg89vTSy4w-HO+n5F3_n)!mjScLTV|L zmz8bYxbf#z%=*CgfT=)Rc6<(&$Ec)OA5(O=NlHpe*pJuSEmAA(=HL_jzD#d4Mv0P$_zO&p+Ysn*LvyuCJQo5hIdd9}(eo?QjS~H)&zE5-}Ye=@T-p)vc zS*#)NLV<*ieQkB6l63Gl{D(`RFd;DCKE3zV&+ejj`;aHQw>XaVhg37l~-Ndz^oS`~Nh$aoo#T^i5*{seo-8I4CN?BBnirvtn2%UgQoRIIX~HNo9o z%qOR@Y@JJqg0^t+Ck8X=Ao{}mD6!)uY86iZT1kI6+z()q8VpJIl74ZNf zBRo}(vx9hC7eTfD5})WQ$VrmBW@-xCl}VZ-XhN9TFLF7c_x6qiNpla64Uyc6^a4Wm z5+3a4riy3dG@HBQ;bNO%roA(fKf>?62~SdCr*-tFuXYcdZ8XnPcw>m$wHNgRf8#XV zB>#$Tna8>1vXgvxr2F^^o*T7B7Vv!b7>ptLvRLlMiFJO7xye~oh2&o@<=+=*O6;df z^2_Sne?+oxUmJ6)p%r52E=(DvNTlDz_$|q2)iIzl@XLazLcBv_3t8`VH1Xs`RT%== zWZdWw*{a936Qk3u8798`j>vsg1*6bPgH+PnJoL}$n^*ACDdHi7SQeNTS@7Hn%>mnm zE_C+LF<~8?H;OtkocH5Z0J#RTS`m^W@*#!|XQ7&M1-*L3uR%x+yE@p}*go5z^IlyU z6fF^h_FA>>G(8|6-ohDu`26$U!NFiyU_dB~Jwr|!7#w7{Zv$TqbS8N<^|l{4g!=AT zNv1yl1nTSS*CDIl5b1y^+*k{b8Q@!J*B^2l+rAmXBq45pJTkDYdPuQTwbF>E1ws#D zK+PG2eY3u{Rti2XARptTrc^v5L;B#sQ=gIyN=}H1I^kr(TXY?V>yjmGk?-$pVPAe4 zb>8jQP%J&aURs-_i#5i(gmxI=sQ`ldTzD*;HJ&HKtMl%2ZLLy7$VIp;uYx7JjB!g$ zcHwDygyPH<4L4IBn2}WN^be+)?#LE`wirIN-5JGS590$EC58CLSQW)xEpXQFg8LxF#sIPC&8G>X!v(NLD zhX-MR!(KUO9Gv*+TEXw3jn(^inzQFZQVUmNXd4%+mH1;jBEH|Ikuh-^txcb{!||_e zs#c`)b#eX4UjUp%l2#+m=19F-G*??nv8}!lUne1G{gj5N2NZVW=^cYlq`IaQWD%C9 znB9AtEfZMmU{bh_V0kxEgq^I!hV|y`R|DQ)ed}RFPaQdY_{=ZbqvZrOX}u2Io`~C7 z0EF8F95Pw~HJ!eD29|`_yC}m5fr(h$PgWF~>l@KAG2(L!xr&mKZczras(3i5K_0<> z=j%dnW}@QjXZHD(=^TMA7sq*3TeYPP0-jXxDAiaMHf6CcI#>m?;=!AZ4$$&08-j-I z+`Vo-QgG5CQ~X4N^mEQErswLCqsBO_Z8>Q)kbfoq%`U zCpB8F!6>V$C*af(0n0o1dinV)phnpL(#9XF)Z+@SZCaL3=x}gwfZ58FH`s9+%ZErT zK+O%Qkr}>uoels}!g`=120$AKU*Ds}94J&d&^tX!5eWN**12L3xh@I8I_$PrUMeF*z&K{yvtJgR1v*NkiRh4_> zLC80O`O8(uve)t#1Sa?3ZhzW+$z+>GA+jXE=ikr_&aojqoytoYgS7L_aT&njz3cMe z#jf53^63ARPiXiiLzll`3^dNDz3{;KrKdyOkKhv=dTWzrPCjqN9Giu$C*Dp(06!j_ z`q~S=Ig+IsY!_3;CC{UR3q!&Btpd1T=}`}Z&iXTwmq0@56BtUs-q0fJ=clGl7uqyfg|V)wWd}>ao4DX!~Z2uWXaqNe=4%^f;k_9}Gn-SI>G(er~Q9eTZH-9wvh3 zIuE|O+RmCaA*9+}dzvWH0`us7>Fcgj9Ajh7RGKxZ(|ac-sJ5U7vcXz)E$xT7vnV@U#npQf*)hu)p^cTyP2PiFOMFZ&)7;y*6 zf2D)#Ohs=47(D%WP#dWJBMf1bcB;86js9m<&9U%CmkM%vtb+??v52dwpdiGvp#W`> zqifW){nY-~{_e>`(%*F^o_Q`Orwwd2-LR}f+Wf#{`=sLiqI#jlcWd^Dh&k;8aRNth zt=|RS*ga=YDc9(vkss#x^gSB1v@A4=WmNiZYXXlhr*3EXB?m_`n^WeVBZKj8T7Ouc zWO{%DBkG=IV%R%~0>^{Rku}Kw0_}t#6?2uC*jJZ#?`U1P20wF?UwK~+zr*k4Wt8Ss zm!Z40C7y&Ng%JqL|E`7LZq0YaB~Dbpa`amRnOa-Hiegl}G->1W$y4w841In5J6^M= zI_2E0h>Kw0-k2Z|iSGN9Yg)U*b(*{`vY$~>Q)B*13Mchs#{Lox(A?Koj_u2ndJ;O$ zY}Vpq8uAsoKTs2zZP_dVzMe;%Pvnm^d>_{C4-t`YKynI-KEGE+;7ayi+oAeHYDBS> z_8bI$O!F0|Jn@uh(J3OShbDl3y7|(UVM24hl9ng)qGl<1HI4raNbnBC4u~@N3pDG( zMHm_$e*9%Sy<(=yS@Q!>-=CPd12w@KhbpUdd)p}U7nDM_4_DtsRru(pspv^3Hkh8A zo6uy13hW0jgdsyiF{v&W&>h%v8S)AX_kz?0zm-Q-1+*cgPOg%s)*z$T^GeUjgb=l& zqN>^lYU7F-X7Nd&C^xt5@HW4IYeS~^tb^jCc;2ZeDG>w>-|_p(D;aVZ3jMms635ba z{1z}?GrAA+iH8yfVcSc3vDYCim)o#w?*QLqK?+?*3TfB*BNR%J~TSQVAaEQ znYet)qS!X+d%TbfELW8ZfzXLjmn)jVTAQWD$}E30LkA#cI!A4bzSvKp?6xF4e^8sz zj~7jLq+O{uJV$;d=E|7nXy{?NmxHUS;_)c?|{!h6qzmH{a^O zZVmdQkI1`9~ z!l^GO03WdZ(wY=B=Re&G6rdkZHt$^Sq?&_Y-7@)%35Gn7iH z6sP7`n_n`PxuA_F*p^&Yp6B=ayRZq9PEwjiL_`Q&YL@YMq)zTr8Ra?=75M@ZA?Ca6 zg1~Y>0gfB*r=nt9RA^rmTV@!v!h?*Ey|g|VBO@b}KQQHRgETMUm@u4HD%g9%hy&iz zwT||zmfgGAgJ(=xm}8erZbtBkO#c{EzWc}2q_7V)8}q2gX5xq_gM@}wV9)lW-8a}G zcm0U^EuHGju-kCgu3g`{c31va3lQ>k%o(;=dvd1dDWOWkoQ@vVoaTn`wW`9Jzd8mKqAQ<%{&~S7V+^R?Jd~(=fA#|XJ%Hr1`lPR6%f~@KC?Z}&QWB0ez z8HR}1GfObFCTP+eBdV!zBOvL@O#J++y>Z4PQI+wJhX2}euPsH>xbM{ES*A5ndo-eB z*cg%6QF2)G_IU_c!0n<`1n~%(@@BCW)+I34GZ3PwaMwACAgJd6gJgr*5tO{x73@g1 z=pLg)CIDvY*FYAf4m=Ij?Ri`%fpVf2MJ&xzxhm*{l$yJcZ-x}MOd}_S?}68$CujrUC1^^5D=WuPX5YUcT?+e1wvN;ayJcwSQ|8^`c?(Rxy^}{ zGLDstjh@K*4g3c4Eo-XyRpUOnD>qCM0;pRcx!(^D9=r`BoLK+fWJUliy!r1ztOQU6 ziUjO1&$jLHKMHMtlE7WQxx4N))5#Bo`rd|i@jM6OXj&eb|Q84 zC+=;jRbO8%Tqyl?^O3;mfx!WYFh+i-PkcOEu`=ylpB`tYOgbMAIJP0Ccr|%9Zo{{{ z-tR4+gz&YSoZrjDm5fXv1K|$m<7V+Sq#4q z4J|-`aP{idiVuJ}s@)_I=4Mb!ttvPzo?=-9-2ke!9H(aN^GAn{Di3v}MB&})0v_O= zK(Wxk$OUauPq;Oj#^orG{~N>xEyL)0@-xuwmH2#dz;M!HsXJ67;6EZM9~Jj!l#xas zQZnm=#ye3dxry5_IyPC(=trpwnsEUQALI9Q1#mm$ZqIuNQ8JMV3!JXWFhYhEhp|W) z#mXhC6Fh#$0+cygqCXZDWzkY-ug`pH?^E7dv9b5U#zwxc+zEG@1*eCPOY#M*T>bYK z{B2LsVaCqNs>zo#VIR9Vy}Y@NV&FEheJ40qa*(s}+;7Gu(=2${h`1mQj)sVr@&0~( zRs$9LV06VYMHsqE2W%RU_o07+rQ5Ifp%wm}5W=acjlr>BD;lz>t)Kw$LL)jw)nug- z4*0aX(JKw#u4A?+qKvCa(*(JXS}q8B2MADsMPHd>AOg&Rqd{m3c$b>G6KMv2MuTRDCP{PFSLSAkza6;@5npVZHfHT8{kLM2>Il!E#%VJNY=+B+kkM{Mv zE;9b(tE!JiO)b9k0`vm8w5xus2bNkkRt+1QdKVW0SJ%&l$kWLPS!-*EM7K~S9?B_L z%T`}YP^{agz7gYVw=w0JSn?Tk{-EE=m`_}U`TrExj~xMEMagTcx6zq zT>Q(R_Cdw0Eax9ePD9Y~Hy9leV@LI0*S~t430_(sJxMZOs3F;ARQY>4tjg$COyIIV zPAIMK!)o6kcQU$K_~u)EZ&>hy3!o|H-_wi7<2Sc^zW&Bc+#p34g4SE5+xYZYj62r% zU;u5m1p*-Mj4!h`3hBHQ;dv@S3_?-hv|;0eIfSZ9hUFFdtWXu{=+A!OMhrY z{NMk-6My)M|8E)3#}XV&K5|vETmKi5x1hFHJpTQUllQhI2-><0dJ#-r3N={NPxPCY zT9m{!&sGguhv)fxRXKK-xVi~{7Ru#U+E=0#7NRq{DHLpG4_BWeb~Ozitd7SL+xP5L z77wYC82(>=O`*_VJied*`p2VjQv;m-*QxPqAB_kiH=yA($A!|=?`7```bnp4;>tY? z>2g(kseZJ75If#VFuflch}S7MvYwM>%3`-*wAtJmaN*M|2f=-|KP4Dz=DhQhgSrd+ zUKY=v3M$Bd&G39z!T&>dVYD}sYH=^|vR8jzR#2nm;Ea>c9bGFqR4#1CT6W|s8gdo-${#w)@tPk8?QmFYYC4}K1L zD#0K6NYA)4&my2M$oH&d$9?|KCp=0lk=Eo31rDlJPHcV}a!?8^pWorOea7tI zfP8&D_owC_pQVhCjpX_VDXFlEYKtrv6ttFS-kqXyo%NLyHV7-NaGY}ot@>#<@wwx+ zCegRic|6+C?R1u>;{K@parE*kwe>Fd@!re;;;vwycueygms&Q2ww~W^Wa3FA>AH+& zO+}F<d8GU(>gai|}~dqW>7N5#gT{XZ(#n|NMVbVh~;qO(+pPT4tC7dno{-*jnQ2 z+~XoPZ=)pOPte_4fMQk__zYVv^xTjaw~SH}FFJpO5K!E z`4Ez{?-Rq70=JwAM&Mg|93&s%&KY5h#-2x@f+Ks(La0x|hgfX5Omb<6TlsN210llx zmfzw`o65J7Yw`3R-T zNBWL>AN_y+@-lHDJ}Qp5q}9N|j$MzA_;C1vZTf$IKwQF{z38lbf0z-E*r$0;B5+Q< zEU+ZdJZAY%z#W^b5$?vl9hKGAlj;`7Sr{dlC}|IOGe_uuEzRz>BYsPtcray4Lipe1 zu89cN$7-G#XY9%rBb~I#_h5-0d)_wHlB&68aOfCbO!jHZpI7^cd43z+*?o2+h^=jad1rezt`=fDDmFin|adz{YZZ#RpAM( z-~RnIWkLY;IKjg8-(UNkMXboUlQ|0iUJ~sW#EWRA{Qvy`vSNSUTP5e=zb~pn4?^}$ zG@>G9(?9o?lK3LuoWm=osQ&q~3Xh4m8FxFGul?fBeGJzi-bF*^AW3t}pNmgs_~!?7 z_`#`veqjIS2ix!is(;>cXRy6A3D^H*N*k z3-X$FT?Lp>`$V5xDU|=6t%T-ZpZq|)IU%eGDprJ->?}+|P6EcjsN`A3m)wMUou8BQ z0eW#oB_YJK2xv^59rDT;A|S5wP*YhoCYPep=h3 z`bYAJEF2wR;NNMLI;E*4gM*oaF=H+Zn>aOcWiZZ=AQVz4AFKa)(29@Sl2ZJp8AD|9 zziGD@%l9ovx)r(vS>5Z5H?!Z!TOV#_OL7ol!i&@wuD*SG6I>K9-7w;EJOaATchr0RMrg?lbC) zpZlDE!-7bfTU@kp%)fn@FwcH`(68mRW~F)ajFl}w2QM!#>FKy~j5lM%2ss4&g22Z| zhcV}a!-Fo<9H!{kuCC~T6Me-Y^I2H1rlug{p{?cwM=h+BZlPZ*a6Y*!ZXts8W%Ptc z>(t`}sL_CaFmh_(s)@kN2wzpz&2whG1>j^5vvL?2L~=$rih(HESXeYSD`M7vIOdf;@OW7{6)ksQOT1i|8Z*Dh}570|| z(_vcLi8&9W2^dO5-;589*ZJE|fQBQCtdPkAAwZn{O7+%G7RTHk{3FML?kpPibWsBX1ITLt zIYEe(lEIzWng`r*NdOKwX(D16p$r`4@UJj&*Hl&IO=fq&X_TD0iU$voySf=9+*bjc zDHEqHj^Zi>2I|wd;yo?+TwjN|1JUvJ-tXk(1U&>+WoYOzTH5YRCZ~wM z;|$&+BlnZjZTkGN7g%G#KZsbNubu%3ahTkY*gXK%Q$E7rx$uaWa*(?$!P2?0zF53% z^JYRADlA-t8vz%w`p5ebC0#H(K$=$a-JpClfP z_!1#TDhd7vUYXy94Ydm4@Q~Lbb^zJy%HscrJc`@sKk}%m%teCzgi{qdOE-6SOfv9d zkqvaD#zx9sIOkoaiyrU zr2-BRgD_!21EF!-Rs!*t_!PjUVPD7nz$1|jBNt3hh^GAbk&pjT2?w^YZ-axa5JW89 z$@RuwmnKpGw-`$_@ZZy7zH)-DWzgyPREf~wB7uV5O->FrZrwPwunlQU*y6zHZrsl^ zAp15(oZ`Qau#gnxldQKX6cSdc*+7s1?JpGSdLQ=hjwd2SF#c-=a$a9Kg15)!MO(f; zD&vGOhgPR|LiW~p(oPRG<3XH)bSGZ_03u?hFh58^mqhiMm`KK87RvYFBsX_+U!MqK zzO|N-nhyya{SH8<0S=RrN~Mq%;rYP96J9b7{Z`$05-C>qi%wb#WS6Y0QWOSIx#5ah z@kN3Rhq9@PE?J2fPq2;r@NvT^)1Ew@6DL0NpUJcVMh5d_F@j*ylhKCEmI18Q#w?5_ z0mMo`6cYw%Tgh7pNO3*iA^Ktc%rF3Q!W4G&@t7A8Z0GQ<p}w(4S09~fn(MDhSCP-&UO8I9Ig2nJW(xVRKlUBW(*n{5C1gKTI71!-UaRo zd=M%g%h2vlXwIO^frNu4dJ3T~I2?fs0uh8uYJ?N_SQx_?Zy(O9Vg~~&{guNFh`19t zVexpF;)G9~D&cU$xeuq_jUNoQs=26&Fyw&ob{`aQ*k&=NfK6gT%oK9dYK(qGgh}^P zH~_2PLbZrDl4!u9-??Hz1xfZOf(1-?y9iNIHQ2u0C5I7_BhB4sH=c}#4o5%GX_7KK z1zi95E+Ao3keUtS(qPN~qqL~WPDLjlCjR)5q=AeREBinc!SYs%8<}F6k3!5(zLtV4 zP85Y6k!0kXuATn%GZqV@RFJ~byaqw@;@=QHR0y4TUF&9^JuIZw!^DH+j>{=#y^Pro z_s+MPkIs$3XztYSeqPTd6LY5E;hV?&zt(9!M5gL`3NcVxAYCr^IZu{RtKAP5#&ysR zNH0a+5FzitG7V}Ky?PbeO)2p-%)&YbYvaaJ*v3t9BAg%QSpOH3Tk#}B_|Yyvt8gA1 zl{w?W&cs$`GdEAqfZKV;*#rbS`9CxxY!#z#N~A<1g0y0Ymja>@EJ4Wh25CQ~h0n(lW7VjR>rRpG9UyCi~P zeTeU;%j1&W=v zb1{0H*c?w}G&qm63gQGuqX)6e-;BX}&v<9@xjziPn{f5Wi4R*2-4P*WYuI@ZQ5*wS!LS9+%Bf{|kb zLM#H>(^2o+hf&IN1#q*m-Gj1jVTFR69AlB6lw_*fqr~9aZH>L87-NSgwINh_d+x3r z*aj4m^z1a8I?t~>i3$q~o7g~jp!4k!i!f+`>Lz^UsMraGyj>Nc2ikaiVvF-E)AC7d zxER#wTu(;3mztnn=3UQO46E8j_s#TUSLZR$K z`YWythfKH~LJVhp5|Nsfv^r^mb)h`gV8aqwk+L;0M&AaaLlTPUix(d^vuq3^WeW9> zjHINc-IlnM&@{|mf~q-jfbkIS8m>5(eI{BWyZkBneNZv%-HSGe#Wfy}ix2`0;h*!Xg=Y99X{^gOfy3P@5o)j0a z`R7Jtb0Huk(nF-|YW^?`JBMJA3SlVrFb*cA+E)&{%weRMT)On+SRhKt;&)-(g&f_8 zb(?C~n_aCh9*>nSp6!M*ggf`q2dq)yzvKhn>CfHCLDx5BwEw2k+5i zY8`Om$XYvXli__PJ)cq`KRq9sxVk{@uXio@QG)_mP`;HxO0hhslsJzaT+m`j5)NW4 zG^?XZXbmPK>3d>NViJ-GFC7w8p%cPHnb<;qB5D|3(bKA+NfU0RBu*6>rKv=1M?R(n zp(){0+YmisE5*Qh+#$+1g#u|YHA~=DG0e2O7yb$G}U7hw-d7yKz`|3 z((PHf(i#|PaSNeT><@x50URw$`_=aWPgtM3^s>?@lusQ1GHhCPp(Z^b7GKFWPAr;D|;TbR1&1{MhiIr&DWUry5wfY3Pc|mSWIk0S~gi{&}IV^6h=2 zn`M1;n+vJ*G;^VkLv#wpZH(KA0)klTWoKe~(DCeVCKU_e(<>^3(iBIG`QcyCyo~O= z^k@ou)35pYEINiAgm86rGBt6#m7rQr^+^aT9m}qa4xOO1pr9)RjVMM=gfk(GxxG{; z4Vy{Zkphecf#_L09#Y((+97dan&r;1HN=e*&{&Q?(eTg-ci(0$$e+qXjjD=GOgZl$ zVl9tw+`0&^a;+SV`GtiJ-G%sWyai6MTgAUnUqJJihtgd-zknahnny7pJ)e=i*(sA` z0$TvgLC8W|!z?ykWr62siVbDO3wpB_!^*t7 z=(BO@>_X#_lw^hkiCedb4{znO?WmzEF*6KFcaX><+MPzgGS0Wc{ivW)n-U)O4)heB zwEUp0gCJD?IvVGsBrALTdKW5F)k9K-u6B-hasg)?Z|4vpyAen&M7Lrv1P-B8>goDd0{L zbY#ojsF5fC7Vl{Ui`#2nYeo6pG^d9_dqnFHVp{}QAhbp?M-lRLUIL%mC-!pHkGUju z{$@ff9miN^b-cZ?07N^A=ntclSS?Ip#m3|>Wg2gmdBbN&! zGL)P6i&=0ca|y24xF6=cOkLsv1f>V^A&Murkk5uW%Meih$ZSur9=bo2euRZS!?-hB z3=oz#9*(Gql)GK&Rj!YWDb5C`&DMNpNtvEHIbkejNhN`a$!8cDuZx=#&wJ~bJ3I?@ zdBm@zxp=JeH$43VY4z3B77wWrNCHs@zIWJYb1aSX2`h{AdqHa-fL0*z@TzwR0_sDG z0@<1;Rb!=shgJ*2N3-|awO&|CtSwr+oQraMAj!)2ZkAfKmL%ij%k>;tsntG*=WsGE ztYDnwU38QybECho#rrP?>JL6N7t1m2GUzkng=BgC$Sp`y(4o#=`GSlH+Vl)$=2TP) zBL&MKgOm#)&QVSM=nI;SAm9@Yoa?E++;>#fNS2Buc72yAVi#uROVNs={7Fs~)6jSq z<+xve?8PRQC6kW&-sD@Gc*qo}0By=%fdrozYAq&BNHo{D^R#%4aqVXFuOc0sDEF6w zv|e<6#*i_(_+SZXX*OnNqI}2EqAyp2P7vEw_2o2fLrX(qEMbQUFN*(O_qpu++y@tD z(=}Q8WCX&jKLfyzEt(8GY+r5EmU|cfcWr!Gf}}Z{{#wblcyz+4(uOU|ezuYkBa!gT zd~74`}8WS|CvOqey5lz9MVp_Yv6lRgJ~V&5Y;lB@7$z`Y)* z+|s!;5jKW>n+6d-pGkn5q!@g(qHiOpi|Y{&3yU!#Ly#mbFHQ&nF}hvg36xoWrUVmjDkS;=+57J2Y2APWSmP4i0eAN zfhIZRexTeKT9MJl$d_xmg1#A}9x3L3%{!=IDi<l!9uISV#V3z6-E0)C@Ie*0uWJD}RZuspZOCU(^xD&9P0z3)+76oVx$b`Aa?5TM) z_=GaNa(V~ROrRedWHfoH${!@Tl#4@UzBmk#)pNvJ?kkPjek1i$7V1-M&=QU;<30I{ z$exK#`X;Ww={)r{>-(}ttEZ~ycPS79c69blinr3&b;U{snq%J*Fd+iGv4hSRTnpF0 z{y>C+IqD;N1pgp(0)Dn7fDC77;KD+lyky{=`0)?4hq9Y9#OH$^0IUcQ%YrfujWP=R zU$e82f2F!%&Oq***!CSeY`?#tI(;5wUSv|taxn%|dEYPm{lhhHNBml*25ha^E!2u| zW@O(!JQ$*(N(zd)mhP{CbAHZZgxGQ4b+e4Z3x_&}a7Sij$dJ9jZS5ycqG}x`b!!VG zPXWKhnvlPB>l;q_sDlsiJk|Am>BLyHv)a(z)mB$mBiT|}&=I(_c^T1!2*nV?BwSqn zlY-k@g!VXKZQP%OAZ%Jbp8G1|*2L})v zU~b%Mq#X)-G|1?C&=13wa8~936&0Kl=T~eNF{7O8Qec`~*_rebKZVrveC;`mt~Ti_ zT0=)$EcbhA0y%8Ie}!$FE#^g0-o@dDr?(iM1@8<-1_mXL7kl4Go<`w^4x^4r7Xfb= zu0;%twDOB{d`Ii;3o+G8)o4s=#oN(g(&p;T_EKVC7vxm!x0#|5fXHL(%mX1kF&G@T z8W}rsQbXNwC*T!qN<$!?^hU7%-%P&EQo6__(T^(8zF#+CU-pj*O-xfAX!@1$Saf~@ zHF>)!D0&eb$wuzGEPVGsF&6#n#8v22LveTxM-zXQhbIdgWjZEaPgc3U1N7zj)c|eEhc}{ z?Z{=wvq8L}*9Drq<7v1_C5~j_dEA<#+JRsaFQaBfn+CbwdHpJ1EXz(u&a+Y*d~8Bz z0EQOg7>90dL@Y@MU2eL6Z87>N1RTMg%<$O#nGmTr;e;JJ=7=!W9=gK{v;IMl6vU0#QKO7`eKO zoZK?BYuy#UiB{JqAYl0W_kD*CcL2G2`8#P7+5`dMdn6NR#t^l0DOdR{G@j6eRt;cN zCJ^AIH9@%SU<*Ka&4P%52IkDq;7rBYg*Yl;67S!?Ps!81ing9C?ubg%0WzakQ00bI zGxLR@QW>QjVNL~#PrMoWTehl|pIp%`G#FO{|3+Y~!CG(=w9)nEHbmqj^Y}Bdd=&*P ztGitG^r)uL=;VEIRVFZRU*9NSJB;O}jrp>MCorJn9$>&y>o_;(0L?`SO54C@gX&OKH)$J529DiL?s9aEwl;a$I#tcCo~ zQQooW$rA9W{S_{GFPd4*uK`HCI5#)Z6zyuka?u_e28N1Uz z%Dwq%vOO1me!`KC=X}ZzX@qPne*xs>Z`s+i{UGT(bA^$OoOKTP#AYT#jpT`xO<17H zGa<;?qF?%f=%xoMHgfD2!o0k`&k2LaR$#(G0vW*zb8vEZik;Wcg0fUhpu50dHqBB) z7k0>;WahNe1@woQ6p)@$izS5eQNQOsb_&E8@jc&;6_u4<+ z3s`d}EP9VBHGr?Z*c$1BbUEgrb9YY~3OKDhATh$vj~LquP_kkH4XY86NMgU-eIOZh4q+O2t& zNLF(3EfS~+62Z*D+-q6D9|#Md8RLZus{{Iq9EsqJ$te4`ap5{=f+1vP7GJ(`<0UZq zS?t6k&2;|+C(fl?!uP8S4oRFTxV8;ME{cjhw0sR+UG}hz{~OsD4^VOwp*wY)&!T)X~;y@ajfOx|#k{oO5v=YJcI|!(*!MZ#k`QaSJT8A%&rm ztAsk_u^7z791V+>MCCMLPnmf6Pim+5a{18UAgOo`sBw=~pw^#2g!6Iuu#L#YFOpdT45Ux{^8n8A1 zQ3K4D5D2WVuP^qb_d040kIp2f=z1ek7{TA;ORH z5O&bsexBpQ>eDQMsHola3=O+Xc>hdEK?^o^F2UrJ{+@h0=xsjJ6?W_)I4dnW zComN)*0hVJ!^y`wEhim84Y9Fb2bsFc7|svgOLaD%>uI0p!d?V@HinY%9VOH{ z3DnR&J|6oXbC47r9qWE<c+p1AqVdwQK%wImho#nl@$;$0YuUV>yN^uKw)q-2 zw@F!0IqV;x>j-zOkoOePJQcj7W_cu}(yUl`C3$hBH?U*8_ZWob|t=WvS>wxE#t>i~|CT8LcZc6{{6cVgxZ9|DB5e=hh1_`og8Xlw52YRdh5WX1{ zq^6)S(BH4C{bbiFu>~O_?>mrNPoV{sEj*zqqv)pyA7!N;v5Vu80#k(A#0h5-)=MT@ zX+MzxoEL@gC*zu|!8<;eu&*w~ZbR8SIC!O;#tZ{)uQBle^Tkjvt;Nm-b9iwPC@!Oe9#dz)iaiu3D#t&*2el)UFS z`+n2TsgLQW-~ZS&rNj`l;yox@+`?6DE+H>p+0v43&Lm;65;Wxh`t=#+_aDDKO-kQ! zW`*N#ZVRW>?`d7Ap|hajR5!m(-b0ZK!|y6wy#yE67JlBIPCHe;W6PJ= zqTOE~1ZO{T`du3FdiiY0oA#Idg8ar=2|ZJ#eM?*>VvmCDo@m;=eS5h0{JpAo*D{KG zG8dXvEwV(~+xoH{XUo2hsb^16hWp^s1@QXSunyJkxQeCMK{+ zMr9rOHj0RkVrclwJ7Bgj*0j+qa#%tx;y#zFgj+Vcbu^;@#FUz8;{KyYAHnmFCWraU z%trc#xL9-(3Jl}+V=^B}2tYWhZ;dckc*9M53;5}(v9t5QHFg?yi6eJ;Ac+ckNza5$ zJhk=npib>ZN;^uk9_MJoD0zdghvm-<46}tc8_DHApv{>ZXFsA#=Uf*voA-H5D~BUT zW3j)JCgm z)V!;40Jit?w}pj5wfnr@yt(*Nd-TG7nfD6J@Y*U+MSp&l=#ds`wjpEw{mYiB33&4F zgKWf(EEMtG3AGg$oaw0fL1Q?Iw3s1zPbNeiTawXcg7a(8R$28@};|Q!T1@TkN24pL@DBV*|>Je_Cx9sp#8a|B(iOO3falv2LT-2)nk#G9{KU3 z>BH?S$=NarvaYls|ypUKYYNo4C(OXJ9oaHk2KbRzCcIkq;3+d z9GPah8jb+K%Zb9TweXvE5?+h0yoZ~iIMKoWS50INVYlk zLe4A5dp7Q;*OMm=MWKZf&%_TkMHfa#(X$-f$t}-q_;st2Qz}{biBl}xCpbfOYh=$@ znodkjj6}6wl^1)EcJa(X>g`gJZcDKPv$Ljx*&O9h?dKkt-|wF7@_#$dDOM?VOp3YK zHKlGvDb`(qSwdXuO_iRgvna&^#e%h8_c>}M z&Bkz+d`&2>{v`aYSY`fN&HUSHWwsUT*=YA@xzWkjc6pw?VLc6lVfMOvY-Dy>RPPs? z$#oqrC#O?CWwCLSbhOr*ipo)tW&KHLz4bQP{yXAVafRoPQXyoXfdNP55oM$zB#S;{ zym{szDtch|mX)Sp6P6`i_q#lg8OUx3GVl%Ezw<>*Ow4LIz<(T>(Q-_Cw*yK|OdMk0 z=g|+h{Tcfod>&6fpqDV7C>~ow+`IgTR&d<76{!3$y&yfE3!b-mf5i#y2-)s@8-jQ} zz88Vh%6V7w1#Gu4&!7+sv^E1`$;iXww@hRxQM+h?46?P&y?7jT7CQ@zD;U8Wr*XP8 zvr+n1>H)1%=rGFC6?1o>|>V19CZD#Mda=%w{-hJM5Y_c;iC-}Iivl> zX~9m5Qn!Q8w#xD6US99dmfEF!R-vzJ&Lv`Fv3El?t|!h{JX+hCb$up)t|fSWTIkl& zQ_9ZxL&d{;gl(OsKNlvPxOs|^Ej0hR(^y?${`q@}TVHz|=K4a4|LotVu&=lA=c&## zO{?CVps&_*rHwNYx~*N7^W%9A-(Q#Srun6wqES36J@UL}LUP{Vwzh-NMD6$0WKFA1 zjbf`c9k;QznPev!iS|#qpWi&WvOwFBv6K^5Aox&zKjXQF7bwG%vkYX^R9}mqF7x;I zi;b&KK2(dvkOA2P(SnAA6yh|2(^A#}dXGF$k@fZ(Z#FhI08pLrfdU@=I8SC^1Jg6y zFs@hvG=!5YDLFY>E*?=*8X6jCvw#lE{;rP-!-YO*wHtA-C=fP1`G&I%>=nFc=oE8*JJ|l6Mc%jVl|9z+N1)4XFX+&{4H`Iss$EIUg>e z8ogrZhUqmnp!mm9kxaCXq!73Z6I#XG1c+1@;PMf4@bd$#L*WUK=o~daw1wMW@3V!R z1+!ncoUZi%GXcH?RSKYBE(`}lKkaqH7wk)_me9O1P(92l(O!!~_m2kzBA?Ma_#eQ9 z_&DrE?qD;}JK!k!%?juT%s!J-<^ZZ$P$jc0x%c*yJ@)wadIuSq-N3avVoCi_bmid^ zEbk~;yT6t!_Io)`L<>gnGr~^Zc)|%=;h|S13GSLA{zpH2D267+j8K%Dn20K#g%{Ctf26x&$Y4osf}Mw=NK}t zba~u!@9Ck=EOI}*1aj)^AQJ+@7!p7P~B+h=mF@JG8;=v ze|Jn3-@DfHNcR)XnERd$t5>~orYxz{#hRriHnQg-8@&0ne`rY5^|U2MFw{?A?486O zAk-K=2sfD8HAYq_Cre-L%REoaPx$?yb&Qa1g2hV6$xKU&5a1$$C9dp2kooDo+re@j z+`IRpYA_(lurN9ydlY@h`Br9gayXiA`-@>WmzA}3jJE)FDOQoXk!M@j7Natu zBR;fP033d~$3F%TO-SonI^f6_Hx`?MFTkA@TrM{+Z;WH4Ol&BrQ5Ypz?FK=&B1fIL z)JSm2gc9f4xX)i?pAP&5@wwITNF=KiGfe>oLLTpdi!L zS36jWRVt}`8y|NIZL?N(JA723K07owkQDs4bAw=Sp1u4dkyhKju}qh|gIOl?atUG= zayJfIbv`BSifa}vTH%ehcM4f|{ZguH@6lHrYOUAqwd*Te*1cXe#V6_au8CcXRgA@v zb-{7$V?uVCMEG*Ut;>{N^xi*OGW8rIUqnY|`T0fs44c`^C=<3lgxlT2_Ey+uHSOm? zPe@bYDG~fVr8=BaCN|*x0hn`^<0Mhm(jua!feV5#=PXBGj}y-)Zy1kwrvEsAPa;(s zU?>m=B#g=Zw1hA5#pT;NI!z#6#6uuK`rY0O9<6L=YY;aG2q3l0OiW8Cn&V2RQFs75 z0lC@yFALr~~a0 z&tV5cX6_gxqDc}6tIkE49b=(Xxf)4w@!cP7|8BLN?9Iz@2~O~??&uildEg_Md9(Jc z<`Bz*U`Ve;g9`uaSmlwT)4PqXGIMI;E7ZcR_mBQWz0?kYetn06E6tYps| z+`hS!h5tV7A~1-XyyxKjSBracITNr5j@O_dlvpIIi>a1q(5O z;_;@Ur%yKpJ(0jeBgRjZR zeku^6&2Tnm_JFU93Cz{y62N z$Fk@(rZplyF}U9)LBOQE<;a+omb0^HGvf=c@^rc(J>iNoXKG>%T!+~>d3e4DlR7&b zGAt)oJ%?;e`ds>c7hhQ^mpmpG*kj)xl9U)J!o!fE|;Q{;Me`V zE@4$g8 zEO}Lfv*6Z1IX9BEGDscs^oSM6g02w?z)m7`44_dnpX%!p$X5`{iNH09zm+L>zPNhQ z#lu4@%ZO56(eg-rRn_}BNQi^iUqkTC6!g&JP*&WKBRKWDuf`$lY8kdXuzjfvQ_HK8kIF?}L zmawCLph#G9&Y- zulS3nP?nTjRX@q&(Ai+BqZVR?sz%F??0y~}{!7uB(~$92cGJ&MnY)wb{sE44&y*xoc!ZimCY>7f{ECN=*|C`J_`c+;K+1hhi{ zhU)apQo>VrcNiMr6nLnoH-OrOY4^ZP**z30@_iUceTO!&xOf9mHP>kFPIiKff*KQP zn@16>B}zkubEYumr){9O zzL`LIH=RZCHzXY>NZxE zJdapxcxr#uT?w7+T8x`w6$#J|yePZ__M3^+}?XUG-vG(8c3~W8uc>9|6Zd zA`JsLtAfPM#c5(|r&dg0J%9c@rm^CHSF7is))$iyZTKWkHYS=W&WC_sZTvxwW;k)(k@)^PxGK-(o$w9qORVqY++S`@TNNeD@+XH8pEq zex12oSsoPwsiNW)FJydjlJQy+aYaQhF?P$*QMh>Fp0)J?giZ-rW{R@v*XH3ky+ine z$?Qtg;;(ERxx^km;i3IkTgMHHh`(E<0xqWrxA}z`O~yNtKJ=7D-(Kq5cer)%rlx4W zv-^IZV|~f-dx{@51t%yOs2m)c>Kt(AOi(;nE_0N|_VjDIB4!`IwYgvY^xE6zk0vRs zT0F!Fw;`A*leK9gO(a9u?%TwO!n(~l)iNL}yEpn*J*gJPIwhD_3_WbGM4ag1?`n0@ z@E>VzWSp&7+D6)Qug693(Rz)II&Z@Qdx?MMz1|r6fT>m!`4{Qtwpve&&W7f`$bGCR zH+gLf`@%+wZ_)#Z2_{#B^hb_-Vj-eUd|Mj0(i1ioCnvCF(;hm6&DjE4MsQqDvp2A1 zqG?7rXybYV?N_MC+?*XCWQXiE4F(IHw2sf8ze8WFQjC1qg~_FB(iqBw=2dLVJ-K*G zjDK`XL)nM;FfVG1gmOveO;ahj|NRS=4H7wdj9TtMkb=9s-?a=@koV`^U%d)9;_2is z&K8CGIkA`yhe>Y4LXx2-7jxT(9r3&N>D=RCshG(+DjJB}#wSB^h7-@JSqMBL0MI?)^ zI7F@K>`N$7eQzSj&K}hIn1ojYxy|a!Ry!GN=d>wramw3hT_lA>7C!UoVB!|^q5EB_ zo^@|9VV-5%=H197~bp29V|?nZp_G;?s>1M zO;w{hH}%$r$AkF{$DOh3@&|V=RZP9hG0!MtkQl+GSnSy?fj(B}E;PT9_6c*Vvrq*(Nk1{`UKFhWl8qz_en zgj-E}djQv0NEsWgUtEr8oCRQhaIEq84`g`n6oMciF-uv>frmb9>+IU0y?etQ3kTa5 zF{Ou#i|dC7krRE+`|23ylZy?Q<(+(fGudNCyDDup&@);)ne&Y)Usd*>)z)%QZ(3`sM)v*0r9Svpz`sO-{416J5QG`HKR9Y4s4^I*;8KdK7ki3z{whi5^$nA1Y$K z$DUEIL-0iWk@$4E(WpJWN9Y6=^h$RWJ!!Z&($(m>ktSfO@WR|$Cr30v?U<^*ZeTRm z-J4>KKB59NJ9lqeq*+~1KSj-VzQHbi>ww`Qjc&Rtftrb*hSm%>pU8M7aGAkp#!4M~ z85#;`Nu2iT?VA;b z2wN4TMH{+qtg7kH+ipeg=VhMl{BZl(@|#vv=FRDpmT@iKO)S*uRi0a;DUT%-(+RWp z(-Dd{sIH&4DO*`uwseT}O+dt-DY@AUqxDc(LZl*$DTzwTLglH0RfZm`o%s%=qZnQr zbEyjC+ng8^+d-GB4o~zbM_N99{P@#-$+20b`l)v8Q|Uut$BZm7&9m~KIeIXIh6{(# zk&#`X{D(uBT(OU;Q$b;VNT$O9Z@SH9-qV32Gls4xe+gY&8{A8X8cY z#xtED8oF>qVXY(OK}q=|`vqOM$&QtAOs zl|-G?k|KX9c}6v%L4IOyizZM1Ljdei15slIW>%e`oMb}Ig&g|)_MFB4MctRjW7&4m z3L#UHnItJfW+gKrBpx!)88Spsp=6e%44Eo4P{>e(sDwxv6NOC4oHCTLP;u7X`+nzq zzs@=TpVJ@T_a@Kt+|PYq*S_{%d#$zK)nX`pyoJSb;j`eIm4o}`dE<88+L^ucc#Lsp zytGQ%CZ8{}Q*%IE&TagfQD3%aF|YlC@TZEt{FTwEr!)~pC07N09AUgET4hYKvGh+p zb@0IW)mVk^m_{%foXm7HV0otVPNZhpn?02uCohB+k?t8=J~lBneuR0BDO0n>Z{Q9M ztIE5@vdYifRZY&|JV1HHQ{Ol?2Sp`1d{a=V+_}KjoVT+4d-Eh=rNpx@VJ%*KP9Ei_ zg++>b#uN0b(PB|oS9evgTh`p+$RB_4y?Q4HgXQnvq=%iLT%wr#*7w*zIJwEG7~0@> z={E7&8rwZf52P7wu*I1Vo+=tNxyD{#UgP|iSIS>~Dl@~$xx@Px`Ln$B@#^X@+g6W* zbOgNigK8ha?Aaxj$==)7r{Ys&8T28)sL0#bcMrqJ*v~`T7f0?*+?B&b;?Sd2X&_S< zImVgE6U9qh+{WossHU$Y7aUBnCni3BmhErx?NZ|N(rdWx`TRul>o*HuI}Ly5u2Z9+ zkf(O79FC$SuNiKwQarV)7nOOYXCkZFRNQl@XZU@;RYz6Esan5!z3lq-oe`_cT{W2< znYYW?etsf{8e~k%T3`={pW5Ncu#o`*`k#dAircA{gmmH($TJ}fytit;_*2S zrA4*%$Mhl(;BzK_+uidy8h2sqtn08L0Z*iL{j4lnn^}9YUH`&?8y@Xh$@kI(V>+{3 zzolgz`*P+}pp1&sFeyTP^;373Qa|wJ)Y*gPa#1(K$io>JVs7WbL zNpJ6{#eov*_(|`)XC$<9>coL+N`}NObaiJY!%N-FBR;}%Z@HWxes;R zVSml}dbj%z3|oGqil2hIBEZa*=efD4a?me1pUZWtoQ_xs&*D$Uc=NRasrFT9x!O7oPdR z*Zzg*s|HZLcGw-DZZ%kTId)6|SQ!M8?E%E#x{3W!V9Z>=oGh|dTEfeSMECj5ls+Gm z=*{Q9np>~Bd#nv7idWebsk!oH?qNOr)J^~OOZMTERK=<_bloauy0X*)soUcMj_&pD zP#B_qGjmYK+{)s2>G;yj-UB(`T3&pZyT;JBY%x70e3kUDq-6Y>g@l9z`fD6Yt5P1b z%Ln5Z@(OM~a}T^&6jJZRx_=E?`|Wor<^nzE$)Ddn z7n%1lfT4;>4n_kz*)BuNb@kS*Hzy1WUk^`KU~XSG{3;jO%bz@P6+iF{8W*66U;DR; zA9p8vrGth6=Ftq;J2FCoFy&xLpR0(pz5@ zmFM@^66h$yz;IhV&@_@W0I>C5{EE_<8P&i7rMhkqp)pQ(r~hjg-;WrXc2hDIadYrl_s-89!_q@zhF|T+uIvr#sr{~o&Hc_Imif7&fMJG@XGK? zn;rRtUqnK?5r%<4B8(j8n4_O?&$;Y9JoPP03*p#~JRN>BE3Dj0xow*hn8{c2>r%J$ zow5#OVAulZjZUx1Fx*_Iu*XM70T8F9q+oXG`M9fjS8>KBCOSGf39wzZv9`|fJbt{u zSQrYsLeSEZ3s*6u{RVnZp{n-iP@-Mpe2h6tKv1wAgEmFk%uY>&yYw3b1Sqa|$1HkA z#?I6cBQ#7=LgwVaPq6{H90skgXnG|>XL1}9H&RkK>%9vK3IYt2_eN>(C+p&?lrGNy zy4BLy2%$I9eHl<-F$Q>|!5Vj%nQ$BNr+r*wkl^!e-EOI7j`mmlCFv)Q*AIM^G&dP% z_L*|neogE2X}bc;;;;3kTo$)t?Vonvd$CB1>`j%OaAojRb9A$DiK^v6P(Y08od zU}NO+KD60uQrY)~ViWHn#nXNrLdE$ztqbuQveWCpz6!bZ!gJbF9AC z-e{;D=Xxq*`J=WMmDtR#Te0a41uI^aFy^xumOrC%EL&}kF=YKsqdMd7< zvQD47WmnR`gH<(0&z{sU{%0-`lY|#jh#29{(02FdIR7e;IF?|)Iizp#>=%);?*X9&Fpq5c6Fi{TWO=H|wMqNvr-n*i)a2zj6m^RHqC z!T^%{o0gU>DnS8Y;y&WWcZ>a>-))o7vv6H}*il?YVaPugh^R#?_S6|c4ZDiI0|WuK zjqU2f{IL+rmW-$;YtiYZp)DpqIJ%6)zQ#4SidOG>&^#wihreXJE-W(0Es`)iRdCiDJ5It7_E8WfOOr|^fYST(p&efvBo`d)%%n#LNU(3 z@Ow1T0OCuLKr~T1X!f7pPDWNS*ZX7sGFdbinw($R5c`h0o<; zt*Qd{IZj~^)7;EV&KqxxyZQ`i(k9vn{HCRWX#qIM%gcG?K2;CDBHxXc1bG*eu66CO z(qzdAU!0B&#=h*QK3iHZO^+ViwXuEck+Ns<>!o|veZGjq2~dr{zkIznihZ0-NSlK5 z;WQDUzKuD`RY2B&KfYlML|@{Yuf&hY;r}*oP6SIYDTyV6)D2iw(9>+d05ltL{Nv*d zQL3XUT{yc7HVJr-LqDz}lYJ=v`&InSpq=<+J=Ab$_7`dH*mRgvF z7Ce<0sz?2x>L6GIp2J&WXp~Vd9vxzZ0arYLU#%9vMB@l6fktjyVUG$XMqgjwvvTFt zk#=B%=#cU=M`i2Zv@|k$!67Xv`L;V;Jp)wkp`W2|lC;wP5y}q_6Jvg`N^v&i--i8! z6tvIyi9f7Lf>##Y>dcXgLSukX<3ED-6AXObz1C=&NcoH{fhweq3aTAfjbX8wbt(&Z%L~^ z0We1$U*bc5|L@0tn^U^5)kTgSP1b33L4gZi+7iMY$lkTSo|H~R*dHy|9# z4Qm$X1-{8yv^?RcG&4K9jNbWYi`Ws+pS5cpp;b9yF@)5M>%i(Ob~|$`D=SM&z;}>= zfveZi&>*yD&(&LS$ymi(f+P%9I=rjjB4NPvC)|_yn^%A;gK~w{3$`+{6rA4}e+q%u z+w&nvEDjG9mn!d(E$1Jhs- z$^J|%?AV76+hJfL=?dtOk0DgJ{lIog8j+|&O#=51+?HeM{Rl9;Wu+TxIFNe~yXT_iwKst;L8AhVrp;hCm1PRc*D(3lf6(u?FTp+W06@7M<9SbJt?MF2al0y@*83)Ko`K_h@kzXbVwABXjceDB?A2QvL+U4r_WelO>tMr43T@UsR|SA z2r$4`O8DLZqk_y)(CF2}tOYD{MYnTDj%>T#^BXi}$jf-@`=MU}3)pzg2W-4N4QxW@ zwQN8^2m~VH;sZsF)Sgi>F~BO8W`=-jWb6h%FG*Vf-|k!%ox;o)*7fcc$d}r`<5n02 zegLEOCCB8z^I!;CJv^r1B&~l-QKtn%2|w3>+$~fxKR^G>dxWaq8y-fe2k*LELm!dV z9kY~%2O7YrhAJoe(xp2`UYvY-L%#+N!8lt`1|4cy(!Z;po~ZsRggi843+8wr!!xi&zw&C6M*y+|n0Lo}1-&^r#724{0!#K^sRA`d1aYLEB*Z*RkH%w~P7m z>#9o+twlrhv+mtP7c^Ds+2_xnv3uH*+#y2at(?Xpl#4~(bKhTG0|RM`?|u#I3&RozUGEi%`eZ$Yp3mZg~a!w}(K z4o8T?VD$a#U_xRdq*4aSQ2?`n5IRJsq@@|8NJY?6z~Mqj>N5HZ*V-hyK_G?4luR(GZ@}}&dcQ57EvCQNnaXORc36iSvK=_0DOJ7%dlsag z35ARm1#WKcRQa~%GiuDw-|Wv?TF`ZzMts$7VgNtPRZq+l%BLO}J&m2*_xlOx#<|AwXXl*iy3vlw zB|nbd&csbedwbR7(@0N%(B~Q(d8T485ms={vx~;UL?*=H2+>r=Li?LHv3a9-vbybS z2*?Pj?ae5=GCvA_{P>ZD@!dygSWe?Wo?xr%2Ji+WaV#EiV9uW17dQj!>!9CEG19|! z1w#Mf0xW?}-cCns$(Xhh)Q1aNSebX)5A;1>{=^+~M-vA#OJ4jsvh;#l55GcsAPzI+ z+F3@IrhonZ4Z_2{)eG2Dx5IWr`=qpO7*Ym9Nv_JPBXYXg@TAu^IX9})xBNC6-Grvs zuSJEH?&+?8wy+SQo{wZ`#T(M83F<31Zs?V~g4=0)8A)_(XegtSX*Vz@_e?Vl;bf!V zmiG31o8i4(o7=8>Z^R~<_zxJ| zh>;l`X@si`GGMG2zm}wT|tHR(=bX}kS_7${rj+K&= zh3FDFIhj2+dwPoF!d5d3;TGRoH8IioMCV>!lbGs&fQDduj=7afS}aAMgRy8x>q<-Nu>*4AZR0;_s@gZkeZQ> zH*oYl4}SjMN>cZw>llN3uAvzsog5@ZsVT8>^OWSF;o%eyVyvvKJv==04o|`K>LFNd z9T&cBp5V8#>cjB`Xeiq5!-&^<%M(s$Qeg$y6^Gweh|4Ai8q7kP8=$t_t?^rKU#!B( zQ5uFpP~kxaZdyR(dhlTOu_RfD``KY}fd3)oRL*{-ESILpYz2atU=VS;t`Avl?1)hF z-L@Emi)SFemGNkAY}5(N>Hq;SXK()LXGXbt1_t*u4KYu{!q!%Qb9L@lcY20hrxTmU zVq;@}(fcEcmOXq(8YrpL^9+zpsaxkdc))M&3+vGMt-}U_IB>+THNyf0>g*q8>C@m? z5u9;n7q{eSe8i0Oq-34mp+mbiXF7iB3Txw7dxo8c3)791??A{OS^WA zKHtbSxxSt289a0BqZuH-dH1e3GxNN|Gx+`Lvj0Xw=}FX+WUK3Oljw+>BvBQue|OJr zq-Qw!q20ydwnf&Rg~8jz;G)p>zH%QC$JY?<;rR!eSSYjdCm)Bceb(!IC`4r9xD9qD zVtCetktgUR;}S8#m}GJj_uOAS6aCoO+l4#Z^>20TiBt4M4YYP}tALw)kUFq#o2S`46FpohDVY%jzLld zMAO{Z7-$NShU%`sK2Gakuu!rt7t8D0*oCT&iJjmrTvxAzZQsGb)4T0bXvoM6BA%bb zZF7CWUs6hb_44{NyOxqEU3+DTNR4xTSIqFdEEh=!4RpkaUG+F}=(60nN>5Y>dJ3Wm zJ95oGUA`DO0X5visHt5L(u#O@X#Aq|J->BwVq|2$)l!~n4CSFM_1?w~N6{j)efHRU zL@QOX04-dEBoym#!XOL+P+D}@eH|Uucxr|90D^RGML|x^#rKY5=*Sd;VO>*GgWdc| zPCsy=V8wnEkSSDLgvsFK`$Hpglb!ho#!gUB(O*yEvF)hC>H90N& zpZ+{)pQu!RD^il`<`?6x5Rp}YbLJ>2DCh$Iknu-Zyaw;O+D51_92`bZo<#SK&Vc)d!^%R1(Ee|{!& znmp7VIo-k;&_T<}%5Ws%VK0IE!Rd&7pGENpIXSG3wQ}#H)i2#_nOjMOY3I<;ESzwZ za*r)fRKQW9@Ad2Z$Zt>}?pqVhvc$dC$~@}g0y04ntSGUpz~N$KV93hahIuubua3hG zBI76~xFE@um6ZI__gH*-0!`jW7pPSH%>v(7pgJ&8%`Q?F2R=J=syrlwEM~{)W#tTi z`Jk*=l#7osT^Yi9s6s$@$XHEL4wQF{w#!p@wAoZgn2M#zxMA3I7ihW=lFtrA!i!K2 zt%2ob!=rvU(eZwZZ%dJI;tee8QMM%iQDn@p2t8}xN)#{DkTR~qY_W5rh5)lCH2-+d zM-OvDLu){MZQXcV0BLM*RiJ|7>)P7zcaKmZ)B4HmR5N{4n0w}wQn$m z#DTw@tOw1CBjH5CwZZV{(VY*Rbfv#;p!@?-Tf~SO*pNs}x9`W}t=BMD3ZZX8HV~#P za0Osd!W`t!xUD*I2zeDJ29$;6f!1N-&utkuW+hD>e%2>Q@aIJw!P9cT|HaVUTzl*i zlE(bgI@J63*MhOzK7!5fmNa5`8-+d4VTn5QxysSmTje0YeSa*Tt?f7bjHz;pxC-<0 z!PinzDgz^4Rt5pFA@~O1@pn3$klJG7z?RRTueqto^%)V$Sx|GBY$j>Sphw2Na$tAC zJO2o_6qEk+_v}aFd)VolUrk6`7f!&}G!teAfREy}JJQuCrX|y8Blux33t4GHLk>i# zvgVFE;rHDRzrO4uE>|~n0rRxjK@DF6=gmbp4!O)&3rl6(}c(ZTKUjT6z z8(<1=pw~WsfsV!~XZjTvhMsKcyOP;~DuE+FVdc z^8G=8$+UkX)Lp))U4&VBDy9CufI_mQev@^YzJ<(xUBHY8g|id`?KR>h`hQ`z1H$nv#f@9RIuJ&?O6iUVLkG zVA55ybIo4?s=NGs?UUJ-mcEhv&*T~Z`nuLGo#n*}EIsS~en7GLtj>NDn!dX!(){q8 zZ2s;fP$`K&+aJGW=I>{ry6}*=N$KnU`XGA6N@3y!uC;%ytMCigY;kD{Xa0V860YZ> zh$j&){CD$UNXOQTxJQGze}6hDg58vOvmD01?w*8VvOaNZs5}2&a2F=ppa#U7rTqOd z87uC8zRL{H-ybuh=blM?%b9@x?O%9qJ^S-7c7MOy(6Zuzo-KAxX05Nv_6Liz^wgC6 z{UB?D4O@tZp%(M^LaGg3=qOfLr>2CAT^55^Dp=C@wVuc)wzc+i%E-q)k zXi2&!0bm7_<4G z|5p9>rvm)vuWbr{^7nuKvcO2hpnv~V{(t%s+ib|?0JgX&h2Vd2f;?y;Ba=V>CzMsw z5mJ&t=i;IwPPC1IDd(S+Mr%_MqXBW^_Yh~q2D0@1|2(A%d-B+kwsA5t@wb?JMoxjY z6Z#-&5E|s?i)^{9%4Z)vYxV^n0>4~vogyUJczFS3_}!2pJ5%$|gEkB^n4Oy}?yZ-&qdSfUR3^gC&4bteb2Y4NOeE48DK%w^+SdoNziqCbIG1z6-&8 zO5r)j_C-soi2t-a_0nIpn(}p$34{4$fy{} zE{aH)uWSya6So1DUWfJ##v!Avc7vgxOq;neVhEeOg3u*tzA$Rf%H*N1{{u z{4d>*=j?Ov;;#sBKKtX6)ZHCt{Wu+W?rHI`tcW~Pg3s{bA-?!Jq_A71k4B?_U0AS& zLWEqQZ7+H}H&D}Ijl*{xIQ^cJquMv_$ma`;oc>rU5$j#|$-%12mS#$IAZe_>`Jl4x z&PFzg&<9<5bmPb6fF6?hu;IOz3JKYWa}!HlH|j$C_r>^!>9><~$3`0yq0W8D(FdP= z{I~a=iS#=iwaebz9FF`4PNeM&lwf9CV7+$RD^qBa+3|Ju7>nWEDmg>qeG|QawaYD% z&3pi&tL#0jQP+)iXLjFw8`B^!$3l`SABUV*dVKs_kcifP%^PgoxDhS08~5ckOJWIn6ow+{h-3{0Mr(7K4MfBNm>$jZ8grPG*Xfu4Doi!9r zMg?+9!B5Pe**yYip&1(*i&04(3;G<8wx_ zbk|jX^$Nc}g*8T^J|fCZrue+Ajg)0X=q8+eNta&(v4Ut>H%m%JhGqQ0*M{edTk7TF z@9vdS$k7zFk-yASxvy?)V1;p<0eCheG3u+;?bRh#EC*OEA)0MpVRFBQ`V5VeTPndp z_$N6ZA2q{w$`-3z98Y<_3h*T>jXIR5jE9ANb|*7X&YQS{40tkUc+pG&w0tBQxIXPM zlIjB>(S&apmxPs(QP}1s_YszNVdrn=?V7eecSKnsCxVjI&c^i0!^Fed-sDKGCs;ms zP*l$o40iC4NTjxqbrfx(ByI){2|gjA9N4Nt4ks5{ST@{Id&An{_@tZ1<=mQdQ>ijf z_v4d|jXSU_y{Z1Z5dzwbA}}=FQ+*jf(!bvkmk3N5Vl}-HlpwkDPm3Yr8@6Mp7xKBT_4UDvDL&FCg5mA~PTE*uYSrz_nO z81qF0cb?3Lu)jES6c5}fdOam&`eb_9-9pL0tf6G%tHF_yM~`+g-D7uGSmA0nBc}3A z5QC0pUPD0tiUU$p^)5Bf19pxpy0s#?_XTcB9(CGQ_a&k?wyJI+86yKj+$f6_y1f=r+~OgplHSheen+e1=;LE zRDxt33`j%_E zC*6-Ys{Z}+`OiqIfB)i7oDcv03Hhi-Xg&V<^Z)Qm=)HB_w@0WO!UV+D77usNp0d)? z2a`$!yNFEO1pQ8ES?ax`C2?NBXz@mzS+w5Hb4xSZZaRdj4vvmOgPyl~5kVgvtqycs zs_ObEz({dFRN4>j4l$Y<9TEuC?AVGfU>T4FkR}=O$Gge~fBKH4 zADM1CN&{1Ju)cw1Iz&gk8pd%kSx^OCiW@Eufe5&stgLLO|EjY*y5L@3Gl`7$P;cWa z$jSsPvnD~J3_-G(xcE2lPJoA$-s%!J%6$Yp4^RM3%(sB=Ony5mfS(Ki0PS!OkNbcY z-_OU*4t#_RrqH6~Q|D6Jwm{mLrZKbAXv*Bbch%=fRI^{L!GnCzu;GJfLchw+WS zmnC@W@t_E^f6G=PqLhQ5;pQ2134A#q_U0BAgbAn+i)p|4#vOu!gkLxx6X9~++gq;1 zNSrGK_sY-jx%UY8BRv4OFzun9;~Az`0IV>b=h~jwh(_B2Z10ubB7w=-pjE%(29ANP zmzNj3+f1#r{7!*gg@#0HKQCFje(sh|Uo>ATpbv*Km(vjs2ZJ6g54mfhGZzt#$hmU0 zM^j5{E~Ovltzd3|m>CRS2h1Pe)nP^j92Tu7eZ8wS%)-!_Jjgn^+1cwk z(2#skoRR&fHv||xf7RtB+Dd3>b2#FO<;-J)hL|-Hg0Yg#Q5tZ9z6gz=t}dKiuR!-3 z*o50FC?KHNF8E3AD?Bu5FfSP?(C*)9x)`eA>iSvmc7S@a_u5TsF(TFegPWaBR8Niu zFa}XmM?ZCAYwM5M*&%6#Ro+oBIe<`Q6Rak)!l%Hd=6?LRM=vHIFp8o8%NNzbb(LUc z*@ic7KH}Uz^%$cokGa=;@Wm}b7u&t3c!#qH+Iq-zEFZXEz!8oT0i4W3dV01C?og@wh72g5`R zooj=K%sOW$d%Pm3zQh%0f?%-q8b4>WW0{=swt3gi4~<0o!%6?Fw+Zyl0gGjn)Rr zyjdf#0iq@GH2eF@(8t)wAu)(Ep$||2 zlM&<=JoT6y=CWWgfTkO$IpG6@(H$(rFe*m1eJc>N4ARp5>C)IuWP_b%bU~Xyw@(lo z!zx&XZEH>wF;Uu*!DN20uD%|uRG@IsSI8g;AysbexDd1z*rV&3DTDw)uu(8U^EhCdsbear;<++f^fXvyMwzU|4`bV(&A#;jT`TkN>P%l{n0Iugp+0V71dd_ zdDBL`&`m4^(pzVq)%x!6!n)-V#5(X_GL}k#VFEbs{pRfI>gwPC6sP{_Q5YwOpT2}?BCV*j&zMek+6Ci zJ-H9VP9!*RbE>Lt)ecE;&_67~Ud?&Gh`~CxRRJ45MxcJ!i-o{jo}Ny|dl6_iZ4f=k zACziO%FEqde{BoMOL-bG)HrsMDm)`UpDs?5IVuy~O>9ryQ|~zjdAPX`GHJl^6%atO ziwByJI8_k8{AUJ3%|$IEFtk!AJv64zU=7$|A)QBn%T zs-#q-q@u!zHJ&}DW@hcF@d9T-mhklS1UC-#0kpU5?AO3G3Jb~%N<%xZsAmc_&m|51 zN0K{tX5$Co4x%H2d>x;O1~ey#E|*`)2P{eO^n(c4*5-u-e@SF!>w|D8=1Y+%o#;=@Um`F!bj6{7{nfpk+)r4x8YI; zcTiMg9-f|X3w*vbOlM~|(A3m~^5M~2#105JeHALs{U|__088=i-Mi?lB_+FEz(RRTDhNC2*(YWY$5gp_l zsXgGRjI~FuE-o$(+3JshtnzRYrX*ff_<~3#eDGCoragT8_(W%3XVR|2R~&chB;bL+ z@9H8(fPwRigaDo0uiw5El7v7PL2>|D^W_U5l~u1`x|#H8R~MK1v6F?}MYgNtIM$}1=k>ovEw23+C9 z8`lMBNuo%O=g%E6$L{gi!=1D%j1R=vrlTbpqc0BhX$t6seVGJftNnasWhKlXg~D?V zfrpCc46p;_N%SM9zJ3J-UpG(>j5)~iR#sL}ELbBsC@PZdyn5jy0x*8Dtq(Ip)c{nj?=N?~T4vKQjHXGR>X$uJa&zTp`YHI8ksdpaC1)4>TefrzYP6W>XugkZpjl&(mY__QS%Ee7Qh2E>?jhc_`&LpC z<}k}dsINQm_6lw^l=8I49>CQ!JEo<#mn&>PJlUgOie8__u~IV$tMH7JWFthwK#^o! zc*oH^RYc~zpXnv?r1}_cYLP2AL0nCLfP@M@YsUuHSe#ktg@?!B8-e@)W8;vGFD$e4 zcA~tarKdl?2Z_S|NR;5pu3jX4I$Mwa@FcKG8{M!Hu>u z9->5T$B7JdAsfQrj8XdN5v5H+?NIuOA!K<#8%$02;jv)-+OO)9M%BQIL=2B#4MUbm zM!`CFxb}q?pvRhu45?%9Ma{>NTi=@=o;?H0-X+&(+Whet%);N!uIK#F9_(kvsB!SY zy6l3Lke+u(c&Gr7`|^d8ot^qb{PR9cOeOWoc1Q^cT@+}9s05|;yE=O}wa5h%K z`FyyAZ3HWQVrq*1T&@8%9@~d9PwojyUL(XQN}pwt7T0LukB?8+^ZD;pR{q%BOvi`= zUdzT(3v>0@Y>&fLFvTGRNui*Ql$h8XSjzL!Xn&?ZI**{?8iTct5sLaZ0?}19QFKoFu6TAyHVVd?{b5}GhLglk0k z90_FIGKO!6WD&Xk6A)=Vz+}zK&D}sl6C%oi$f-R?ag5@|+*L6fcSpy&rU~(LJD3|`a>Pozp4kM8exo?w7%dYUo2iY>p#*`IJs{2=apu^< zz8E|+sFri@)6~?j&u_OU2)uHTEN9v4(M@JY>6)s@D~?>Kyj&i>KZ1hPI|&=comP(j zgyCN;pTB%jyFsnSgsOyx5hv(A7-Penlhd<>RolP-JZFmeo$~TrcVuByYX1$erzU?q zxcpc(HRpL{TuBhrqWXPe{k6Ua0r?H)=HhplK7k1qw6+?UL83Y8>E`wY8L)PO^+Wr0 zG*;L}$aWX;4r3?Jy1ELTX6E6cFXN=lA_wZVOISFed8|PSJYcvr;^CmFji?;)_S5L7 zv55(6>{)mJ2unSS@xJKPLjeF$e09l%5>S!HTZg_3BILH6#FH4LhT(}?8D`LgM6x`r zWnf^~#vLbrite}Sf*8QGJiHho-`PO^sWs!9kO1Y|hTK089n|NqBSQHX!1Ii@KB)6}7=BMKj|rxRVHW4~vS9 zl=R^2CwQf|46Uts7M=t4OKRFP3bQ?FScnyX?mK+`)9vjPeX&fhKU^MP0H)fej)tio6@EoSh$)mL{8h z7Zw&yuPiJS@5Yh0$;$}A(>3tj`}b@tow$PVI4j7Ar%poDHao1Ts!FD@`oh{dSruSX#GbQT=fP92H8D(s3>^Dgf;j#xjMBiW4{7Er>PUX{EC)_hHU%3 z9Xrc#lXM{p;PD3Yr(^WZw=9rsJEHrLq#+>zfz1rbFOpF%9v;1ez6<{e z>g~zXPfgL<>O;NHC-qm7%NS|10~NuOJr zlCBT^91W(INUDdX@#eXW*03!Y+%3F~*3X+aj-7=?!{)&q&5|%XCAmb!nu+0G#>O2m-En<}?0}eT1JZK_;}Jz3#&LiO`)lsGN?=sB#*jl9rGcC&Tyg}WPbM4ZF3seiJ3To{oNEhPK$AJcqd)b(gQ%d6x8I;Q9 zN3}f>n&;!%VVjpAIzy3m;lboq=HeD4SXCJF?Z3_y0fC!(7$2oPpQ`Y(7Ac+A)$V|Ax~${Et81 ztH!~B+K!5Xn0g~hkJ=K+`S}>_db}JaEMa-;F@4BO4hYoT;v&|ShX261zUs<#r#Zny zf^RWS*_lg(IZD$mxE36h;Bc*M1|cv{RqZOZ`)=}?wJ?d-pooS0eFUZpiAGX?Q&Om= zG>F5HWMWH$6o&kh^D6a*uqVhePM$0-DUs%C1x-JP*$DGVP8!m&ynsrX=CRX*op5&H zhVCjQWrNNnQ;r3Ciw!P#^Lrng4TblP)*2{zKl#!$cJg8^%1BJEHj{t*n6!m{DBa8C zzIhS(4jsVEqPus;0DuJ0cj%BNT?UyPeS*M-_X!B1%yT)%lC?wEcfCM^9Vc0RUENX8 zT*Hs7Cl7_l;=E(^m%AQOO{jIQ2yB?hzyi8;%htz7c8LmTGpF>?w!Fpg4;EHd2NN=L zb9cqnZ{D-c_6!(>Gf?Qv%^9W4aUx^Ivih_&6r^l-b^iF#@p0HwVM6%bN3Ou1X6NUR z0p;uNq*ROEqJaKgRmaO+kDR<7Y15c*{!R1jGje@9Gqp9pi04EGCLId$23I>)WbBuqZT^38-}*ULPUeDtdEkTEmpvh~Dy^&t!n!G<%K zp4#7s%;mMqt9wFy@d8mY3SoRWdLMLT&K86Zvk}I`*v#R~l#g2%56zsZ01D64|FJI{ z#|z7C9LPX8Dg&08zqUZjlx<>Cn3I!!RAhgU3s6(zbqD$5RmYc_~1da{KnnP4)GW<-C_a(XyC(#m@iu5p0%n zmSsCV1I~;qYEfiXiLK*M6=JLA_^m5lM)N=HBx6`fh7|AtN2wIdt3*ocSQo9f{b?_y zh8Mt>ptfQ`qM*TTwY#jrzfH%;%8J{~95wsRRIHz7OezC60Kgzg=yhY`ks|XP=4&J& zMc=9GbLLP5ZzEA?s`Di-j!f|^gd|Q)b zNU^~7c6KZaT8|v(b)Mj&v{A>mz??!Z^)a7L0>bll8g&e$KYVyIYfJbqX=8;Cpx_r5 z8?`*$p~L)v>?QyMdio^GTrII{`5zeb7XhggGbp{id&)f15Lz|%9xkNCF8z2&)bf## zoE(P~4K&Rd?ar>bKYzg1jfRM<7Bjo38nrYvL!~VttpSQM{zC<5NPHQ%1QD0Cip=jr zABlDfD495X@4RGE&zL~~aW8{2!8+&qmX<^N_ftF_5K*`iKDjmT`K{ZxH%{6JZRQD4 z{AJiEJQH$Qh{fQRV$btn71>l&)9b&L@8aEe@+BNL_?T1+WVoPs$w@MS>@jyFgVqHH z{)Z+!yd079UQJ$Ik;Yrnd(=9Yk$q|l)4TZ_N+$@Y`GN3%$N8D6JYT2a?b@M`A(O+0 z0h(gr=pWMWq9=v19Un)#Y|xT}nVI}xwtx<1dQ-_L053(_^br>VPDPqh@{Mr`$&2ZvIm#!zF!)ieOkb?AUxclGk*3xD_F!;Pb=P#0+rD0p;B zK>T*v`pG3#egT?cBx<;Mx*1neQkI`Y0oPXNh7<*>7UDZ-ZVk8Jh4mpRY45))Yaq^8 z7-?u5pePK?GQJv)d28ZrQWBB1$V}EP<0|>FQ51xVJIH#Hxr`X8vE*U(YX4%%RfT5@+LMA-L^djp=V_lN~V1~0(kgtfrJb3 zC)O(@*^_(MU4AcvR2L=D1~vlqNo@Sp_FeZ75k*f8CC-<@MG+}gxWZ@j`CXN#jdIb0 zRF;S@dv#lNi1y0y46yhXPspX?S!-tZa{#v<`-YE(EJ$ z>f^^G_TONhgRoB0Ze0OWkty(4wRoi9%A7f`s4`i5}=?8oG910%_N;%PA-T)bMxRjC*MN#A^te zWet8qG@qs&YJce>bUO-Iqr_@ zzF2kJTBYExms*3hL}Pmb#|9JUVKXyoVcx}&hXt)8vj|<<3DHnlW>=}H_An&wd-32Eu@Q>T4=JU?1gq9c%XAq$)_x`vi*Of-Y0hfIb^wK#rj z>GB*^Xot=#o^Fu!ASmJ8o#Y`SV&R z4ti0l>7~kSP+Wx~Jf3v%su&91i!urc0z~dz#+dm<^F4E3d|b#|^+5@p1bYggrLe2n zTAEu>a0>=&JUI|SbU4^z6B!@Ozki>;;uj_PI;XMy^${mH>G_1Lw6ERcq{2gCOCg2+#ayP>gaYzOF-7%O)g=cS2sY zePf#eWrX_B#022!+e+uIqKkR71YNqM+b+b(s_%SuEQvFpO|(bx*lKy;&(@0kpXHWc zIxO-tEE+y;erdO$!pY^^+vm5^yZBr^vdHi7FF~r~{Xy54uB-(MzZf>U5TBUU!WZ%A z>#yas*HBBxMKc5GL73QtZpK@K0ExaCrb+DIf{93V|hKW%i9 zvP|Bf+OzjzULLJ!L}f*VeIR>hF^2uI`;>Ag+o>M+Q$-d$>P;XbHyJhiU+kwvP&L>1 z{WNQ_U9sV;7aZ}LdK{5d_xJZ78O434-p@|^C9L-R$pPjl${lK9dIz@l@?yIxTPg4E zDZsirzcKGHD=QXtgNBuvnP6fg0(FBt01-7KZ2)wj0l?>C9}nZG)VUMf6PBDgXSA6p%=kasmC%pjMQ!#}2)4F73i7+r)bH z(|PqH9v-4P2@rN{-|h$+2+G>?RHTYz%k8)21&QG4Ai*)%HIE8gjt)lltgM}Af-rqq zSX`_T3Z)OER8vIRjMd7@3ft&mz%0NEBw9g3M3<#wM7`CO9NV8Z+XS5qFje>#H^kNV z;Y)|tkd>lawv(TqJW3o+CZJP>NbTHed|_?iASf^}8%Fy~Sz8%-3oUw&J`IE;R6%I8#=j)0ZR{&F<=@)PGT?}8oS6Q0cp;7P?T)q;rVr$nQ7Ar z_--^i@BX15Q$oPYp;l6Nul1#9d;GzZY4b<2UomS~uFIeSihJL4AR0n(47p2fd> zI#=&r3+_3^FEBMVciT_rRjF{?)f;nX2I3F4P4&je4U4bLYx`fB{W<+}!w>0<+TyvU z%`SJ3_aEA(&AOra<3=4Zt9J9s)5|Z&*sPlK!uRh~eN-$$KvbBz*hI~VX-0BW$Sxr%t7!r#!E}AE zkmVQ-V5DmgUId-DIe)1rmU}Pb{V~9$M78s&H1MY{e)}{V?oFFk2I)LXtJ(dRJjaAL zlg%+`SR@!WrK3=8^ad|{HBnu3?_6oHg3>jW?`YcAabdEeKQ;99a4k( zKf8!{2rf+V+D?v+rvMNUZNLXbXnTT4`@#+3h+An_NHop%We{I5eSwu0XUa{I5b!{C zkb;Q0Ele-LZcy8c)P+cWd+x}8o!c5J(1_U^n_??4E<0H=qal}ef}5ZiSy}>ReOX`s z7=x8TZom>3a+MJhYIyPDPDaL1r6=_G_vh0~ixC&~ZYysI_?FwWiTvc_-22t44>;DB z(p-75gM}6*D}ez4=AvvLF7Y*6VaQB!?92t=^1&E%ixdw8Cg1_OKR2{RUHS2B?o86L zUh*r^6#a|wk^QMVlNjHb-@L>}6C51u-e{9$N-10lx6kt(^6oMHzxXG?}yTGmlARYYKY*rDw#w8@*fUYNCEKOkuW z0{iIq&z(8DTW{>!e|b)|e)|1`KAgC~NO!Z)!XpCx&q#-&ZG7bVY&VM`5Cpgfl_;|L zsGVxg5m(m)?CK=DiU9G#98a7usB}QC+vc~|;pIh)oPC3m<<6a9ATNV8 z{(vZUCY}W?#ZPDAHs9w1>#p%6Hl9~861%2Aj4jrqItNG?9&uEhWT4!GG^23z_4VLi z9w65YrCE-C;7j-q7ohy~uKWC=R%KJr$O16NHDx@Nc9giTQv183UYhN=%;4u(o{8K6 z7NsVqs^z=VgP&=e^R{L>2lnJYo7*I&RrhO1DO}*<^K^{_-nrQm6QuW}H*5_p9(0g) zCnWGrtN8bX+*SBk_}0&MAY^`I_(XP#-E$}BnWBfKFQ1Q#|2}-7#vWN8<*zSD2uT4H zF(71B-|T8=AX0bWAdvwtWj23CRba1RIE!(k_z_?|G-;7_plOE~fs9tDh3BEeD_Zk1 zushasZ|tQ9XIj`sbsWubszg>91^46)WG1Jx8qcP?Jg_L)DI!AGS)BeU@PbPWI-l?j zAPF!petugE?hF=G!~9q1hX)-l+&TVsKkXSZJ_YNRrzT(TorRwoIyaG5Z@|ANDQzqI zpP(l+lw%z8W<{k?=EwFmpk8*+)|U6fDthz33;I-?93$98 z*$(dCKLY!$hP}#&oC|V*Gq-GED2kbQv`vSZ*VT}hfhv3xGjp+HJ>zL>#>f(!Ds3g{ z`a-30^3(d(CMKFbPT`5E5=Y1@VxyxqQu`rR$A--}x=Z=Q`Z$6j@W$ltGR0^{VCvP0 zs%5H=c{~P43F)brd+tm#b-)^Au%LB(KKWoVuqP04xLWop?h9|{-_6V>K;f=r?XDqQ zeD(hQ`>LylH=pK*ZAQie1~lnm?s=s=qJ9JuMz$2wQSdMx5M>kT`kelTwOAWk_ybln zi?g$5aZ5k}sj+q}GDm0qMj6oKr=YC3JHk&0^TPxl2yeYsV~@(8h4rSYmI($(0aZ5I zh?9I1R%?8Juu#$#S8_JEu#bV=yzcwm956%%FIkmG7cU?ue!7} zPwCjI{`YSKb~ZNC!^2@gQfNbmaNNKztqF>sr2lkV{pXgHOfCiv!;z-?#*)2B-W9~y8=v?kW!@+j@=7yS@Z98_1!O>N{ zg_v-<&|6cZhUId1njel-U^KSrDd0vTY9Am5QA4Ux8^=a_VN%^loI$qN4OY zj{ixvIM(WZ9g;yC1>$Z)TU(4E&`v-_hOymB(-$)JxrI?o9cM--WJZ-P$Q_jt>akR% zbG~SDOK%Nk$DP5qN@#RC`LqH?2KX~^-*4TkSFaG0);&{0cMA&|-uB|HU6{m^nwSW% z8^8e0A?ifFcx@niJsx}F>d$?%K#jUz>ug@mW1MJ+oQzEhIj@iXdFQN?clWt7 zib?62_wVZoC*x|lxVeK}>w!@qBzL}lzeienf1L%epZ)v8Lqpf;`d=*Df7Kb(HK(G= zYuL!hl8Vel#jYI#lkQzi4&0EDV7h+;;SPM3UHANdQHM4UuKgU?pFu)Re`R`Na~^0k*7oZ~zg~VoGhy(gYTLqKkK23~x7X>duOiasqGfw}pYB_p zF0b^l8801G4)$Vfw5_h}rWT{f&UjpliGka%qX4a;ziweQB z*`DVNRx@hr!kFn(JY|?^@q62deA{XaO z6yAF(O-*#{_|&T$wk+=Zq&d#hTBYoBu$o(|N*#_P0O5n;N${0h4!~ng_G5Sm#6#Lb z^eSjq=op)59ea-kZ$}3jBpe(Z=|QW}Hc2Td7Pw)#xxj>S<}M;}#|ZfHa!Zgf4;&ab z;IhG^#A^g}K!oxUxQA2_<4TPV9EcQXL=h_dKe&7EaIXLVe^h0ZGRl_JyCf?!(NePa z$j*w$7TG(ZVJ5OFgfg;6nIWT$kWEo!rLu*Lb9;GzKELld*SXGhoqx``&UO6p`Mlq~ z^%~FTCcQatvCP*(%I(|TpkI%cAR_Bp9PTPJ@cxBKUia9Tvt?5Jv3MBoSQ0co$r zm{0k8(pr7R+qRBltSkimQ0gTRWx=?^dtoH=F;0kV?B1QF@4(Un4zNYb<72~NuM-~w zE>P6jNle59J5(4I9ymo{`P_S`)&S#-#>NwZg4h)z**+NagN!YyS=WBTVi0^L6jtv? z=YTb$=h{6Q5+3gA=qRtK2wui@Xu6gxV4nt@^2KH%xE~e>%O*S>SHUQN6&lW)jKeL> z%^-Ii5mssmLcUjMvzE0ou5!(%WZE}lh9PUUR>y2Jj!)q1gG6W6bgC7(Q~ z-O9tYDxnmxFkw&m*NRiK{*i)NLO{6J)`H=H_#ZoivnP$~u1-a;`SyDkbr^Z3lO=AE zCHsDUzd2pPT9pv7Da!q_P>F1P*V^8EtIMsM;7lZ`OA28Haq^XKGL_%ci%>ewLqE-T zN;OV#oGioV@TuFaNgqG^uw*BwZl$nLlJ$sfB@PhgDHEj1v&lPkm}tlYF)Y8csB+-` z^@)#9BQ`%^p0;d!Uri3|Z#W2GY?4%V@6r*~!UH6v0hc%#Y9=VvjjjlvyZPEw0|r1(3nk*sab95zd*lS=q&L9?$jW8*WC)|c&P{%`_t}z1K}$=qbRiap)MKcjfi(IT zwo*)Qh{UNe3`w5a)aP}5A0e%s0b*n3`e}jKwmYAnczK4)CG}et#D-lMs{5_uV&i%boEEF-JPpVk%CZKmH_fu$=IpwU?qNBYh&`e*UdN z-al@C2G?1~(&%3Dezt3AI9Ho6PTH3rK*BQe=jwg=6QSF)Jko_Jf3tIRNs27M5s0_E zE?lUDkE`FZ6ZQw!3qMTL(aCvwcq~tL>?*J!5WdRGO~q)V&-4B{Wnoq)>1r%jCuv%cIDfMWbXw1SR zPLc3b0$$A}By}<=uI0)etir|wh9xFf$`${EY zuf|48E*JSKJ>BmyplS|xj=H5J$J?iloNz_;2^{B>G6AC>DK7u|c6s)sp;joqOS zzD_kmIUNq3X6?@g;v4Qbjn($DRuvjwwtF@#r^Oc0EvGgyyxuOYtgprE_2tDOBQ=ki zUZb7KuRj+R)~n>G2V84ybu$eT+1!8VtV`O9GE!R=xz?Q>?Muyej;n`HIXQTePs#y}T~Upr$JyC4_leaTi$x&^8|7rNRX4^X=;L?&=ho%^)fth31%v%n@VYE6J$P-&uWsT#w^JqKC1A~Uw|WS3wRFE7gs4~bL52{Tr@rmZc!)m$ZE znO&wErTD?oJP<5RIbLAp>n zyXZc;G&~l(Y+y6w)-`{!mGYP2m(*JB>R%%3EzW&(3`{@1eIsW2eE!0d6u#e9>r`r8 zjqIl$%qZF_88(aT_c|Fu;k4*%d26zNaEI5}f!`M|A3Vk@DQxAUY`}A}h0TPsxH7)c zd!Fr&iw(1d%d}RjWfyrI^E1|u_eGYutz9%yKb>`Z?K8%bvK3lUsC3u6rg>O&Okn8! z&DFr%OJS$1)1tToYHr@Li~9BZv!|cF_kWnBV%~W+FXN#UgVHA|D(bxFG7t6}uxm6m zHBrZCyXe(a1Phop0MNi>>v2?6dz0HW{==;Ze@HJj6DIuL_W>>=X%Ttj2Wz|D8W5Sa_D@kwU-#Dk`H$EsUe1lmLd|12 z#d#JaK3*q2u2VV`2x~q+_AQj|^xIV{j+!pjQ(bR2{0178d?NPjuM*lRt@dc{%wiGK z>2^)aBlebjc|0Co8SAS{F29EBmL54uO=T4b#XQeYc2`>H-o_)Peh^% zXdif_Jq3nFn3N}SaJ4Y+^Y0~o79Jk(;ktV82NQl@R^FIF7;0OIXzZDh0N-`XcX-dQ zTvPZ)p}xVvW9NV59_FN=`g{jh=#EK&swh=zCGMl@5@JjD**U51PF5IpOW*_x^Mx>v1N=gP&DeGY`l`9Ai}&{dG8ZtufSo{)=_Jkf6{;3ip#B>8ru! zgnkYwI0?-2?vrL>jGd18Qq(`Ae?9wv-28kn#nrFx_xyXYwaD>r48BP*=2kkkS z8qAE@5!@&}{cDW<)Tc&9YRwBRDd1?QRx8SdEK1j&ZrK$%hGP^52;eB-YK|v z3}XVNr5R5K4xQKr8AUPDh2eMItzx`_P9rVd9M7C)Y8E`HPCqstD)Q)g?rtO`92*~R z-&OQz;<={sB`GuKE9Wh56&z}Bd$*r9=S}L}4e!s&8+@00{D&X(sBerORSHeZmb3o) z(^%o>g^a~gk@sl@-$ogXHZLe!hNJD(@Em7mc8n?k4T^9HynYz>Q{w*&lZv8IibE{Y z(XRTC`w|cRVN}+rec^Y`MZ3wg=RGzj|Ll~G_ z!Ase(l*JPGtO8gTwNhYE9=Wdxg`@^oS}56bi|FLF{>otNuwbA0n`1inw)EBnnwg%u zx;u@d7<8%VQfRo;c`{&v4Fb6>0IPvE^TL{U%1<+o$Z}{r=0xp8KEYRh!Tn~*qNc81 zL*cMJyUk|@+K)bSO$J}eU4D#yq8VDFSXgmi-B+sL(LT#AMHF0rCrQowg2CnPi_ZjY z2V?&@=9R`oIsBft)t<1M;1hX#z9>Onanb; zcO?;~N&NtETy6DiZVcuJ=8Ie3>TK4Y*|)qUk^JLzM|mo_WkJEb(%4ZYeVu)TXPB|& zEt$<5V=+r03qTBSP8qfs?M`f)LCb|F3JiN>q7K1&d#nm1GP+@h=sRz6uxRw|Flv?0n5v-aNLXB=2g_7-nlRuix_Yx|Fx~jVzZR z$_!Ub*Sin?AVUpJ(x9eriL=rt-Bloyc<P}p16c4WK| zWb#YLJxBwt85{fE(jk!2$7#Ml&3dsV4HyIy8}xtRzRcDy|2Y;d4~KRUpY;`#yX&g~ zpkISdYhi7j!u7;A2v{QIV(`%hjbOYS(9JXiP?$BVaqf!N(ALJlx3s+chPip>z!qsF z8$2ll5E=aF#4yulz^W(FUE!MpYZxee6Lzca2up-@-}Lm}T)@ZG@iYB}9goJqE$)ge zj@b3P@?DH98|F4()mFlqap3)RK@bbuucD%gm?hBB52}Mk2*~I4>pz$|Fn7Kdp>uoK zJO-Ur%4r2zSwHf^!(?39ec4wHkIFfMyo#C&Zy6Zi@7BArZj^ge<$V0j=zogPxm~i&cKWV;J79yspj27+gt6e~ zw?A(WSx)7VE!(~_za=2J++TPx%0StBw$FQZUt4lv?w2<*Uvjcrt=KPE*!QwhpE&31 z&M!{AQTb$5Bm398@aevHq~y)47u=%}sN+el0jj9nERWL1kGxuQao=!Lf z{7pk6wJVeyg2uP7IhLluJ}gE09aP-pIS{T0CNc27)mPa=cuajGx1wxf;^P7SK~DDI zS(||G2@IwPcthBszYC;I*q#vBR3iu}RZ-X9!!_s=p@oZ%j~{3`M$SR7W+xcTa&RQ| z5UaibTz2&6QFeCl$GCraf$eq%)`&Pxy2Cl@)-U2AUINmaHvsa&XT;+1mxE9MC)5pS zP4ad0_4LYs@kbTIecD-84LN%L%cyS&!m{9c^gO^YHE-l$6bovu1yAittB9;FWSBDH zRrejBxxIa~bhf9z|BSFOogvn4fHH)3;);aIsK_0+yGHLG1CW{?vO~(z(yuE=Ka@CN)vNuQwW~$1PM+DPSBbyt#rziR(jRTP zjI_%8$vukc$GKj8m8?xJoV7|Wh3VFbQqP&(n&uW)zjMwX@0fMZ$xR)2s52%Bba%;R z>cLRhp{b3W-MYfz(?9!2$eVc$OReoKh&wbs3Xk~&nGO@B@eV&v%QoxD%(rWcp8lh* zE|?r*Q7}e|ouHW3TdSTs7WO|N5}4rR8T^*7?|QqSZRkXSd>30SokD^A)EC{Ty)H z3FRkWZ))5vOQ*Vb1b3&^=pgJ(ljyi!4!*=K-w}CKlBX&dmLHSUl1E#H!@<>+y^PMr zqT@MO~ffGbf$~HMkCk1%CW>fnDGY zCG*KDr&;p%d|Uw=t5Rkxd)r!MLh0|NNpT1Fgqm4hIs9qs;g8gUL8S*1m+WK4t*1=H zl)8$_EkF(z-yIec!yp>TP5S_5X&_1m{PDo^Xl_1^^BFUtaIv#Ei^jE+;9L!x@7=ts zSP)fJRj9s~m4(@0764pBf%*>WbLGJ0aQK#2H?c=|nX$%M>UE>&sIrw2kw{3^hPu*-3`fx&92r#FD< zDMpWHUB1Amp*vHvOGoY2tp!3%d9OF{0(=>1VhLW4`DHf#>w}G#W%ePlRdw(@>DszEpa~3`$}`*q%D}{W~-vq(ik5lo};U zDk?HJT8;T3E50OvWt~R(6$d82HVwO?#gHa_z^Z*``RjM}qX}PWg$m}CpLjoV_+%d| zGw{VUz4qN_-BI2^d+FA%fjeYG#^+g$hF^c+7%aBj_?3F`^SIOIAHI%Hebly+>IS}i zHwv}R7ggrh5sMcI3fpBW{N2&$>{Q_C_D5vb$Aq_yTxzBt+ij<-&beOSRV<-(#Zr%U z-Y0>jiUWUi#NVLofsRU z+0xn!O}BLIa9f;IDyE5QT*f|gGZBZ1_2tX8xV|7GeTL)%n-44^syz%rRng$m^sE_d z_%9dW$Ip|Pd)=HKu5d4W{rWYu%z{T?h(eY#c9UiX=fXnA!R^kWf}uf1)NI}NN-r^J z6DmLR_E(H#9Q@`U{o(qLsVO8DK~@UO27n6Ti~>hNIAq-dzZ&Av)cMDp4`m7C!7Eo% zGBOCZ%Ruy1{}3i5Jv~;|)`k5)p`}KI5?m?RAKf1*?Mepc0U`nT?|-X?@w8MO zBcm;RyV}~zk!(v~1^oOOwISbSDM5`STT9I46xlnwyKQ@Oo;JxwpbiJC^1%c0Y`YHY1+J*cj8;JA)p2s=AF5&NN3m%;U7naaFt**YAwxG0!-BUn*< ztbSc&m+1=e)`g)!SvL6DK)DUmkRo=x3q~?HI&MlMrU&ol-pdAi0$2n;|7` z{!jP5qYpVwoOlVoJ8z6oTnp-;%yprR>}+qyG4)xYn(!Kq(i08?ypr|eg|vb~76gDz z+8vD#5k;b}-(t+4emCdUE85_CJh#+5`bI`nNA(~Qk&DDPgvb@*Ih>gKydr#jpg2Z& z%%Y1x7l(PxnB%IKm@VHT0;I0s?4+kBT_wIfJ3EUWaNe!rgvv7x-ygXnMy?l3#qOv`ts+OFYyV>vN5kQW+ za(u2f_W+6$eV+GI7+ku(J|YvhLcv5=mt}hms+mK7YnOe4@3Eb+{ip&EBkWNBADuou z;pQoy`0tH5mKD$b`syXe7;pJ~%f_Z>XGi(_+iut;$24OdqWkUB07U^81q^B~dqWhi zGspS)Z$hqjo|Vu7;;bhRe2zgBJcBUcCPZ)?@BT;55#bHk<{_yC#P!?t6s^+A-@h2E z4z;%af{?(t=hMFTK;<}6fZGw5I_$@xT3;Wk4F^ub>@UhzS*IGY(E)$Y#WX{TtZ7NQ zEy@uRug@Mid;??$^z%tvhX{{kC+x5uyBvlxybnuwkN^7*A2_+Wv51Mq;bIM%#}@jP z$@4%mFpHP>{top!-a)V6J5}&&98lm$Ux*}ue%l{rs-U$A35 zMrUO~3QFG(s&5APuNj>`CGsu&m;ZUk{&flL7nEp|BO?$SpZvabDUz*@rP!k5a_NCY zcbe9HcbdmGVIF}bE{sE9u^%Yf<5R!o8-Iv&fzLntrD^Bb#^z6+lAf#e zKfX*lE)JE>q^K^u*{AgQY^w!h3IER?|ILflCf3E{TmSqCbiN^8y(0cM+>r8u)9)Ci z;A^JWYO>njg+A-J$g^)n+u9}Z$n3-x4Cgy+x-bDiX;-VxBo~R21RK`p3U@+cFH96< zY~8=V-!EH1ly2`@$v}G#GD8{uCt%nEd)QWiH{H);+Sh@uSsXubf9KAf>1xKf5(|rq#8>aG5&xc;xJ#L-oB#_F z*plg;8L@}Q|J#k_gB6eE)6g7>pJis&#EF1f@cNwU%TRf8a&qH4)D&wD8yvlhFla$P zhNm1<4)ORyO*Ao&9*utgzKDj=Em$yC@rmeufR z|NI&iEyQ8U?|b5_DG2ItK~r9dL6AjXff*nMSyRU~`?qN%JXs&WhQ_lGgFU}Y7t~!4 zG|jGh?M|+T2hX2(#;;a42OG?q^E>kGHS4=PQJYjOBX2&71OjIh$*Svks;jyZ)jd zxZUVEx>@SGwTbhl#v1H}goM3&7f!WO{&dkOQSdHTID|9z$S+6iM3;iNq34kxgt}qg zyNlrr7iu(7_xbM-@M-2Of4E+NVATO>&>6seBxQRrbNe|x)DoAcU;XR8q0vfd{sQhB z908IDWlc*v?&0Nk$~{l{E%cc`4}=l0_mhdwZSLBw63InIyf}1;B$Z&$uhXmtZ-Ias zS$X-(wy><&k$e>sqT45-bulEsKPxNMWY`RobhWhT*$Q`4QQhTHhHh9uV1ITr3NMAO zI+&qYzEcfi`+%~R>9kRqQ$}Xy4-79%@>ejoAR668zqZ?-5O@Jtkdjve33RAnKnC`v z56e+bKt;Qo9YZbbp46%=bW7}Wt#Cp3*0BZLs3@=DO`Z zI_DPA_j`1WNzBU)cs=*cFh&NmM3v-bAT_NJMYV*8`VK}sSm z7k87J5T?N~&1U?JF#5rJk-82bSjPKvd!G$KOTEV*OHSI>Hv4k2-`gsXm(#txYH`Lz z$6k%ySW`&SS9?3!OA{)uq&78Q{MM=ZLvwe!OMqA5bXie_6QgC#!0-ZeuG@`K6y7NxzlwL3$2lU1=Do7mXEZQ}<# z4zNu)^KhR|c#4-%IgV2u2q`WjwnJ26H~qh=@(~OoBx>jZ_S{K;P16F-6xm2rPXq>p z9lrw_{gyi`O^ekethBEm8f49;@467HT{-yEcL=V`fAmS zjtVYpcC&yFaOMIjoQ)MRZ(-Dnws!uc$9YjgbEA9V;kL+}yl%kC<=%-8}P z6{ieHUY_cdxpL)Ey$O;j5&f~_fU!6`B}W@d<8w}vs{F^Wqn~HAwzLE<&Uv6>x~t|A zRLM3S&+BFWyt^*=P;KPv*Ce3bxw&t#fv)gErhuGUB5?|R-ajuBeRe8Pb`QwR>l+&z z>+65Uk^HY5Gbxtg?mKtba;|;4aQ-}wgi+1@kT*UZ66uv)jZo26}Ku5H%wss1NU`TK~wT;gJIbhCQ^cwe=)~ zUmP3+gG0?7upeV|j-Bt0$UpX1`ipX;oK@%H8zOW?1|MFp6V;QYP*PKacMC6sh&RZ3 z-OK%EJrE-N0ds31SCnzHf;i6JAy6eb+`)C%r z-}?GugM)_@!hTsVJ0#q$H@V$`B0vV1zfQS74T_LMXHS*gdK?q;ZjJkV2MRg_D>6OD zF^2VP^R?6%u17d~ZeIi5MGO6-_#3dM-v^WZ!-M8zhLw^qgcRGWk#%B==TyuRh_E!o z-$q9lkds4u#|;_eZ;ttA8R+UVxy54skf_%Hdf@>n)!I;+s8GcT3T9Q+NR4xUtoM)P#2p*og3Cpz^oGvkv`9nx;<8z1?U5jVg?n% zDjk| zvftTH*|Z|h78yQ$H}mQ3aZMnrHvNL_HN$!nunL z$?v|~@lP%WBcO-;F!IDX<3HX3b|?kaX}`CWP|Y&=v14L zMduU}{Cd$R%Krs&IKE+FVaa-KR{H1U^wM$Nr*}^L+6n*wtsEyPWn^^N@fZg!d4>im zS+m_Ff%WFsjpp1cz+3oHds5gkWX&Zee&V(XLsG?o0Wq}405huf8&u?>9&6|-QE!wwPlLLMj`vc= zZPYBLAOhRlQ#BhSHVAo%_?=e9HUbK;YQMnQYA0-c==Lo1-neKo>U<5o3^1GOI>ftmy5%Q)$yLhiOFBTC_ehl=2hE2 z2gTp(fYi|rf*Hz?zwr({IFW3YR#r`;b9a>d7>3|ag+)Wit)7znfyP_%di(tYI;c8OfB(}7U9B3S)ZxGHT zwAy*+LGP5Pd zG^s6Iz4d2tiUx|nmZ#SQZ;gM(LdH}YX>YpE-1pJ9S@h|9h{ss)RkDPQTHIRkp$0AK zYSJdke-+G*-?G14dj;KTW(*MM|*!AXs!QI74vH>q>JbYDtrua;fr=HNiI z_x_++?E4k+u!mkll|%4#YOM3@aTdF{^WYXs{O~0Yr&b4+FOsS^2v20@2P~p^taYH?LYq(6kUwx>SELYD0Dd#V-v!OhW#&Uq5Fl>!E2|h z^s--&%pW(WFer5l4DWA^6-dEDgwZp=GZdE^u_0@g^Q*4w9BLKdmzS+@w4Gm%&;f#t z=c_iEHNE!G+uI=maM;3i(g)7|qpbivg;2w)>q&DgbpbD-0?6{Jz zzqBUq29lAE&Sa}%vGR(#(|RnU$NdPWIgN4`+seFn`Ls3E<&36K5adA03gawc(O*X% zv@th)WHbe`Fha%U(_&KTA42;wMXik>7u_@sAAJKNQ(05jUOVzEGUg%{+{tR|T8Gbg z#?nuS!z&x>8IgfUVw&NOvI=KA;D4EbsA-QVC@a61=JqIP#%Z3iLL17U_Hml`T{g^j zv1tM>0vbPYE{VTkWMpKL#961*b%r(cayjJk?*?Ac@EUSc__51aQ#49c^|&LM@q%u% z#@DosU=Od}6n3Ffw@Z^Bl2QzZAhLow2IHqd$)i)~xSgC%jfDy|G$1SZt&4nGf!oroeCMfG`7jyVm$XtU2m}?za zG#>#q2KJ>9`?x(iRG;^y*QHI9%QHaM!F>Xqsm3cJEoy( z7k5X?OO5^5M@LJ$j+8kkP03z?Ak$xa$rc28f-pThK9B$#IhbdA@g9`gSRp^=0cDzn zo5|U9ILFoSs0`kbj}whTCCxLDudS+j$$DgB;)MPUABjm%iYjW{@2|q8s7(#}gYMqt zL%g!@n`hC{#W>8bg&p+uPGfK$k=c5Az-_GJx1igWZ@~MhP;r?r!q)}k3@HfN%LjP^ z_RO%S$A{MZRq0spyw-TNlHz;s-P%B>4(>-EfHN$Xc@ui>7cUUT_NKhNvA!N1LNhQE zD9k^6$k5IJ1y2RmOK7zJ<CyK9=JVcESpK(|qq#ho6ilf@IrKTSJD_*aZM7sj0x9X$da$fBx5!w%y&^vJkX0QcaWE@shwuKZeQ)L*A!!&&4%Vg!ra zs08}``}4h49oIIL6%-Dhab%;II|J=`)15LjeNs0UcPcuCUdHa)vt|#mpn~>Ea4TUB z|CQ#IUWtv|#f9}qw5y5?yy!aNK)ybnV4r>^FDuL1eLMq#$&CntoDPTcDPJe2BD9)P z?(nALKys#sq2Unvq;4zW4FJn7fU!daV6H6oLhG6P;%pmTpxiyad=~PYJy(Z5e?E`W zxYixpdYVEaq+A(k>66#6k1jUUQS(L|9{Pr{Gg|+TO--;6Cm4Ogz$$wI`xJ)nvu8uX zF02iqMj?1h!0(FL7X(N+cpYHX@Dd+E9b{PMbpP^eY^qc67gTyF?>=^M`I$5SLQ3RR z{R_f@YA7Us6jF2mjiaJDu)zVV4<8pd?>SwvF$p3 zrqD{{%auDsKB=PbC{meLlDk)O_|cp{m-)#YIu5#PloyTyhLd`12kvulFySVmLk=6A zOkTkv0SVzFBRalOzH#JolM8-QE?8tyOjcc=eMjXbe}02sMp~L2Yk?yHwd|PO90zIL zjqG5_=XrT~pm7Q`AaVW_)W8`UO}*gJZ}nv8VHyd({gLt!5qt`JhBxqWGQ3xQw|SjIN-um> z8e%dH%1eea=gFe6JmI52cl8vH_RNYZpybX^EdM;gn68z zVn|@1RNR;u_VVT%htctkIhNK` z{6rB)=!<_1zHauK{0JkKmxDB5O2xl;eVaKnh<7%w4@SuZ!e(IoaGAlj(J!PgJnE9h}Rz$O-xeYzWmtR=DxNZMFcIlsB(e2xsC403gy zOEm00xRWdJ`z^O(n#})l0m_t9cn$tAy=#En2M(L<$0>a09zhtQo`K3IQ#;pg_P(#` z<}~jG=1}Sb$zd4b0VjG@iB64oDWVAaXTbV8!<{G-dA!gLX;4rG)o9es$znesPp zCN!1YUcs2N$?0^T9PliTPfR-Ni-2(iVNN)&_5b`&B$2TbbqOJiVf%;wETQcA&ky6FJHP(>&qN`VwJ!hbU!=+KPXGN$ z3CR1Ou%iy~?f2XMZ`G4W{@;5WzLq*k*B|Xx#TIANCnxz|NHB99-%k^5M}POrUb@34 zL{ss#lH{vH$%!iX;}jbhk#Ql_DJ~^*SK!bm)iZLbWv!r-{J9*s{RjB?s=|a1&)3r5 zA1AO3DDTuE4JRkY&VMMPBj3aa@Mf!rHttjX)^SboE+IimV?VB2^wd-bZthFSjAkH;1T!nzKcl_!&qc3!WKwkSBR<=kq+Y$AirSK|=j zTQxJDb>c9!!Q{~5Li(FYq89;7Tmo4GWj0L}i&=diR2@2YD3S>gF2bRsVWWBFJHASx zN$7%i4T93az6KyF^H)5OV3-0G4FoSJ!ZGSMA=5I^zt6R#!J!QY{zY%0bJw}V>r*~F z@T4u5V#`lI^hTU5C+GsIIaTK)gScElX=!6!8CRH0vA2D~eU?bqDbo7|WhtX6iX*9( zoKH0Ov-(dlRx>uspa01COzU#syJ*(3mKQZdbwBa(GMTZQzaCe5cD@w!Csgc*E_j?8 zpyqmvnqj!o^ELhuy4QxBEb{A1o(Y4edpPL&|AcESmH0hi|GT+ARQ;OWppMpC5f@h6 z6HUURuc!bPii{Y@?#w}jv5-#ZfcYfBj|!?T+8eLbZ4yEb2&fIc<6h;Q$nv;)ss3T2 zqu9(hy8Sf$rbWuG(G5YMhJHbqijSVs3$#ONjEsF=xP9Rx6R$v+VG4&o`|$GR4HTuIA1f*H@1v~H)5}IC z&L4aeOc*id#`x}IOUv~TWVk9mJxe#*;IC>}`}@h?!8aypITrWgvZa=!)vXz>D3snW z6{bl@+2X12VBuD??k<%gc~JZL`q(4SLE1Ylza|y0H7;F&C+7U+qZs7N^G0S4TQ=%2>;MWMoVXG^}?0rwbAO`R(oPa2@W-(hl#DVmlzvuu|v*3I>uaD&Zm1&u z!e^KMuDgea@Is~m|GrRG5aER!IE56_TJGb@YsI~MA$WrDsjC$TM|1TXM)tfT&Ll)3 zH2=83JxuWnrQpRedlD4qDv))LdF<`DS_yjvy5OMLAn)IimYb4=XZAO7yY z@5z01M3mBYFOl&bSk;^E`#(Gu2a33eDvnY)9{6oOr2Jl4woRp(w?#cVT{P%i8N=x{ zV;z#KqayNklHGOPHfb(lTFOhd)8+l;y~PCm(cKP|n zl}T>g82PZkIq_+sv%O@t;f&syV&`RhBfj_gHer=JJn$V-{I@^bB;f;ZD*1lC=ruWX zyEgJNA~WM&<%DLXyei4=8ft18P&8pTIa+kOLY-ywRDHaclAX&na}UEG0Z&%Elvqs_ zxgJ+_rvDwJC`(?wjjvmwyM3RlFJ30R?jd}ylA+I$5#EUcT8$0G85QmZSG9{yRya@< zjGEG^$(@-C$zLm>AU*AQ_)9y{1UJ9(_Fwm7CG3DkH#wJTgQl&|G;~J{c%FOxj)I>t zfvkT{Tm2|2gZYD4j-vYA!vnT?!I?Zya;x9}yC%;Q{^r(n8`;Z}&!6iU7j9boHp->( zczoMogwd6EPEt{t*7WCwxx_#(MO|2?|II3Y@*UgP?#M`-(2eJuL|@YkrX-@Wi& zuJ5Mz$uGM^T<66l{O7EHe;?H@KV)k2ZmAd-Bd;-&@=0z|E&d*s3zm>y%; zWKXiL<5oXwnkXi?)7!Tfb$ZkG2b#musg0~XdpgJ2)}X^rb$@rUbGGTIo{sv;jS;z@ z)!Tn#^54Hvu>Ch2#Ku@mUu9IB(WBzxJ?l4R93;OFuS)#y@5B>+hhh21iGMC!Y;95u z>Y__;|1nUe7xw|HlV8&Gc+di!2IcmB*HGH7rOOlCue$EN7T{@|KKq|~9vAIXHQ}Nq zkrP&yq0Z%!-)e7DUY(Aogsh;j3&{td%~-LTi6-JVOgPY5X)M0VMdl%N3gEr{_*`0u)RdaP_ifrZM?E8GQrCJpKk~=;1fIZ^###TN6f8Ow9;=caJvP@#C2O#S6HA zWr4kfsM;cWLx&KojP3mlpoeq@D`Vp%NpFw2Kf5cR=m5EOpEzkq< zA5gIy-u0k@aXv$=Hx1zsCkl~bdb@p$BZl4;WL1y1?hE5)AE7;zcDMjz@N4>f1Rz*U z40D`U8gLhFZE4vjmL0ry9PywN6MzRGD0mGGA8FzFrzg*x(M{=)P5Xqw@q_vibT5Jp z13)S1gDK2=m!7~Jhl605pywpt1Uv_*0U1_Ts? zrRNtWIk$(dAW0m3D7z8{pae;n2_006`+arpNQoDh^Rq@qf?~ z5`GLZAEovFuKQGR^%@660aAPznE+)3!Ul|<3DKt1)L%zOI}sxRuH!c{mdg3(qeqLb@#?du_VXAA*Vo@DA?I)r>H}3#?(D zg7KmxS2QM&4~{y)V;Zxel-E$w z2lR(=<72JCw^5;?t)M{!Qka;Tb>qV!=9iFe3N#0VZ`zITqIOvAP$yupoRkZbTW?6k zIV(7vU}1UU#0e^@aP&aL0Pu*3fec+adC}0rV~r3J??}jAfzdHX4tztofG^opVt^f& zkRXDw2|s@x{snJ90M_hz+Rg`o6Q2F*6)u*~#*%hraRH3y^7GGlt;`1VZv7edg*B8T zt^{%`5cvUS*xcOx;9zc*!JR}J7K9oOKh?ncH|@dJ)9a5D2*21dE)Pd*52AN3u$ zIDzag(>outu^yJM%h|aOoFKZhKsr@u=yd|0fsvl-r7?1P!c8i{}(4SRP^!LM0=Nh z=LuZLzuhR-`vs;VlPNwfEMrVUutg@;UPXt=%f*GhPgPm@BiUiEO9~ipcln;ihbZgG zx%!${L?mYP4FCfX+kq&766a~HHTAI3A>XYHbo_!1aEifo1A~;7h6YImQ-gFRRCs`57bOGLn;1>e#6muAnBu@wCvIwz;@sx^3HuJq-cZ=MjfgOaXG z6vPJ*dRZDdX&-w;wjh@Vj})!+c@WdFRjR4&AHIf%EgNJ@tkFuS-Z6-> zn8xaU4a>F6diIC1P#J+w$!H4h09Q1Zu&^^>mT?k9&op9b$PNJobqK-$Dn&hmV;`an zS!ieok_3R^_a)(pTtuM%AC<8TARq|84vE;YNEsYIAcuic+DkR@%J~-4d!wQQEjU;9 zOgA~OFn~ZZ`bf3%?K}_o>Kjp~3C}D(k~&9EP0ck-i@Qp!isQo`2oCnZKF6432N4$| z;kd=m*ZSF2vo_{%c>G0=cwp8Ai~_&wZw6g180i;=Uw3@@Vvwx`n~|n%8v6rYr9?5L z%xb?mb!~{g(E+~NNklyu-rWgc?aICy<1e^v$N0}p_Xm*B!t za{S!6t7+=C2zPiv$O2%b%u-8f2%F2BIc)!JX3cS7Qlvmh)14m^40kZ9GUP||&X8`Ct(!9`nswC>AGu8Cx9y;M8_Q9}o==(nqw3uTs~fcj8Z2QvS|%tAs9 zMJ0^jiH;XaPeeQTeX~+;2qfA`* zx(rI0a=R~Q8~UEB3&s(`#KEPRotsNO&DnO|%mWnXUmjpDeESO%ozzN|X`^Rj!-%J* zhc|jDHU)ArQVfyCsQ4Rn{=G=&7w-H!0WroJ<$5?iImw~uG2*}?vuf>F`eeQW<28(6 z5n6Fk<1)7I7n1u2#@Ur+VN*2*s-G2%J5?S4nzcyH47F@&A($n+!z&^mM@35OFK06=x zVq$FUB**cXX2j{p2s9C%yu)8K?Y*w~sA~HxY&opfs`2fU>7(Y&ZYd!lN@rVM=`=xcn77`GU%S1S6+dpf2w0>h>!&d!Qv+Y+yHp+`EUN3Y5xG z!3;DsxA33eZ#@VLtJ3^|S{f%55=PbwrSk}xY$PwA3DMUSj>v;#=W$<;rO_6nQF|wi z%;9`1}5oXvKFFP#KFY<(sijo^( zr68E8iR{!mET?(+_;Qh;i6TP%&;>58Ui2E@Y>Gl5Uj=jI?6HaQad3aMV0s+A_Oq}J zG6J0Oh>x-e3B#(9&FX#zbyx$#3x^Z3=H~3Sa0jCb6;pdQ);U>87#8Uje`>ytRe&T` zxHVQGXInl^(B>+UA9`rvr?{6-&)jO5{T3q2W`&_Wj`$^VP5y?*Jh}&Pbl^+`8FQgtUKh(hJ6l$pZ6} zk1IS@EsH~FNugH4Oyxmp>Ldowk;2(~dfBY7^5~xNoT>b?@9`q-u&D@IFVVA&(0oW6 z=x;3~ZlMc9e?d-3F5^fI5?rK#k55(J;otc7mTvv17SMLi5$LQ3e45u+7e+@%G0a91 zh;$0)EeVL&JeGgDZ)ZPGU_b^=49Wx)DHpfa9}P2TRJ08Z878at4G!KgGus$FPkJ)> zU85oAh%{Is;G4=`(`V-T9{AW7OdISD$PSpjLNMz5T|T4U){nDz?so5u(8wJ`s>%P@ zy!<;i1ij@2InT%VY`*ZfS(jjqmM;b^4eyL1ZEIReMF<^k{LfoCRMi%+R}mHx>iqHr z9K?^g7KgCi`~k8IdkzqMbY^OfRgg1L2|dqQcNSSzUVg*_6W@d924CyBdlcEQ7v|?& z`t>wE%4K}=!<)fBlZjy;l@FB@pPs)d6q~vt#x3$G@yq+!~+F@ZV`BoA|#G z_m^Q&=I#wY$6x4ZcDimf*(M$p>GimEsNO1y*vX0W@NCv0Jv0mWRKpn zL-qwT`5uWcfHsIgYxg%+Z2LE$ZU*us2-Ev604_@Ur6V*E{XLOi+&iDOK8BB|AGTdYs|= z0Vsy=oIT##Y<=?u1tDKKGzS460}wQ zD;q28B&;MQ{I!6C4Urf?J|Giv`*@Ie10WMV{Ss*l3w9D$>Jjmx z$vw>RI}>5lyrKNDwATg^9%DTKC~^=bioH#qzOd-Ak<(p@Azm_4U)q)>OBSk)ioSp7fQE zZ*Ww^QHt!i7*2V!H$4?6W3IzpDZ3*98u!tpkKfmx>wh`3Kg!n{vfrENju$*w|8l7> zyd!J;0jH5jYn;HmdDC#g)`O)S;hEq7IcmYJfkUzRWsmlLq|t;S)EueX}l7W6Q7?D6q>?_RLTT9Bv4WVC*8y$ z7{kQzJ^=ywSfJQJ+x#}LUCDC%YvQE=Ti)2-ZVpkN${kC1B~XwPR4@12giE z@*<(2Dj)DODkvxkvBwG_3G|dEG#MI}0gp-g*Nv-JO-74N!JHjt7(|^Tpte;b!t54P z*a10cx=duD&2$|AZmP$h1C^Yu=I~#3BV%JyDk@=sPB&@T*c5<(SHaE(TkR>l8KD0| zgbBnwEC&@PH>9@VF)7`29 z-&`LRxJ$!ES9TiTYr<7OMcLN8_HFD)CW3vrC^Fuq*xfhHRlu!hC^+pct>(u7;qIi& z9p^)biK@NGWflzD$c!sW{_~eM;*g{i+Y1ie!d1?p{;YGfBUwVqmn;ozp+akg_w!k2!MPCp|?* z2Uv~Sotm0;OtMr3&j#NRR>@pDT0f|Bo!6S|q;L^r@tHx7q*PdE$Iy+yeqA5mSOlHM z4FIk?i!ZeR785dez$bUfqsq!eoVIDIA>0AwO@YQ)SRSyI8}|qg*qxOEIima)Kzj|M z;FlG4v{S9$M@NrAOyTtE<<}6g6K_L_>DGSCfT6xV_;}RGCo@A8@R9qk(WNC5AL`cm zZK%ay@dI@UrEwu4#FhKeBFGwDWf|~Fga!We2??k|FculJTH?l2wKT7R)U7S(-cBdn zhFZkYb~~F#JRs)5#7_9_!WU3iWB{2ZLaVFQoBR7<2y%zx_0_Y!hKAP=-@2}@Lt%Mp z5<*8mAV$UPgg`zs2aHR?eV5dyAAr8!L1qqc={jrF`B-@R?Wgt9)DMdRJMxRGB{r4dNTK}uA5_)3+>X3rf z-KT_1YL;(>AVGx@z;6(qkQqYxk4RU;<_==I?h@l{)Vf*|H-FhGI%Eo6o9 zw_Zs>U8%DZAa^jlVTy5)g-vs0Hg50iKw=1a;7I@zGl*yqQ&Z>nn9vYPLd~=N&Lw7A zT3U#)MnO&=3rTn8{3)eGk(QduKz!ZrxuLP~P=UUv@Lx}J)plk*AYjNIFsuGB0F_cG zI+kc!0@5Dp6!}9Bfv|sS1)9QOMFB9wvVsDW;evZehBUQoXaPu*>Vr(tCR2h;cg3i? ze|&hpUqxDbeMzQOmBYd3%jlb?llQ1Sb@>ra{Vw`nP;RyBrs#>ngI~hkx?gI@?M}jV zQx}=uMv5?NJDsQGeGGtwTaPVzRbkci^JoD|-^KmJt!q(_bb(17S!CDtjSVxQ5;gQK zvJ%g#3O|*G<^Z2UCA$=DJziS5?j5I z1zTO8<-dKq4ORY*)PeJ|(+jkHb~2}B!S7GBWEai~mf8dA?K$U2e~N_`DhvtqKFeZZ zmHZa3k-?lZR1lZivEnfp%pPXLs~ebC)tUD&w35exg)`Pq6TCB1qEs~7Gs8mtLVqyJ z=wwtP7i)gk)=`Cp7Q_9(XE}>+M8+(lX12CpO4HYOiEZy*hXMHdF#UnZ?cJ^J_MvYA zOV#Atq~)6#N>Et81+_Q3lUMkuj0aA>0LjU=o91>AiK=9dB zoPrrs-IOD=K~`5OC@EzxnLz#j+*ar&)a#)a0y`!I3pzA}iq=96QIyXKwgx@7y<14{;GiH5C=u6;U%t(6HwQW{rXfsC!+_g{%IKWk z5nLFO?tT-hB^i8O6B6>&?> zzPPT@Y`VBC=PM<))i4{ElNhqOQ&UHWYZ2?pAhE&Cbs4TkR9=|kKfelHs0vvBetnxsd9sd zgj+76#}gG!F3q1UPs%nZ_l`8G$T3w_FI>JJ&!NzGQ%!?S6*az-m$+&p0hjzhR#97< zxup0X^b7}YaQN0E(U;^G3Uc+04UKnlIy;K@ym+mX z5|X^7ACy;W$PYYheEQoAM$$rcEvt_hR-O$ssjjNCX)?rg=0=_b-E5E5j!_~~hN#Hx z*fThPZF)l7?2RqWcKIWXChv%8KSu|(u+8|^Ey?Q9Z-&Yf4xJkmX?`a&=+3dq8b8m{ zZv&%6F{_yZ)imjTZpi+RRoCjgXVc`aQW7=ACl@!;)}9xeE)V&7?A)N_b!|w0aP-eT z!?mTj2bkM?6*g2Tv2P9sO$)*-x+Zab5^@SLDAnlN5?ASsuzi2L$mQFla`79JwVqFR zzGKQm809}gOK!(dK@f}@FNx5vyp4#C4mU342#xe#)M$IPy`$i-0nrC=*Tn8KbPt9~ z-VX#uW$2!N&9?R-KOf(zVK+Xc(e>;Hx(0C^V0{fUD{QX|Byd?|`L169@Ts!H=(7QM zNivy-rKP3a;l!iI5 zV1e}5?qgsBJ#O6=kpsY&*-##(xGU(k9?AU;)9q*}IRL^FQ;m0w%pm*mPOLcp^MA@nXR z6@AcHB>oKQt*(h*f&B$*U+8F96Lazc1Zv5;@7W-4g*AvczhCPEtU$`U`k_m((@~738yU*iT`V)N`)OPEfRmfu1Cu8b5VxN-ar)h1Vu_b& zf!R`LHCIa!1(QR!BwC*8d?ZtpZmfSNNfy`iY=3S#e#=dLz|210K?uHa!pG-UUVTzN z$zetDXw5nA#0|<_UZBpLqc*N~^6QV%)Z=8J1FT*kofQwKRLI3E4OFHI(852c9VmA7 z%bvpQBl`K1cOgIeRN`;~VX>ho60TNxo^?I}_qEb{Um-AWjNpycL$`ehJm9M@@#3$o zPgTPMeS*M5#>)|*g-1J-ugJ?#i7SHisKH68^0b|QQv$tY512l?%mU6%$aVE=B^Mm z?hg9bP>RPDN(}WLRjI_IkcQq7>BERvglGEDHH7sfdVYw7o563k967F`__9dhDXY|{ zMY;vSR`k@Cj?YN-lC!Xv^cs3VoXsfxajg~ zW`$l6`8$Un1DXfyv*jr<(mv9k_YU7%f8Xv%9xyuyaaaVCC`x@9g>VdO(e)dHw=Rrr zwX0d$Uc2~6K}AJOzv}&aocbJI04O2FRq@9_sIcemJZMbxNS7_lFPyJW#^rkqC3&C~ z*MXe_y-?Xp+z`(D-{DsRFbq(?`Z@sUzl#)pGP}4K{`Kp3TWpyhfbu3Y0Fz$2<)&dpCm@P-Se4IdLx~~fMUna})>}(i; zWzgM)cC?9U@p``mRN;7`dwu^iWEa52nCC;oUavA~0RP+1lqiE$b^KBEnqveilAx18 zE#%yQ|LED#7bs>V-4T^ChL2Q(z@Cy4;a;e}msf)AD!+g7S0=3UYGGj^M2v^2Q0q~= z@KB`d449S>?!f6`bL6oYelpJwx($$>wc2Wf;nma{_QtCirc1#iHa#^JjOu!vIhw$& zHAg9Pd}1PA(COLDTZDu`v9VyJQq2*6tM=s(t8O$g&j${2XFTU{t6-kI)1zcz{kpL@ zqATYS9Ck@IvbE#~;xAUqlnH~57-$=54JV;M?Ch+PuX|dLk6W95!yh5CBq}XjgBkvn zcXs3?<@4^xpzX!yl#{8rT~SfdE8L$UUmMKgpOBv<8F#R|gE;-JsDq@g9pvFD#6`xX zs|eI|1tzjqSB{4J`+N=hN~2w4)3kUcT>Rnv8t#WTPd-^OA2C#)RqcFe?z9m2QJE@Hu^X57~r___t^2 z6%@E>9X(oqO&hIT{>n0exaU@hn;Z=7h=OR=M0Bh80ZvEu8ybrIa!q@BeYU(Wy?k<2N!0WpygbX!IHTe|L~ z0KWd9)oP}aLXATGqd}soC}$p)MQ5{;(MY27z6LfD86nIs&AH_0G5L+eq92e2y%ri2 z${zk^M0AUOX|i_6JHo3)g138IXew3xQLJ%k&V-Eb@m{)Y{~5-lKXZcMqHJWb;(UI{?~CI&`7P45)SYD4-k+r zSq|9-mL<%L)lun5wrHDuOW#OVWix%DG1s3;XcX{HnqJAt(2%CQZ3r^L{fZ$-CTP>@ ztwSqJ+0hnqCrDZ5Uv_iA%;}i}!BK3dKBlFy@eMQQd5KjO#Y5>AeOzdx3aZL>k z*VC=$;)jr#5f4sFbO8*d6UZc>C<%`fih(AMF5p=pXP+`P z5x=NZ`C9lqigu8L_2HSMZu>6<$b5 zO1jLs)}>zXu|YJrS9gN@*rlVRFQ}*zGxEu=6f=D2u}ECg?c=jr)+48pFB?W1RgMu> zw#M#{Wsj!52)cV91!_3Adpdnv12^0gveBeaVR)X(`j(U5KYFV*oH*rhe$%?@!9I1B zyV=o#Dlv(6)viSK!0n@>X5$ULQN-3JoVpkMq*FL}q4Xvesb|BfbfBH$o$fxA@)_-C z(paebqksYjgKX!?H$(S5qalQC?NaTSeQ%D<@mQ_HIb*Z!YFK_^ZIoVs)nf86Bo0Gs zBTw#Chy=v;3eC5*v33m2Cmh+Eh~8S2p_xG(e|~pkImN|)Pn}COJ=Y5JuEQjHg~!?S z&7!|VM--piV9M=N{UjN2|T{zEjWqN`l?mb^pMb&e`rTd#iBp8 z_g-kz=RIm3uj?J$7QHs-D~<0MUr5TdwYTb&$&_(ny4H={dE2{m)el6C422N$&&csi z#*SGSLp76?MAViD?X>{$E$vV1OgNui{ zASlvgt1Br15)1H6SS1&w7VjiO*SNd!J^Rp>VmEC1`Dh;yg!9_+qIa5m_95n%i{_Cf z8+iw&JrNJws$hjNGg|>L-{qU+Vw?bBfk0tp+Z4R!KG2ar_i1V+JbyAqol{Q!5)}x1|0mDlM9JQMY$1Tm4S3fmrDgXX7~Enbce1$&v8rzH$Q@UpUr; zStP2Acdb$z zrD1RT)XB?wzN>EpJNVob)PI@&ke}LCjgMKavJfuxn@Qh7UsQS^8IW;DqNV_8)N{Cn>p?4H-#?$I~xy zH|8#B_@GuS)2t?_-Wa7BzsP026C1nB(^iuvM0ro;l2w(s)g&+nZ%D&tHniVxS3^@}>( zn==*)B_6GMa}cM8*up5%_{ROXL6NQZ3%StC?^>vPG_<3?(kD$^t?wGeeGtLr(pH{H zWcHZT4Wh3v*(RRjV;!nt1BntX$v#n zc{g*kLo@E;Y?S?wCArwLN z$Aug>@7j9<*?h))TJaqSN0nHPg%x&?gaWt}Hr4f>WKXQdhuPr|eE_Z`s@tm~P+FQq zxv-T0c8v>%$vz{+*P=)X0(L(yFE2m8dCyODfb{0lf;LtZ_;pfHNJoBj{q7}I(L;G6 zl4l&by}g}*S%4B6{ghug;L!A%!>0k*0#=>9P$>k#Xb?f6b$^plfkh_z_&A`)B}a_= zaX~&G%OE}416FyuBI24j&z{u!RYfM~p$NO}HXp1FZJ1U#uLv`Tw|j7(UyXMcH-9nv zRbhaC+5#JTbhJqPJdA4SH|7UW>2;9sop*zc(^<5pR}It;?e2ub645*jAk@3#q^`49 zE?@3ls&tNwYw|9{8)816J`SzDjE_msS1!}^=dNFL&nzoEj~yGZAHXD2JT{7$bR)-9 ze*V@38z}>M=+>hLyaIHhfldo8lKSbIlg+`+p)bGsFAmkPq!y3YIE{@>d2ZYrOEoUA zw5JfZ-9GY>@==zq_sAV}JQMMh3DtbbWqnqw*$(c?(i;c|i{Y>{nyMGMJe*`?C_$*H zTV#!ejR?P~M4YhZN=Ex5nKq#2)>=^`E%nUKqF+{cW?`x#wqTY;yjh7bXrTKlhY~_3 zGt{HH+D*-f!Q@&o>X=9%JG?6B+ zhK>-DlbE7A-=hsI4Rgb{_0lPEtqe+%5D_&;>FzSZ70k$H<0eSIBYp~VpnVO-zU7k z+({+qbm(YQY1R96i&tv+Ul)Am9Lr{h66y>?J;&Ap8Ov-c-Z$S&E5oCs&5f<6P+IA~ zF59!Hg@4O(Y%TMxjc>Mg4g7_k*B=ZW_|a-RTqN&1){IY0z}tjRZodD?1%W0gaalH9 z{;R}nm-_gy_ke_gvmxBbOO#C5{q+f&lFFq2$(${qKM>jy=V~1j?e#hKL6H!TbD56x z8?XbRIx@RI{xzg-VwVAnD%AdPwGI+C@yDE?fCy^y5FW6T#>M0a?R0R0I3_9QPwx!z z-Md3(C4lsS8RkEJXCKu}rJQZ;au5>|LeuR;cT5=36%`&Hjzzv6MY6P}z6Q`cfWZL+ z45;&b-TVMBT&;dE>AcFqF0XC7-#4>N%bupXrUZ}1(%=A-nDC+>OY7?H`q)qoZ>?z%lRGWs z{Y0Eyd+$PR=>Di)idPr$POjPOb}h@&`=7}3UWGyB**VpMk~ z859=3_FSI4?5OGQxhsfuk@D4rUsH-~{w@ZG!3Gz&fAFzZkv-s*)$uRi?Wv;n@hM31 z;Brl9Iq_5M7tM{LI-^_b#++1(kA-bt9f_0QRm@cR>{=c1fQ|KG*GyvB-29x+09q$F zOt#}PV6@%yW92O^25wSNh_q6Vx@@)*e8jy$a`STi(dJv{YT*QdNEubKuDGg9eCDkkc;q`gN1ymzF1+#G z!d&EqzAFiL2CT;mzGEW()vni?=>C?UDwRrTIM6>0F8$KBj)#xD3xn#{ zK+ivvkO8{U;7ht%_WDFs89QIO>r3K5@2CDVL<@kpeXL*i2~r{8ue0e?s)(^b>I2Dw z^I|Mw?t|a`uN-?YNW9`36kaN7(uSYALEq*6n?AD==)nN)23q0>Xc)O4PJ2SoVqP*z z&TUmg01hEwB1Ck{#<|)ZPz5uJ21dmO==8=O>Fv7)eU`0aS5yHA0WCMc#3*#FfoH%7 zINw3B1&%_?Bap?XkM?|>Yj7pHGkm$g4PO1plnB*0%4fI2bOKseBB8H zq%|lzRlR({NcHCUS^G#fNJzS3&JL1_3dsJ(vfBxoyiNapbN?yu%Ks^`w`+_U_g8DE zO7azl7OyOBxmau(Sqk&e&(=OnD=2yEkH$CT^!Ckoh2Bq4^K(=5+}{{2n_bisCozg) zvTP;QV>_BTiH%)rLsFNx@MK?~1kx(>)R$hXhI)=OJj*lU0Ilyd zxmZTRGQc|de0`CJB5aLXQW^y{$XvCt)6cN)L)T$%ZG`jQy{Dfz?C8{-ve=&H4`JOU zWGLt=*;|sC!5t5}prp(ichkNK*v)xqdxO(o!_Ri;d`9|fy1`%t^?!HJH-zepmv=2eG`?Y@hO^6&8)WgSYWp_$3;dmaO6We5OFI3ob54yYrFh05qNJ#i^}D8^FG5qBND_Pe>{5i{XJA7 z0$?ZuTqsT4KMkPv4;W{4UAM$RiWYhaTiXCr9Ni681)p6<6m&%%I*8^)xcvGMZLd3% z0<1QN_0dQ_Qy~zzhYljt?m#PP?sWkO7#p!XY-kNX32xB|fMUY*%#heP(v%^SF|<-N zK#tP+o%3ok!hp5;v(<@Ps{r-w`jLr~x#7H&{qqVfbR|9hfQ+=Hy`6p7;wwgi9_mN) z&fBdI=)}T%-9;~ZneJiBnw{il+h+?6!`b>L_$AB3gWKM)ey+UHYww$GZSVA1cz3&T zly`P+De`67MHfKKuwYg*Ws<7Lgz-sd7B+i_vpq4wyD!S{!kE^NX4!1jN@@o3n&`Z~ zfC~2zS7wMgezut}`BSw!H=~3Or^9_aDqUZvq>hb_KIY>m8TKeWWM%^pSM%;)*8?M7 zP1c`j)^W2x8ysmIsER5plOKTVIzg;+Qp80Dg%s|n8wOvgB|i`HV|=`A*YEK{!Z>}w zQuA-#42tmtbnt`Av^vtdj|{s?{j`Gf=@wtVA*CFfkmfdLKTu9BH61S;S+I|`D=g&f zwNG=iATl6w=HgM?jV`6z&eKdCTxThOL-)IN6~;y`_h$u$1v&5jBKVkMHj!AO_qA5< zD{`p0vQy*HN&23M`(`aaEYz8jtybtfgm!cO=lpuVmmJny4PNfQ5}&2><5jSS(qY$Y z^-aXL&`(Q&Sv@AqtG^&ijdNPK%`U19^;pnX6-R0BvR}o+i(JzoO zO$)$A1}*IkwNQ34s2IQcOrzGlI^x$F5_1v{pasFULSW>;KifF1^1??ATvx$3>tjo3 z2jk!3GeiUg_p&ZPHCo_x%RfgNF#N;p-o6!gQkRnQ(Wa-{{uhYiK3Uj&cHRT-dBVM__{Wpdn2 zf{=cR!4_aqee+OTBUsD@ev2Ir0{p!Cu!6W))|5Lf74mfJzUC8fbCg}P0g7KEp&|nq zu&~j+OUk(mEE3`K(uz&c7YFyfdcZleX%@Gk+uf9QJqgtb4v z-k0TOZcS~taMHAs5An_G(n0TnS?U_@?g%M_g>r7C8kdgjmukk!w=G?9f=oWw%{_?) zLu#&W>-*q0(cx3q+ARFLyn;LEe_kVS+9KKK7MM@AN8bMySRa*&ooAit*+F>|gV&vgtP^K?hiY6TLZ$3qb)S=Z z$~szhyzax}iBlDPM#X&hQ(;*dTTaaeniwe}9-esm?bK4_-0s9opz-FFE1u3bt_Spweyxp`NOugmgL(|WKU@GCY*3*+ zp!zESGz?RP&E`|(mZ?s`bV$|Y`R?S z3MJMM5X1^G2_CJaQWT{k~yNPNnI-qkJC z+S*8w8$e2=B-=^;fx`04XTJL%f85m-0PSO7F%odM<-e$PKNAxMG}8_|BcGAWz{CXl z0(iXv1Nnnt#{B4GCz^ciQYV0o1>np#!sLIVe^0jz*?@|5%HyoCVKJ zTSWBsp!s%+T`lID(9ZKcJqM#fYmu{KneJ%W`1B4}+0@c4{N4PqpNAigAW(}FvFGgZ ze@x0>*!`$yTj_=j6T#7==rSu-cXnN}{TMzO$)Izge;zjR9Z>e?e`o(D9*ke)Q!4dp zA_~^_@cV30LNmt$t4XaE_P!5`o>c7Q-`*Vm&OR+6M_yak+M!u;y2>VUsv=YKvP##o zBzC>Lwc8t0`?2bVmtW1uXZyuL5#w4x9qp2+QXY5TSyJM=W}c*-x?kg*ix_rNaY>Qd z#xd=6;ZfNG<7@Y91CI_T#6`eJ9R|45(HJj=2eBeBlX21f z(($Du#M*@TyV5hW*6{mYu)oKOxaE~I`n%i4_%;p9)*g>62cIM6Yc~Xyf|cDhYZb>G zZ0#Ak9?vk{+1h)4*h3UXCu)^GORX}4`-;{UW(9CZa_g>A7? zJ%8b3XfSTv9Rbb&5OUSWS##Fw0XGZsrE_RBtNRyUU!spp;)M$sQ2G%oL zTP>zWsz*P8a8B09|QFwjg7N42pv?vdVId$97cQ z2ySm~;hquQR3ULOP*Olb=oD5!sWR|P2j+{Qko(+t=0=Y0`QB)^IzG}$%wjimJsL^$ zfL-8SZ7#~YEydxfo}rz0}>Ra8@=hPQ;9CJt81U_DT;08g9a(7 zSd%2gj4Jc2eXS;r?c;ZrU2Rv$1$Pt3#@^&qxGcXc;$Mrq!%ok{xs&{|3AIwB7bko& zzig&uUn4oVFt_r}Xw?}%KUzoDY^eI>mxpSl!{@Rud4-3W-K@8uK!QA24DiQvBI4|X zD&%*p(#((hH{Etoc?LB{azc;e1ziQ%_ss&DVwvL#GwRob6O0=waP?SEJIKZZVhvE0 z#iv!>=7YJk!Y=YI$fg$IdX7H(kB|2^hO6LRFQ#!*G?;NNbaGIPXH{13Hmr3-QySTP zthDZmKROLIBr?q3H=WGwy7)t#RgWM)Avk-dymeMq-~(~fJKr=|deCl9;lm?rB&lOZvdi{g?@?h)K-AllYK;Navu zna?eimX+nEJT%P$uqtpM1i%vpm{69-o_bUT486QyiJf12uGukabcgGp9{>I^=pq2< z+jZK5R3^F}0H{MbPb`404fUnq6Gobc4}BEFlAdOPn*(g9=B0-5uG^AkW@ZrXH3p>V zD1dllgNu~kb4~zz_8r7Fj&xsWJ)>{9cJ?g@ z0>TmU_VvJV1em3v6Sv>d=$)~n=XaRhJ2i!Rotx@L434O4 z*IHzT1}w?8XXE0h4u2Uvao}GG^2;6Fy~lxx`b+)`8NGYkqezRcfzEmFY2NU%)$z%- zCy<%-bq8oyTUOH(5lPTY2^h>oSb8E_5Z>3~)U35O=A6ylD=Tk`!k?!q4JrCehb{+D zF;3OkOPY?q+RjmzEju4pKC3-33>KsuXt|c`DSS}8eBIjhk=waXfQ-E62Tu@oeJB&V zJJ4+|gHT->u4?bboQ}e&oFtP;@N-Yjt|&SZ9wU)n9bFUchJBNIbCTC^U61Ahv+ywD z@nN1LD}jUN?q_N-@jDnlE32Nwz0W$)*(TXuBTJ3##ypm(hZuD39*I`5piHRLKt%xi z)Of+MOVMA4BFNfCM_I=e+oBEvg$s1*i%=ZooFG831z2N-=`n~Rlqzy}ZzkM$@*Cfs z@e;k)`e` zwmig!MgmTns?B33*(7g8{5~S7Z;TWoqetd5tm?l~JDkyUGo|nKoKO8&pE#a4&1N)q z5N*PnC^s)UJ!>ms6FE4g2%ckUa~f~p)pI_J}qX^Tg8xa8VRo}j8G$lNVOsaSZ+u`--6Ht-6F7@WI{Z;fcu!wy9dJb|a z$ct`X7KNPwu!}6UB|4B!LE`gYI}-$IAUOk)0dQ4;NG~H=RtKC5?)&$jr7D3H7r65% zeF%zDVuofel$jlDY`#)dEX>V${UE--51K@8 zLDvs{J)HTaL8UZ&HHd)2N4vV@ivMCT@a)81-s8uk;4lLU##2*McAnzL4%>5*U~dDa ziBR?f2>Q5m_LW$<@X$~I5O&tg3V}{N$a6zjA04g5u6IxeK1(U->EO!>?gru3>ONZ- zUd^DCMa^#pw%xLlLqYjXO%%&M_bv;A%oW{k!8w#12p3ufn%I87ouX})%)<4Ap<5FJx6o*r$k{kj6s9A&gZTlJv~J}#`-5V5=NepsqJ_AkG7Ut+L_#SS>%0? zTdw`@OWk6$W0Cv?IvpY!5#4z1^pd^l)wPUs?kX0DZ@LpmYMJPr2_O3zk@J#I=GRbL z@NOpR`C6ZRz)S??(MrTrC6uCC+uHW?R&)eXeu+$}vo_Mul4IHy=jSS2oceRL+P5En zjf+YgT8unvW@c#|m$y|MSmsb=l$=HD4ySTJcEI|0@YSPo6YcC1HH1A|!Xyg=I|I+- zhrD#WOq_i^t(j`onrXD38nx*ju(*AH;0Bv%&0dednJ3=YaLn=SplNq48aaWo z{UaD7Ky>~7{Rt8?*7N}MsX6po6iBJtV6H`K;(or6xzRO zqI0__I9dYLROiKtO3S0wKC!5=4Qu+4{Fyj#L^5cOVrh|L$rx3R!&u@+&&d2QtP&IJ zCl)#6eH3WNUaLDbjlBYtX*p5WB?9PZ`WSZeUycZ7d}YB3vS62h4!pjek>y5Sx>{j} zHiTZDTZWV2mYLOwX|}D#*(#B*aP|`?0?d|QtVZ@kB4109k3Ysi$i}s7 z{J28R97;!QeD~fxeZY-DZ)GMLcpc$*R2DIV>A=WXABzr9`n#I$tRaB8Uf0O|1zCfs1ci(5>jCLl2-N$b@ z?*@3Z_;TffK<*nXDuj&A2>LpF|lMi{?K5@L3=pJMpjbv2G(nONPP#8nCE;5p z#i_sAxQY&jD!%DDDW`{CaYv2$X>;$E_qsA~JGvM#g0@qVvS3 zu7OY%nh^2)Zy&O-bb=RC#~_&btSvj4M-=^dH4HN0rpAw;W^{Pyh)Mxz1#w>1i#Q2& z_ez;W0rJSu=T8k26U6TTWoWRX=XO~iYl-oaE79D9_@UM~*LQorw6b+ZbTB1zB|r3| zRuW$xOyV>lFq^IiIXfBOS?CMio4mQdGSI&EqLJ?wbc6&11e}826!{xN z9BDBA95Q)atqVBsx%I7n+Xm3yJ@EKP`3DUhUAzE7E+_>${n2vtug9IB^yM;+D+*sT)tw{K1ZO&U52p){rdd;O*K*3uU%r5(PVY8MaUIk$(uh%~dUGZ^nR=>vse*g!kkrwg6aVgPLjOm)< z_QQ0?e|7WmZ{EC>YLny}MRv?6*$X%xtj#8b1#4?-*m4s1vUJG9R2A&o1${|=u&rQY zV*}5VrJspF-X~~pJPx9PwNOG#%!`H{IPdEJ;Jk8M`fV?SK^z5TMk8Qhxn<1r2r7BYOG_=mE`?dU|>$ zCqH1jkMq4v!4fN!lu!M<;CnoJ@L48I(vF-VYPv+5WFiPGJfa9ii0!wq1F=n zhS~-Jf!X-a5JY7J9k;6aOEg&qnWHpwjb1V1eD`60fz`2oGBR3=tR-t>#J2^>ZG;#| z`ob07m|s}%u_}U@Z%EGsuUg{I;l)MZF-QjW!}bjlo|%_%5+V)@ak1yQZTIe-AmFl% zVOI-E`u$wtu)-aK|JivwvHfrQz`@3Qe{4aB{~P%K@BJceT98T*&25^C>3Fwd54lNd zdkdtr^Ivh7>w;#@HG;9f=-DMol4&IQo%mxOtGt^T(m0i>XSA*Uci@-vC7dU;@H`S4 z1Y-ngC8fG0=lc_rh-#Z=)XCMnS8wH99)d^1cn@xnc42mfNm9wq=>GrDuR%poannlr z$X3;5ii*>@`!(isy-mQsn6)eR{!H&q#wkPrcxRHps+g#K7wq_uGFO8{01zu5_RN)zeG%?EEuI zQlElHGu;%7bwyX3_O9Qe{C$%waFdAor|UnN$^#(KNk&l6TwMI;mhV%JJ6|SQB$e`i z3FDbv(G~jr5%S+3;lzF<(|kRSTgXhWU1pqO?+SdPeKJEN@6E%(-HeG62YKDfw)d;I z7+HTm10#3_=*h32MOA}V<_3}_4DoEp6+yC&-)4J7F*Jp|*M^==a~>YXErQ=)z`qCP z7>pz>GXv>&r17}#PHMnENleJZTS(SQjK1;A%H?eLS zUMvpw=82GHIJ{TNX0J6T^|8L0U%4P?mPKizFA^kJ4 zy`Dwoo>DFBWfqs~KApzC8=TuH%J;pt?6lisM636M*GA)4*8O9uzFh1tn;NeFcxrdI{tw%D=WZiG3Ja8?>L1PiS|182Xu)m zmphf*WZu5je(C-f3DK9FFFwb7i`k9opX+ECE@pyJ1p|df(oRWW?>btP`gz2Rv&VKL zj4YgS0=OWhu-N!B_5OII#D<@2!1Q?1_)+6Z1Fa7NL`(GThujo|tfe_uZ*yr;Id z#*mgG@AL=34-ESZgE)f=w~KBNlEx4o=5!AQ(Fh&1XIw98zMc@I;%_E_PbW{UJ_X}{ z)!Fk=!;Qutdn;77)s?u|VfdXAM(X=#nJP`}&f2Me(Nkkz?fb%4^)KOGvHyg8{=GHA zpZ>pIN`7C?|G%r4jWLv6pl3rX1V0qv&m_Ju1Z<3dZ_?$Qpg#w@ia$AbR>ZW9ib_8O zvCsYQEKg7C+X6ZP2mR&u%{Owu_6V>OC@&Q)ZOZ-a08CYF@L7ldWrn~6=Lss~#^sB~ z*KvrU5hxkdpi2He>D}5ec4IIIfb#)VrUS%ikDP&k#tofPIF-*WK-~NT&~;pJ!LdQW zba;{oKj;-qOiUpBkvT9234r_Q!PYGhuZ)09r|xrjFIA$j4_p_wxbh@Y1{dw~BoiP+ z--Qf*hh8C1*weEO)nK)M@A7*Wc~7_m28F-@_R+0{z3N5)ywP%r-#1PlDWKM?Xa<*V zvjN`<@0LTHbo}=L1;+ml7>M`x-LfTxzw-(B{Sau?G=5N~Vq=?BkKYFn$=|aoFOWjh z`WGuq3iywe2Fd?U;`93?HsKv+tMnycbVM)y-vgIUyMzcCh2ITf{k<=Z3suzlD`Bs> zHK`hdrn@3zn>g-qy7DWQFHeNWN*n%gp~-nj>GQbFU#-p>)B`t zR~s68J(p0}Z-pP1IG75vCj?t8sM+rLB&|U>lb`}mi@n7yAJ<;gzuHozyJBgt1wIw6yS$cVBMcHKKb7(NhntF`rq%pm-7GLw|uY8 zw)u0Dp(KCK=%VuU&!-vb{#+!Y^SaOf-UcJZ{~c^L`@e&?{v4!z6Z(JW{QJ*22~jhD zzP;`JpL=9i4f=EG{|{wv9aiPqb&q1V7=)sr8|f6Jq+=_Bv`CkLln5dn3W^w{w1AWd zh?I1LC?V1yB`Jt>HwgU3a=-ii&i6a#pX0T!eJP8z*7MxY9dnL3<`@%K|GiE=rknne zw1j!$Mtb4j$CfRv`JWrt3;uW5Nn!)Y|MM)=&i(u4d)|CW+yCcD-Vy)LCw@F}#m@fE zJorHI?*Pdt8mdzN`8DQ$2T1g)f3J27VG1hS{QGMRnML-5-*WTx`p-2JU9pRQOnA}? zVt=-N{4e-4e&+k~25#^RtZq{_NNlyOkY;sTcF+{C{qY>5S*(^clj< zihBHeA<9%FUBQR`48W)Ve#h=BcEf)bS&ZR-F3zp(hMs?K3%khHof%zu;)e;Aex+pg z8mxcb$k{bph$-IVdP~!9YL#oz$tEDdGeNzv>fq^9XHGibZWJj>r`OKPuMTgsp!$|# zY#>Wozcl)mGWzM$yFw~SN6%r>hp@6AA#lvz{tTNmH~&Uf%e061+)Bu1xMyY&Hj1H! z${U2W`IQpS7{B&e#!ecDxdN$3W7a-4T&odb=?oJFj%eWFJJBiqsi{d?sY1I=C!5LP zp4VD15sabW)_xtys#07ar=yc5#(uLyWo2RM%uN@ zkED@m?RQ>C&S7RD>tC$?6-m5X+oh}tw+8=E>dN_}cLk=upJ7U0ZVhK;jmW`v zIInNm9YyTrVU}~({pHhYIjZ9#4PnCeKbsWEG!@Q<*CEfp|2IAKh}|;Z)Y)ZJ{urEG zA9^nv>MJQpSs-ZJa%S-OzN4ELEPh+xi~cgX#p|f?cW332u8Z@S!(zvE6;J2Sjju^~ z?Iyqf6=k+j)z5y;Z)@q9?snJ154WyKNCgOM@rzs#(hjS(@TAMa4V}f@!G2b{dgy>A z`OL9h2JRGlawj{o^=+d&*L!o@S*dbwc7N~g_BkgMYvdCiK%*^Nd|5>MzL_VD)J?(S zD!pz#1>DkA&+`O!Pr!9qc+r-kc_RFABbXD88C&xH(Y{BsM$h82Q(J!%nA*^S) z^gg8frKf(+eOR)N5%hZ7s9*cF(j1FxV2iM85HWC*-k~e{^zBGmVyVf~<6 zX3=~LTvs7>UGSZan|le=wv&01zGqF1jp;3*`PA{=_SxuZpuB|Ri)bK9P1awVqf%FP zzW^1TRLi^Axc;!^G%XI)M~X&fdgrZw4v$QA<=;PamfiN=G}+eWZR?_H;!IcG zNRpL1R=>k#>6&Mbl0m(_t|u*C@)CsfVKj?A0!TNxEVZfLXD0#Jw)fALqMeyZU8LVK z##!NcM1msR_r8!L-EZ@s>IR1n2{=myWM0auDiP$72rYG(uHLnAgk<8~-EXPkIVzK} z!6dishneX|RMg+;q^l;kB^04_1Gmw!!9o2ycg~QL+XH}sPSVSl$57vih+qzhNYm|{ zM_&{`La0ihB!kvVm1LEAPkBZnQB$Tq7iv5K>0`M|oxbuC>5}xO?@hv&%(bLA1q@V% zr^g1(ClxY=^H@1DIItMrCR%o9DF1U}0UUR;_KQ)0jIH!DBKf*KkcHeB zVn0)PSDu*NYb5QZ885L}dsaq*=hdKIkGn!fl-2Pr36~>pC-s6y1S|-!`4ZIbp=F$H z)@BC5?|(c;Fm9_TZOEz;Jg)DpL9i87rgKiCvG{#%c>evP*aZ&JyShY5qI)8W1OP{Y zGx)<7x%5VI-opXqwXN2AW%R0Px&?PEO%~W>S=)n4bynI!Qbjhih6Xg#>(6o-={KYvn71?1V^49<8j#XXdx zj?Kob@Ud6cMEi{ErnU9ERSsr)dR~#T-p_t6C5G{8_j%@1UUw}`e>dLnD-+-kw~T)i zHz}6^!WG2Ne*p3eKk}CK6VyLxIR#QxFu|D3so^Ln z&nUl32mJi?i%`S1w46B;oBJ6;{HWQ3B1VRXN=kY&QI68<*-j#b@P8J4N@k81>rvfv zy7(`Pw70kCZ#{ZzJF6t!^wPoQQkG^zmCG7=7D9$!UIt9dK^D&BU51U#@?;lvR^Smx zjwt_#gh2$>uR{Bu&+}Be++8_HrD&IU4Aub&o4#I*moD8%;X`Kt{5885#gOL>Ud89o z^84YuBE(RLd_5=cu`?7g+k<@FLFn0$c0$B*kPxsCDG+&1Dljn=B{z|=X>}&6vbRn) zqI|#jIu(=fwuk^uyFc)oo-egP5Zl*j5^50wcMWv89PUHO&*aHyF?$4-L z9PD;7uTG5ZhzsPp$yM*f1B_8xd+L`M{@SkGjPLr8TFqCz5{O~}7(6smz-%{Hhx`bN zk%56QzTkl`dTYr&8ylC+r49gPzP?nPhF<_&UwPCQ3L-2P_Myj2y zEotvxASZP#yeNVou(`R##+O!9ACZi|VzaWg?nYx4=omh&>SkQ}vF`4l(St|mgn1Zb zT#D+z7_eC2y>XqbJBdEfG1amsU^_f7{ODfr-ml7)cgdYc`y~zuM~w{Myj?DEC^GW3 z{?Jfgm`Hb9*X>_tEQ|OAG*fgQ4G)hzSm+Hmo!OEPcq`ny{;+WNQWi;qjmPu>?b*5F z4@0+jmHz5hr7NCCYsAgs;;$B7Z)#F#q;$5TxWY;-QPT(G7-jvqxVY$O-Q)4rKqMf0 z*H}|y1#Rf1rT9lI2sQuBz`kmDSdeejT9ye4IHq7Ti52S$?ZfZ5%JJLO zwA{7}?a_z#KJa4`N;a)!s#VL?A9Fre%51@F+2hj68`0W&>8pN`gjJ?nb0cHmqcb zV>2`|cx-giFgaH?Kl~o;v}e_o8;R|yYm){;LxU&ueHI3b3fDIF^6_pSW^)WJvOM@EH&1P0!*v^1U@6)5^ApC~TYa@TpEmO4E$K~H|-*Te!y zP)<&TG*S(04UUd$JZ3|?*{@jUjSeBPFdpN)J2gppcGC9r=@E7`v3D#hv6eqKj*t`n$-#+&#T`kzWFt4%^F-1%W~V$5rVi;kszk-e z-i<4b3gVjT<;^wkHZRs;Zc{8lGo>KJyn%6A5gw4YCiRs!8${2!IWpG zh0eo1&ojYFsXM4WK! zsjdEeM^7WQZu@!p>e6)uO0oyEPRqsW+j&FetseiA?D)v9Zln+CP+bVI?8e> zxODl!blut)>pd2EeATp3*0XMjQK#o+X3B*s$%r>k(?#Ed5mM6m<>jM$SXj^e$<S zeQE{sku?onHEO$8zG~j63(@s0?J00gJgi;VHDA-JEBs)q&Rf;^`FX}m%*p*t!t`>{ z7qv%4yx)?D?Sg>`l1279mSc#;s0HRTSamBdy}jkoOcqg?za)2gef;cym5*cKhF zI-ug|s5O6pOW+yzt~(mOoIIxv>!ucjY3%JdklSf=nt;=|NjJVb+&zMfAc(Mu+qqCU z3GqwaxYC+pJTyNg%yFx(qMv6{O?dl8@LQ*?;E}(LR+i7q=&tU4o|(m`%O1(P0LWzef@}V z>4>3>Lr>DC@wthvMm{axzw9b`b)P>=*|Gq^(;|h8>LiuDOQTeVM(5mzz(l#pp81Yn zIU-)c9jX(G+q)ilgSBDf!0SMs1YC zRVFE1`o8-y=absI#VW+rP-x;YX$lbbWs%Z6}#X(jcpMo#@TdEK1pJ5m8VU3NXx z$WpH>Akz|99a+*WIy%boOP{&f?uOEhP?ubs){@=!+OyNoat(GW-TRjdz?&&z&zl#2 zj>X5f^sJqrd0Sy{qwpo2&?L>(8p!~fHIoN@(U;}T^E_39FSquSOE~$RCBD;@a=VS` zW@W3&+iT~_*{m$G`@lSl6 z)nmcoS8LN!s3;*>CNxEv<5T!i8&eAB+IDl|p~{+VlLr0nfS+&Uzobm2sn0z7dYe~o z3D`9|ClSLjV5meN&63Q6=56I#_eCsE^vZ9|`8D-drkJ^J5OZkPCu%H}@7jAkAp350 zdrHcrmnz$ffb5loMh>6X#ezc7XEuu~uO8IP?RE8|BBOm6NH4=vA8UShiq1EJMoQ^Z zPIAT^2V+u=evW;=OQTIu6cv@%$V0(}oUrAa(?yxQ4Re#?TZ8$WuxmtWL@ zK=Ar?PZoK@^!Kc+kJZCJ`zS8nDd^Rw3N6-3&3$ld^6e*10jU6S`x%lj?YO-@+ntMv zV?>&m02@!u1l0a2W!+7L`c7(YZpU@)EA*c449L^93m%FHD88Con#)q`T`yeJP!8=m^o?K$t`y+7*~AyNVK3-E?Oq)$f+F z9_DhbRIM8dAa^q9(R!_Y(0Lu($e48>Nu^tV>S|xkORAz3$@}JCyLOScq@A`eeVBOc zvrFI4m>>>~Jw!o&iVAvS{O-YvpHE;UB7V*mT{l(#}&*zwb@%0ZfujgAt zl6e`CCk&=lc~Mt43a^XHIIHSZbgCIVh%cjOWkkL52_fWj3%;S;70F0$+!0;cWo{7H zGGQ64aG9U4?^I=yoxSzRrJ)+rB-M2Ky@fq0ly<`N#gz-eA9W{fBuP}8t8ca#FDx!*tJy`rBJJXyYI|3_jNB*a0~eFl3-8^=(Iu|+c^}2s39vAhDZVXKjGa7JS~8nN|EzDReJGvox$oJyr@jx3zZZe= zIKMEn=A2hK9&e{bmP}q(B;7{buj3H+HbdnRa}c-ZBt}i)Bkwz;0V+~Ky=^lj)KW^{ zGQ9TjJfp2n2&#Q#XVNO=J^Fj8v0o-M@omCUhr;cb8ScVri={g0>7+K7cr@nM28(}d z4&6+rr)Ax;$*9cgQ+I#4S3fd%LM2>o&mFXlmkHec(ka#`<3M*KvDK-+?gg1^?iZUP z`o<^Gd=JC}Xhyo}pJrvTcJY?;Yd_6zzW6rwb=Qj#ku#1e0W=$D;@oGh^cJKi8GNuPi&i_ZzL7{nYsaL-zgscYk@G zAeylze~ENCS6ZQZK0{6@pUwT)oKAZrp(m=>$X0?F0Z`UC*9;nFW=%s6%lgQSDZkXJ zO-H)`ujD&7XWpNzmO0TKxrEc(W+>O!rXaw#>Pk500w@L8?@z2&;+#g&(Nnsq}=zr!rDaM(PUP+dvY-Tc;d z&r6`T$wNZ%SstZSQOK|1nJ!xw$-Pymcm0`eV?B+T0*-lGTUe#@;ii{t^eO#$wip1)I6vUlbsD<$o)xClnbq*Q74h_+@rQAAubG_|5X*uh}YI}O$ zP>lsO^J`w~C`(&|Uuv?N+E4tlL|%2p$bOl-QSH?er-==D-?Fn(z*}u+i3oesam_NP zd$s%qIuxwwvrC2P6nV}Hq5ij=&U4mIk!|ODN=#qZw4=OSr(lST_~4)VAyd-E4ZD$_ zhG*p|2F~fV_r=sFJ4E>E8%ALy{0j7mmIFy6-M{AC<`s`+{IyXIPl z9G_BGR8&>aS0yVmS;||A=!(qQ3(|7m3{A4WZ!>?7ecXfLPoP5^qsQ#jbmaXfNct-~0h6 zZ2&OJGtMjiltEAb*VhLf{5q{L&XDQOIk$EC&%vYOkw-}=wsuiUAHQO!z|tqO%Prt| zclrBSK-CI`3`L)X-h4TFuzJH7@SMJY8fhPP2x%l-`FBXV#MT_P4--kFK$iRo-oB!z zV<(T&iu+SC9sJ)PW5-Y=!J%mQ?BJ9CeKp*;n%w|te$4)_tJ!eN6d*xKQ2FoweN(0Q zcuw5wy&B%#dq`&~C63QT$Gv$YXz?L`AJM(&W4LOPIb61zl4KVpL#D))W@zU^@)~_0 ztt`dNvzyjn0-&iF4#yIxKYQ#TR3h-6Rl<8XuXJh0W5k$VHZ?WLMe<7paNYlTt#!6x zax-iHqzV-6rCQJs2G#s8UWbW>!5UH_l*<*^05CnlmwCW*vl`^J7bPK|1=cpRO!erc zlu)EcncVF@aHeDeV8sA<`Q{0duGq%`ho%idP$0P+=^}9z<$i`8ga-|9ImSiN&UlIN zfkqnlRCi0Gko?#4DZQJ7Q(9WIEAl2DhswvyfizLn+ug(oH%%zglb`~{Ea6X?Qbl=a znoyb_K99LTD9ogOW=cHb+CqsVRH%=c8Lsl30#4{P%mT6z%N$6%37K3G`-oQBd*S8-S1y zYz1L13muuvXp$ffbYS~j9h#Zh{E2Jc#6xf{vM)(T5mB;Yv<$Plvq{d^U85iQ@nLcD+47C@+w7sr$ggs|>C1jEsx{ zG>*>B#1Oskm!vWUJq6a}s5rpe<+g|zg8?L*Q1t-O6`h6M=xl_!>51*=5`jlvncuhf zJ$!mgv`OsVY3^zg@}7gLBzaGi^4Y$XRmRWv)eT?ON&Ut(lM|gV91t9=8RA$=+ZvM0 zXcTtn3B#L!LtZJ=JE>zXemtBdvK{(xBXZ;SuhaKL6;27ypnG{};k9Fkb;HF={cBOy zo}MtUiQt8F>)hi#hnf(FX&%enmH7Ar;5@#4Z+qMLX}T^yBMed4r4bCJcgD+?FF}Zb zGgxVc>cMZjjvqe`Uk?$N)r$t^;K1VV)gRP}-jVL_esn{OfYrP{&@yedCt&h*734M+ z^2#>r;l8-G_F%DDa(}1T1E_g$paBMaYskr>@Km-s=w(6;rpy0)z~PqZ>EnbC03rx) ziknrPpcR7$>+SzRK}0>Z9mN}{^j@q2lRRs7_8u1rQO}_#Qy-Jg6X0RF1E%)eZZrbM z^Ytj_!SkA9xzBlqRi`*VLv`ObXPCn|zzy!S0s2AzZlL^szO&(=seRjHyz@T958(Qz zo~lwY8M7nyOQe_AbuF#4zY2D_QAl(ieSPo~Hp_vYmv;85*D|ezLDmrh;~dvWxR)v& z@}`*In=`Ix;;4Q3mxNrD;ERx5Zs8c4|GaVWrJd>?jB+%w@TwkEry!94SP{)o6lBTp zMlf!K0WUyO7PSvVsr!hy-9AwAkrJ$UWBf(GM;^f&X`wGv`oP)es`bFf9VurH9Z^I> zfSQ^bI$^B*QZvRiV=%@QUrYndK#J-+8r^4|D97@;y!k{0(FKXJ=kS=?+tte zNKZ;e#zdAF(o(K@W7mxdiCKddSFPA(b~y*o{q;{#L2K;3x%D53YSnl%5y1Tid($rvA*qVoJo)d~c`-Uwzbk0GAc$)E13XR|M@&&=`iv zj~_?5ZXsJ%)x{5>A{fDWTe??!eYiFh=6KETZziL@#}F(%V&RY3iH2waM#dK$@ZS0k zBReU7XQd9-&e@$lglT`zZ{2UnvcH5iz87ro=%qKO7dUwC`>lsMbB8Bd`00B|4r zJ+#hd)V#ba8#86b-eEFyRh_8k5&U;fMF=|1KPb8rDVJwZeKfEJeEfH?6TY^r+6Y-6 zsC>e0*=k0N4H7yiE5YXJ&z{j9DPRwq<)yJ!Nu>`wpyyXtRJ?05%j)_aqk+tb8NIJ` zfoK(ocU&l3U%Q8r_v~ly z3{;}N>oAL*+y~(=aO^KtL5bYSZv=j1UgYczb#+>qhBYP6rtqww_+Ih+xQBFAzv@WArkGgRm$8I(y;RrFO#azV%Y1cSM8j)utQ;*D|Oe-`i=E>TJqjYYwLqI>_gl1wS`-(b-w$ne2(!cC z2uE{p?XaKl`ny%PqfxvZ92xnm%i-5?Y4a;9iA(!r=mIPC3HHwhb@lbKbb+URu0C9b zq7O&|*e~(~V8`;=z6&aJ41E=+7Ut(c$ixR1$26P3?-SiqPiqVzTT8)rF9wghg>y#60*5(j18?G=DRE@5){?n? zJ?>pddOCZwa)Sw1NKlYMyD#`KZS%ew=Qx$q zQE@v8G7;$QY0AMW>`?Ry3JGC@K3GEMD-Hu#Ww4N4S5SCap9YH0b*2O+bQcktjoR&? zn=j-w7{Ieh=;O3=e(b&y{Q9*_^&0g1U_>SXm2Q2eJLTUWn-fkNBE1!Q!U;e`M63cM zL=P%VM3WV9h(lZlpl89cBl_tin*QE!$d3 zCs87(VCs=P0QHLcxuQeM#i%LD#J#A;k*Ru1QJ7YQ75&$FcAgq;C^J_LU(@?+n~i^XNAX zOMm$A?%un1{)ucKHRh&9u6Y*@3$PsS`icfp@iQ5abhkuVT3dq;^N}a zluM$kL@H@?gY?_Uvok+}q*P&*M^GrAo|w4qULVh@cE^lk_x{c`%8wjA{t(xm}xfTOjHldTTG|{m~?AX3fCcSQu<;0#| z-B_EIhFrmJ;g@XTap|W@Ou?8Lbb*Z2)Q`WO6>`chF77epoD>A=q%oYzi|oIg5nK z%QsH!ev}p_6UmQ5jfss7yNpWvCTcCf(*4YP-c=T{1rE!y4~)^mcr+mNOpe?-xg-LPgN~HfG}@ zzL3CC1?+%!|0kSQ6?1%u1P0u9l-;%Vqhhzr1V|EM%~dOWmpn~Nf;adz&*%8|V_h{%ZCD06bYu!MN+A$ms- z>HV+lPeNXNxC0$5JfryL=Uf}z0kqfm5>v6TF;f{Z@Baj!UdH(8)V#hE>8wrIt#D8p z8yO*k?!lpC$l1)$3znLOkeg&Vg1RbIqIDk=_r<4y>Z} z+0Voa$7ImEj5YwDUGc%pN6+%jqR(4sbFmenuy+Q6j8ljAu2C*C{o)Ddl8sj)cm}8a zh_vsEb#@){;jN$r$HIigSW4=JPI{iec<#X!rAxRFv~a#Pq4PLe02P832@StDcA9TL ze0cfE1N0PvkWWSBV|RCma`h$3V-q@;ssfT7y-s`u!8`?)M7FlJ!v#AGcU%_a_xQC@}_YWJ~6)VQ+f! zHO}Jfm!obwcAYZ7Wa5g{LaU_=-H@pj^eq%EULL`%bBmTy>&)!RiYvU7pr5+h^yRC<%Vb1ZBrSs-7tt4Ls@I^Oaj^=| zb`l!HHFJ|i)!~`7aaPEoW zw(Ic7$PLf4!=W5iu%SYXfm0UaCacM&Q_KhPm8woGHk|jLB}8}}EWSfcfHB!CT@6EN zenTy}O=(mzUa70%!}K`Sou>)Oguox-3U`-VPIV%VzY&vVr};!a5L)IUHCx+n)^=bf zr|wr|g*<`7d<{Lb^Hn{)^OfILGs}Pk-ACwD@@MvNRKeJ0ti7VSZe!PM8ULW#~>eHdx!*#>WJAnG;4? zmKjF70yd+1)^*XYTVWi(rlw>IOt~x+VY=+#kEr7TNUg|6eEj_UJUs`)p6(;2^7i%Js@2`1PNJe~kR2kI>4+)) zoNy24&Tx>>N{@A0ePdyDcR~_i@{mMm>^KkNU97_X$HyosS)ddw~8VTt^U@%puEqrFAE@qTmf-pC~i5CUp*Ky%og#23eRTmf}Gb zv-sHFOj35C5TJ5>+uT)=K+or(d(cBXy`z;ImJag+Ll170{4GmZY9@6IQ)#NRQ_)FT zY&t$0jHN%#oyK69-5;GsifkLsH$akz)q z8*RyJuyWDR&~R~aiHJmVTvfc}bM*$yf*%f|Tb|KIJTUz9;k^g5=aktg?tQhMGgp3~ z6DGq0#GHQysD>j)s)_)JhZ+<)KnPtv{Dch+;}X25Z-Y{e&hBCd>PrP$4b_3)OHO?n z5+-SbABSL#Z^G;ln(D+k5&+gkIIf(vV&|5q(f7^()J1W4uZ|4Dgf|(2y(xB@6>V+7 z`mQ`9vhwoL+;_+fCf7!yRhfd}!L2g+VDJU~dv3c|iC&19ubs`hE+>~zDT-NHl^pIQ za4wRSil^53@z7F@WQUSm|AVK0GEXAq|1bEfsw>6%Swm_E!D$g zi{XY8|J$HhTO-r#xWvQ}M4_h)045_&j5E(fE=mxy8jJvj7_)x>QipP%Pe4T{GBi~3 z_(yC=4{+w%h#s_?wGokC;*6*dDzE6cNDHIv`w8IV>Nxz^qrrBbo12?pw#O3va6Jim znOtJrdH=-3M7}~*6_sW1h37{Jw%o7?Way-iB=(*44?y0C+>>N9_PHT^0-;?sMp0+9 zfUV0kTqIZ;4T|P9{?mh0cM_n8g3#ML0|_Fa*T88GZf;vZv?O_h5>9vWu4rj%OF|}N z1m_Rq?ekY9C5g}Qc=J>3Ibzw9FIKKqswHJhpzgkhPRc5zIey(5g{sP2@%3;^|Maus ziXstF0}k@F$m-mcm%k@z?sPl(!&M##+JG>h{p=@S-j&(y2FhYLjc4B<6QVIH2iIIR z7I~p164o0rtz$GBmP6Omx4<6H_IM-sH$0A&x9el0xbK8?nJ4Ju2@}f&DJ3aGJ?zBp z9|Ps?*-*w+Jhofo{bLSM_smlN>AES zPA~VGL3j&l>@=hc^vP}fkn7XA4pvQh zhf{Ek3W?_u@C~AG$Krc8mp)6mZr(c)KnNdLxhf7p>dkUY*Bh=1?7gI zhgZf-g9hI!B@x;#tcI>eb%C`22kGMxUwS=BnR6|AnRH@4ns9jh6&GUPPdYlL9UdBlL8n3Df*;t)1%$cobG?EY-EqH_sSx=!^_U)d=GXb)bOmk0DAxS55dl;lQSbG~dim(>S-l7p2fy;x*fp&*A~2d>(` z_65}#8fAt3(mcy=!@$lsb-=g30}Sa&-?S1DL%~_%f!(Y6jV3aPT{rg5lqrxmrGE_L z8r@219fJ*(UXBLoK@aKpaahXs+A4xq>Ecq{W`=DQ4YF~)HO=FL#atC_`WXx)2caBM z8kMAGYMRt#4p?L4Rwy0}HdR2(;WBh+7e=I?4MmQ5K>_Hh=%k0%4%bI)+h4ZL>T-b! zS4)c$iaIcx0}q;_&Ul1x-<<^bI?&R3=zHPb@s%%0k^*5grVM!R%kX^<@n%q}@ud+v z$-F#T+OZ|PFZv{byA~IJj7wZxocxw_vOdB1Pc#Utbr@7Ic}br%m4Bxq?|l9b66*(2 zE78iiKG#^b7~Myg#9a5jgxYEgQt@euAHcc71nkr5r5SyyH+2fg2$PHOhoS%(t_v(J ze7}{WgNCM?;*cQ$@l995i~sAx+``KP(9!arKTAjdiERJ;^Z)lh?rr0Ub1xT793qbC zG5y z!he+4w8aoO3z^pyrDIgZ5a7jb#W=m%=(@F_mu?J;1E72a=;r+XfJg;;oEMyc4+^YD z#+RJF&(~k3Zn-!Yn~VLVT95$!NyD{{i`#GXiiIK_&z& zRS?cLP(0hb&R)W0(Zg5cKOj~JIl<`Yb7gMGW-eCQ&GZqP&ta^F_Vc#h9AvTp&R)qR z;GfNoOHP}J-4U9eI(F=QU=2;98-E5u8AQ^kf+1S+^xa-YHVo&RMZSv{KVTT_8kwi) zK`Zxr@j{U)7)QTSap}uG%LhQ+aU&nyZ(TfvR);UA0&9nZwM7*bn~`}4*pAb58T1nX zDX5=7WvqB(x+wU;tGz_@beqoNaSAATJ}5Gclv_!6-9$6X2sWVH1KqudJCU8;_9p0n z+azuO9ue7Ih~Aco;9;eut?cgBynoR_4_465{7aD4`c~$;4LB3@|4J`%%z>^5qE{hc;Insx_(_s`Qyj~5?K9QY@fpgIhkoRA$SB&a-CcKtnc&iC0A5Gn-s zL&L*44s-hWJvR>Qk%hobzx4KQmfn1-#kMj(ukXzmEFGb}y|q#XxCMrj?Z^wix8Me< zshlTQ@H{888n@OOU8RriC4SmwCIn#00E#-3KD>SRtgK>9D17dny?oy=Qs?IXAk2Ze z&~a>a#~wnsGX(|`fW>ryFSeJiNlU-khx9jquH`-whrBU*qpUTY%p}LHZBr9(F^p}t zpWILAJ0cQ1b-&=Xa4{2!CqRjwX>N$k0-RFHJWWI)2u!ri41sDmm#GqbG{VD~LTl0I zQ7`!tSPfRq*picn_*|0&agJ$g)ii5pP!LoDzZh~Nn~9a!H%7!|Z*LFp-mRMjWR1>q zgIA=72{zrx#TjR+^fO3MUkwRqAwGbffTg41_I^s<(7CQiuZD{#{KE+o5IH>BfKj0}Xo{ExK~ublGzuzSmG{vQRR!zy2pPId6cAUnfFifP zw=K%7SoG+ALmv`g+RvW}j;O&U*Hs<}DUo?qn)9@3W>xA-$;+df#t~7EHKv^0)>epd z2!cFfxI41%hgeo2uYDBfHSovL@v=c(M+d>tA%NOj_k|3dGxV0s)1DOFA3oU2Lb|ZD z6ij0E&bvNo_5>&Z<&%AP9 zQt8_4yI#^JyyN4GrbD|~As%u>9A^b^!BYmnH&Rk32*~xA`+X~`3`1k>@(uQHdlF|< z7tILGY^%&{uESfW@!AZ5l2|71c9?0RK_d^FpZzzyb+ z-pt!xvK+8T02n294B)symRIyToGB9nD15HEi27WW(0z{so-K)=hO8DH4^N2j_2;S3 zjB>du`Sse}zTz+r|XNn}$b_Jdn(c_m_#d*6C8h77J}*0Sgxk`?07LGjL?8 z*i|86E}!F60+#VzzbD@cJK~#deLLMRB(f*t9#Z?Pzqs3#>2dBaetwP2ZTarpyF-<4 zU5#P%4UF7MFXCvI59UZ$irb!vk<}b0iH&TApw7ShFD52Wp84P0 zB|43tca)ZvE(Rm55BwcZaq^@AXBZ(7PUfy>9=X<;ws&N>@|zjAkYaj=D{30qb2uHr zyGM)lqOmb(;QW!kQLmz-<;inV`IWl8A4MEiZD`-c8YW(PN52`?D9ZyF6HBjoBu>+S)Zev^F|_$UGuXLn7wROt#hT1=1cw(q z$aP{?D6GhgMMXa%7%?y~n5t5cp}T=%PcW3hOdK5xY7C|2>ceWKS_U+@n``wU>VvpE!Kfgp)eT*h$IZtsQo2|iBt_WFvbxMy{LZj)o-e(~ z5q>E-vqUZ?YHMPe@S4*;w7Mgr zI!+!JT0C@na`2AZWPe%oGC^Y2<^svlWbf?gS%wIuBpF%R;YK{p>_|3u@*Bx*Jgy!l zYZ`sKaa0Qy(l^A|eCV6ZEa<1`(A55L$^ATH6A%fIGV>u#ep`V`11s4f?fucJqwt#m zd=2Uc1hnDmZQvao5`vm&+w_uB!(;R@BO7ZrfmH_KRQ0J=FLk+Gf7*4Z>WFZ29WsHj zgrvn z;-4}=Y>vo~nO&k*fbae-Zh`b>6R-(54JLzCbuuo`AY$oAQD69eC;f$SQsN%w{X+g6 zfSMT#&Q^^?q`!Oja`K4=;Z>+ZR8&_xJ2*70N1>jA@J~oqs*2o{m4SiJ`qyCtnPLrw z+mO*>DqY@Lzb8SNNo4Kk$+^eGhz1Z?G8oiBZpCc}C$=~^IWwEA=;$b>Me7iFgoIi+ioJA!W7wBLd&&OUNu+Sd#l@w9 znPxtw4Z!@`MYT_5Nxz1Nq30MmFT3~fDLv~WN7E`avKIRCt=#FB$5FGW-yzxe*X2f6 z#r(hHm2xcmbut&qkZ*n2J|>pBu)NI1!XgN>6POf%mx*1q(%1po@uNGo8J|BhKV_ht zkE1O6{vEh(r~Xg?=r*35{yl~1dMxi(0cI%8HZ&M{Bii%(Bah4hbLkLP8kq_&MWCC+{087rFVxgwDSvl2Yr7`_1j@zD)T(d(+Gx7 z;1A7l+BLuUW@ZatCgz7XVuuI^V}I(m8mHA}m$9!sBzRJK24Nunkq0;oVxkcKSvs1hrg zSGnGEZ|`gYULMILHh5Fv6q!aM{0#{QVZ$v3B-XbUP?20r<83PQxBCHJR};+8#Z6bibfyZo=Q($c6R^ zaZ~sM}?uY$ir)1MtUXwX0vva^`2xa zPwXG2|DM7e@aolCrmb^U_M^kl1rqr~${5rtlKoj~EP@~T0o-JDy+)(R$&(AM zl-Umu-a`&rxzC@I2YjtDIY|&KEB<9MBClfXmb1I{EHL(oW9Kd2nmF zaKYWT3>9DOYM!pD1FnzXoygW;^_W88xzgums#DR#W_wEC`2K$&Hexkoyh79O1~~y< zeKL-*)>2SVfREkcSnFEHDyw~y4J*OFvv&A*>&0`?`f(wxVR{ zk^|6DFy1^8sVQjB~70 zC(V9cMW!bxJPBREFlj2y5FdW+b$l$1`$X13!qw>CGr zf9sJ^QfdRfo0ymw8ajFAjHa4eCtd^cw$VF>wKp<6>_a8Q&&Vj1*a|{l;@h`9Io`cj zYZ@97&QomPbj#ZrozcK%D$+b=v#4eDx3_paLYNrEyn`N(`^Qj@y89;j8$V~5w+b(z z#J$J=?x*~t?GYu(xh1-i#Urbnalz{7!Jf>R$HG}+632N?Y% zslHGl<>->eU~1y-`_WP?^Q74h`I8YMuELfVG(H9mN^@mU7^Dyw5Y&UCOnwP-&rii? z1qTOrv1kTGMQwe#;P>R|(}xIlAD@3NDci?=I#6Df7ruc}VOKOOn3a!x^+VzNQYz2D zz|ysbnhGo42!};fE(!L4Rh>AF0VpbWl{7KM4`vIX#ef@i_3)=}fMj4%*&G5#o3v~O zb*e^WqrYs1RveJ);v9Y9x7;c(BDCCT5E~l{G7U&Tpc#A(lozh)=%hs?7k94(PX*PB z8I7xgUzEMY-$=&?@bccS0u8KWe2L-hCSm;-2FmJO)J=TMPqm$;*SZ^lXAOPy;UhxusK3$~i-C2hxDcA`s+=-td{?E%(vaA8_U6otSBl0}5* zC-GJhie!jH3&D#8wG>RT&0%)eKLnNwq>W#`d_aW%^6&HxK(oF5{be)TP6!h4%t0Ds z-iX>ol#>Qz7RjBVH)2VdD8T{@J@p15Kfxg`-oNdJQj@21i>+27q7zim-iG9DW-&L{*;$!(#eW?&)U?e0>MSJC6 z5ZGkz*1WF{VIGOkslx`!2)5udRg$tu4tti4Iv9nZl!>)HR`TM0=ITMxC+RmhOq$Lg zoW1NI6kyFsWv=gCf*cxHI!{DB7&Ay%W3B}%C20YTN9V)sl~1ZSqY$Xd=1I=Q;k3GO z-V!Ntn!Ps#w>`t@> z2%-Fw1%uLEpsoh}`ACf! zM4evQY82R8VgRP~HzdmP(g6>hfd^*Yp#T2NAwWGne97jm8GBN8-cb_40}jEF5}QaO z&&S8dN6rMH8Kvx8NR;)36~{6EE4#74hPR8y^i8)2(91HPFfy9|Z~@B7P&n(=wjy<& zzu|O`Pl(f5HuB8q=dwXJZr`Lp_4>63|A8Y?m8WbAH90k_6vE__a*}FXP?ddCPdfhQ4pXF5}@Q z&aWqa1)vdnzdHGV=v8_?NqPAL6gPA4#?1TlNE|FJEhP{f-M2FiXUmSq$wrtFE!fD& zf(#0iA7dxhrp4B@8^eh#gEh=yOI5Z)-(Ws04Wd4qF{4gJ@Y5jyy(sI9?svFqMwOo0Ye9-#TJPp#!R^U z2ii6#c5bfap8WG?5%5hswJuj(Igq)p6f1}A*WB}d&8&Da3&M*H05gBSG;<@?wZU{D z!IKBx%wI;ysd>bR~#wok(Sx`JRC{6KBnLRvQM^EpM;LGY%WsxxSpsECf?w(b^a{E)DSNr;u zUlCV1!54;K-sSPK@dVS?*Lr$;%j%EkT?o|zDKKDr4^g%P?y3Th_!_iMR|!Wuk-uYC zXcD}O{8Qtg@XB^(;xvqlVY@NyL_^8=2j*eGhsbZ8?@q)yCIppg%%mB~isAjMuOM z4I*^1=g?kpxOWeuRhrw|mw@{49`m@X?*P{-jKXUaYc{emGGdcCxCTtO7R416`Mv^7 zyX7Q1ov?YM6AJVh%@!#2(6senbRe=*fcVPxZw;hy`T{*1cb*Ay8$g5fYgN?;wPbV= z7=)~!awKZ=(gHt~W`^f84cR+XaASDkYu9QJLeShOmm2RZTq0;B35w9?DbXD>+lEoi3Uhg!PFb&NXO+}?X3eh7zO*v z^77jaXlM*g$l8Q{EOD^l@t{`Q+P)ml}ml^JvO!-OQe1Zms$ZGU6kFP5o zJ0$M4gQR*nN`HVsXal9&omtzl@tn@YAk@l)3n?vsc<@z+bk80ifB!Y?n=+=+usw@b zg{a4i@Jnhj3gH`LAAAdiB3IYdZv@KsG57e16OHCydJet9UWMKb-Rw%2Rt|Rds&C(* zJ>UwKzMETs%)<6M3Fur1p-9(R5A@0?oosSQ0%`-sgEljMBpA&sUc!Bb^{<| zB*LWb1e%+cmIkF`&%LhjeT!BrI^4lX`n6H4*S;<^`zf@;_1)&2i1CT^Oadr@ROAU6 zy`TjY<*4MoAp-=z{p(jW^2b4OuRHN;6*UQ>kWU&ELPzv=%#x=QN-mX?1pi^*fA|lP zVq4BtLu0q`ig=ox8-?Kd_y1piV<{2v@B8p>S4$4!`i?@bTosrfPCwwzadG;HFVL{O zrFaS-%h#__grds@4>a&|j!Ce^K<0wU(Xh~!V}ZKh2gX}iUj0|%VSqKIee%?)I^swFqXuo z10f?QEKI%Cwj32ON)*sbK$zv!XwddQ`yB*6DA1-qA%}N$T>~X`;zwF9z*6I`qLs+= zZbd79Z+_+5%)5vC{Qf${U%WcpG%I|U1Hjhq5ZGA3+iKndaK>ojg{37a{xw5%DgX>b zN%^9l1K>1C8=jxdmYssaH7BQ|=I|nR2eb66 ze>&k@aQ*sq*)YL7cKKlSLV5?3Ols&TC}zQ)xXQ63 za?`p0x!3vDLkEj1z=i`17c3o1WE4Tr_~4kKCOCJm!W9yTIaZMNp~^wJ%=(*(fg$|) zbA=lk2$+9f{X`4|2EQ(OxVzr##NF#}v4Ey)^&Ot=B?$=zh!z00+h%7Q)N3K?p=y19 zy9Bu#Sm-9)!RU}*I1ZTevb=m{6%%$Q!D03FB_zbhRY>bjE7JZ$2(*Z=xC3-_QrTcb z1<~;6)%BvrtVQ|>HWT=c$}ETUKHS6E>jMOif{qR~r&Jky{3kIA4;maFE(j{BD-(4< zJ~{Nk+t-&t#QwA?&h{ldU1Z?Y+Q>gw3H4Z8KHBmq2kLt(vo1?WV7Ynvt%11`z@L|w zcMWk9Dn8;8{rxfB8qr>a-2xqUj8}fG&hb*6>DNIn z7met3q6RUxNQ6h@#tj-Wb%?`)s``j(ey0X#*fQ>uxeIx=V@BC2cms=d8nb?oI)GdOX^#^HdM&FeVDU;%gz+aLMNg{QVsn|Z}I zC=qynL4wXyN7le=rH&ua(__|tCmSIO{It{-1o_U+PJRjy4ngzo?bXgsndiO7yH_QB zEem6^pt$BEX=g$=wwaT8<4$3EnNN z1L!(y0Z#B8Q{l|Vj@1p5_t58|#cFwwKBmnXqAwpVc%u>$))An2{Sc_ke@E^L?m|+t zWIlM46r|g$MiJEnMK9SqcESwG&K}iQ$;rtL*$M|ZBkZ+5` z=A{YPU1xD*T}Oy3`1Nh;`6qsU{ccyw>?GNnt`720?=m@B29=EWQb|0|Lu(AC-vmv{gEaALj$Y%cKh__vNEo6K&fn+@g*kw*WaEL6wJYj zc0%5hm%|TBv1AbhkBEEy!HMifD9yp%Tf4sh5fFmMz?&aG?jIQ7DYv(%L!)?EJii^Z zbJ=uuurFVV-Tl4u6ek@c<9KiHr)HOJ)DycyOfu^}o!jUxwNL{-)346OJfETa1vhs3_W7I=xf|L*`XxuB% z#uR}PmKmF&4RZ0W4G9^=|6J2I1Kx(Mwg@fKLk$T~H{Zo>Q_!48r<8a9qStx&Pb6!JVV%+C!Dg)1Ir9II6Adj^7C_=a zRs?_*shLq`9!LWGyQ`GX$29^6D>2GsJ4CA1)I2qyjAezcP*Fxk6VyBCPSw`#8@YB) zdtEy2RDiIPvo^W9+h)@WY1pns9+D<$rClj_vyHFGa~u7L_3z{+{{6;I1+gwLQ0b=^ zaw;}f)@LT$@dFsELikL;pS%VWM}da}_(*pv$%lLp&bRmQ4+tR7!%6He?^ec0;U)@R z>n7hMO*aaXj~vV0>+j%EFkK@IyXMT)RP*K%VbUK^IJ&?{ccNh0Pe<(j#TSytwcllA z9BST1#_%8c{|292@E8k=0cO4Uq*Xq&>$%UMZGvyW^Nqh5Pm`%uO`Y#B%Qn1^R%p1q zDP|K%;)eF0#NvgZqu-8+!3g}u`9y{eZ!iS8%h9uXqW0*q-@kqY|E7ENW#r?6jB(^U zMxPq(m@@;q;gdEvXwY<=_!tRNTSyeWrT1@bq820r$U}WG6}Kc_7{s)ak`lYK%gA^R zWVtz7B3pu*Bg?2c@%{V#6uZdOu=dqKx;Y9U zBZ7qk6$OQaxOk+{n{KZsPgqbeKs%vjOCq;rBYK~k?XYPO`ew8vvnS@Irj}3gtzyRJ zU1U@?w}-#MCBglC`Y*-P#Hh4it2;?aag3!qCSvtnx^zjBe~V(MauOjCzZ882RuEta z$Umt21@nqW?(TfhGr=Go8_VDvNj!(nI(zP1rqVN6l`@X|Muu<%2F;L08~YEmvv?5$ z)pyDx%L~&q+ECV9`nH$E=wDuHd{(7i&Zl>_a`|8*orX;{noUHLa`Yy~!Vctd*$1}I>5UFhB7uNbfp6W(>JD8UkzuGvX4w|Rs68o$f1 zlmV_69DArw-$oqpNyFfHx@W=$`|EPfVuak^{A+RA3o=-lc|RN1F*l88V)D5r*r5?#t(FE zJgvu{ciG`#2~jXI7Fi8kqdi5~C_j0!vq_*y00j$XjJ{1vBfL#;N5&a8f{UD$6Spv) zn9Uf5?xArXO~D2%2cXA+0yhT;G><|Ja`L3l_sA#S-i~Mo)(c|J5T0Qe>AJwM!}Wy@ zy7r!V9!tG$`$P$k>r2she9)a5#@WTlrS+(|*cFW>bVN_PP!5MQ8=X3J3g+6wAdSK} z8Qqziii)49jXMh#@C4J$PLebo{jXgM-|eQibY>ddL2s!ub19vV@TlzEV}87Ozhl}{ zF3Q2Kyb^WGv;Syw_YWU2Z)i(4bQG8vA3w!tW89gUrXp!$kl6;D00rqOsOP)Y`2>@( zfQx4uqzGj@T5@VMBt{2HZGS0(c}+r6v5V6A-rqNWI<))$B*pXF|56XNG5NkarH83f zUqd7L=;7B*FcJ~JP^6;e@**%0I@ZT`r|Ql@@(1IIOtqi5-KgTuuFm(Wa!{hr`QKOH z5vb9c^z{eRD;poK+|X=&Z!<*O3zG=Oum6U0F=+$7Hchitk z`|H>~o|MB+zMT8!m^)|=y>TW2b=5oE z$h%8;DC1sgh$XRK)Ah-9w3{1WAbnh2>U_Vp7D5&p;*uuQ@PQL!tG(HZa+GgB42`Rd zYh>9v8d=0e8Aqkhz%@*&Bi-LCmO6Bisa{+zZgPQ!1O*r2Q6mZ|GsfnuZ%n9#QMy#002>&qQc;WfwJtT4wxsf&qKOcu^_=d`;T8`@N zAiKgdD;MDxO|6aZY59f>Aji6YY3KTmvv4{7HDb54To&26Z+mH<>J7iC%-Xb>T=Kct z<$SbrcrUC6r~BYNrMJjE@99s-HSM}L56Q>izyU^WAJ%pk!#br%Y$N`wVow*UN4M;?qEOzO#G_WbAAA*s8vaUs{LRG*hpPfrft zXMX(ei2*&>vGsLL5~thL&s~nSW}sy-7{Bg;gFCkot1Q$gox8{Ug~v7j@BUM>->W^F z+3qs=MYqd8U*+)<*Sz=N%Q^VUV&J z0&~(~zcMX&9-;E%LLJcG+v`?I}re+=YKC+1JZ82&d3x`Y`^d>MsZrHY3WQT|iBL z)mHR2IyigD$O1K?mstjN4>5if-2R+A(fPT5{x2prEu6rmkrV(+AllMjb^LDK#38Mt z17*^Ss=nvpYr5RQMUY*9neh!gr*vYT8*(lI;$&`$#X$plYAifVe9~~pqr)bYs2T88 zyrcv?9}p0({1v+b`iO{LHu6m{|Iz3{SS3tW_z9D?FVC1}yA?is_<)0M;9D^8pcAb( zCeXM;f0c_6G^-~Y3%jn0XupF;6ykf}=yGbPfH`Prfdm)!y^;GiqKius$w44yk>Bx~ z)e&OFxST^bS=re!5!gnt5PVy1?gkxhaJ{8$MX#W%IN`b`e4MVlynJzS@sBq;Z>Tz* zJHbk-Tua=i68iM%xtB2DlKooaa2aGvUfT2fL--Fx?@2$hD0hik~m zeWW(tpSgYwzh;PC7|#b<>=B8xq6@zR1Ul{A(!;jzrDr)?1UHs-#}jKP(k(5Aa6Z8e zAV~=gkuQCJ)@nP$Dl)9EqY?jn9JX&_k~-d)Ae^`jG$#*w9%W);&FY0#!Ga#*kV^x=2{o0K z^-N8H;GJNb?-7tZb`X@b-Me?Md;*pP&OyV~N*!(t6Yh?K43aI-t5-0O&RV6gurN6} znJ~&R)_o$51`sf;=w>4t?ZsT`@Ho|zDFO>@oSgbT%}cD#;#6NEWHCY=1yWfmTGLn? z&0;}7YvG7-;msG2m%YoduaZ(yg037}tS*Dq6tu}N4oDq4i1!8IZIZifPR>+#;-QE@FCO55xP%0HE#j9i zUuW(c9Tmad!8XQ20sADZR9F-2NqqRgz-F|$XE-DNn(OLjA{7qz2No!O7;OH!Sv;C% zM31T}_8iC`?*{}lVusCpskC1&B8`r&?ri<#!!Y;xgu1V*%M}Ez=H_O=v#?aUx4JN} z(1@mxMv+r4?iV03Ll1nK@87=@I>ibwaO-7|E~~4mzVi2%g=PVoUtkLO)Rz;EGR%P( z(e%LB)U^6mDY99d|6noBL-|rqxfb zPh^dZIR_AEawjrX0F-j-d_Ycb-n1I_FDg#jSQ9I(P-GZ_>d^aJOj^J5E z@qy=eXb$QP92;$-&?{g$@L5#Ek7Yzg-bQ7kD98MJXlTJW97QN;?FnY)eiU*C{W`ME zBf`TOX50TrN=b>W&TFp*5if=%%jl?Q=wjF)1m@<{GPrh!eODK3oZkX!B`= zTVYxYIiCmY&8O~A{v4APU3jGF3OXX0;!{Wux^IFd2~)%JSLz)8K0Z1=r_^&M2?qT0 zZvf&}Q;6ytH0c4m3&Fi7BAmFv-)fsL-OUNWL_N>iv&cY4N1O>5E0&Ks?KD&|(;hAZ z;dU%;+CK6L3@aD3w6)#!bCA5NXx?)lj{_U0^&kqfsun#6op)^ATE{>s>W;pY(2*k# zI`wpP?CtI4I3O8Yh$CjM!@N^gtdE$>guIDxbe-I}48h@{C!jE$VU*wXA1*+7O^u&< z5IBQ}E}cPxWC;^_*6U9WPEIk4U+0vRnxRJ@yslOp#ifnz6{>BiUAr^cUDj6SoG!cw z3wx)Kz|F%0RqoJDg@g=j5=Hy60SEkva>)oCB27(3vGmy3$BRN;juU6gf1t&Mo=9(R zFOVJQnL&A4E1cNd$6q1%6wdz+kk#S7f$AC8v(ZBA{81cM3rx7Np#hdVXpmRzv#_!f z20*^9hA@a;WIdQi$8gipI{Vo zS;j#P7td^psL#qxUk2Nv_1Rm_zuBHP)QJv%jb3g7;In?KF@b zBh)n}##lZI2?)9OV03A{mxvVzRtTy1OsoaM&|Evup^tHnldk0rG)9!IXl6ur*c=gl5LAx*^=bqo_h9WB$P06z}+!?s;%<0{P8#So~Zs z;jC+~3X0Ov4~Wu<&jYR;!_GcLvTJE;!X!Fis5WJeK9g%4#9d~68kLs|jjGKEWphb= zhYouC%VEJ~zCr2;2!M8sa`i)1#cE?0keD zuV01dG0WGeZDf#hxpX=5>3rEQx>d(#tgF}+b^w5NA=E;JU%a}Qbh@IuRv)+~@k;6( zRG#91h~N6&&0PjohmIIt86gf7hNQV;*fC%9-SI{h$5pwZD$Yku}aq_kpMpLZs@wWn$C z&``9t=DnpqfS!uyFi)+>MLshEb@az^1Ys^3P151T)~Rn5SgWaFe~1TBO$|54O5uru zi(-4yR6Ag|vWU3x)9?o%t08YRXai2j#u`o_Yb~1Z*}bahUNQUUPZVt)P-?Dn#A7=& zVk+5>AN)#ZUU1$nCnE!5Kzve#SgcnkS6A1zi`efF7AD$75c`A9Vfg~S^okYz%YcB3bX1(0m|-W=4$K0izr@5uM1NYI$6U~JU1%q4 zp{bY9T^k(3tuk!hrgi7edGm$i;t83`%mJt1B9)VP|C#{1jU{(EQhl^0zPx-*NYr8! z3XwXKb#NIQk06%zVjGzkOg*l-On9d888v|*vB1!A9NS6obhIj|e7 z<#AvlMBw8_QYw;G89Wzvn1Vcvlxo)-$377FfB#lonlNXI#wr9Xg8cizb_3oJwDky= zlbN8lC@D!vmX0te*K0N(5*oQ(XW4i6%vi*Qvk8iMh-}@mWnaEL`Kyhj?V#s;0tIxa z){ul2#oh&YYLw}KP`W4;yZ+S9F*ScUNRKL1)5vHTy)W5M=w@1i!=%P&jXpufvsz2> zqwEN@>CcC#fysI?`N>Z5j;WcG-wcF z6gvqPanA?z5Hti&F^C0%?@H~ey|6p((yzosw&736&0tR$)#<+K|Ni6Cy^_UV5G`C! zyb^r-&Yff|hkvq*K8R^31ssZQjWF8dNWe<< zRADANIx20NXuYs(;<*Tcv!Gw}%xNrn5LXfu6-;lVZHo(cm zo^U_YwZUNomt=RdIR+%}tW!f!Y9QlMR;DbIC4Bd|d0$_6v%f~Uyd`{gqU#p*ZNfHD z!~juRk&c3zItMQVoyfFyQOYN3D5z4eePBzCjg7^et&^13?bv2b@>)EfJbB{f6~d*x zJ(J{Cj>Qoesfb13l1XdBxIcreE2qubeN!-@^L-vx-Ei}=M#JS#kB&s1-bUVkUym%fiC5O02PQaqX?GQ;mg%D}UR03*zGqa1dE9EOvBs z#M9(vWV}f1EdBJ!-NtCSFluX%S8uuh;nWW)9R3prVmBepZc<|x*T@DV2>~CuY(}R9 zny1g6$xBL-iVgfjK{q^7AMK%fGV8+!LMH)J0$1jxk<;aHF(F0-ZdaaMU;6hSzqv|@ z`%HM{lo_DFCTz~iS6Tp*FPMxF`L$LEvUVsk%rIaKy?4T5lDt;FV;WnP|E@GTxW|QY z-tusB_p~2ei1fM~cOeim2a z$lN!Ay%IC((KT2nT%DB!=<Qg@P?yD<_|}{{bLIxM;go@}SYaE47ATu>LtqKu zJS-i;%gV_)0kr*^q+}vUkf_+Qm4Y^Nqfoxn!TdSfU7=5{Z~#V5;wqn0&CjJ#Wm+_d zSWCu0tr+OTb@*^Z)l1H48w>ghdE*me8ko))yZ(; zgUlb+3c&Hi&|z6NI{3N0J+v~Po}L~@zpU*%g~S3M%OeTgFv9ZmMYQ|l#|m0yCvFM3 z+DDIHQS&~B^Zjp|F(y4MqdIrjMg}oNi|WwS#Dq3S8zdd*k-xWp1Aqc>>*9{6Hr_i2 zEB1jD6HT@J!lFq?^2F8Yx~Z5u(A4h#n}V)GfRNC_(D3{<)o=xI(H*!GeK#H4jXghq z{`_AH`}(7aWFHbgQHO$xt+b3JBWNG#f7Rl5L?4PZjSKyaaa=~`j>+AKGlDz>L zlWDQ@Qr0BwPjaBtKy$wcr?_7)td9`Dz5qAdt+E67O4H;>e}8$4SLv4Aa23Hje|DHJ zTczbi{drJCZTF{V{^dZ5+6VVtub=ouwc9Zl7u_!Xz0dEkSlry5aN4nD|L9v0Q>lZT zt~zVUhg`U8USGA>Yr09!>>8P%c(!c|slQ3pqB2Ib_2(N1T@(Ym?zQ?quibg!Wy z2DJjA2m4SX6 zT!Xyg`OP{Ew6yM~PQN*($Q-cC``3J!U!L(oTQ*P%W8M&aA;ShrJhi**G*orAr- zOd`#|r4nzU0>K$^z(w5S9|ZFUL(`9tkE3_DKn8L+m2IxVlo}Eb9K02li04Q~5H|^f zvP~KG?8W1s0cSj#dsM7~BA1V!pVCu2t@2S(i}^$O`ipa_zx${dMQm+r zO9E(RR>J3HK3h(3s?}02-TtnlZPi$^Wy?CjJp0B;o+8;C9ub3(Ab=BwJ1czVj4y*QKge0;v;e~rU>BmC zR5(GMsU|ZPwCoiHX^SHui-Z&Mujr=?#eU> zBj64CZ}+F>>VfdPLAW&H@xH^IVAep<27W7`LgfjoOK0jqVHvj(T{Lcc4rr>u8;q+z zXS00LBy48(mckbQUilAX0`5}d!@gR}3Uq*CdK-nhY4anT{&-HBZV^9vAcCh-hv3}r zssQlnFa@>^<6a#O+C^Ww{PWu%CUnImoLLzZD4sSMqvmwG;3{?&4q;L-l7yK zAJ3(Qzklk>F}$`qu{KC7?1gXRkR>c2?vGTncxGn8=|2wB3Es@@iWU<9vIO}P`%G5n zG`dLE+}I_DuANX(RlULx{-Ov7!4T)yygQ$^$0&U5vNGBl8zm8bO|`QA(MUI`utLJs zpdKl&HCoT&r?}-W5(n%-RS1Sdo`ttGGkihi%*;57CD;PNNgqkAKT@FLbf80QZ9$eT z>NoPF6DLkYh}?T#IS8gC_{Y=J#@>V<3&^r}yMKNB_z^|SWPReQrNq&CaGO4I3YF;F zqU5fruI_96gzC2Om>cio+ELIYFIsi-t&Tr<`m!ThM1X&y&0Lv(pK^+z?acMQ+%yln zRDG=j+bq6+&n$K_X7}v;p?opP*}R0d{D;THwVsKAAN6jgZ=WZNF^F3JiF)vJM^UL? z?Wm^9f-VLdk&tAlA07W%qqcccRo?5tEk53xw7$$|&#plKXOtPzD+nt#PEOA7%>m^; z2NF|KVp(LO>lKxi6`abc>39v~OiV^me&85t|JX9o2ih$NSa8?`rU5cL3_TS)TBu>j zj!ceMECe+(fJzUK9X7W_FCYp4?K$KrjwT1-r?^l#%pHfbHEwCZ*Kx;Yu)*^3+F}k0NKiLxYWD0Cjt@v0R#o{;f3#n+dxYF$|(8{W>+-k{cHRE^_Y6_wOREs zDv8WA4Kfu~`xCc+JsK^DlBFz~tqJAy@-34#d11+u@9f`}Sj#CIzS7o|wm6^=oif}x zvGCbAn5p!l%Zg>-HLkX5x*KK3V~#$%(r+*@-2ZueO13q*<6*%~_vU84*jVOq^jE$N zuic~SWXrS4MmC~qbo|*F;c+pGqgox(bP2~!7^Ys+X`QspO&pdCR6Ck>TPqr8efnLq z8&anVosC=vTt91&(kv!=rp@>FMf?<5Rk2w*-!velY`Sag=h){5GI?|FX{!8^R+gye z^j(_8B*ICBH60v;w1f?)SC_y^IFqkmk6cdVE=s|s{?_~DKHaG5t#Hx+$U{nsGL_eZ zR@(&F&x}VlVriD4v;H3;hfun*+?w9i1;Ow2tt`*37$i5B@BiEV9Q>Qg(f-gms4cM@+S4Tv!-}2TfhJIzHYmmtG#H5+WIxz4oE?p2THa*P^w$!|W~Q zeZ@vhfnh=!xmGIX4j={B*OT|lb^NXAkX3PA&|m3w-2J^c`}RuV-MmYAK`;1+%j{C) z`gZ!Sw*PH*zPRizENCUP8Y2+(=#x>>`A-j{#KM{8R=d(mmDpxyS|gljri*QkXa=9| zsLo7Y&E@USNiF=K(;IY_Yee*g+SPLDcc$A@t9to)nEtjtK1{8>MorP*|Mz8h@#+5H z<4IXzB38#2+GJL@XUWZxj>;K;E9dEVr>3VL-BW(YLo%h>kRr;ps+L|f1 zikiRlr@OC}XgJ)AQJA}D^!)S(Z6DJ`GxMhOY8l}a-Jeb`$>UbMxrIB!FO=2X@^7iJ zTj!d11rJgj_!po!c{Vk4p-ZCI@SO9&ADbiSv#kq6yLX$2WRWKy!WdQq)n`6ehigF$MTey7c9H1W_HDs+4ctAGWgMH%I-lnRx2LG z7P#103sA3@Q&N(h`@^*152{-ec~9l?NhRfKuL)}f-OCY<>-<75>Z0eM=b~gIL+-~u zvnotpE++8Sw~&n7TR~y1;ORBdJPQ5Te!VRhma(?z{mu&a&JGyzf24f-fK-?fbLB`# z_K>U!688om7*G=U8t%&2zv-D|4AR0^5Nt6;T&s~|Jw%$v9W0#%)WsoGcGIdY_l}Xb zJne=J0+&yCgmYC1@9<9zKQd*OwwmB6?bH6F{d>?*AH`StQQvAC;}Lv-PNzBY!ii?> z_LPemQ%xnlCC(0YBj@jwRQ!Fnk8VmCm){XQ|BR`WTHA0aGwEFczh%?=C!4S)Iz|g= zIGv{_3R@cQ8XRb^O!u;(GtRf`8w=~%YZ6O7QkS;U%Ea|^(XY0Ky+<~3s-n;IXO4l> zZ@E=d+woIIi8i(kBbTT=7q=~$ccc%9xvInH!LhDcZ1qwcIq5Amm)buJ=QymTPgPwpMXg|n{ z&()Bv%6%5ZV=s5{M6!bMOjh%7eY2D~om6clCu{P2*V1r^dC^*+p7-wYm6zglJrPE~{-lNq9ikIW$cl=E9#nUxt6> z^7+D+lY@D8oyfLDJIdEDe_Sz9=n}E^wN9mA;|)wSbB-8r(nv^#G&RDrzGdTA8cudDzD$UnsLWjSe)mXKo z-FH{LZCo?Ibo7?3fr+A{>xHG6(>%rcLtHi!ZCMHWfxr7%f7Duzj^2XB3R)K^>^eW5 zDT03nXde!tIO-#hV>uw(_rcas^^wK&`Zt3HxhG*A{_;&sG)n$kyH`eAn~N_(?S|y5XU{CQdD5h=^d4r~E-ZW|BQTST zhiB-_ueEtyj`))6^6Hv$_AQ?pl&Dw}!C&skcs7M?at zlbY)gC;)x-LJ8jQocH4m{_(I%baFysB3UsTJ0F8kMx*D~Ys&*pHZn5$5r2Ksymz%2 z^wyXM`Or-BiZKgdEAl3P!^D!7#Nm*)FG3k#yLyf(nCnfY(z$kQ7i`Kb;x8C{kuoAhw=dg5y=!$2xWr{)q_!mq^j{^66J9j53 zOXurzz@rrG%De#!{U{mFfclDGFw9gd-1p`?zSVf(hF6jS-zrXTZ9(u8=}Z@PArN|HBzOVE?=CR%}!6xn-f)|UYQ(+sH*x) zeB2T>7NOeK^-o(5`O(3H2dTA@TSKpXTU`8eZ_Y0I3h??30V;zt*3bS$;rewN?Trqw zLze**g?SRPZ^1>X?q-f}9!9j{COA+gO}}RDObSHtH#i;$rJdV5sq3>cKYgHLZ>`Dl z-yj=3LV#_yD8_vb;D;ISbez?xl@&3-|jB5L0w4|ADH}b1j zDPM5(xzf#J99zV{KluCS$VAPpiV3G>_UT)%W<(o}qWcSw+ng>hTD=nyGjeWCv^QLM zA31-+^Gl4`56+B=bcAQWZSq)vB;$@qi%8~L(dvfH+vRcOWizf;$u5XMg_qF{y zNDO>2D@958>kH{D;E%9{6%-N@^$U$uPU3_~6SX6zS@^CA4=v?dWinX#*~}ExJHXV^ zE#+rbRnnP`M_3rZA)EO{Y)4|}j)-U~ni=ZF3U5kVt=y#`wY&UPX4CUd+Llv==$B6o zR2;20CXZG?H6*z$dL@*LaeOImHo*KaQ6*{B&;+mE;xwktOni{AS1O!C_35*kIP z9gL0cxXiQ|NRHdDQJ?u`TWQ|Te=3Ts^-MO+2_vQt#g>*WjaxPw^!9z`RdeXU$;PkX znWU$&mdxoa>QphYTTuSC zw-a9DomMFc316Z8J$dq7m9aFiGqm!P1QL~j*kP0&irKNzQS?E<23iK~14=odBg0$Y zksZ!PXD&AO5@=-NQTQv=_W+BFEiWyjjH1yVKQcWlYIrIqaX9^tBoouKn3zYNhleMO zlaxY61h}gz*=3}Cbp32o%&xsFdOY6rVx}RT6h4tuCoUKLlaeK+l9ZYL{K_gFH#cZ- z>ASrTm6!KqaXYHm=@*_o`@?d?<`iqP)#Q9z(}cgP-PFp&TBv15QlnUBj&AL=_UpyD z{xUMo%kA%UDw?-Pj@K?PMxIboS2r=f=_T~AO1LjbP^wkVo#>Dk%)_Ur*rO}2CA zxEf+6u)6bvb z}~7|IZ6fOhsv2wfOJ0kFnmWnHL}UIqpLRT+4KAVi?Tv9z^)E#|rk z*X(Np+8Dq#-wP}S3gOltKZx0HYl|(#Sb#7Jhr@KDUD@RCC(=GKSqf6dNgk+#k`}(n zpg93C6!`XFUmY3o1w?qbE?vs?0Pr$@f%+w#VQe`}S0)!O{M;$H5K*}o$+b(s&o zrA$>MtHjm(`O3LBX{Bn*d4CJDnq=Rbe=)x{j4yYauI;`p!9-TE+uca`G)sKe7K2xk zF{C?pM)qIs1T2F2Zm>zBqx`GiNFyV1c_rD0@VbG3_JvoX-nUm%C~Q(&p zyEecj@k_h2zv!fc+z31a^kB#EULc3yV(kdIdJ5Z5L_~c+an@r9vm6W{#_8-A``Y&h z9U>`c_Md^R!^>+8V%KsjY0@{e7zx%^Vfe}rC=6h@IlQt0=jQ_6&CI1{FF=Xr=5R;{f;?n%`}S=Fl=J5|6~e4#3XP<}S=@h7&|3=6t_(pl zeKSo>pej!3!+|x!@@5{uPP|Ikx~a`_*MtNel#9%) ztRl22#q?m}3kU}!0x{RuSuZepax_JeZDH9M@Gd>79PHh z-Wf=)83NsHwEL`T?%liRq$hx!3vXnY*;Y^>lD7t>?JW-hfS~Cgz|BOQyi2d5saa(9 zGvdQ4=dGeJv)k)80Z4rT4hJ+w5PumCALb1BO0A7?N0AKZ=mph|Lb{}>rk1FXFyCHE zJ<|GNz>V?cn%V8!zmTJ$wDxVC`ZduvJigqlZflT?qi(5F_u39L`Ehd$Wa@O(MF29%v`LVX%tJRpFb9hm~LzWTf}<48p z{S!AgH@K;a!uQs4ETP#1J(fLu8pI1O&;-kgc@@e@F`9Zp15oyP4O44_b^GG9C>L+K1Eu*_bDZ4!fq=<|3sD?6P>*GEC-l_EF0IN( z&uabe4S$)k8uqGW|0*y{8Kv>7zg|wC1CQdIm0ax%q@A}vCMG2zI9F2d#_eaz%@OiR z!~P!3c=^Xu7G^(X0yDOljZQX`_Z$n#D{b@URdvpEbZu~-n^Xw$g3DXwB-l-A`9Pa~ zm;UAYxb(Z_KY+yH2s_oGkM{A5-!v6{Mg5WAcNbu}!*cLN19*mrM<~BBp1S2 zEMzha?8Zl*2#y$S7P^vm+@ry?KrsOZ=t758xepD3e;PVkN}~9zN^H$ow1ejxwK72s zi^|5H0HwQsj`^S`e8JJ)GFxXb)X(?A$$_mLPZnLlmRkv1eobiU82yG6IVFUzUU61D4?^Pt%lr8F zK|HIbd^TxU7(m89fX+@Dbe6;~)HgE>C3r! zd8Fo|Wk!UIJSz*)TJfTan%ZJHoq3&5uF&N-9RaZsobX6R`(0gqT^e8co0#xf!gRKp z@O>G0!Sc+hu9q!P((4u^CpRXdKH{UpGVk1eNIx<-ket4dtq(Is;-!@jbBaMuzALP- z_J^9IS8yCwDlhucqV1TAl~?>c_p~8Bc_s>_P3bfI9`6UbZAML>C6TJeXZNbXZP%fl zdN!jW#lUxGxc}g`!1}S)50_P^;@nDekk9390dc71h75*D%ROm@Gq{I{e#pH4`Y7UV zd4zUOjXd!aOqAYW?#(Yu7#z9njF#1Y?=pxP(8KG3Wmo5b4`mJpJRA_UTit|wiH-)uo%K7OPY zINr^;Jx?b`6zlT#9~$E-hd)LGWGe7s@aGi}h|||MH2i9*4qj2<1ad{$U~W+5rI-W2 z>w-kR3mibCQQ24u35vLySlh5K|L*4C( zw2d!8f}E;`jR;OEa8?Xbgu<;8G@aPZAe&)n?H2U=9v%7P%KY&nj@tTqY`W(~7@n??!iGK~pP;C? z^>VB4WF^QBN1T$BlWyJXqo_1~?Kpl$a>}|t(U_#ms~zMg7Z1gEaaIN{;iPvo7_~<+ z@+kK1=~BxM3*-|>UHs-3{a^~Bn2;NFWgWL@2*1|IFZ>-FWmCp@9HKvEEpSA4zP5RZnag(eU zITD74@w0I)$Oy4;9I@0zL_|R0x2p^#2FP%iXQ(Bws@wR&L@^TNLmV8HqhOVkofW~_ z@R}AsT8|XdunN)vkUC)UH3FMR2wKX2ply5x+uD(VADqxzWcj#Qt2O1U})&*z#M;d_-|xIUj)<74eg)3{gd^o)rbMCRmF3cp#=EG z=@J6fT(Td!aro3oexpY(Mc2z6jV*q7zVMN8+4k+*@pAI1G11Z5NUPnu;3yFF>7Ii_ zLl6#T1@SBQXc$zO16JT52Kh(J&=^HeOSCGSCu=T)-QSsK!yfn{_|+>XfJQ=Fh+W1Q9y_>#$!CPp zA>vTsE0KG5(eyoavxJ(CTjvX&(xZF?9(dmLP&LFPMRF3xR{Fn*2ambd%=9l`N3S|C zt*?cA095QH)U7pI+6cF^#xOtaZJ!bM;JQ@sez0P`oO+0Saor~t*hIIeGc87_|d7E znYYK1(1{fgP&r8{48m)0u#$?(^@g~51N1#;v@>3ngExZQ2VQqswqt7DH_i^85s)!5 zGSbw14OtwNYM`z_Ubkvy)>!}@)|I$!c>mG?%vNLz6hE4lolWKUt+o~lv#jiF^Z7Rd z{W;Zge;>3Rcl&vSJ9rIbzesZbT0B(E_}Bw}(IWMmB>{j3ndQl`EV9keL?dB5qllE{{*idQOka=g(NQOmM>sU{cFrAv+{EO^(-$wA z6!dJ-P9%Coy8}UYzP%H9;mVhROyn{82qfpvgX#s^06bO*`jrG7@v}HSju2ok3E8t| z!`sC7xGlZ+nQv_T6)&c@W1}-c{KL5qZX5jq;+x3Ujiw0kcapkMLZa~Rmw_#jUj6&U zE4+S#HogmCSbwvPZ>sldtq*x8zWaapHg3nYqVlAAC!f6O>)k45h!-%RSbxv^-P~F6 zg&DMbj9eM^Gd!^ogbqAo@A@TtyzN=dK%=dedC;F)O=yv(QI;0}skUqVl5W43KBYmU zt<<;8{&QVJeeElk2K;B8;#-*I_t(*z89GCK$0HPQsZRCJDfG%J6Wk-kx{Zv~;yci4E7i+X)RPq>srTp49) z)HoJ5HTuK3l|*gd#`S%9C-T_K=QxGe2uqF|r6gYDO%4Zlkm|iXWjt6!21*;B{|LEf zwQ0do8f`D1Pd=9R-|HGIY{WG5dMQ{BhV~BOsbsKi+>DP`+r^Ca+U2jy%Z1sJ)Y7U2 z^<-=b@!HJO?$_|Qwx^!>QT~k|oouyrk@+khlU) zTxIh9^=En7DVD#})`iFTrY_Gurd&75Hzx=7N$8n6z6%NcBl#9>q**w2wS!TFH(mXur)Sq2#gHO>7UxH)x3 zI1-7C4%N5R^}Er63sN?gq}tM2157sK?vr~%w)pm3GF)9CEwd?q6>NIBy(aaI040`q z;6;-i+qV%uhdtjf|;Ni|S!Ni#I8)(+ro|x_PO4 zTkm{O8>+nbk80bUiLQs#dairw=JRh;3=3c0W_G}K<2tiTZIl1?(D=fTo)2yB+dJQv zW+eDZl)OO{@TbFaf@O$+U{=Vh^{hRy${cDET zZ-j+`Sit%HBxJW>EjLA&uS32PkD73DOP02_M=pJOgM>xw@N+a42|xpIje7}!Iq-_c$se)U{?`tO5m=99Q?iVmk&9GkF=Eu6oD=9c-F zY!9<+hj$bHsg=xsj{9;}+v%DH;d}j+Hs2lG3dKro*F}fT+qaiMBgTI!=_Y?aM)~_& zMWa;h|9r#mZD~vEiR!>3n|Qk|GWx%FlC;l1ssH|nkjI>c)5i(kTGlHB$*;2v>%Rzt ziFwJiKEgfNk~r(8PvjftN4WMa5u}e1K!zPx@qa1z!>ac1aa7cD6`a=1O4)wJW0NEl zL5f|SfAgzSZuVP~vHYkVYEl=fmHE{tTzi<|@J_QI4sJxRE6Nscf82b|gd6(j6(jPA zN-hb1zpwsXSMOEfb4e!7zwGosCu`gp*u3=&f5O)mkDSXlrk{Ixeqk4!@gZ-RC7c}L zuKqcY>>_jT=i|MEZt%<90X=jy)Pw-*U-$8aqT7m^8{rPlN7DBP$Zu}K^Yvmy^{QO| zISl#V3*b!O%lPLoavgZle+R)~b!+FSWZB;*B}(+)j}Pwtr>Nsv(dM(GK)n3Vw_f{B z88-breVTAT(-!`IYpZ$0qrczEMpDSZ%DA}%RKDr{{rK>UzaO7ZOVR!Bw{H3S@ol42 zEPqb&W#!+KOp98t*ncAQIe~&Il@%P->x^iy(IY3SVfb?%X)#t~e^2i!61(3I?EJi%dH0sh)!@(b_w-oB z8G8p-17TM+W+pgG&J}u!{%qx#=u4Yec7xG zjJ-!0HXo}$GxgtdU{y0;s{g&j^x6Mhhd+^A)PPyw=7O}+`+F}0*=|gy{61m1(|=zM zt8yITP1@!vB|sQ{ze;kagLx~e$bO$i!r%S8M3TQ~br-%bZ5a+@0GXt3RD*s@pcfCV zT~*3xW8EwrM|7yR$n5?=*e(65YGz6Thq~5O6Oyw`D$>-CM)e*wEo~N;&+zhEd17{R z4@bq1{=^~2ET)pjN4B&kL3yhR-n1ArVru8$ie^P}QWD6lxh`Emn}Y!e{jr)ItE=9b z8d7Ms!Q7A_QQ^fU&IeCUK-~^ie%Ani^cec_W*{?(VH_?j{I80N{qU56K#Ty|Y`nY# zDwY=)v44Qv6Ff{piGUlzTVX+lXVG*+Ki9a#stu&9Syv4Jy$Q;cH5Y_4b$*vR@t7ZC zc(hoXwc}FSA1r_@Gp4JUFPh#Y=uDs!9)9c%VRi?%otRUgx}${yhQe5!3FO@MR^B%? zLB{-FftWA85oq+{-@WbYTLD+({?@Z9DvJvXrZ+iceK5{_`9YI{zxrGR3p@ z)vNS^0w;81hJ2Se%nnFPd*SFUN0->mrqLS_eToL{+37pjhyS_wZGOIWwSWiw4a=JZ z;<}WSFghMHiDI@k8`Meya1bue&bF;2aE>4Zb0ahq(-luJ6|Hu6j{Te2j@HVgFUgnf zEG!Z*mV2ZnZPCd3#;sKYs~)H9;f$9i$#e0m-H46*FT1`0_L@19H}|ILhTmpCe#|E8 zBU$4FIfQ`{>*%nst;r!}W$x&|zy@r-VSm0*EebM}XZGgiZ^|A)ZT@KCx6JQNLqkJ- zefo2+uO84ZnFK_LC9DQWgPVnD8=(9Ua|DDzWI<-Of5!GTQl_HZwDTp*!aLG1lsW z{e}(zni6%FAi#o?@Zmrgu@hRPI|<3k{VUq{+N{9LL{SeANagDNXHuY&t(2fGASf7K zy1G2@?GV*_n?;Bh{?h>Gb@(-7@QZe|9n1FZNPnVIQ&Xd(LCW335L#9yaWQa3hrq6b zJy4YLD0o!k;}0Z8Q{ayYIw1fdtY$bfmaZjmL|X%05a}iPj5e%C_{Jv*j|2Ixt-Xgi zjMmkDhmg>wCgPUi!it{;)mQ|BP3p@1$|P5R$XRqZVujGK_8sp#dFrA&i{ELh8F$j* zQ1l1mrCj!krJ_YsG&uV1!v`OzV~PS94nD_?WrDIZ01|oz2CJ*9XoSK3L{d_64dXaz zlPXw8gOgiP;SEzJj7$ED9=M8GVPj2ACYoztTTp?3Kue1u?;s=&e7!K1v{7Sfws8jm z9f1Ur7Z}AquIV7a>(GJQu_GFzEf6bMckLo{-X5Y)LC^>WH__)&K|w3}X~$YI@B|$L zxHWL(Z%0S(G{fTjjloFYkNGa}7lMij3YeQgV+mv$O(!QOv>iXwiCP>DN3Rb8xh8v~ z;ietjjTa5^@2SfK9W5Fzg<1m8yfMQlaXzf15=!g93f-y0Xc>1NeLsF)UYN)246HJIentU z-Mf2pXpt1}5`Dq^uV4Bw9EY*i)U%Q5oSya;nK@cvrg`h0!6 zQS3f=NyW&X{TL6`5tDOrIp32o%vd`}7QqM84&W3*F zv#CK6#z)tc$+mAde`u%XrmW08w@>DIT|cRiJrh&P9M=_x=A%o4E@y{5<|2l^$=HH- zH#Tbph8)^z^XhyI1VwU;sIDEk_u+*vkW~ii{N}f#qT0ZAMF;Qr-RS5Yc2Gs2d+ev2 zsd0VK_3~x&XEQdow&??J-%`^V~BfH5Grw3hI-L7#rUDZ7>Smk%DXOf(j z?f&RR7iVX=O5Wg`>{5rNq{>T6#rN%_7%hdD1vrj96BprXQufdNGQObu%^9f83) zKZo^pDCQIu5B3~FQoX&=ZQzj-GAa~a{H(xb^(%=-~&eaD=BE*gbq#zGL5IPymw&P6WGSPJu#=zB5f?H%^P` zr2bhfcsaQ(*CEV7;Ire!Boe0cal#lK{)|b!P=spq_y{7U6+GfK)Ya2_w*&whfvd;3 zh~Q)q{$&5Mudr{3Q_zLNpNM6x3@~3~q<&ITg7wCH(2(+;rI(i%L=%oZ-U#D%j3hU# zqYUJx3@mX*pC6+iN}fg~Cn=0ppp8EGD7r}cJ)$ryR^Y~31rq>83Hf&+Axu!-@y&$8Y*G_pz{QS!;`WvE$4>O3v)|Z;em5K*B z9k@;C!FRQ``ahC{-7%Pilsq`6YZ{!~lAz45AXtGkj`_vMz{MPB_meh2wBY702|6|o z4i1EgO1SwbyT+xaZYz3}MEzs*?G7tgeEb-a<2w{E86_A@ycwYld~PrL>;Y~)H)Xp`lrkTIVEXUB)?UN} z1I_1lpk-a2AC`v`0fCZR^Uh88VCh(ZqQ&-6R~N`rJq;`?EBpF{_~ly7$bv;vVvWp= zSg$SU@b8-}1p?(k(Sv*U+Ofw&O1HHfm;{O$+(z@0p97b(;TQ#+3~vXS5~(4b?hDHZ+ZFo ze()TAN{0Q$g6pZ6Z0fcas`Ctd!SEzYkW$}VzipnZurBxpR^dP4H$qaW1LWv;>^M%j zFh4KXMCVy1*Gor;74)7xcH%O7T*?jW*K+GIV%nA6+MOsLZM1cq)f#An5R-OWO5|x18Qbiokv7u2VXTHK_Z=<-r) z#l^>a={$G&S7*@jGK9+h91enm&Dpapu#!;Ak4;VG($v4_Du966Yxe`Mq4he!(p>cN zg@i;+U0upkUC^Dld)+m&Q)k&nmR}xk4rWe)C+t+VxG5k6gGKS6bn?p=fvhuciLM?- zgoS0@s}vB{dL}!wS&9$kY7+5epLxd<+#t{%uT0&kzwGk@^2*iCUVIEx!B62?DdPM6 zLLuv@7Qj*0)ia++jvnkjkNt$@ZqtKr=PfPkKAaZeY;QH<-%>rY01gbJ>Q!z>vG9W@ zHv<~?#&!G*%NMeUo2h0WI&^WIMw*%+%@cpNpyYw9qHW_VKms%{-A1(Zxq`GhCL+~_ zv(>!&u}7I5T$fbQ+QCAWQ}wIlp-;KDUs19F$Dw$+CBb# zESMJE6*3JhEp;=C=8HMSvnx3xWA~b@hJ6&Xy;UT6rttibI$0#K*~o$iFvM3q{bhVH zF@|hm)|HcV*GQ^XaZqQ=NRsIr&fyH9py57!$~xW!Th};f zWEK&|?)UHSNGUv2Jv|XXPaK$og?f0~KFY7>0*W{Yy8-t`459>@pKr&i!BcI;PMVXO zyX%N2Oo(BBh-5iF9N>d^fDONWJ|--D32tGH(NmL?Nz$&5QF~Em`G{b}xqi*-nYDN? zf9yuhC+xof?UIp_5`^d+?-JiCv3Mv=kbeV4PoNnz)*p!Zau0T*Wa1e`-Zc-gpj(Y8 zC8}f|PqnnQ<=-rP{d)WKD>ooH@vcCT09m^JXh1_RI4zf;q=bYNQ?p+X`3g{k4U`_n zW+cnr*cUOihfX@KkUAqziJShVm9>M|W5M>DuCxl7g%C=4btvZ^v2ywg8Gs0Ego{z3 zIXmAzJ;}Utr=GSp_V4C1ACQzn&?0pJ2!#7?15?XUw`o>8 zf2vzupPby?E&Et^+3I{ziv zAQ150a_2^z%SAhWp!9;|!oz6Q1%Aw6Tc_idR8nN5pl9w@0qQem=cA;rfL+0AhMt|_ z$DAgWEBdc`!{g+Nr$*0@OTVWQt2js2Gb=3>zg^*Wb##lv^E;_sR#%qFNFO+coGZMq zrK1xU8ymQ1ABf3&_mYop3y_oRPY~@wDFYQG1ln&9cM>b5_&J5ca_G}t9{UT#P2Nm9=vuekI!^G>!g zG+l6SZ>S9ez@78xQ9y=OUk>8kOOeaSBq2RWvBK8$Qm_v3_mu>|**bWwQ7%PA5w)EG z@Z`|`{n4QpmY0Dj4jh3G0zY#Yif4EZrR{;1Xj22xCCeQLe=#n|WXE^MPE2=`keC?= z#vVN)wYoU`WGrCj;H;gd-r$gAW1N9vHUS;+{rh(`iF|*~n*!DVAAx@~AE0=}*7W7` zXF{6StH;kM-gD*aC|W^Hpi5LhBTPzaCmY)etf|guQ?|1rcfmnOD{BV_uRvS@P+LOH zk|NXl^ioDl4AUATFgIII-GVT}<7S~s{SwuX?Ckx)8g8H4$=sly$auH|gLyb$aJDBc zEUy8g!5pSoEb0SDBmD~~>;VGw0qFz105NIcWj+q+XM3uW!z8#4ZOZyIyS z`*;Zt)`^>E6qp%>^n%bY)FrYcw0a@S2l)9>{8|7%yjJxb6%z7vt{+zj`kKbEuRqeT zOGeV)PDyzIwdKteKe4`ES&}EB4meMqV6_RrQ2GfT8vFN0uuFYH0vIm(J?24Aw8*f; zpJ#n_775quZ4t_RP#98sYDDUpE&n@lh&C$J`+7-igmKXrvo%DfLA zz7)J0JgDQs8q#0xcEzfg9O{9c?01+~SKnog_qQU?!!<%5^_4*aT&eKFzC70&uQKc! zwD-t~TkdUc-Q4pGvKJc|BNh3>GbeQHOi-JlMK{IbZvKv&SF%L9N>KXJ;Ijaru8IUY6OZdMDkCt$zpI15I1l?pymgyd663OJ zyBgPC<>v=XJt9==W5(?Ltt&KIwQSIBO+9qF!V}96HMOOsCE~5x2T)p6lO)rB?mx3r z!hzk6@CpOw@%p1$*$6P*bRrgxj@x_*fJA&6x&V-4X%}g2)%lqSwB5~{H{;{1a*W>2 zWfyv;by_op)ix)Jy=!kTdiqrNquch;8M6PBfa^Pet3lg_V9uCyAA}fgdc#UD?SnQsM6SpLzADYJl*fxmSy74DttR{Du{7f|Jw0X{!X&^HTD>>FO#43{6r} z_tIfdKM-nVKu7w*kaUL-K%md6YNb>~}CnVzi4hie_``DUS>gNA@a)3kV&$a~ za%H>A7hbW=;f)wqI<;Akgf|^GHBJ8@1H(otpTMH3qRG#~yRYMhU+e5KA)y~N3bwGW zaoi?PKU&4jNS&OVjQof|lYq*q#o+@t@@BXC=>f@)Mj&!WK$nz*bOR80l}mpCB~HU7 z3zpIZI1YFQQ1c|zrzykTQ^@e1D-!~ilvKbEAYLdfL`@J!@vNwLKxsjetYfVCGva)? z?umcX>JRYT4-Z}MKW84h?gnjJa2OO0LbN9J3IS&}FRGqTd(<46LgN=^=Na@4{5IC{ zRfvUXM-nWVkLu*=lW8c!kh96;Dz^&3;V&V9>g*yuffq}K(ONqNXgs8Xbk~qzn%USq z&dTZ@PDdje83`QC>PA4&NvArk|4nUE=_nm}IW}w7{&fu$t01c2-fFGf3YgM+tpJwc6OJgzd`OZmlTYxL zJCEH^=KDH7FZ7sTTxfush$ZXe>zm#f5*NoZD#$<`LJ$GuRq*h5dV)8-X55&|s_6Lo z*13l>x2T;q5>et*y;|6f~hpOhGWMGL`v^}OnU_jOJCWf*2~p8I^t{YrAT`@MI&v{G-p|XEg#o+5_0Z6N z(aw_miK&bdC7cXgE?+JwE3+)r9WLG-Oz?nZ42QnzZTp17A;V z={MR(kybZ- zD6`s|10n!C=Gyw6ptmh`=@aP;`7Xp0R1(~0E;5S zxqqJ!svyaC(M?lF#{|YqYYl{V6}DA0UR972K$%0y1BLvwDIUVzy*Is44cuY+cKJbV z$RO~L`aRxGDxa8&Y~Gx32Fe73t+^qA{=79b6*Z=GbiKj!&bmg{08$IBZ$m+gJ%A z1`Wm~A6(H24j`crNXkh;@2ELmnB)Z1ovtPy^=9q^ZS`Sa^O!TX2X1N3%?8XKc=Bzo zkmtl~2fo-~Akq3m!b8RwJ26w@SX*nWlaojIqC}yg-Ma@5N*|om$bKx4eM`eg@M^e3 z^Id_%?<|VZcutoNzPCnO0gXhyxL}8u{zTBET}C_53YgMn>=;OZtH6%ojGzcdI0j^< z2Yq(H)tfKZV|&45u?MXtQ_0N}5hZ&z6UmG}5GNx2-WXgc>aX;3f1kVSHHp$sx_RxM zWv}I#myYf`=8E)kUKkG&y&!7xoyh0V z3_scJaAK`MN_5uPFuA%WLBecMDPwPmeaFf4k^Lhoy|e3N!~xug4xK%~j9tThvXzK< za2K@DMo|o*h0Dgqc820$;PVP7n-hjNXhedOqjTr^7;vEjXj@^?axyU7yMI(>_ii(A z1P(Ay0a+~!glx~oGY_bwW4?3aMg#H){hOtn+qW-ZY_W@t4MQUhM1{BIF{hA$9z;O~ zw@W%|YK@)Q0j{X~;!(ecFi>*~hc2rYicS5npk2Xyu z>(eUXe3!p1rQfZpavIf;sBp-)4t8vCTRPN=A=}qnu;;r+%D#4z|ve_HS` zbac?o5ENOCv>j9e+P)%&k8;FUAMj8<70TDj(C*aC*1A!R?*WV?{Z9i@y1 zdy;ZtY3W*nzOzd|E6TX}8vG&FP9{INg};9@O0+-o*!r#}@2AbhhTQj58G%eco}UCr zeDJk*!o)F`k7r!y(soMztecAoypeL$tFQMxi_lD0=H2Y*{^Hvc72BrGjjKv>4%jKh zPuu6-?N~UvkA0fmF4wLqajA1guvW3zpo&Zr^558zPi44ocVw|PeOV@%D)c6}bZtrCbeai0O9rS~IhGz0$p{|Bt zo<*T<;?20o#6GrkwG%eBoucnQ_nL=Bb{Z8y!I0I+sKnUByN8O$t!=FIVJ-P(lK-;$PDD(Bn7_;m@;_CXuuP>|M;e7v-AqEB6UmoJgv`kDfy<9EpPAff4 z{o)Zj#bZ^i+lm#0IIpaZxi@~3bjx2dB5sRqDopj>skB5t*8Lh&c?C zK(8Ou|74vMo)AL2_Q;X`moL*av&h%qZPJWmeyLPLk+$YSW>yx6XABB(4}!KV<8B|E zD{3nm-=~HSXdkmR8tNGt(RS2-bV7LyGQsG$Azi$7d?mR%uB2_*=QAs|Y-(!rs~7dZ z-H#5+d9<;yeg1H^3FaPJ=5wN-vZFJ7%L;5xg{={h8D}8FK2z9g{Lrn z|M}UhXSE|wC_9B&Jnx*8XZiQYx$gYZFV?1GeNuaWFx&gYue3HialtnP->)h!! z$nWv%o2c&G8XQ^bW$(2(U1R6&>MZtYmo~LPo}y7kc!|^F*x1r)(t0)Rm~L7VE~|>; z`hpla_x1H5hxcAuZ`zu4_b$A5GPAP@b6czJl%yD1;CJBJVRyou(HX0|qy)TOb54GG zO7vDUGBZ2Di*rY-({ciBeN6NHSxHf=V={!zFh&&=O4DAc3F zc2q{Dus*LmCA+=Yy$tBdof*JU&eFi?QpJ1pjLnDp0JZ5Zhbg4l_H%hK%3 z*w{tH{wu${R!m+4(1D$`+|U8E_*B33N60o&o%f6Z{4qR?DpvlAw9~LZltqwvp#*^R z16u6_h%Pc>>3GayDJUq6j0OmrMCQfqP?Z{ZDZ}VW)rp9?sHVW@gZxal{k_w?$Zq zpQ5n}q7RTh9d!eeYA1g9XTo%7*OGZGRLb-&H9pY-Js2|)L zy}|8B|DS5d`s4FQXWT%lQynm0&pEw44qKOqyW-$;x?Lod6rG+Oqp#h>?fWH#%>xZb z7AL2S*Ha?ex!xL&dOcNW3T~|XT%g0dUFk$;6-!NR6@9_%KwPM-eqx`+-a~gzMLk?8 zBPl9N!=~XTG&}t93(?HJmefd1){evNh7^lu-YQ4!YJ9x7|FxT)_KUMIYCqR|c!qMK z&QiR%ST`<9RJosw_@~GCr-ZYzspS1#<6Ste)7|5;G}oVQPxnd18Y5Bi+ZRm3u@(^f zW9W{gpuPRWp4I+WMq1jU5+Y~IV-lVBclNa>{s2X?YId2dG*{Xn%7V0bfG0N^z>8{M zcSsIM5us8qXe%^Rdbr#QyD4;46*4fMvNOMUk(N~`?Q!!v8ZIM4LyXk9CE~y!Bybcv z-!tsE=$8j`jQPbyGQG&Uk+v`UtJYU+AufFWd>SgklF84X-{wZc9UwRye%hF~u7M`U zUG{2-1QhtG*;zXM+juOgCUdFi8_lBaPt?COH$;*777JkT0L+k2BK$(a23VlRcwtEY zw{rJjo;^2IwE=$nM>ADbx)a^1KoeZ>rb5C`8z&Pu#h`$hBra;tcpji6(A#c}AlT8M zmXRNExpXPreF05I$S1|P89clE`TF+V=li>t6z#tQh?A9>`H$g-BQVb6O6h8nXi+L$ z4+*IOgYXX5ad?-UVf(o!!DTB4LDU-KZ^>;Jp_U>(4LSx)SsFE}c_UJE$gFgm(DD*8^G=hEjQvUhSx zEAu15x7k8nEq6s`KUC29IjwiWxl(8LQ_NOwWdP;EKC+;<^CCdzs#na~B+=y*Aurx* zO~N8GJ)Ncdc}80oj-LrBMDah^?PBWP*`3`n!a2b=hVL+aBf%SNH(0vd`)#7(J5TUh zk)^?hqk3!Vt*z=y4j)?nZSbZ~KK#a!|LL0B^Z;F4|9Zc;-obq>SNs&;C?%Dru&quu z1{6DGQQVq=rA)*3sEZli>(i!*XHH(8?vgXl&W=8Cb}i`6XnQ+L$Uh~XGWI9W-_a5< zsu;UAME7g&-J_{;i5&S-^8Fm`eUab(RYyl9ox{8WO}&8^zIW-Jr+b78b$y_=05O_^ zEO4j&g$XJK-Q6sz1b?QYqQj505|fhbEG;P%_2&jED6+13k;yqZ&4W;i9GzG`87K*E zI`n$u^!4@OXFxJ#D3x(i<-&zez#vlc00nx<$tmrz9%9wYRdJYcDAa>RO<pu+iYyzRhhWrEQ3*!UKj=e=>sv3}vb@JVbJYhZ))s2w- zO`tmdRgM(&g6P%Qg2$;_^8Ac}b`%e!%FFiz6N(>%H>ovAOu{i+n3$N*9MdVC*Vh-g ziRzc{cdDzrKd^Jfqj>DXQNt-(Is~Kpvp2JP&zgNQm(NL6y_*|fq#_V=)q#%8&+yIX zU8UzrUAHHGhzQC$v@*Swe|bf8>d}i7<5Xi`bKw))xXs8sCX+w)S*@=S`D=^3G$ zU0n@sQ;A&Z-=cHQTwJ*m8)LuX8Qo~qW7)cGDA&IKAVBLBshZZZ}mstPm$>)YVSu=1Z=`< zT@bWgy*<6XuLTFUMk5%p1|gPSdu>|W3o3p{&C#Pr#UN?a*@-|+x7!2=C@U-e#%NF~*aUYFf1s+3`f|>X4qrvv-KscLN!>d;T zz2DGa9QJ}@dj@A2p$OJ{%iIHlvxp{(*QD)_P;drsC#RqYaxE-$rbk|J<26!F@@%8? z=ed7U$FRQ!I#4bv=#87R3yPB?X0S1y1}<{5OR|k!a!Zh?u(0}C?Do;7!2gWD z>!+&IlI2^~^sHJQecShLeXjZX^PN<;^)`U7%fG7=$;Gk%biT+&2bq0;iRmnxxQC>j z%$b)t%d;K2G`R?+ddkp1U;Gqb;bS5^|6-@c9M6s3;Gn6|_c&owyet z&)UnSAS2UbSE|exs5l2y6t=$u>s9hSU0vt+7?2x%^>~hK5REWSb|(O48ZR|0{{-SU zZSQMvrlB?!UxBplE<- zXErv?Ls9Q3#vS`g{^e&R=-tY=pWlxiF`#ljs%7FhM<{X$ObG+57JDsIg()80yGQJ$ z`R~7>YW!$SRzkt(yJ3+z6~A7%I^+*n5=AWOuA5v|eMzpo43Rb96_6RqdBJ-Ccn*Zl zTX1;&A&R&i6GK+^{6Y;i+gwg&COX;23w00dBh!#%r&G2=cSc};w!0iWlUjsap|o8ET}&s(k1T zzCSwWfMEXjty+3~ORH#qkT1u(%`B8Sfs;0Ki>#1jL z?b|`uihe0j7TUhO`4D>b@uPh$obJ=(eA&vUl|2=Iz0>f}@=#U1^(eH_fj*9&qVURaAe(?p8vlP!BuKt8^S_5j)xld#^ox(M8X%qP2>p5vV(W z*80l=%u=%_^@4U0?Y{tgB;+pHrv9N|;<`q=tMtmpfUOW`vAP_q{Sh@9e z#^sqlrYokXYtnK~SaHa3I$|6StOkrKDooX>syoYh{6^VAMqROX;#YZk1yvK7%+?>oXjK^5!zp3k zV5MJo`*W8I&b)Vrac_Sk}7Fx`y{jWH)_p1Xdnur?`{j#DWz#s*xTQ=~X7GmRFE=9&j*wqXO8Ryd7J<{r z#o?hZT;!I1#I8w5vXXiZ$asCH%#-Wf@4wfUL>P6-T}aYa&R)iFZXz9b*e1wLN3~jWSLY~`Iy7xqXX$xZC;S5|2umS&;t233_D~5i!NraIaIOvDR3Z z!L;kXO7fHEm?7`pecZ%^%bD!!vX70RmNN~|Uk`32j>o&ec$s#n8%h4C&vl>>xJiTN z04o#t1K$hj7`#1q%)9k&(SWtJZ3M@{$G!qCI*w!CJ10&%48EZ9oH9%@{;K-q@<$1h zRT{<{#wRX0_pp12*mZZM9ps99?6|SS5WT}}#KFMz3r(Ih>fJn}XA1LnpMu`hxqj6= z6leUMuUD#; zu02wn{dFldH1wbQcZlC>bqY9F@ZUJ*cmXjG#+L~MvTJlUQxNxTKx(s49Hj9@sJ98#hbInN=i)hMssPZ8~IL0 z&h^#+=6>z><9G)&;n_X1kl4z+eN^QSY%e!Z!m7gCF>MGdMSzS+y)9}YFDbXUPsQU= z_-P~UruH?**$9Dj`aok^+ApVtzfTP~+V^bBI+Q|Oo|_t1h7R$yTf=kTws~#iJ$mGB zrDRKI{Yp>a@hVQ|%RdcbAlN5uxnOxsmE9-to2b~)Ct=zw68pMI{MHUKQepYTlQcKA zxcrD!%r=tog5_XIVRAr#tC19?McMlj#)H?)94w6W&oQs+(1aCud4Grhw}^;BGWN(iy#zY9a2sQz8McRcJ$bpW`o@Ze zpQ>^QGP;RVU<{|vBl^!SO>$ydTeL)rh+FgWFwi6p*rN3uv#c*uQ`;Vz!TbxQ$>sdvm&ql!2IBr zW8oV*TJ)ih{RX~m<#}`6@qJC7@oYP0U%nelrmGr1YosX*_gz=`HPWbVakgixgV@Ct zi1wS+#fzuyyB4l?;%tmh$Ni}bkW&83aulZ0?D0%_^ zI9QAq@GQk{z4Pl>lu2$$0KL8uN3!tl+FLt?&t)7G({|CgZNTQjODBrUHQ4A4QY${L zPo-t+{d1nD(k%1@3=IwE^Fcv^oUDw`Pa$sZ^Jw-oUUsz;?;m_|B`Uz&=_Qb=R#cR_ zPT;pd@^b_fg*_}*;zuo>1S4rB+saI@z~td)W9)pje0-Wa13i)qlA%+Sx$!TKc!n8OmMv8dv+p7|^v zX6-;81Vnwy%{+VQICh?3W1Tz=(p=4tU%s58cs=oLqUo;EBKi{q)6$>DX$J5=M|%}e zZ<6tD3Pl-^_$bK#4dHn%S3#$sjFtru4e90-m1KMB#~nU&}56mg~7Lm39=RsEUu8OQSnf$|MdO#1G0OR)O`o_7R7qD9haqRYwvQ% z(AjvwQN%yG(6J)(X-{V6>eLO7dgB>UPpq8E;U{83pWY2-?qC>Un!Rmq{^0e^gapyy zr!-YpI(wR1dz$CvPu;F=?pD^f8&7s|f0r6lCfvp)TFFIT%bSa_ zw3=Uv3Uy{e|DDja;bVAJhlrw{VJ=1xGXi-MQO0}m_C@mRH*bC@vEE^|gojQ5mVGUP zB-j=f&fK@>?SEC1v7;9XE0BqAS!WXN{iFpDsKb8i*062IeAMOddM(L`f%6!|4}eH3 zzI{^j9Qq?u=hT+=o{3LG$>b)4O1@^l)lEQbY#?DJgi6K`g&m85k5uf@8QyREU+|{cLE;%`o#-Tm+@$ z!!y^d(;lGWWF=5opHu)+(<78T;x{$stJS)l`!5-jNvl+q)Yl)Kn4Uc!_TAW~nskJd z(^E|5tBu4VZ(A4J*1j~GFSXitt$nG~Ch3wT`L|{jm1e4|53F-BH(0n#+f}rSq{_H6 zi2FR>btS0%Afm7)$NBA?Q#kPkFjr2l#C$sJr*(p_e{lHS> zcE~PzEE{>MasKo3b3)M^fmT*l^UG^kB%l`Bq}-cd_EDC$u+dK~cLo&e*st%P-I|;@ zLCUXJR3$MzNXwi{X!QKs0R|gvW6m5u9`qwY*sK=RZqr>_oFHU;iO;Ap)ydI?FWb!) zKU4pKa+iI@`ui7W14eOzajwK9swIvdUct6!pr>aK zgG^L72uqQghoq&S0eA!mEh?vsk#ZE_!EWu7`sIn7v5!A7d zz2N8wFqAK*`v`DwsKq1^Fb258enn1R(lZ5p<4KloZbUdY|EFdahsNr-b!v4S954b3 z3<^rWO{IAyvp(S~{iq<(fZHb8qeLUI!>#+()7SGaKMv1-nc8DQt)`;#BQU)|J0#-q z;|~L-Rf5S?jItU{dD-^eyDT#ro7Tr~PWEODY76&BL^gQtt$jdmJvH;WX~XXUXVgRK zuPwI2-Nlpdow~%C!^Vyk48Dj<5{T}cwx8LM;j$lGaAcXW=@(mjBbF$lnjm{}hSt&O z+0i%oveNN3ZqaorRL5MC^*1d1zV=o}Di-)2U6Jk_c@bay^X{S8plu2XvVe=$dl%V; z3{g_l@n$}~KlYdoPF%oc~C z7xuvD|2V4nP{RJ}=-V?vtdhg$gP3*Wf!+p?=KLy_h*ohw-dXHpa;9L_4rdX9$dfSZ zGbA%-lyYJ{RQ_NAlqQf$ymwR@W6??7nhdewr&lPy5!;#L=yy+ zf8e3a+=jm`17{m7uyad9ou;~aFBYBP5a=SNtY+4uSc&L=Ng=tz ze%#en%%|gzFl8R( zKco8N!%%E@lA?vlDQi8w@eZ0xPmpC*R?2$^xj7!z{t=zCFHnFetl+Zicbfh(ot}KV z)DLUVlb#>2&OMM2RcK1VadPowL-9mQk#q5z&I|G}a+=3G8rt;>1M5z&YMs;iPBocq z5Lq$XznF0?B7LT=h5fGZMl`0b4oMN`Wb9o6_f|Z3wfL9`O1jbD|7vU3j5)*Qu2uIQ zltha#&O!kIV*$*nK|(0!yX-H=eLW%q^v5yha<#pm!h_}TQcR4Eg+j$n*AB10z5PIs zuR1AlfEvGfaqqKdht`k53>4+6;Qsx%m%vvQl$JV_+H`~Bf+@dHxM-U(d^*+mfdaGZ zctBeMs)wbyxs3OZGvL{0w&S(K1meYGDII5;hRDcBHDhDoxd0qu3j4-e-%sA)rW{7h zHHZ8!k-YnDZT;E({=CISHsnpfgm~t%OJA8Ru1RHE2*1~?6qJ6Jcl#>E@}9l>@{C?M zG+r-sbXqAioId?(k(vMvLk+9X_|xMWxQ(JuRmGbOY%7khbMUIW4zq5&8GSQU#^HaM zL%mJnq$(T6KR0Atj%#KIym4#Vk~n>bw0r+1il>*(T77r~d?e+LVd-U!R=4iz>s4HH z67AjZd%pL5-o<`!^*3f~X8F>b{|l0#`tW;iRXv?56$lyZ9Rdzab`a#Nj$N3o#8a{ClFcRaoD)N4U`yzT0uxZHR^Nga!i=83-yGPM1LMTD-tr;M?Wk4%FbWjl?N(`~>Raog6n&j>EB7gK=iBJy#eczVLB!geg}EuDN~ zG$3P76G53&^$B8RVge?6JAo$4*0(Vi8XmqUm=*uAvAt+BI1$-Jyb14H*Jl2G@jg#* z@$%6FQzYH{?^A(TNyYQ*+0UihCxJADDn3>_dvmtv6y5_Urx*6ZtmZL^jOV=K=I4m|pyDZeHF&_oaf>W(m;?IHc^(g78YHl z_6E-gyso06+f5d>*4DzifQ|-`Gbz>+xLP)_bI8f^@t4pO)fUB4?2z1V!l(t^ayTvm zYd`>Qy6?o>iy~aO{>B z_6@W)hgrJX+S*>el$*`o9#)gaLrofp00m4JieqG}QOjb#GA{8d@0Ta5vf6xnksE>0 zRj<=N|LTjMj61f!%4OC;-)^s}r7gFh__yZrim{f4{`kpliG$n3j*u=#5U?QK*iY!n zMgHI(vY$Tf!IM@|frRsw3=W|8PzRv_LqJWSIX6B10mB^-(CAkwc>oaXfMes~!vg&L zX-c`e2*D%Pwzfl+-f`kEA(F$T>*y?@XG1&Kif_TV34yl2Z{rGNRPj3iQ$TLRy~N0? zycu8@5V=ObEd$VkF9JwXh7)?>Ii;nsKcswqB8L6|^cMv1K5S|@2RdL1a&is`38@(v zcw>eRIBI&Cg{376E32-CMv?ETTi@jHaO(?S@9Q_n3c&?#Gd$>yqVT%{CI;{kDJv*| zg9u=aWpQzFn9!p~l+f_=^eQA3450q=ZmhPhP9y^KV?bdbj4OY{u`zQl2NG7xd8h2`1BvH0M{zHErts?H7oqm2%FZS>b&bp-Q``-%I z=-EHIGa6f)bUo;$?(ce5NQhb9mo`?S@Y5;qZoL2@NNU{fDM~>{hp4JrID4@!T z2B=S@qEI1p#RtKKKu%FDt{L1{baAU;Hf()p2Q@+HNlrF`2_ujTU|uFvfVA!jX^Its zcoF8okpH-S9s&nO?2{fMLY0ta*%oM79Zd8sQcs zgrg5SbY)fW17u{EfjU&A1iKS^TIJW&quwC2a$G(N=#FgFmA8q1Fc}Ts37t8f;Fbw! znH+xykyTKZO?w(M;3iTCD!jD#(>QSYd_atFE*5qie2%8cSe-w2F71CxS$Shx#3EWk zEHd7Kb4SlGI1<)lcxkT2Q(-tx&XuL&^2x+Izb902GWP8rD~M~)yPJ9caXWOt_& z=%w#jg-|&vt{nP#bjeXMf{B5a ztW|KnL4q*1@_y`tze9r#dEczQ5E^lj-8T@8?mYz`hNfB#1{+YweHn9-vaO>dD9H-C zGNjuDA=L!pQrZ(()U-K(z>}Xi z0pDo~^Il+e*xA2g91Khv7Be7U^xXtRR=&wG40As^tt`!LKrrdJ>=Csk(2B|L@ud=g z3?}fq#_Si=AJ~N$UV0Ts1|U#&NC;V2%{_8CRL^(rK+=Z=O4}3^*U%Uip`fb!>LK%V z3ThG6jHsq=J{x^rS$SMRVUnle`}WWi@Ur3#_VDz)B$seWr9v+g)*McMQ zEb}2A(QuWKnYn#|UIDflmqF8nJOI7`SazwP`-jcsBF|A`f83n)~#B}0-#l}=XC7T@^WDcD+`O-wfe?A zN|fbJ9~Hd3p26p+qT+~sBVjR1V@73D=qn4S9e(4Q)UoNYjQIFv=TDAV5k9Y*QiQKNZ1+trn(R+ z*l4Z?)7uDunzx8hC4Z1F*zV8l*66J)8fH$K!?!cKs!+qcjiDD76AS6-fy70}0*YFw zq6^#Vwe}O;*+~*uqQLg>X3%D_AGoIU(v3pVLSzT$v3FN)DOwDv7Z@H06x}6i!%*MY zxb`XRkX%eqS~oD_*E=q6q7_5~otM9kA;f299{SJ(T37)QQM}eNG1VN@U3Lfiz|)+H zii%r6o#Qc8HU|%%u<&+9ejpCYjp(hxsA&4=gaVW}94ZMrC7rmn)8u}daVqAz!M~(L zoj1xq-yXVR1b^ij(I-h+S^Mno+av-fi-l7Mfr6k!^0qhhEItH`ekGP|33BuIgAdPe z73>WB%Fjr>1l^5;$_Ps#p1eY;$oi#Iu;p5K>OIo(0`NiMI#wk%rQ82=Ic(kMca2W` zs=I34u@-?B*l71rh`dWlb}Aj>X}=)CBT%|IH*>#vLou@Z6eP=Dy2eCBrRV2YSv0Y! z`N^(Mi#)YEd6L`?qsbV0XGlItvtM`ACao4!IdcX?9^lnM`+_+@RAl6NfRN_qxOVQO zTEGp=gkrg4pUu9QQ|Tzwf0;f66PtmBg`!UnD_2X4arz&A{-1cin40;veg(V-wgn)N z-`{UEz~a}9amN24@4f%I-v9q`?IP7tghWGyNJM0(WN$JmGBdJANT^7e4I`A1%!Vyn zDP(6QGP3vH`+I#juh;wY{(R2)55DJzb2%qHpC03Wzuj-Q>+O2GUNMU7A!B(na*GHt zSfk6g0AA ztSTrh27&A00}y)$9q@^-2jsVH-sF6bXyI))C_(7{FE#R_)^YSZ#4iFa;S%N=L2^OF z;;DM%Q;KPn`jY71VWtVtAhIj>r`QQKulb=nUN3>h(brzuHdO&up2sXRKMr@Gl0n;L7$~p&}2qZ z@U*PDtZb0McmGArL;o2Pc#voR!+zfU{z?9=j>iXvhp(xtzm1D4Eh*6g^^}n%F!`C%?D1(~BB0AA2@{1O-!-h_{ims2oM!4s{iKV^aBB|8&%=2UzV#^#KT4 z4iJ(%X)PRI6)EpW$}u&GRQ!QtU0H&r<#qtJAkQxBtfN#8KkhEzFyWT)Z4*ddmUh5+ zT9^W*E}n6}phHjAy!s|O8bltzod9*-52MSkD<@ZtQvzt|*3B28(t;^G?H0@_QdW;( zlGiXTq1azz`XGkQ=>}|}m0>iZWyF8<8>o0?R=V-5b$tJwKsr*ji7MpYsn6CaJEykS zetfu(f{rfl&bStnxX5b*WIs;zFYVJn*W-9mib@!X9{9ZrOH1I@T?9gXlF1f!I>+2A z!v(`aZjmP^CsT9kOYFZRpTUx|sTGug&LR)@r(pTs8EQZ?+#1A?)1JF&y5Lf0T*r7{ zgv8)h$O&y`Ybm;?K|$LO$@r#1I|jlyy4Abr$nK|Oaf^^gl4#Wh+^cV2g_T8wW6#ngwKwJZKpKl z87l8>6fZG3>R(FeF1_R-)#wb(Y^k+W5&e!ieAme?F@O*hPl(XyIqi^#;eQM>fKG@D z5i#mV@2m5vyZcsDRq=7K`ZK5Aoz-ttrslT&Yk9&8%W-ERhN1M$Sfl%%{)VkfUkW`v zJ>4F0Sy}RvXEAVE1Uf8Ed|*4vnEPHvjEq5 zZpXG9N)=9z>K7+vTQD$qRKGpX5m|0M%B8*}nsbJ3Tl_ZXV4mVSo}2RG=EaeitNgTn zq-V(rH)BJ1)T4dK4pA#ap&#T@IzP-If_3Qfca&D;fzI2En9iKDzM3+|LK0~9rMg6b zO64q-w}F`%c{nd-=HW!K#}luThL`c|Stvf=C&;beN=hCS?K~j_{uDq>w6|5Yw8o(M zHaxrx*^SyVVTep3Av~0OP*eiFiONdf!)z`0E0@!yR+}8ZKrXS>FXUrp7Q_4j#Zr+ejh$1S+8ThOI6t7temu7R2i9N`H$i5o}pmjmMCH92&CfW(i zMKA54LltG-0T6Y>coJs6qoQgre=p9E1-hNgy>sASktqHhEn{oP z0SMjsSCp?HI&ySOoA~&@16jFb`1oH&sivF$6=&;!>fgK)q?dF*{~LywNdf?HD?Tmx zub;lQ+bH+N7Fm0?z5jOU`qG=t?i}E1&XD-m8)x&sYMy%u!eQJ04SH-oW}K19j}PD8 z`0ygb-TA{!-&WT*t?b_!c2?!Vkz^&4+#&Yi z=W2$!+2IfS4|a(ft3IOAFH?9l@^s(#Rr-m!JNYNwYE8&GXIF+X|8%1D-c-SS|LP`@ zUwdpxLm>#Q`qfU!voSH9pRu`ddzKc&!;jqF!MCl7pTsS(lP}@7iDb*+=OZS&t|vi? zc3Il@5z|kf_ue} z+($*?A{}>-C~#jtWlH&4GWXK+8>8;Sl=xAReWdb_ye%a0v>#t&`0jbzcC_r{&!SmE z1zCsx2eVQ8CK46$rm~iVN3q0@g1-LaN1E?SV(_Cqmif?B|KE3&8uacj<2w?mTOR!5 zHz`!rk3H4jA@GlT+Nwmp@e`AOd>e&BBMWi2k-PqJOBbsO!*RF#@rWD$&x3dn>&iiV zN&&Dee)PW|pL_YrSK{&>9{k7cO2!un2NB=+WBWh8v4||cmUvh9=l*$#>64G@i2GvS z_Rnj)o3wEu6QuwAm{z$d@k$Qo0bBlmFH&uyeB&Yu0e<3V|NBjLHs*;EOXH8lKW|`x zKV4?yE2;jmqIS8~lWjcXB(i_roT;MD##he%^D7;0G}Mhz>*0Ylk^S>pX1nUgcH&yN z|K)?DOrw4rj~MwK^8b17BqpRAH$7vrN?4%${ZG6-Uey1e{^tib5-F6h>~|ILZ~QlH z+9s0rBO6a9(JdL)0B#@AU!vtUX~6tk#tO$POj=_=1cH>{EgI+TB$?RW>9mc6L}A-s zrB;E3qzYd*Y!V7!lYpFeYHrTZ2TXetXm&srz*ef^;|u&A5a^oo@ABx4pcDWTDt`9X z9+EZVjRm8!o!I?5Au>LJUt_g6Ww7ME&QYm-%0t+VMi0|(g|>qfa`YrCr#D_{{5~R% z5HIb|8GOwzb@ zV?mp2ES?_*s;82V*li<8#9@JNX&`<#No058clm^_6C`e~T9gN4ShNtcey9@nNivXC zPNBZ>HRKy#Bl`EB7LcZ?u)NwuGBKVwQK!-=gRgq+x$#EE>Sb7Y^6C1xa zp0dGOb>my8Hoj%64&mjXdGY1v2Y49q)f7;yFZyZUj}6d``mQ;+V*- z|9N$RQEvk=^{+a`MTRV~4zf&xQ1qB#yh+ z$sfP`uHNyh{98+PYkPBfbB5ORm7wa3)wg(p`Wr{guRS7alvGp@ss>}|6x3H4I9G-> zGfZY9V4esmO-P!2joV~$Aja$Tu7e*>c*at`HObpKA)j{c(|FgP*-T~mKRlXc5=J=TPHY<{sJ&x%doA3z^o{y2d5gdkZEb5Ys*M)qSyJohKG_d~nZcEXE zxP_)VoX>9gEG{fS!xUij+QQRL?K}8mi~$0+4&wNU<~sg6`Zp_MUkQU3FLlK9V~#$f z!8)aukIw?7KM0?m7?-Ym;w@De7I3JP+9uOP;Qg$nZP+%F_=|X>uOB2Ib~|$cB?J_g z-YX@*Ljb?f-|esp446vX2A4}Q<3N_q_IxI zqXvzfl3!@su>TcW@Lw(f>~StTD`fl#{N}ym_*@{RV7hUCZv&a2PLxv@^}*16bRky3 z9Ov_9zkfR9*!^%bN&MQxY4}_vzD8G4q0$^g62Q;mm3tD|1O@W}v9SYZULBG3@^OL*9q$r$xY^Aw>^-` z@`I=w+J5j8g_QBcGg04U=fx@Zf(21|`Ee-F#M`Ld#T!V<$??&9g>N1mX)|3ObffJu zANp{J`RK8ep}%Lz8nTh{^gS)aZf>kVvlEuPa2x+C?IEo`Fdx|Vs3oWXQZ4DfdY8_N z_dCbOKw188Baz#UZ;iK?#~v=ty7bqM$!z3CHpEsI;Z6m@3SccaCkLo$m(Bgq6Oezx ztQ1fe3rljUr;(2|M-HT>`71^;S6K99Y7Nh0|!5x!N4 z-Y8};ta`5GCl-K{y+SvJSU+eNhVxZ|T+p?p!OTmkIEe!~`{sMv6l(UE(EYVP`$7O^ z_A+xq8Mg=nVD`e)Q+~R+9KkBCxp)=>n=(`MoD%XT$ZGZL#d< z29iz7qI^<<>g*SuM)kd6KYK4^6G^0#=*BI0pmB5g%9Wq*)b=LWD@4y?^am=O&z?O) z*!prR;T?rdcRi_675NE?jEA%zo&|bmM=^dl!p*@$AHhf>GV4wRSQSVR1=!U&0_~r) z5|I_x)?1Q#D7SQc`l817uM`~o@sk6lGTLy2i+{9ng(jVN`#vcctnKV}3-v1~nF-wf z`apzoP^kVXV>kbUCVWe@^=dGJOT<}(qd@bqpP!)*{AQ^bb~M<|aK|Qb4ZKZ%pi=TO zP*Tu2PociH>16?|;S|V^5=Td)sI|4VhQ;eEz7zlFYRZ|*4ShlmY5wW<_|I=7aWmOT z#Qb8alUb-#$0ib{8!KIyF_vDJ)z>J0EI}H_6Eg-D3C% z&x7tP2vu97Uy4uc-n-Y;=9I>nU_w<9lz9OEO%5rVJ9q7(5pYO`PQ|J#i ziYHuJE6R;Y$P)7G0p<~tt$H#nft)2ch2F{SUgw9o$3Ppxe$v$leF*5GZN+TZ-`8i4 z4m?OxP*FkgKUqOM#Q1oL?hotf*xP8s;taXK$k?OZK|}KT{>BxA`gUiH7c9#;?1b_a zPChoFt5`&}_G7Iyl$6EP((>|{dxpK~AKo!?!7D>J8!&pVR|$|5H;gd>qD4-vcj)}> zm*>rBT^D3Sxds7c0^tYfhL&QFbv8zR3v=H=P7ipGPYSx6rpOzUHWsT}D7;+;ky`qs zK#QpZj4|NA*upq=VlN*{n8<=xCkRXgCB#=2Z<}l5#ektyfmX+{XTN^`2FcHa6_05m z7M)b|$scY+dAON?Jh%!mM~GVD9fn?$0aPv{0~#Vg!t~^1qqdw3L))Yw130yzbHQa{ z59%vYS~>#2MVD7;DNKE(e|!MVOlVYM&ZTGI7*btxrj32Giejtv`L#_87oqoJwMv7X;Ep9B4FIZ6vSJ?v>Y+2v6|0EO?UupIfuCL|xU4(33rb%O> zaeb^A@M0j9Xcs`+Ffb@6HuI&-$>nj^b;zs9dvhE8xQTW)+Q+oRD25!4!#Ek!k9Phy zV50$&j@VCq&XATqLbTFp#%O~OLG(ij^$9E=$oRad=xt$t0VnEYolB7Pg9hf*xR<~G zJScopF>IRYMmU|(*n@s}GMMAg?gk+tL4~D69U`LW6Jd-BhtTTkDxnP>b!i7?5Y*I~ z(CE~^b*r$!#iYEZChqr4vd&kocR!&{=P$Hm1Zh=JpxJF-Dx% zo}Qk*zEv=9=<4py&(Fs)l{g1>OMhj^r5&OOln~xG1JCA-7+H-qu0A6<8Twzx3)OM= zNCMf|*wAJBbh|kfBNt#pBSmca^=l#8U+9eidb7}pT`pW-twDqXuO>}46>fV^F6+XT zfy!npiR^cxmW=<>W4(w;PHH{STG5U}y%VXoim!i1rJ0@Ra#CCD5+54Bye(I!J$DCj2|>J za-fFPwiU|2K;$nUdv?Bp5h~$vapy`FPM|Z@-`yQ;9{?@3x4Y1e7R*oG{SvCTEgWlW z6_5rc9A~ln(pzgtYX;C`O8AWl+DI@C@C-FuTEu%7gpFPCyg(04%uKw~?kKJ|dmB_? z;JOwtTGo?^Qka2xxvNwYm_CTRwKE8o2!#vSg34Epj@G%ZO*6O%I)@J2esSRp2Djn=ajvAq@9=ND2;bM6-3mpBqe6t73hI+bGoS1~1!^O%n%01DC&xBj zu}V-$1OfTS3?fBpT3VpgiI~CcoSe1EQihf11lOA~Cp#O@S|ULO^8EOTiBJ#DQiuI` z8v)G9Ong^(*oUSh?T)%1BD7fzdOSQm!H&F9=puOL%ty=u2i%m~rQ5=415UAKEcT48 zMa)Y=2oi5WQBe_nB^)1%qjevGx_Nb2me7_ToGahE=!ED_d+Acxy?6y|1mhIUg2RIX z;&ZGTsXZX9fK(eAZ4*CQgAi%JsR2>Z5BISRj$)fcM!GRX1T!321I2A-4hPD2{Zves zgEgfM~+E5)&846upP8JyuzIYAS_yF?ayr zh3qdGLB&%5PYx-bEa$~ktPpip^V&DXD44)=n-qjkuqz?*fQqP;`ZtWH$FFy&?~>Z@ z&EL>0KqNTei+K{3!bgO_@8~RCQ6le0p@V`29ki?fn}Re5MNA}N7=T?XZ{hWwcH>{k zQ86*ScpadjFRCrBLbZT{gM$!K+>md)fd+-~eWVRC5kmRM1#t|U3_7p`n&1%zY$9y8 z_(qqOmWbZzHm2kL93}nT*e&x&prNJ#d#`we2rDa&Do7OpwCBJDfBF>n_$WhxzE2w@ zJf@hyK(4%XWU~k*kqnZ=Cm>s!8}E=;9bJ&SgoZ9x3i278mZ1;`I=^ievl2&~Q%5^H zIUu95Rq z)oO@>A3Sj2M+6cW1*QWyxEq_Anha@Tlq7Zd;dBm35!^KzYbC!x%XN1o4lYF8H#h0p zY$604MLUb3Uh3rFFd6j*FfieJ3aJz^y1r=b&^`9|0!Zfi{TB zbAB*Gf3rw1P8Q@ssCR`P$86=dC$Iu1{f$kGW52#7e)%j(-aZoo4QWup^Olv9i|yh? zM;`j&IN5$!aH$ldHcFVqZLyWS#7s*v<38^CL)<3c*30IdqXae|Ef6J#jb+%^{zx2C zR?tnhHNCqu!(1gJDXEyCqM}v}c>$Kd*x=|oYh(tXlaE71SXdRM_}uW^@~r_WPq1xwIEZd{~+lXFtKa$vAtjstu;c)z9EBpFG)zmL*PN zBqc;lL6Y6wwEG+ta!IM~QO*(^@Hk$Ov4Kj91O+5&_Ul=e8>UfcgPo@Pi<*RMqc%`D zZbkPA^>fQKz!!hvHT6-Z04W1Y%d@?#Kc+1~Q-r=}Mlm$5;0`ZSA8-(+QG-!APYsXk zg>x&R{Mv0HiL9*X;$FfF2QS?CrUr~yVETg`b}IT=I7=z@HCPBD6BZ**6lm?$O9T1| zs_30bgi2CGmpI6#@no1VyTNQOvC9;1-K3VsX?sckYvZ)Nl;Op=2`qjc2Z(V`eXs^q zQoyEfw=d_Hi2W@L!PYC+Ff%LloATr^bD$I-mC#m4f*SJmk?Q%6!#EtoykT&toTc#c zhQ#T&$v1!~x))m}T)l~SfcaVBSkK_#rqB1caG&2yLV4+w29Zyr&-R3KGc*&yxjEOf z4&IC{vIE=8gp58jvyP9VMKcf{kUugW#@L^a5@H2;1F4^h_hd{gmS4L&$O2gE^HkGvFfjS>MoygQg+ORHmobGf%w__yWqw+RKy6SVKvvxZ-et;c zp+QixZc|J!hwY!rrA$C+2kMk^Q z2z|T4^oZ%1gu8e!8tD7?fAu^9sUAWAm?IZ?b~sKF95rYpmX(*kF)t#5mc$8Rd(X3~ z+AmWi9@QEoaT-Os*vrEO`|@Ky0BE-$D{7nt52nY#wG(_h1fytX>n6y4v|#hfwegv}6q5 z9nUXqYF-U*Ye20$luBsu!xJ2s*ql5_q@aWd z9l|;;!IK`e7taJM^Be=M)Wn7iv^SY}bZ8<(tFQyq1v?j9v5MzgYf=KSd1W;pFV<7r$~vX=f_VX1Y>E&t|+_#iVP` zgM;TW+Dm$One=W^VoZf1RXFH@Eq{`oXKbLdi&<&tp95)~ACZkn$re`02kK`ditSkPt-nJwG!zKqypD;ZWyFDf0Q|iJp4B-V&a>= zb{zQYuM{AlNQ?gVe5ti<)N@gFh13w{&H4c`L8lQL)QI*&JS|L>9%%N%@*qT0)(8$# zl8u%CrBIRL_c1Z@01pCJ3>GBjO@{ z!*TA1F6e0i*G|#pUdnp6LWH&z+6*B zWk!iczri~SQ42z>wCn|3Yl^o}`M5t>4NY%Gu}WB#6VPyIXyRm-wD;r3k>%gOv72E{ z0jWjxcK(&fJ^omdKmr^=`N&XSlsO&0wueDTW_h5$U#+tmgA*>W0z6>5jK_;OM3_1_ z4FXh$wiBw^h7rvQ>T6k+M~jycq09^n8bO;!@VI(48W`H2ar{Dc)T3<;pv@?EE-jpj z#REFc#@0(F1nKSfINjli%6#%agk;tY16+#Pi3cq)b9>$haD14*cdYtN}$t zX%`-&bPX5AtDsRz6?7{yT*F6hXlFEgl4_`{zt_z0(jweEpk9hx^8Wpc2)Oxqd04CB zhdm8nyTRvlLsIJRB#V7^c4@t|%PBnqQQ7Sh9*wj#_e87Tk)U^9e03Ma~599$r; zqmEki9Jc+)1wUJEvld&d@RifLDKGu&FYxmEFbHdP%aTlNR$V>6oun-&Bm@wAB{qQ4 z-4nvX5uB#!M}sRCZI=?GZ)%$iyL-~*U?M6PX2%0mbU3JAPnc%sp&L`V+-PlT!Oc%=@L)G^>X6YO`^Z}(VXi;H-~HU_QDn9$3{7Ldt4XW zjF)GJHr;#<1B=kma;sODj~O?_*J68* zjEqq05m_=kwk*q#w}I{LA*y3yGBh%BU4xNnL*7A}l?pHkkTa;bOylaGNyUImTtwwF z_xprY3}!WKG4%?;bR6idGf4GpI{(c%^S;IxdKznpY`>oKi|^`zoOB*T^_&;($iYU`Wg@18A98k zC640swD5ilx;58z8oWXrlMulKq-JYxPvvsDVWNWpcbc)O`;W)Oy`N_LU1`2jhy6L9 zmKm}0$FAQ+KhKqH?r2lpzZX`#;L>JCMv5e;AROf6@M)q{-#J$YDucdpd1W&Q2r#8IAP=` zuaiq^s)kvSdyuqpfj8{rvqLls+$vMCR>RQ!NR+fhJ>taL?TZPQNH?e)cSKNuJOpF@0bs-9hOb{IY@w0foZOuPEPOhH%|X1p*7p^AgcXt)()tde z)fr_B6Qam@xds#IR~Wr$;pC#vv%JnS`sv*jo86>d{MU1ApB%f|U~ANp&RqO~!07Rs zag*`ArIUatA#Oc3K5n6}AAlje@Ngl^KOzP57ez!!d{a&YL_~A|y227y8ioSu53LV3 za)Y!@0HJ(9;Kr&noUSAY@&5`*6&lpsR@RPBc?A}p3Hrbyl^Fkz7( z)B_4uho(V5z*{Qst$2*_X2=oaDO!+Z_s%a(L%>grhr6;w{$h@=Uwtq7R$eAJ_#ae!L1W^p(#OqBPT zW`DBIesyK$6oy6!{0D_6K>q}fbTn6ykpPQ?E4)imJkt|()^JXPay9LH2D-XM@@n={ zsMknLwxGa3p?k)jM|+q*MjJ1!&b1oVTk5LBOUHSagXZ6(nn zFR~}ekkis?N6wb;QgAk!3$VtQLHOmyzhc`3*CTO1?CqC47C?+3e$I32bB2|XKeXUx2)UKYsw!U}A4CjctTxS~ zzDJ^Z?N6`#`KC*VJe$QJRRJK?@F}1V8#q`~k1M$et3$dT7$>c%Q}vfGI+I<+P*~UT z0W9wpAtxb04Vj_9AvC*;8xtvCmqC{S^zMh&V=63^daUQq2VL!jTPg#CFr4Ipoa3Az z?ML)hsK~D>FYoeX$wguSKWikxe6|CY13!+s+~yogJVNCy?n?`W>moI)^PHTas58+~ z@~97dt%PUn)*^xyH|PO$*sd)p)gk9j0R|h=sdrPuDpyyRa0RN*bmT~6tbfmT@Kv&u zsYwQskzPybli^Vo1R)a{szycxlPN{JYy@b;5G6`~7~iQm2r-!#Q%AELLhcx|P>ZM7 zu=J7Cb0}65$=(qX$;%g2JlByY#*?%nOonk87u6hma(NskJgA3_-a3zdx^~pBo9S6H z3QI0^Rig`1Y$_F)gX?=kmmVz2arwz*6fReEc3cAw00KCO5M|%Kxo_4{x!_mrpX_4k zF`dzIjkZ20sK@k~C0+2VS27H}kRc%2IkZ$&m6bl$Gc3boyYUoApydQJ;&D7p5xp@a zjK5o2-Ym{2A%n#_1q`yAoV+$<%b)SD+jd6UBVP>Rv7kR}4eB?g__?!Zd13QX)gvC0 z1y`MzJQRv@YeKo-J&iglF$`dy!sm53CorDu$8S^ zY#C=OwF2z$Mm^3l;9kiutW|hsrD07>9@12mgQhPg$Zxy-r#ZdG22i}=7y@0u)K4rU zsAf+aTLB}*Gec28=KBpPo&+Nc8=HYo{_M|dD)fG8N=nw4!4!Hu3UKJa=TM-W(8hL; znT#(wEbD#wSPSO2;xzZ%K$R_4(DKQmhPvK5H}IZ`^A}#7^;XhP6;{_36!wWxq9vS^ z5}SyT#~<&o6A4dxfXju+NKefk&k1vL2UhR(%{(eFMB0zQ$Qj~OWZ&N2Zqh6IO?MKY z(^}c7h|6MP2*T(|d7KY`hau)PUEBeE5&y*Zv8)b~k?_SPCtIRd&Q(%`7}z*f(PQlh zb1@7Ap?eIcd8LH6;o+f}ZImCh3#cx+7_?VprqbDk(3Y*iv}j zyjA^7uxWN%xdLezB+DCZ_xt@!>_e$};LIyd125F_CBv$OMqZIUdd{lvL=Mu>ggk!^ znM+BluLLaS^{Pb|C#Z`BWQzuz6JPt{M8+Dm8>|y!2`o@GM;!;}BV_)v^73ll?nKY~ zOtZ#?sW->&-Lo<_eiE1w^F+gJ@EC%P%!kb&W3kuO?;kd0-8|v{=2Wk$K+kr!&~2A; zNE)c{L}Ns15GS~o-Ie?fk<(r59UU-qU7j=Z5dFe_@J zRHJ5cu$+-NB$~z84gW+gg9PBMk}cXBkq0hx-aMdMNo3s4Foizmvt)4VmMd^3^d^Mz z%T4Rv?y{4)IvjpI?69y)YexsJb99AESS}?L-58Xzw=v2}@C~Bwn@0T)C*lDE_1G-b zxl#)Y*Fhc7Zlc+LYr}NH&c4kou#V@xSFY{ zEUPRc^7-`p^>HRKAq^rQ1Z^)d4#X}KlFgG`nsQBMhm&ZV=pf# zuY`WR-XKR;x(b990Z+)P%Uvpl4T4$zfej*HZ%{|XCakk z-3=5wUFaY*e1zq!^QB8!Cm9(L{S1J_0Y>K{>>+_HAigCoy(0O18dNrsc`Lg4-eB!I z9bn)EMXwwS%HZ}Y=g5SU_RR$p+A2vOa5Oj{tOiP^z!wIk1gt>g*rX&2pfi_`DdOKu zX+*1;U=?^-G>Cy~h`tTFVkzpan0s^C0bL0x?w0gc^G2*E%oag~)9mKWvtTW1+W$({ z0T%*RnrZOa_BBs|v9e2&mK1jP4szPdaqocG;OB4|9YPoFLpMOF1~DEu#)X<<9$N~BF-2iQ_A#sys}Nf3N{is$z+=7xFB@!xAD>eZCEn(5ekL&k{9-!pqK%Or zOxx;E8V)A0IQb3d1uscXW2D~@x?97VM}^&9L%<^=BSzg7%GTgQ0Msh!BH{BsCR^SW zOqONZmw%GzYq~WF1D&bQI3i`4hUQOj9>uVtlp#cXbCD@ zTN*y7?L7G?6J#Gg$EhBukWDr_H^f3JZf1s-M2jCarL8umjlnH49#Fq?XTIDoxUO}< zJQ3ZWAC-0;SoP>&HI@j!KC4rNj;K+ne-hRXdj2r@eeOCA*+Qb2zYd*ZLB}cm2%&pM zyGcV6R_(b%LPHCd$8uM054rLoqwXA299O}7HA+&Vy729fgs`10`leWf?+(x6dk}XQ z6i=eFHW(78xh-d-z5!6O60M>W1`g6V@P)V@@seNI){CFC^Bg9Dd*1Un-l)p8a%P)% z!bwGR0k{fxL$#ta4r8ou26X-Yqg4Wc~*wv)a9FlaqAn2~??b|Y6znh@l?}bVkR?X$* zN=ygnN-yy7A!k~MaICx54PKTD0U;&Y2L(v=ZqR^Gx`czIgp(0909br1rljbK*Nar@ zreq;9P|o%JGz>wi2Bmyh5JAQsLBQ1XU5bQ;Y?<)d!ozV=qFq;Y>`4o&atPpZoK;u@ zpdEp`^{k4NI1<4z!#%SE^6~K{zP=P96RX04N(Ln-C`h>6ix=Gu5_uP_h$&8nc(rQN!# zk>0{Qmg#EzcSl=)yB6FY%VED77!rFjUsw$7a z{z`v;f0Ap~_^Q*%QmgZ`F-p0@NqZ^j`A;yKYfQ>&{2uI%D&k(=?QpBUjvVaZb(j8m zKl;}b!n36Dj}wu{8D96%LiNXJ zFkA{oplpm%V}f#NbF+pG!$JZ3wrvL57qI3KmDKE)qhCbE#Su-)S}L$qA(1&DsShO4 z*47rU62tXrX)ub;pMaB^63Qnly0&0FU0qx|sCH2rJ9DAcdFm9Qt>=@1H5}yoE+sTaODVQMk}OM$**Nj0#|Ma*ynzZ=p$28e-|%L*Ld_ZX|AUbc@#>DqV-U;>B(ui zn2;f45fi^4xm58CXK2KVa)v+*#Mrs~l!4pTUvK>$Kc)sz5Cz|t8nk~=X1gbEnF7ZP zC2ckwo*|7j?|KRu0vZTWgMhX6&~nA2i3qr>+f~{q&87V0SW{AjW#kYzF|jc*#v|i4 zcz@Q}*VFbMag)d(WxN<*5)I6>I8hdX=L-9+*aXFt* z0rROm=3}d=uAfV-B)9O-pX1;WJnSOG&RLLL_p#k5Bu*d z$L1?*XKD0;F!8e7Z{8+&@S{fS=fTBBR%W5Wdr50ScJI%RHK$s)rwSjVpODTp z>M*(XL(WEeI>5b$)c=OA@g(HK+rkWZ9^cuqyz7&0|IH?giQK}q1?eBv4@cYhj80lz zYD8Fy5BP#)xxs1ID`D60rCVV5=(T29(Usyv1-fb+&`@#+sVmkKQ%vYT@o0{pfEID; z?m2XR1T6!U2>h0RNbbp?z()LU_;hIikTB3ZQnnYNp;DjV9+QlNV3+i*-87s%#1XlJ z=rwcf2ZE&&%_Sh@9Viwbxv;_cFlaB+ltgm|;oETS*iu%Do56oHVy zg3OR;o?$Zi$q_u76;2NVQwCtPXISCSaP}hJIS95 ztO9vqw7Mb3qAB3VF$Y&q@WUeb8cou67l(1(9e%}s z=Oa=Y^itL(X$~D4?(Doc$%~jy`_*07`+$0bbqG6-Vbojv{qxz1#DB<1RuoFZzt*S$S3rzmrR43=4mk?=J3t z3%ZQIxreat0MCM><~{2by@*UfCc`-PpW~zRd3Oh+#`nzKarI<)I7>OFY}C)g-=J%6 zU=>us(?0FQbM$2R+FK@>v9wpUE)2L2pOk@)BDMUxjAkgK zgE_4U!9m7bK_NT9NT!EK4ha8G#0#Jcpgkf$NwC$?Qc?Adj;_)U|K2=6zcDxRb8=?p zdY%JE%n5s3V?t}A%F5g5RWy9^u+Vyet)%$N2u=Zry>z9})~)yV zI@Ftfy$|GiXy3%qpMhXwKd;=GVE8D7FL?vl^w*Uq!2g@NShdjc20jbIbOKuesxnaE z*@6>(ppaw^0HI)Rp!Rr-5@rK>hlWgmiCt4dRSoCV(~*+5DFWp ze1lEIwLS6gF>_%g(($jDZ@m!tf@U%XXIL4uXT#d5zjior2B>_MrUC$P+2eg1GNhHFLK1?HgsO4_G)In$Eq&=OHG(o&%`g^ROF5=@yV#2oy==PD$zdcHZ!dN8nnP=} zAr*+LJ;2or53t0gecyr4YeYvwBCs(L+rT$BHwTv2n-m}5t2Oe|DEsA_O`zx#sTJe= zR|#hRCcGgELx`<;UE8sBt3r)A@cT8zb*yvb9o@W6^yWG`f6>r1=h&IDbew}=7g)w; zORxv_Q&22Sw&298hZd((?u!@oh%rnw_giK_xnhPPBhoSqvGVhy&DvaCEQaoA=Hl;f2+~g$GuR}FM+tE&f5~Ae2;77Y@reO48dhW=q>Cw%HGd`@( zb1$W4PYfrmh?AfD#MQKac>ZvM|8|$EvT8+^)6_OUzkiRH%kNLQP{9|}5U83Y;2EEl zm6a;(6&v4iJV9@8q2?4h!}?za7eXW}gI&_zj7Pc{s5Ol)FSzF(9J|&0i_?zP=+^t; zpSa$-{lS6FOZJV1Ua5!kol+&ePpa_i_PkY$sAfOpCCJ9ieS%pm>&YgD0-jsVc}|(L zfK$9P*@A9sYS~}67Sl4n2z-cDO+O}>QrWaNGsdv_KHqserkB+B*p<5JK9gar#W+Z% zqPjY^Ul47G8HIi{q5>Qb?%Vgdzd6IaEp#X-Z@QX4pqmN~*zD*tmXwzI)0``TZBlb{ z$T3-pC-71Vq2G*S{h4(gN=Lbbj{nfRKh=}yvIKgS=SVU>2T}}{)}!)vn9c3jzI`f} zrPUmSaAr?GzLcfqW%$pfn>2c*)?#G!^4BlD{r&G$5<%@Kf2^Hlse>U1BXXn|?C(dQ zCyt(>Q7KYwkUmUq-_AqI>7?a=m5sra$Mjc0BXWjSnQaM#n+Jo+PYol18bF5Q3i4B1 zYb%R$7Ch`E{HxHAqdR;!VV&K#_F_~G(g8)YVKjDR!v#X71_oVwz_|(#BP<~?Dxu6w z4aYq+G;7z4ezI&Lp+_^5gv9lW6&?2%q}jkt2V(qssr4{{4LCL`1QgeRJP?IW>M+!x zvj?n;5bebtMWqQ%vLW*{SmT~xH`x4nLMQMT+)5j96QY1jXBK@=WfJVnJsWR@ZFpYD0>1qx|8* zl8#!oN*}a8gsT_M=N7C-M9tk2lLLWPg11d^ZI&^JBG-%VuN4$aDe<1z4BFM$ zK_o^!HebQly5jG6^@FC^WEMyln4ZD(P<>k>G>9W3|6mz5Yzur~;FAJ+XZ<%cD%}V5 zZ1)3+iK2cH9!|6)VeUEDOj#WLKOFd(cxH^2Z`MJ)R(;nLJ7?*gIo#DHIvhvkarszt zmR0n`x|qDY|IbS)AJE1Mg|-2~>{n*|$eJo}(@ivr7Xwz54?id;M!tT1xUCD2AzD@9 z_a$^ZJ5qOR*x0nZL)X-b4qV|&{!0jq74yeG`pBG&K3cm_T__dvTrL(M-$eC0rG$8K zGccxS=@%gWIavMiD%aP#y3``Y5fYJ|lv-FkYY-?J1nsfGv>Sx#1Dc#?&qlU$An=1c zI@(bvtmiX+sAyf{2xwx+Ut^7jQZ;8eS6(dQ?0*-NsQCQw`pp%LMFELEwQV8Z`v<;i z$8PE$7+_!Hd4hG*B|R5EdTMp*>fW8Kvv?mJ&y4i*GV zEjT{E@#siR)3?@!FN5q`?wOo>ytU9rx}MZN?6hhii*)=-$K%Q49vl~cY}fV=ME<9+ z)r2TIZUk@`8W=zp(F(nJfExsAJ*x4S!FwAz@iHp}t)gX3Ny%Nk!H6x>4+VZTH)Bv_ z83hz%NRj04vwviVMrlJbMj*WC_s|PurFNg?;OOM_d*g|Y1?T{H>;Z>fMnnih{>??k zMpS-;Dbv8z6g-G}@NBg(+<@u0yTBkZVCO5liVkrtd2MN_ryn7V<&A*I~8>9-8 zT?K3x-$=iSM0R6>Xk}ZV{z>Oqt|-E_d$U@K68JJm8LC<4J9g}VtSadX#h&j?O==6N%N@Fqkb@N2L|x!?|$+T(YLzPVg2$Z#iEv;fiV~3es!v2qWLU+h|k4 zUO801Xe7N13bIFui917svvvjThfIr(c07^_g9e3g6#!At18p4cRFu9^1-ca)Q;8}p zi^_1kOQ7}3&UW725943g&+se`TZWi~93(mN_B`F(JI8n4zxVR*rK0@) z@m223+T)9qAG^!C(+>rg*Lmi5j8+MMm5{zyr1DDhHN8fZOm~~BsqihIl3cQhp{zH&HMyWnma_q)kL`K=1@l@8$PhB4jEbVazrY`s`UPO7!^FYan_x<{_U% z9gLBGy2N z)Fl)9@R6sdD@^P$dhOK73HhD45OniQ^jgaGIfu@h-ns=|1hg>0cms)ES8WXQcp4cd zsu(~L>q1ZOZ51b_ODl5RbTy2T6ltXtX&)|H;|8-Gz`99iHhw7v0w;uXwC>Lh$1$8m zwgQ35qCJ<aJh-t*80+lM+s+#rXCx+=ZrtB0?_?!ytM*hev z7K#Z}lz#+Hd@TG^Qrnwd(_TNPNq771KE!QBQ6R6#xc(vU_xqMu?fV5^rWq9Gzm8`b zH7S{G15~Z~Ir?sJ;W|k)RVvKGt*lVG=VDCHz!xEyoR0TtHH@dX7LOR#gy)+yvIuQr zLz|8weKFPafZ}th7?U!qfR`r&r4n8h;q+%Rywmk<7mMpf@CxENL>6^HYb&x3jTpp; z2Xi>L{`Y;)B)(Y$AG;b*cIKG`8i+MnofI0g|S!VbAQ~|XPiq_?=cWiA{m<}{(|EjN__7G!%7!TXX z*qB_ch+nsn0I85ldH1^=O7#!u*D^5ujRexldwG z`H>>Jl4T8$4j8D)_@i)lvb)l4pr)}9y$rJ;!c5$=2c5?rZ>1N+QNSGh^y!foWh<+z zJND2m0M(l!+bNzKeYS%vIANdfoXBBgkL8fSK(Xj%3QW3e zk(r^}&8M=>vK*FM4p?rYto#tx)LO?`%h}Y>P-mVQBCVE`{qrDqFjajz>pUk<9!0F0 znB}Iw0>r2cZmJvhuFx-y-5JY1XJll!B`@4{hPoQ)Qa`JGbzaT#v||TNlr>)3U=^>tmfKG)#|^Q7dM*f-YoEj30h{Nq9Gdut5_ z+rEE)ois6LL}`7BGj*(c{awOR#F^3dwbgI^C9=-u*E?rLy(w3OIx~f%oQg_2=FORX zoVM>A&d4#54NO+pF0d~yms$_?=OTQ86BH;IRNio%0bAClPX^eMRV%1_OiNUtf08j< z_l%6(KA&(}R^T8V-AG?w2{8RP7_t3{61+gxz@QhNwC*X%02UN=TQH90UL1f?5eV)` zBEq9I%)=LA@-_lwjPEv*xA@( z4t3#q4U<%PR*pCmhQ_R18hg8+jRneFO232oLICVEJ@3nohr0RxFj*iv6t z_y2MC9qwHI@7tzx6u22zwi6?x?b0HUgvpUl_NEqzeLEI-Fny~aq-#^WGqSuZP(jjMFgIw>kZ+Rv>vxQKMgeUVjdI zLFA>0tlm>IoRv5|oOahqU%hxc)r5{WGpI>|}iC7nB?D157r3P$9{ zz3XM@c3i7^qB7BW=-{D!M_ZS)qH6cw#|*f8%g^}w&d7NM_e)smv6=XHMO7Id?yA0X zZgN?NOU2ljwVNRO7s@2~##%V1jH@Cxp8$!>E z%*-z~Yaz%3t|^>|JU27^tA>AOw{K|u=q!q==;0oD=B79FH?X>{9Y*GZtl2s+MJT%A z2(Rf+a6qFBttZYsYr4&GQ~f2HT0dk1B&blNst1E;Sww~zp}#t>^=)G;39ZTh724h@ z3T7QyQPZ%c{Dtylp{+fm@{=jsWo6btx(0YJ!?uR)fFgSJw~14P4Y+lS_D*LB4@{C; zVW?^meNhCmDt``J^s!lS25Ug%_$QRFjeNI-Pwn@h=6s?dm)3@UbM5Lla8+ONNO0#m zvd+fqpk(GAu(;_#(9~Cp1p>~o=fh_<6!*>~d)XxHlf>~Eju5xF>FM=mjRHmqjLY(;bPT+E!7{KFH+<9^v_c9i)_Im`_YEl`s( z%#r?{GtPLd?!cEXI1|igTe5#@I}4S7fljS?I~b_KW5FKT2TF4e7wpY`ATYDu@-a_y zRyy+_PRttnFxePlB(HI)bn|&|mw?>C2Lo`S7E?5;FCd8+*bvzDII;fn!U~rFg;>vL zJYmpdA@k|)Z-ipP@l)ozckeI(!$aicJ9{nk1u;PzeN&X>jj*r}wtStu(uEUgeRaYq zI&lYNIOOF1WjfM=tK9KMsJ2p*Rv57NbI~nACkukyh<`34CZkfYAB*RUjif$AHb{@3 zL>#1h_~&&{&@HrheZ=YMs{yk+fx&0_^lDBa>N7g3+P$E_gRsZS&K}*qMQbB2{`_VO zB#;oPTUHbmMMAwK9%+u<=o6UwoB2M_ZHnptN9o z?71!40jZtC;kAr%Ad47qebx66O?{LG47G_}&3$>z%@NvZhzgWCioBi>trN|CUK5{y zOJG*%CH~WY)ct%l47bBbpf-`_qTu3%ti$8t}P0z zP|Gfz9vd?#W-WI{m}SVPweH$t!@Xy7x$Pic=z; zV;fxyyGAAlfAVVj$?h!M>;?lB($>zh6np#PUg`C+?Ts{DH3eRd)o~sebNPbpu13)M z#nk|tfs7qOVmYS^_>xL^erB|NWzCq%NL*W=X)YVnnQxnus@v!D#AdjVzGoWBqePyr z7}G!wMw#LFsjV!v$5wKa&@+01QCNp1p)T3Hu!RRdFlIIJiTw8q@CE_c|nm(DK%Y`gODHf1Z!2 z?RMtHn#xR%6JY$|bred+;DSxOPHQVTr-o+H8ZoHOvH#7JZ@#Ob!65m9_)^4Fmczpp zK-doOB@-Vo(P!{zC#I`uI87AQ)Ofua97-szuJ)W>aG_)tQ&9;pb>K`xa>cF5={zoV zNE-(`dPLlZi*}Rv2|w6NCb_fIr6D0^J4lWzn_}iKuI8YBF|Q#c&$WK6p7w zFtD(**Hly-cv&RxQ7pcFte-?%#iBZtoktj)O0YfVk>#f!P|{WE4@?`bmMM zJUf{Xb=|xf)-a5b5J(LTtNoYfPs4W#_`hY#+js8>=O9oa)YT;gpR#^qq?j-@HC@=X z#ld5>djhHOu%f~le-z&>Ij0ZTi^MB7ENYvWObiStm<$GrMBo6CiEY~Ee1(+?W%R8O zelkM~b|92MJa8@FzBx1ePEbNg2Qig`g0DO?CQB2yEmbRdTY_d{izWuPeEL)lYD;%_ zx40t-cgCoUMSIsy`(mzQjpuI-r=;W*6;#xf^nJu5=cqQN8A&Q2X=C1j$Ci6*kv}~9 zSAlS~ybas(kKea4uD$0g5PlM}+uGVH-Jt2_Hs|p4>|&8q)~2Zk_390onN8Gkv}zCQ z%yHR}H$7Zx*sIrGZPu|8WAeKzouwz>JGtQEv(ULS?0oZWZ}|>YX|AQNmPH@U=dID6 z8;*%|Pm*3TF~-|xJP*Dryq{*iUBu|PpkE>OQjxN3n)xg78C~ytD0P5%ac5B{V*DIJI4XAx zqk}rfW#@q*QK7t5Ls)vXsjYFJQ&v->)i!SWq`+OrwZXTexrbkNm?}EB{>gjCx??!g zmDU8qyCGV9d&~3RUP}EH+~3`4xII^ORq=XX-~4)-VUt~oa>(pmOZe$M(%b5+vx$US zQy`RKn&)NCJ+M3R5mt78mH)9$7(r1(D2e$Qcaj!BbO3MYj|w^eI_1Bn)#A*4u+JfPHs`_OPO+|!A-uG@WVMW>j8IF=qln2O7Ub&gn;v3V9hJ$+7MoU%e0bO1KKSIx2|q zrcf}~0CENm8Vz?B6sX2mg9{fU&t2{;P}-jVkZ)EWV|3;}$!!Awp;s&=X+C4QzT)lS zYHP!wxUAJ4eEpi{yLbI``)}7#;Zq(btW8YyU-W|OQSS(lrUX(8gKAIY+RT2Mva)YN zL!I<*R(AHT$~Uc{(}tSXJgot>TnfGZ=unzs-;u6slV0~k{8wKp4^++3+Bf#*zvTtwYX>s#<=RA!CZ zhPNxUMpHMH^_SB~Bh!n9tjtVPS{ukDiIca) z>OC2Myy9|`k|t*{1|1=%gt%5BO>>bsNeD$EXGJ5>MT9sC-Me+~U8SNUTGgPHuQaMe zH6-(K9CjISm5ekAK)wb71miBR+TAvPR8PFdEU)Hvx`?{BZ{8GAqd$TSv(F#KYYi_k zl?Np)(MjZ-15SrVrm8V~j)0&I2o|!7bPyItlbQMzM+1= z=5c*3Oiu2Fd<5Ns5J4wm5VL#IqeqXx#jbk~^Gf1tvW2jY4a@<`P1_APf z+*}7jenP>cX6b|tG+g(y(&LJN+D<;6vHbiBLt zaDoAQK%3IX%S#$!Xtgs1N`&*A;ir7C0C)LAbtjwL1?ybHGGr4lhb)RBF65EbBJM9R zRc8MRObKD6l|ttth|H6ngxdmC@6;_QMw7wYhE;}lnNMIKI#v4Oo-on_lXRuD0Y-XS zbqYu_o;}-9+zQz&cK2P?2dL8?Z`od-*#fCz3s#}>tQFEca2B~~JT3+ka*S~Cec&dQ zy`cxniNqPenR^l@ztHkOcqL%Iwz3G1JyQ1jF!(y--yJKsBLC1miGV;#T7R^)!8m8y zX%8*$B(D7a_)|K3j4)2ZF%KKQ0C!HrE)^^acr>Qr!U0RX`UhY3a22~Wv_72tx?OKdfOsUIg|<0AKH7~26nDLR4#c+-0bBz( z(V${ZdoWW6A>S!LygOdj%|(#~|oB(-s7w4zrf!AA+P9Sq3mvU}Nm7;bIY zR)hvf5S!bu-|)eM%(kPjS~XTz??k_fiOq9;0jmSF*CA;Skr^DIPq%$U_D8S)))!!4 zFb^^j(dWORVLL#H0m$ivn8An}nTkZDpgk0vj_E|arON>O!skw8-;5RTJ0c;8dj~~; zdH=Jow_la%c>GabMf=p9Fd0IZ22X>`jyh2`rZVd3HiJfDH|oV>+7s+OInN^kq8`JP znmM%OK*okOhf$OG+aeeu0maLkYr-x-n>_UOYc1r|9Mr(qpvrck`xToHY10g%NdN>g z;LSkp=I^fratmv-jlL`35((@H%y5R$kFj;=+QRbksAV<=G@>ewlr1B`I~1apJXceO zzplnKjX=DF9f>pnpo&ZW9B-vlTh67=lmC{wdbt}l%H?qlS*yYdUML(RheptPf^G+Ut^`>_BNTLOBZ%Nj2)(`48)`&Q~6?yjV=VH5!2d zF>T1sEb+1gL{6ajs;eLAEI>-B!mVX_CD*LaO)=KDOb7cC8+mEG8#mR5&!1n7U&I1f@UzR)h*zY$Wao4A_~G5#l9XA;`d8<(G!ik% z8y^E(Gc^Lp6eJJOae8@?rvX7?@E!&^fjcNg>=b}BSRc=K**y~3g0wYEB?lr4GJ(i< zm=sq7UtmNd+|+GdQtE^|z1xNV@?kejqn$8ISuqcv%^B^@oWAf8_d!{9cZ}CjmW1B3=%^0kRDh3CmkZz)Juq4D?02kvA1u{kt@EbamT0(-7SN ziQ>ctSrdl?j?r{5KMN1pAJRt42ec8$B+>rCPJfQ%b$;H<-JLtA#l0^RooLW~!@|Nq zY~9+OhI0TeJ1`xHo7RLkQ~eEgxF$lk25^O*l~n>9PRzy{JE0o|p60P*@KZT+D}4-o zxE?`xT@+wa0~Ri_^SVMj5x|81Y~32uWTZ8pzchl{J`u^?85=mx#GqA5T;7GBNQ4k5 z&=^E`pw@=0PL|mhy9aG!yyr&<&f^6^g+Ky$!fgJlnVPwIGDe?5tJSNHCLsoXP>qv$ z_7Uf>cNuihp>N;v-v06k%{*{^ZW_4Pro-fTb@CfIA%lsHy$klPL5nQ_q#q+ABTy$V z3Icc?`T6rR7N^_944A2~uPK-;+=azv0n0bm??XcW;Q~M#gZIT1Iy`)c{~B=x7^oh$ zw_gTP`(`R}TJySX3zON%Ptpil&4nEZX@XXQlM0&axn`T@2_`lAphQ0(ovdh?>_3~w zq4tSF3XLN5b8i6t3O&y!lI&>+xBRUmP=>HB|kx{5qXTG zC0Z;VH^jw5>_(VUT>XYPrvWK~;p<`oAOf5+xve_k1pu21NsF+m9R>sRD}StDEU~n} z;;HqZ)A*ds%*=3j3R#!iL{*Go(EB@Sc|MbA8>8G@UnmhAvVtycVdX2#w_rzC;*f&a zjyZ$q^oq5{;+tnQa(O{E%*=dS;Aa9V|tp{IJ&Dq2vp)V}a8;RQyfqsT}n5MHLk{cs+Io za2wWxS??ICUaB++M}k4jLS=Ed`xjM30?n~J2S0Jo^_fna?jsk>PsJaH6Wc@$HW@~2 zNG2{`S10Tt+<+yG7@^b(c{ryM z_&_SUArI?-Aa!Oy26vU6n?};XVFiqqs`Q7oVOKzGKIr&TBtiw+?GiJfB1ocmMy~>X zJ)Bu{!4sC+ciYo{iY9h6_5v3&t2ZV z?OWcbe1UBU14PgKeUgBH0O32~%&`AF4^b!t_2D+b-32x$8X5v{NXouMq_6{PFi@^R z)d~}s%5C+e{utQnS!jxs>YZwQSN_8s)%d}QQVe*!!$DoCcw^BF9IgSAmQOH-4_5k5b= zOyrjc6R0*I-1g(7+P~j?pq#RpI`|9Om>>xW_ld$^3ZN|Gtf5GHe;ZTj+YOlAuwl`~ zuk(l~&W@rL za8OQc!6CP{sUECJ#*%oA;o;$xUPL00!2r)q&z2kP@5d@PO8WtUXo%man1O7DJCHr`L6pg!b;m+7`o5Q#>+t&{gi*XIP7*kpv zP^x~M24awh#vn2@>{o*pydCV&VXK71{pL?%zY#{Q4<^ID-Uf^lj0DzEMbmj68qv+B4^KMH4ZA?fLsI2CQhP4^)Ez(yyeF8JR>+6w;Q zV*mqf;9i=w@0?*s2qHDMgSI=;e@R|0SH~A{VIU+{aC-|qIH8dboh>jo5L>G|J0GIL zXk=z$GDHm{%|GQ55zz+V1k zlYlFN!5iUt#T(B}$PB-E880E`8z$C^u1&13d2#ANthmnY2zEanh0GT-Tp8XK*^Se3 zdpChEapr9QO{_dBk%-q(U>_1j84xu5`Fxg{*$5BIXOBogC!tv2tww=1wEuF0@1L9=dk=h2c4fVUHC7?=1B%GPx|!QcbKt}wu-`cK2Ai*8Y0Ku#<5u6wCcHr@g<&#MT)RiB z#fMF9zEA^c9wB4sdOIv&GC{}9w(=1>g_{$(?=ZAS;T0DPej`lM4%r{82 z-9uYjnw$N4Tpdisg^bL;M!(MD@YT`FePk99eL+(IW4HRQeeDA{rIwVFuN9LMund~%K z_#n%4i4hs!8Th{4x_==$tqqaGT=h3FHGh%_qhceVO>t^t3>>|WQhXr>+MXdQL5R` z$L}FACd_Qr)GEnU>qck67WKJaA}R!BiNQ-ada#Zupo1+)GV*u{MVp7KYJ3!lB#uuf zvr~Gm3}7XPz`aRP5n=0=oq(#G9AQT$Tb%}s6Up`EFYjvO-GmAr(FuNgYPW{{?{hsD;QTlV^GDJ3> zHldO!^h3;|I^W0Zd4D%J8tNvS&O9pKwa)-!&Z_6m&<e{{dr zRZbY<(8gQZ)y5ZA_rR4986L;o;qmcm@^y;d2$O=*=chyVM!oF1tLDC!jv+|k;S$Cj znDpFoc%!PNbzIvRI}(D6Xp%!@{e+JlMlFNZRK7l9Aa*!Od2Dpl9+3~o)HE2xL5nxw*U-t2e zA9jEKJe>DnkN$X{#W)wu60xN6$}LgDHCvMzs7M(@GkumPY?`_pTxsv={$ zfkNrjHFTeUI#&jWq|!~Zbimw>AC8_k?%@p5O7CVA62ERi>iYh}2bc8VnwO_&Jlqln zVYR2%_Jk1StTs$OlxjZ;ULnEMG`Hg|QL=9swrmUld!fJW$^qvCFu4jliYijig1@CA z?$ePP;|rZ$*_oNO1{BAWl+`9y2UbU$cUp~iEP4s+O%xE&A)$T5>ZVhc$bYFf8F22d zA0*pXf4~fwf4;*4d2`x=+xiv3RxJFkNzsA%iH$f)(KJ0Z6;6BcI5Y2MGnRv6{8r-l;)9eMbmLHa)24^g9$4IJXe~$y-_YRWyI)? z{TjV7Hw0{CN=?wGUU9M11AJldN*JZL>kI+0Pfp;djCl-$rpc?RTTrR0n4jh zhstEl%|u)A_lrTl@Mj@#zf4N%$>iXw`AyRQWbDiDS$@|&2a-L?>@{`I zzM*i!$De7fRR7qtCTXos;|w1G(4xQHhf1Yobny~!6jAbZSLy1*&zd8ejDT<~l713S zY-tIyX*Sif_%$2Z%tGE z4e`Xa=aU$C80s*+vuF(MW2DIFgV;kY3Q;YF4L!upp>U5VF)94%UyI^(q0R>)4GL{g zt_Wz@MY?lg*9+Y}yk1_XNed!VQ+?i4xa_=xVCC~f^lYLTEj-9R6Db@gjK<%h>r71z z^F~NW5H!*dz%7SrAK#}2BEx8lID8+-2ZXzVj%w6JeRX^KM~#)=s|Y|wZkm1T4mS-P z^8l)!cQBS=L`t517cGCVO48LMWdp8}Gm%3j2&>7u{iGkWfJjFIYR`PUoSU5dCOr?K zy6||OUzU|a_)7PYmff{Ojq6Tyz+&~PL0B0ZHUk_3v`U_NKwtkZZ#IDCI6zAryH4xs z=+yqx&OJTA330BTFE^AkLp#swauc;obOVM`*mpG{oFNlLM0)n#3hU;c*kR|dmoJzh z2`4C`?_AN>xW4ckn4of&xh^~mFq>F2>q*FD!!g~n^AiQvEC4{ts>U}PKVzIg3KgCy zjXLif4cVnbq?mMRKgTNg!n=<*yY?oBXXtR;`}c)$fx@7|Q@T#HXC#8!q#us%`n`rI zkI(e;!59DV;8#JEV)7o^76Hluotq28#RP(FWRc`XN+x_^cI`dB`Z>M87eKzCyy^66vkpy1zTdO-LC0R{P8m ziPK1op88zqW%48Sd9Ni-^_BF7M=DwsC{%r)SXv%QjE#-hOatHmn8wP8b%j=|GvY55iBZ3>XKi(YWGrC>?=o^uup2e<;&VFV;&L`utJVE9ZW->;buO>xGIj$#o}gk{d<0Z`WM*+tR`gd}2 zqIn|DWTJPVb&BuRdf1`YVvP}^;tf4yk))_M}WRbCL1JesD zz2j~>I73^9QD_+Sb^?Nbadr-4ZhGBu?m7sCwtd!2>9`1<I-TChX={-W25>_TA)nm39nkXrg9k;I`ynzR#bQ?i-8WH6hsmjq#>A7 zOsPPZjMHiHDUW*+AOy_tgH{qp7C?j0^)cAWeJs6-fH%B|2`y5Xvjrm?44aRad`pTp zkx|Tpe!19AL20fzgyDqGn3?YfBmtCynU7eMg{Cz!U)PvuEX^8|su*1#GKWUz9}D9u`c~%)=?olm=_Wrf=V_p4v}nKu_ob zr#LUD!uFfTr~&scM*iZR?>kf%u^bIauH>~#)m3vivG*8VTLoykvuUm2G!UR32B z^Jj0oOGT~g4l2hLNT<$hHsIPA-LpUkNEU7^1e4EoMSBsk3hl`mL25?k4>uVr3$M;y4*gKp$X^w!m$wFf;37$e<(4yFZ!~7hvOh&H`n4B zX0KbUjJ7MgdiHnelbygc2#Cz&+xmNIE}c>!hXy9x9|-jfanhwT!R)FC2lvABq!?3C z*t|G8t|1^S=wZeHkbZ!Z7qwXh1VUulXj+|c%sD!^sUm=Hr*k+qmI&84jGzFeV^|tJ zpNjfeJlOcSIP|nnuMUrmNwjz(U+8hB^A#t?wW0GGAu8sV`gDt;$@5z{b~mIib_#fQcUbErt`J=9Yu?iS!i$I2kGbr8Od$gSHm{% zK{FtN@hBKNAG-nuU39qGu&%2Z2GDDRlyL}I(2Y^_R0LQ590*M&Fcv#bFy7E_&i{E8 zPi=s=(k*RiaS^d&@~K;P=c|X+Cib{%uA1Qu!yqs*^^0cwgVhSO_SfN#*c00?pQJas z9eMtd$m28Td1E)xoMc&1SsLv{@d zwMe2z3J&Q8^{r0*!M%I&8i`;sVN>8OP$!~b#xoA#HG6LwOg6mU*V2(7T6NF<^w=T$ zU;6srC0^Q)(1c1$!(a4az0)_%))|0lFcSus6-lZj+=@SbB(!}0X&jbw9nJ&Xbo#XD zsr^X6(DZA#8V8bIb|7G<>};Gs3j>x~Kv6$^{0L`Y^cUI?<<^gRXzFit3&Ue~3X051 z1JIRIRR!Jwjfhhn>wif-K^%H(H9>u7R09<3<9p+L%4~^4MIn{^} z{X-R%>pb#>PXoQILzNU2(W(oOa2x&|_WVlgoG1z^-`KChInGbAMZ1c5an z16wvC?l%rRV1NW`d{Z;n*Tf{?PdAS1Z71>Ax}k`=4fA4yB)Cp|(h{|h{}(EndI5Zf z<DvZZpF+A14|8$fRvP;mPYwp7{LO?uf98x^uZs1*A5YNW7ao`q7KNk zNZ8Wa+<%~GfNNJD4j;1*BqV_$=rU?0H3}x6pMrbCaZ3{Gdmfwf!PFhC$4Uf^E9-aI z^{*YuBp&|CtO>EPX9FZM1GWX`X9F{eiV``s9~_o-+XnOXLs&DA?jeGf=@>C=Psvhu z((Ls9&N)8t?9d540Xc!oeTAIk>r!k7IO~3_jRtjv_G^Yxcx@T8+ti}-4VTc7_nl1#IU&|rAo^HwM#if3fl z=l+|gGOSd~pro*FBQcP8Rfngd_!Tr~PCtMDr{6Yt90@MA6u;`-Z#+>*9b2!|J1L|s z8qFD8kB8^F5pZK`VVP1)O-a7hpmB&hN{%M*l=Nx#;;uLa%f_Hu zWmf<*#jSXNX1rlZ5e;vp3=Q6_1g{>_z81KdR>NRy;|0*M-;lZ8rUakmkaoA@GTWZ* z+}4&f4NPQ`vd`MRZA7jr_5b|8TnU0b$mAeOLYLC_>~dcka#Z{c--8OjhvU3Lyw6&Q zl!k(xWC+b`K7;SmjTaQ`JfgjoSm={6)HjZTSWCCrG#sX`6}LhUU?vx%Q8Tz5anU44lwcd;n0Z+3uk9amT5- zJIkY#7sN81MVO_7E%Hv3Xc%{QlAm1KL=t!K?^~klj``oP_qkx9hYH+t7xx(iA@l=u z+;ITc)Ya`1O*Hg=uDkkVJ4dn90NpR@mJXZk+~;Zgqz1Z~LK@f~Jd$AjHnoN1v+Bl0 zQ36s>MAs8Z6qi=vKePu8)G)Np6#Wtus?~w#c0EnFFmzxcwZP(M{Ey@VSx*C(^B)xt z3Xg~1O4D7de*AEAXz^FPn%>5%SrI-K04U7Or!h6#)F3QL8BX-*8hUt;G3XmBx@8<@ zy7S(>-r^T&!^R8sscET-3}4uHfXswv|5GxOFXbDP&YB5gJQ%Hd8;;D+I<7>3xAKIb zhj6CDa)IL2Jw;Wf)sj@Y66zalyq={;xJmJfvb)B2dmU+Tq$MrgOrk8fuSAP$kHJM~ za)R3~nksJLc0`3PnoqtK(_Q2M{XND7PCG{l!Fl9gHB;^5LtJ~DREc4MX15jhzzzFh&G&Jp3w8>7`P%S{7+ z&qe174+X=5Py!y|xJ|N$UD+2at>)c@87vkQ==f-kYm2{veouX!o%es@eYhr}k9yuE z@0N>nhGO+5DoK(xaodr1a*HJKVnKgBDwr)tn|=t}!Rv%bOfHH>*&rd_(v0 zEd|~uHn+*JxUpUnl=?Y}SAw@Z%{cr#DG4~;jza6&4?p#{T=vHJ9y&HiW8S}i!bx}n zf!U6hBK#`jK=&YZ-Q1_&Q=RJKZ%w0CK4J%8j{G? z&JtYbTNjp52rmjE@e0BgPL-ChDR>Z|>=sN;QagkgE=lTmo`l;L?jd+2p%8VUw+c~r zVx0jNhG}b$v@T|o_*Y=OIRgIyxGd4pd6_5anXbkwX%wZg==vwbBvL9+e!5$c#=utc z`Q^_V`a381l7dt6UPgQS7o<2L5>fBpMN<0_YkT9(aArAXt`UCgD~CAf_Tv9Hz8*E< zQ2ozezKr}mUN-)I+iD|({{7kKiyM{6-@hpT&-vVOdp6FvzdupjP7DbD_bb+!(1`#2 z`hVta9(DWU>&=_#Fg|9q4Iw_b!%1A?iom`SvsTGkooB))im9uOfH4U=rzLI%q4w{L z0I()O9!6<_ic}O7!T~lbv;JIT`0bd- z=xWO11RxM{RT2I%6dKQH$;bpB$)_eczQb%>a>G4;D7s_Q>5%g_Ap z%RZGcQB=>{MZDF${}8f@paZYg7CNzIEa^<%=tsvHu5rbq|yJ7_MS7x&1@fwqAx z!Qs2&!V>-a&ws0n-M(iZ{#6QG9{&AT4-FC~x)H_-<*$v8qbW zo%2_EV)-ork1bpALHRcV4snsD>`ktsCZU?;)E0(K?PaHzj>eP3T~k;qsF-oQQ5l+%;GqXn{(VKJ z*zA0-v(3DjF0I-B^jyBGtuwm6|L6X~Lw7$VOnlpfc*xtFN|KZ1#2))t$r_!y?D-MKzAf8hS4s`r3w@P;V zusi4WmfN&<{wwh$3EcVjO3LbE+0Pb_QRef0uWhX}l!)dg{>g!j2z}W*GV#o9_v=R# z{;xmOt@rE7>U_;)`Yil!ii>|~!0_*7S18--H+<*9TmJbs*Ch$u{_k7%Qrp-x2;(&u zp8xar{dWC-aw6akAYK07=iAObFf72=mk0$p2m?S+w!Y}g zbXw`7Ye1QSMgd@!wOo*5ji6PZgS>tnR{K;Ys;Wc|mBe`-&Xq5D*6+ae19Urp<7s2Xy*c2{v_;-Hh#zdmx7b)%?5E34 zqX4;gFQ={^EER(MmZi2fo-?7EYbz}hF$L4POUPdptEmY`8rH6V zNETR*|2^wS)?NW3Y|(TI=8Te!q1FZ=XkPmM(n-`dLk*yweNZ@ZE~1XtykG1^+cjZf z-R@M&OSxeFA`AqcOTpPt^_8{u^e5^u0{z}7a$G_iu*vt(0fqjMF5APQ^Mx=Cr= z*Ne9xxM1sAp@ULD+Z_-%W^1VC?j)I1`u8v(SvgJ^^i@{sxcmC}0J}go3{S%Km8hqf zG$@#+T15>yhN4v?!Ip$zwYU{pXQC1AIOF`}3AkbxfP4ZZ0pB@Z5!koM)NlzP4@Nk3 zaWIP4 z{{8?c%5{=a3D1NAApZd%20%M%1awbE2M5zJNdlL9BeEXs1AJ=EVwC%l^2}iBfDZ#& z#!a+ofV=-4x&!j8ufM5xT-*azAodGv^JurbaMxgS~!PA4q1hg%S zgcb()5#->YZP7VQKF-Ln0W%Eh6wIH)J6^kY;=~F3I>F_|oXY-wOTv*Oq$Y?*`iwt# zwgE-7Wk3>w-@OBe#D(t_ryd72aFGFXTUa6aHss-U++fe^9~t=p>Jm`5Gl*??woOe| z!1!095h6fogViSr$5tp(uw3y=xKxax#%N-oNcA@rFOL2fllbzF72LcugF1N0J%93+ zuq<>>!UDkk1w%w zyf&AZ0Uv|v0s$CzjG(n)ZZ>j!Al7Wwlq6rS{wJpJe*jI25PERVK{_Mn?kw8`Re)>5 zE9`C1ZX51qsU4-E5&yOy{(cC7igC*Dm!qj?0M*v*(lnbBxU^9Jq*S98_ty9a=Adix zFtoCY11(d}!(xM(%6Y#dbK6`>*AWE>7Q#ab#x6i!F0OjkbHuhTV_K!2yXO?F1WhZKyxFOh{BTa3j`~ASA-14o17>(D&XtY z0`rzfk4TnA@qh`x)^2zz)#J~Hv=N4&^-CI}=zHn|ytQWVtTh)xP!cY((0o&?5VEvLAIME_y9o)Tuky@iNpsVkj1Lsqah($F{>Oo>55 zJ9h5|L-LFQtjO zp`faQwKcy;c@&%?4T$x?9*5FKH4fqR@qZ4XqflYs7BF8cAzTWn`$YF?6gaA9781&~ z6DL7%L!E{(t~!W)V8O;XZq?;D_koN|53@EPN1!kbe;cfJW}UD+CB%d0uHD-~nL5Dh zNp8+r41ubehQ@sk>V-Fn#N;s=8nWT5d7y;HsNl9?&BVrzqVZslAsuKHSB%i=twKbg z4-Yh)@bQmXA(R4>^wXyoi8VLA$sE$gstfZ1NE{axHHd}`Vl`g%&p1xu;jLu*=pm;9 zt?;^}WH3SqU~R)5oEJ6dl4HMTWoOs#N1z=$RWyd#x;QRJJd}#j%-Hf`(G}3@%wSc- zR3RA5KY2a7T>$?m$;*#HQvgQ+qjWSnZ~C3kw0VNL^@H#+$8Ipk;8zc_J$s_ms2 zEAOLoicTKvaq(Z`vzjx462=oC;hu!OiU-l~0~C68(98h6sH<0Pmxf69)QSe42u%lw z!&01lzT#Gx;7hZkk|zYFDFfshkRRN!CgyY}By<%x6@0x73m(dIkeR2nVro1&A;=`Y z9#G>Tp}!_VP`J}JFJ!GRD(}{ggLT2+Lwn#lOh>%x2hhA;xO|UV+hnK7Q>uWJcoN1}3M6^WFn*SouSW#Cu zg~5{j-H447xieDeN#YB@D4gJYRrNH7KaTvS-Nv8kyJn^al+b_XQUN0JfdCXXPcIC9M# zY$Fyb>~nPgA~TR;C4;&JyBHXlKna1y@{&9zOO)ww(Rie;Ay%Os(qzPx@T;%S`+uvJ znV!Y8j54LYx|0vZ9QeRES8cW>Uq6LbWq593LGH*767EC)76xCofDDe@=>5Vz!B2JY z%+)}HVKU3mCs=s)ve(f|;<}rtwZVm}AGQQ}n&M>C8I1|Quh(MWwi}$%1B}Zd zT~%Bhg$t)>3xAwV@Ej+55q%8RPQ_%urxk#C$la(Tn_DANkTWYlEjB zjsdc>imjp8TLi^O2y+~l4(#1KiM)JTw2VA#5Oz~>U%7_tun`Sw2-q6v@bU|Ia-j9kj zeRyUwkPqHOW!hy95eF!pIf5jTnxG z{@Y)E7Qk-#qe-NZD_&pM4g!aBvLf?I1nt_GA$Q_VP}mCwbyTFCG`{!jf`b z_V&Wh3C-aQkqDV$@EJ%3RxvqANJvQMzOF_r{Q*uKIA~vIA))$(e}u#t=KxM*g-;`u zzs0GlA$e zC`tYSPcQPrhti@_csnC&Bg_ON4-Yr;%cv{M&KxMe z^tx{<=jw$4#INb>!6LizMj84iIG_8GJjh4ENig||$Ec_-`)=@}T9 zDPJROgRbw~L@5y-j!3?@7abROFRxHcr|by9EY$~3rJ@1!D!yRc^m7yEbt>HA%ln{~ zK`1Ei!{fTxT8V;Tpim1hG#EP#a^)n>5iIw1sC2>Si85XvitzH;={C<#OsnV8;?y*f zEPF_SCbM79%Xc3QxM|?@#O}--z{ympRL-)(%ZB7C6YYox4@!N1#$iCOHqwuBmz%o$ z;@=s{cGqEQ_eukkoT%C7LyjZZVU+55$ffig`BWk(;fc==fr^E`cUEG9C1A!gnMLyu1}xhXDn4G zXwDhwbVWp1D>b@*{IJ@ii-37M57d@pict{quc;KQ1kmQ;gDVjp%7;RwqNq?ubb%~dpv(m zH2#|6H$PgIuPtyT;91$S+m+{re$z@631_uknBMvVDzBCItjzj(lWm{|Orm}&vkeq_ zhNKnBi{kcnxQ#S}5)iDD7Hq}SR%$LT_9%Ha7D^4$&`8x!Ukm5QA+WmJK#T8W>heJ#9~2A zO1?6J_%vW{venyLHsbwzq@%3P72qtC8RC$WNnb$3-bF@sj{R~wqMd^X*Kb)n%hdaw zKlmBt$B8<$(P$PRz`%2~H{rW0-}?gx{DmxqqYNqXqb^DbZS$CgSsF9}ma|$0j#;Gt zDw{q-!9z7K>e!8{37fuu0kcFff(ise9TlQ?3_&+y-;o0cv|sPp^2PaBI$8ycSx?Aa z9FvUID+XszOFqzOrPK=fuB2(wnzuf*>#Ch#TXaNIb3-K0-BC@BvW5)hbcwt;m9E5PvvNT8&L z4&P_$tqt4Fi(;w9ZL%t-tM80_tTXUAB!~AOh`Ysf;estf?O@8oD*ZxLcTvS2oJ*?x zD&k8_FZ;lA?Rq%hxx%nDXl8ECk12fPXf{{5d?>q2^gPI!GnM0T0yD{*^?Mh6%tBHqtSEU+Q(B&vc*LZ`6camaOIy zEawH8&T^eqif`Am8tHzJX{evSnta!+#M;&~Ix}u{IKx>~irhBpZWT>_p%nkJdL+w=IHMi^Fq1}$mDc|lfg}Ssj>YHYr&ftPTy0y;87zrp#ytQJQCRA4@f(}YGikz z#&mFSrL;UDXy#&P#BoC$Za`xYGh-EE0ew!QDVGSmpnH8SBR6~Od{B44oXRl<&C-t_ zIkZ17#W7&F0}OlV?yi<`KNy7@!Z1>|Pjv>+&LLId!(0r+snR&fxu;bY{8Lj?(+y0c zQvuRPW??iwJq^zxt~z9^9e{cf^)R^28ip528n&1lU}q!F!|1U=b|u^AiAg%NM);6++m@7{eDVg`9UU1qC-i(yTma9+SWP zMpO5Ve%=$#^XHoZXC!#$nAlm`AQ!@dvlS~buR*P8`MV_KZ+!W z3XX6EM{zj%)(8#T^dPSA8JCJ)Fs%Oo2kBD9(>MWuy?Wc|fpLM53)L5xW(YP25b#ck zFt#P~1!Be_KYs_@e+=VxlaPB7&6lwL^788QO+54r2d!LGRH6=~Sd6D%$)!B7UjF@Z zgSl$eh)Rjh9F0|mCtF}zP z|HbU0jJaTO7CtqFFfVq~#@gIV!Gwtoz8O@s=-nxt*vzJ6Z1%_F_y0lm4fODbyaY2-X;3;KT&2Kp_jJOU7syR?c z`iyc5ek3m3p##iNcYvuDDEbP_{-|r4)Uk1atsx+83dl6%ra@Ao^6O)&f&whYW`sCq zBA1XrPalFztYSrcS3DXNWi&iU|LOnn!MP32-MZ>KPOU;0WJAD}%IPqy2rgfs$Ld6e z7kx6F)?hmD)c&>p{*eE00sagfztzDEry)d9lrvGrW)>DG8D6-%Hx66kZC;KwhJ%Fk z6>S>d=5Ng{4>6x*;KwuZ&ny#8V2tcy?_je{Pf1w@n&^AIfvCa)f~BI{Q}n%xB+-2T zfHJ(}YU}RBU1Z%xB#$huf(+v$Ki%tQ@0|bkip6E*zOg=sp1yuSx$?NMAx~mahx_xh zG#`n^u!bc1Iva#d4eVhjcr@)aZl zn^Uq)k8;U2tn-^mHIpbZPPBbo(>@W}@w>h#Rz@iysFx%yJH)Aql(Hho={mwM5nPE}(&h(<>UFSbsle zghA0)@?JscxR*?+ZfT=Y8VqvU{E&q}CX6$q8if~?8DFH22Pfz&RbulqU zrG$5C@8FT-Sjz65M-Ivj93RT7s^BDsqT#=n*A0 zfJK;za-zDj5*Iox#|YL2tbXv{b2J|2v-U5*L?b6}G2jLv80XJJZ?RMsp<{v5~D3CzoXK2xde9>J*)7#v=*1} zWEmCZui3K4C50z^PTo47m}B4IFJ3rXzR*^oxSIW^Ax2xnA^ZBWR&3m|e)eCtK6|MnHK>Kvpk>X3Wwkq>lEyqnW9n=itIA7$zGvP(Xx_Jw#Z%~n>1t>nb~Azm%aVo*WIVj_xIHE z{P(0uIs$cah%6_9Pju0XpaqX%?@sfo7Ww$_+0yuXJY94dghh`sl2A# z@w{cF+}jsc3?G|T8?~u#iIl|g!@S(@(oy>;f>YUb`e|A{hzF~xwSHRxg zu7p>$XKI;KRXM`6p!TKD$|7%X|GJD~cGn82b==nPIF@NvrB(A*@Hyt&rBw_qJq?`y zWPM8PVdpA)e;uo+#(<=zCFy{Z16;E=KLihm`w$zd8FxB%1z9V*E#i_uGA&Zl$ zozHF_?7DmJ9%dk6bUx!9YyX*xPc9iEg`FXWoW$N=UBjDrcBUx4vPi;^cfU)}S0`)k zWFvvirHyxcYdxlPmabXb%r}@dCxsnOH6Avp?lz&S8*Q?lI9F1-YTi?E!JK0#Pp||3 z^Z%#)`ARR!5g9heMw-_%p84_9%Oo~Ck2|J*&s|wG-uRSx6BECYQrb{9Ti4!9dT-B{Dy>3>*ZJgLG)^{C6)b!i zV0yl?@LuzqlNr{&@eh<+h6`(SE*<=tssE*FK=e!JqnlA{b319bxwf^hV!ecfBqHwz z?HOwm6y?BKX>Oh#sJp;rlmYMj?z8ZFKHlEEpy?AX%Ki;-WS+Vo!xl!7LSRJtd3#;n zP_2p%pmCFn-NhF>-&#!Yh~srvz5H2*{2MiX4q^{QmIcS{ zf2^0&Yirgla%bci8q$hvejJ&m#?Ue-btH5Du>-7?KVR;Tygk!TDd$=pVpO0w@kU`y z&0UQoCSwuK`LIi(tK>Fi8RiS~&YOI2oNP1_IcyhxDNQLoK5&0u5$pcQmsBhRvklbp z19hRDDZl2)X?m1DI~S|G^;a=O;2{!T2)Ss?vYD#eHK2>P}vy~ zt@Zu5X4CWB;G_H8?dFsZ`_Gva?mMGi5NVjv5Yz5x@N)Lj3G#wtM;+7V(YF5;!lf7WC8B|ZGHnc z&h4U)zI8?=PA;>WJXKm0T|R83P(?c&s_W++k@+?0ON>i!YdSsOXZ54nM)|qvDS~oF z4cQK^H9Cg_<=f@xHZu#bI{%1QE6p?$cU?6&+phU8;dO29g$B!EktBsowhC*bX4`Z3 zpPnyus@rO3o5OxSXrF*wKS$QQd`ezU_O|FfN+Mrs^?4;(lLc(7rZ2_U3BR;nOWICF zJ_=PAZ;#m#I;O@nCFL4p&p2Pkw%(rAE z=WuRPG|KSt)u!W-R8+LP$KvTn`&r7?rvoqQqg4o86p8&|=dyD0{^*yAOgE42XJ=$` z+jFq|^;ApUcjfoGw%7Ib@ApLAUYM%UITk06Ekni%nbs1?ldiiy>?tkDYp(ymA8N6c zu!c8`h}_Bcm#LoCb!9u8shg*lZkS$^6&ouO_{6SX|6_|)oQF{W70c2I8pnC7yC1#m zH!*l07Hm$x1RYZIq6TH2M=44YD= zr@U<9tSMf|mWub7P26X8YBF}brY~Do9Gd*Jysa)q?c?odJRwo;gC(@C1!{-gZr0gJ zbj`$$=S(oSTYrD)HgPfj%VK1P`qf#b1DlUVPkcQjE4Qho20VyeM|DyENY}&!M53Q1 z#$S=HnV;zAby~U|@g*)J%@BcYDCfjnO9=;lqM*P@LgEIM>IxDoHQA2PrH)VUEnQz4 ze(wAOiN(NC({AI_Yl@~n zzR2Zlqf>q1bJChaq3SXUYVvEC)^E&gIfz#p5JPA+!ZrgkmP<*U?(q)1zj0{4lc3{V_-$^}p(ng7gW5bXE!(X5631eFD|xl9Z)PdX z2!8O*c-e@@1j{u?pjA(uq3LYQfzKRF7*?EscZl5v1Rh5r{hFvxr*lv$IQpXc@n9VC z?99qRq3(9Y`A?BiEvmHaEK4CuTG&mGB(|hz`1tzn*tJXlaj&}FdAW)6)1*6lWPUoG zyMCeD$?-?xTGBa%Od;)n_l;8yBM*H1{k*&*6yk?p8*|AEP_c4zaW4$9rZ;izJsAJg zdNyZr;Y>)n;M%U)hcVB;+W3}DG~bL^>uKvV{^}%q`_GmfCVSSos4uz}*54T-nqly(7KgfRO5%X;&v>i%A>y9XCAR)^!NTJ+(LD zSbqxg&C#a1;CCkUdg@@-4@)o3lA(E(;pOb9DG@h_= z?FZ!MH8nLy3%^fYjk^*Hi&H1FAFdy9qta58Sn@H6Y#1D8koGDvJhBrB8)UBuqCl_| zQN<}(N=Ii}!B+wm01!%oSTJxP02c)uH`0HjAoC*)2LmLCR6wAzC%LEv3JZ2)KlI!?! z`RE!&6+RxGR6NavF71mhR3pA4YK*-3R%+@as1U+(1`#sYBpmnZC{~iz?Jotf;%(Fh z#;@Z)i_(+T3Kr+zX^xo>Q*9EWp^-^9Tf^@{vl$^QbDGgkfCjp|u}mkCe&fg{>Hzh) zB5Da}6d_KrWCLoc|6M}8izjWH7@<*Zry{wTQXDxpyynuvxO9!yaJyq#$&fQOkrTnh z_ho*@sW=9qzd)VyW`aO{Jd5w@K{14v2oJ-Wpi&WEC4LR5VP%l<$GQkbsm;t>yt%*v zv3^y0b9)wD?E3*NsC}&`H(nui(}+haK{oQSY^{}(rtqzfJ0JZJ>_nMK2xsu=*PbgK z3g9#0Qb#;2L%(jI_fsz8P0H~hNEmQ(fk&%lt9hd+$k&&Z`Fk<56DO|#OCge9r8wk} z$Zo?cM*Xw%$puGPPbKH^H`IF6KbfC0l(R@38n+Hs39_yF_zfx&L_y-)(LnF83kfaa z7zkeyYhexmRjo@ZQ00T2z={EJe7`3-Lhthsd^Glmb?epX5_$T=XmPwl~c zd)B_)9XK_D<7D{_=QuEYzvxz!mB9l03SI{i3zDjiehAx^<`6U4#n~AW02ib#A3Kzm zWfaJ85k?H~lAc$n)DeWjF#!SkA&U^)QT)u7KgtclwgtW|%SWy>P{hd*buAFi>LC?{0W7IW+ZZ*M6T<`spX9 zm+dFlu3mitY63YqC@)}ww=>HbL=}kqyu6Exr;i3e+Fl5fRc2eYLHxbVQi*yKONErO6Y&BL)VhTi#wO09BU2x=Fc_UnyX;d3IIXHO%w06BWX(g71RF*lfuw}IvnjE~m4yKBa_XDhYbb5o4? zf+%7cH;UU!$Jd?Y=XZdR-B=Ee>&@epA_yUy==Xga5!U(4z^~L8l=-7lDp5W1t z=gxQR^J*BF&obc=Fb8LRe0-Z&Hvqyx{Bmor5y_v~T$rX(O@OR`k;X3oe6zOgM)E`b z$LjMDU)Tfd05}Xxp5K312qI0sif4U*+X@JU6De!^738FwZ9CrqI4M5`4sZOJVa%RF z1f05GHb5c7pHCBYN)Sxu78!HrYkTP7v1#K*UpbXYJECR-Rzi=3OyhUJVdUkz-I+y} zun4(DRQ*%&daV=;Y1H44suWv?X(uf$ZL6BC(t)g`@A>4X&{&O>^mV32t^|USPb#H~ zZu3yw2IkS#E>t>1@PKt9Xr2Y1ao(d^W4V_gppguC?*2p;tiKYC(|U6piixgKDXFEg z)ZvJN0agfD9roeU(Q{P5wD3HZ?R_#ZIS0E|em($Ot;{CAUG6*wycNz%N%>jc0`3E| zCO|w>j=vU?$P4>}fF70fn;|sxG@e~dR#8>e?g@yF)`8oI0|eqPDE#FJjN14;>^JPr z&<%)L_!;?3Ep=ThR;M%d8*9Oi=jeMR0iCIV>c3@XwpEPXb^RN}k7*iw9n5;x!3|I< z(a~XQDC5X}@7bt(v@9zFn0=m4@VwWO7u%gZmw8fQp2}WID5hQ1qm4gz;ez*1cd2M^ z#;x7522fnj>D%F3SJllRt2nh|%N7=ALi;yZaZO}(bU0jn{q#9(7iDwS0H(;B7*+!| zD`>FjCeek(;zA9ZaRBkkSuO-U4HgMStvY=;PeK61jk69^An^#Sj^er(S7&*=gp9%n9HFsl96(&0ti;y&U$C>cSBSZMN{WW7 z`#B=6+O>#GS1t&zB)#4BKko+rp!DcjtC%NOHEBl8=O*<0sfDm@gZqDz?__Wi^ggHa z!c%tz1fAv>-_P%Gb^X}BNNJZKD~<>umO{ikv4e!*SjhlT@jkgjSm^Ool#1Wj(z0Qz zn-(36C*fXct3e^&1gbkgqbSZ1Faj_o8se^Ah_1PsaP22Vot09x&co7ZxhUD$?_76wnnq zid70T+{%KxNun%Ue!-VkvflNg3Zio_0{mCe!qgYN4`Qpf6kGYAR<<7wmmxyzoF#6R z4Goz%cbR!|vO{_ev0Ppe`F=STw(BQPoG7^#M`Y43ZI*(xF5oGfH*aR8e0{y`N9}u9 zrhR-6QyoF1ntQ@pP*EbXb7BvXDT%2YfHp4OO8J<}?=+%_f~7q!@DS(j zXdW-%C8E;)VF_btDDF8`r=VV%^$M-P5F%I36KxNwK)23;h37r1fUlbf!#UuF9#Myz zBz_ChE#uA*j6dL_lF!9)`vvq|MYCTiK{@;7CZt@^~v(2wXYG zvkUgh+hDjfH5vX2HadT1ROoO)=n5if<7t(`ZM z1N1@A=y_UfFrvV4l=aQ1IZn}s0&yL(|IbGJPEr|_J{xi+`Z`k zQZHogfCGomqZrBg1}wPp36y2EC)9Hd8vMHau}eE1QuMta4c`KyYq@I4l}J)UzZo8u zcG+>nBB02rs7r%=86NJ@T}ZkEfC!hA2VdFdY@h~S9;_YqRmH#up?Cr6z$2F^@g~q# z*^`3KTuRDA#aSww*TcgD>)eZu02dz|PX`{_dh|&mOZQvMTA#bZjZX3zz3ko3eH+tZ zq_T8Ws7Oc7LhBWQp;yGDwuDD+-gxOMO<^f(9lQaR6pfGAtD&{Ang002n|uY!OS#}v zP=BkAyf8Mia=*Qj@|)Y)Qqcmihn5d0&->@aCZspO?m+&u>}VX;J8J)$T38TxVnIg$ ziOLd`sU#nT!o!z_rWVxH;a8P{b71Jz$3ayD71_54UbVHo!E{bdjH?YhwMwz}IFaGj zMg|o}d?H_JEs=D(0rh0ErCJ<36+`xnUmh3W#cH4ZhDD4_ix`#-ROg85eDgnW_*L4k z>vG$wm%yz96aZ9(n1`aRsATSj|5>%1u!%YjppZ!Le}u{`X1C;;M&QhPT%jTh)D$~Q zD{_&aloMz!#@ChUy_7`(lS#Y$+eTh=JN8{*hd7p@PW_$A8%a-+jO``Y$)pd@w`~4;C;na9rS?9xK*^!A zpaWs;NJ~i}&u9)Q8Dz?C%t>wMh(&J!MD{D2BOAOlW1-sDbj8dCvXgRg@tSL9XDlSjfl0(!51<)ziBXC*;sY4v%#-U$ zcM2~5Vk^JDex$^h9&?{F>3%fMDa7XXu?Xt{jaBKNpd^VpUTfZT+$9~{)L#56!#RCe zG8rjIBt3V!OF&W{Y#jKgev<+#N$d>d<0J?uFQGD77x$47;piQ|-UH~It-qX0ycE0X zLxSsyzyBj2-uWcEzAo7FX7`qe3ElvQ$Q2|}e^J8V7(Od%ocOXqQBcFjZp?tQ0QxIo zhGauqP)?q81b6B zZFYdtQ|a^-eYOxLyf7vCg-wl*g_=%GR7!cC&&zVxaj$0m`7L8;V&_?Dr_6xLAKx*c z2E>5g86HoVj+2a$HD)^RE?m+jq35;B;Yd&K7T?RZ_4d9G){;c&&XD^(^j@*1nme0+ zRGC`ad9w$yEXU@qzt^srxRzYxt-G6wB-#ilfnxWXjMI?XtiMATjFJmwzKM@I)dQkF z$y5GFsJpQ4Dig(uWkJnvAB_(1c|NBUA1vsVU_+s|G7b%auiFtu7JXNpv>Za6@s{0f zlTxsPyYVJa7hY(UN@YEvPUjU6l3=}pMr2-$`&Jwld3Ce^f!LBP{yNMST2`YG&*EZ5>w3)4iIP%h`o z0yg^Pbyil%`lI1#<`%U2XL~EZb@Ec4mN%9+lTx}UF;+J*v+lH2c>gmx_xgx>>bato zq|3eQ(ehnH%RA{d`o}6{M5#3=O6OM?eGrlAQfkH6V=%8`Y>3GivOD8mB9VM;c`)>n zO7SOK+O|sVXjNXVB1(t*GCvf~Z@DtK7*GAJtlly5W+Cex$r$G%#o_MZ4%v_IYT8p& z_C^)LTu>ESy&`4?NziU#k*I=p6`u{uTVj42AJ9q53 zT1!u8I6Z%^n@)$jPfHNf@Q(fX!~_GkMj;M}RCH|+&vs|vHv{P*BqT&$0G)8lgdF!_ z_d%pH32{5L9Ek%r}3b7GHX2#fYgOSbuP9oCgIzaz{(=!B4W3NO> zkd*C>Hna<|_7`rzYT^014`iwdc($i*)% z+x)s)>H_5mJ8^qF|&xpqLuJ9y6~cqkJ}&$b@t6 zA=>!Xf#+~mL@fcyvmqZ=I+hOXup+<3_QSqkbi4iD-vs!HWi{|aBqr9SB`7o4?2I8_ zx|nOpEfEr*hsTMggf*cbmYX+&>ApROmGgF`V$a=4fd-?tXl`lzAnY1-^Sda*tNsC5 z%bn(it_x1L_ zO<-6Ilj48ZW2+?lG@@RD-}VR?__U(Gh(OV=ZV;QJ_}!@M?!P~LKU4hQhnN|^etFk7 z=J)07zgy2Py8idu-@%Oe^_&n%o8J%r{kvE49KV}hcH&?2PO9+D`S*r*cwGN|3Q7FH zp?|xRJ@CJ)-GBcs6()_`8dBha-#^1J{2B^v|4THDiV;JYoy49^wu^Uo%J2Vvm9mw; zHx{}p62F^cNdMdZCmfIyx2k8)#WX+e_U~gZTlqBpe(Av9FUY>P?Dq@a8UBr$`YQN% zh*Ff82CrCuk4>|LSE~?tz8E4nL*8ZH%FAde>?4l>{qKQ!b$)weD+MvxMD^fzk~{Gg z_x47i-Q>^u#eaXsy1j7+75TFR|9!R*p9zpZi#`4OcPnr$`5AYrVQa|!bvaH(YkJ*f zV(v-;Veo5z?HBiI-Fup7Gy9I;ofx@A+-i9p`G)I%H-_DkJ$0Uf{34P(zb`%@=B2v+ z6!~KR|1Mr5ZpBJoXkn{=&qbfx+Z%na5pR5F>wm3zk6w8H>xP?t-|&&Rm+ApA@(tJj zz9H*2ajVEp#LDep{;xH9?5PLq$m6uU`@f6Dyn;7|5ktT5dp>lql$MnRoV1Li7E6@x zvvxsH83FEG3HSH%-teP|2s6$e!Mr*ih&9zMRb!ITlRLv^;@`)2u$)J2owmGL$oWz^ z&Lf|JcuSeSc^jc;hSOWq#JRUOKN^a?vnp+>BcO!(@n0wKL0YHil z0NsrVE+ABm;8JFjO2%a^oezQzf=W{+T;(J0r-Sn8OyjTkv^t;!09ZSK4QDou^MNRb zSd9fvq6t$l$xa&xZ;t&gq;H2N8`S$edLHe`O$~zy>xs7s-kiOYIrx=kf7?@aE9>u7 zFNhi!`sPdn4aw5jD@7j>ry3HIA8MEb_K8Z@6ci5-3 zX0QGT7I6~h=9U5V-XaIVol?uKO9wEF2O{H#lA!jBmPw|oLii2@wVpw2bU56XH-J~| z=;$b~1JOmNt>m^kf<^*FRq8dWWTcjn)`-J#(D517`t@`tZe0i8X|@RMya`M}Z)^*8 z+_jq+beDQ@C?slBq9YR8#$>`uk_RO|6rw?D4;4xmLOUWbU3-?Zx0Avj5x0A)9by}CBW zOMLh9pr96P=}6Kk9-i@jh9ayN|NXr5PSGTNGFrC#dJ{P z;`)LWU=@`OqB_iAK7z-{$E-6&a0Yq;X*!qGN5SsW&dpxP(9zOzhCZdU^8$$8vx{CB zifQr&`xrRK1D0q9M*(=?d#K(67w>+((M-~8-PbfI6T{N z(T$Ebxu26tw!XWmz{v^x+3rC+2p&=d<`+b6(TPO)v4pnV z=P6GaIen`4r`5k!N~G2RznsQiYpPM)+wlyS^x|hjQas~hmgwKQCBdEUMF?7zG&O@@PK4x>?h`ByD9)kdh&KlZ z)>CNe`D8Xuqtb*k8MY3h?!lw%9X`-^;5b;dLk%sO8f_P`o6wD9H)&)Pdx(O3P=$}F z)7O@0L+p0!b{F_ygFQKq*9>dO*hEH_8ag7*A%qGK2(%3%FN7iWEzPYM+783}?5YiJ zNcf;(KM1!=bW2HW!kQzaySPzUeZ{J^Gcz++60UtgRZbAp@OrbM9I#E`%MjJnA+xRl zBoh=dAGM%YCqQmOQ8t;S8D#rEgL?z@;r@HEUvyzFT&O`wv9kJ@w|1SlRo3RnoS`Jx zzv-WSs339r&2!)=u$n$u@yG^T)Wc% z3nN(GWo3ZVxK}bFLrA${Lrc1W0=6RUKvyD};gSNN)#BpfAq^MMZxJp=3PUk}dew`P zO`F4g{8|sJXmLP+^F@&pjtF^>vpnojvp7H23PP;zQU>n-^sts<5P>X5<6sG(Z%RmW z`UuqNTY@9zyGm6>1rkHH&;|sgDOAAvv)~IvTXhM7U7ph5{^!#V_6TgJ3RE0U`a#2a zttwiYd3>m{txfIot>kMd8l}uo31p=RCKj=29DpddGcjH894Z!osS)T|LJu)70ya=M_*_}EC1Sio%l?dMY`)4;vS1Q;T<-2yC)*(6A#C(Sd0q>Tl0 zM zs^r=Hgbqi=W>_o2Ia*jHj1>p*2F0*xcohY61My-Hk)bM6!OY%1WpV>5Wa(Sj6VWBq zcTJ9wd{#r#1hWridNIvXWmgl*1K9tNNZah0ci}5&V35i}1_Jl5)we{P8uAv29z2Kq z0i5cA(3fa|e;nKH{HLF>WUi%C{&&g^}Ilk5t)L@mQ#{uah1*R)FlT1RiJ!L_^K z$C=WGj!6PuPcgqy71?J;>`>b0_@JAG_-Dy53g9TDS|XwenSOp+M8CFgJ#+wvveRBV zat)GzI2z5mRG<64Er zTcSY3;k+MrQ;CQ^q>6w5AjDoF#L+E*Dg=;O03>c{P<@#v`2lw4Sy-*bg@uIsI73j1 zrNiZ~vqAzarF2g&eWvl}SsTCjdhMc#MlPkqx}|TKW5vGjoEUb_Ra9{?<_f>O5cKFo z+C<>t1`{PVr`yII=7&9P(xnnl%2W6WFJEbFbvP$2T>wR3Z0(Rc_vN_SJuxK+o;Vnn zECK?}@I><3Xzg%1$%xBgtI0limCv{8=y&}nAs+}z&t5=$?sD%} ztK4g@T=|}FhqJN-1_QK(-7YYSSgPE#;!t=50>vOV5QzE*8?o^Gb$R zH*2A3f>*BKm`=p5v)BUFOFus`C^>h5FHvr4`Jji8p&lw^D*7uWx=t6e_5wyfwlldH2uY*L}$g<_(qHAd{2-FFI)$+UlaaGy9lU*~FHgW)C_UZg|P zJ3~%DZ~S59w{Kk$NfI}8wEMnK3h!`W8n>^=*?TIaT2?MurQoT*uXYu^ppam^d~EOc z@7Eo}yz3jkG@g&hSop}pB`iEwbTwbN`1wJOevYfLD&pDUEDcY5eU0X{uOyn@dc`Ml zP-yRIqiFfqE1Nb=(fRx9jMmm%vek@x+PI!Yf4&Zlj*5(C+Q2{at?C))9Gj0?>X1~D z744h8p-&H$S#PJK%|9*^F_b$zFNR*brmHn`?d3J^A7f=c9AM&j?L*GSXHF^aGao0{ z(J!#>H4r-!Sn`{ zzD`k%W(vNTreadqGBcN(+`Z!G`t`{d?Zn?KP5VqkIfsFfF~j7mY449&ojGAm$47|* z87&X9S)6sN!%{x^H2G^19atuahz(k&^4;$hvus(u*7kYUa>~IwmG5ND%%m42 z>=3(XXEgS)D&|;ugDOAWqIic!&Bd$tmOM3`x~=sm(!XORP>TsR=8u-Hif-Ukr!}2; zpA;sYKf74q! zYwyBrDq%r$VU+TAOx0CWvWuhEco(!>n{-uq#M0Dq@|HDU=s&sh)2iE|JhzGYOmj9Q zD>%guHhcWxf>+!ZK~(w`5#SW13+J#eGxG}edG512?bRlulP3lEOMAN4PS9878ZfgI zhO(U=H|X*44Q5r(6Z+XY)>BsAFsa`#Z!^UfH8~U%bY;(Iub`FZOYxrsNb(k<*YY_6mw-MO1W2;qwQ|7eN-@N7{>aXji!OKS^ig7K+y zHqcLGuhn!cJ?B1f%wvQS#VKMgzq#A;)H}jc`XLk$3 z$&TmfA)%{Q|HLRnw}nNowKQzc9?`TsHju|F(CC$sD&6DV$>y}wURnHMsU^kwK|)h5 zn+{tv;>Apx_$|JdyujC+8HIe>A945&EXMLqGdHo(#%&YhT(r>ZkrbAvpq$ND{n4{> zcCPPgfne|S^E#H}>^~){XP>wpFg+mlaBcA5E)lNNPB!CIJ}XG<0_4ogA%ptp6zSl{ z#g0N=w}gIvt?xRvOX09Vd9z+^fMt2ZVbzog?~lyohjc!N`Y)Cm{wy`5O&pvGwdz(# z^YilO@BJiWKQ)@sWWHG;B3XEGK~8e3!jZ$$m2q$Cy5GSl(|l6uwYHJC*~@%(^Lm!3 zf=R20IroIA<}lZ@5#jH-0!L)ED~sok#ZFxNnEE3YCh0DbFuda)j}O?`rgW>alc@J_ z44Iv~tozOVCC_A4Iv1CBk^h{`P*awDo13RV=IEZx=*Z|zj6x?49&8@i;El-*jvE@O zV=mIZRP%YSfTyZ}!)e7QT+(3hCtq^BT6Bw1$@*HhP2EUXKHF4qp4D7YOrL~u=$6|v zqUXLdm)Z0>F)N;Zs>xI9hUdlfSsmIvm_fKfC2k5MRGdOphI)|~U} zIwQs#mkU-Y(b8%+EPa?y;2L|ToWlKr?X(N^-Uprmtz*X7*=w6b zfXVFCgC5l;>;9&cz&d&=3JM5heZD9yJy;bLQ708B=7n}WA&0!R#Tz+ush0N6xHN<~ z^(1op`zw|eVU-?BYX3U$wLq)ydrfr>=megb7WMkR!=^ufrmmJA3{O8F{!PMU-vVV*}`y5!!H=n!Z#TVTmA*U#nDdSSM3->aao;DXtG11!#)DO5{N^_W> z?iU$q?7YgMkkX{Lmpv7JNH5vXY^+X@?lMlcnur_n-}=nVaPTLF-f+H4VLI{VW z!=;-@9c~)|ZMCUH#r)oi{+4%{lywp(mDAIW2la!~bq!+Wm8WBJKZiebm63Vta;N0Ui=iz%BcnSu6%-q6 zl~s~CJ(H)twB;#8b2>{)v-@mAoC{Y!+kZ?Yp!Tczt<3rlyY4+;F?|tj+$;FW^j6B~ z&+~ot4ij}(am)_m5pBeIj>HixS!dNZJSiX8Yoxmndv<>9Hl2&Q&5@SH!X`4K&8fES z*OUg>oBf|Zzc_Pi&yFv*A52;4$wo+BXn6C%p;2sGX>6%`zR*aEXLVLY#Jvv`tJ?Zb zjA&dI%^fj9D|9=qIxV=F8s0O?b=0d%u{9j}kWzED=GdU0$&nrLI>vND7H$s$DT+;t zD;Wfq`b^!0${%a(qIFvvFod>=viV?vlER+y)Mp5IoqK8gjQ22|t3Jo^)|4LWcI&z7 zP`1xZI+2-1?aNK`!NN)c?48Xu)*lyqcPT8rvNP}Y%{5NHKoffCX?Z%c!xF9Q{d_(# z8|@tif!^~=dAIi6S>oj6XmZfqtg6QCqY`+Vx`~_t{HA3-uBp?Z%kXL zjFvnoVQ!a+L>GzuOO7;^j^_X_up8LlG_v$%z&+k0lwU%*F4m=CAoN8kF}=z*X`>~i zJAGAF)5#~UCYG57T{D~;w_Co*p_|Dkx4M$m?Oic40@E57X@?rwGc%9FMgr0)+-%$i(%Dt@!G?v!_{ z(|sGnlkTK4?%eSbXV5tosU?a7o8?Y>w4G^YT%gcRwWoWifUDV?|B*RmM?nf>{?_eu zKSN+fp-O9djGE{Qykf-NiA^L?k;2kv|6~ZT?>*Y+OI3IfU-=BbjoF>Qid41Pbgbva z@TLh-Z&iMBH~#M(U%sYkM3fB|9scv8R0dqM^Jrr}<)4kvniXqi3@aU}JN4%E-6gC08-C(UNYWNK!f|etJV%dS)XlZui;Ft` zy6E)%jNAtF(T{&hdo7sDg!r@Vu={N28juUi+f z3g|ZeIZ)N>!iJ?bZd&yE3a@?rCpT)_?w-L-K23;2!MH zm0a`Z$R_M_OC3gc`)>TR)rzq@FEuj;3~{ji`KGC<=WUHPH#aYQS^HvakEt2dhD5#L~2`@_y{eVzY~Xx~3ff6k?SKE20?;o7vc<*ydl zL6s*0H-P)M8j*i~s&A*US(-3k&{ND;5s+RFkhV`Rl5g z%}eIQvpTf@ZbtjUgA9RsIH&_vMVV{xoA$r@w^Q3Eh1@Azf8E*U{PI^THp5hd=1lEL zJK4PMAMJlV;xd;7F=scG(f-vvJ>n6=9$hEUL9>57^~LR!3;~!v_OpMzs*iwvZr2H7 znBM%=B2o-H`Ll~0i^K^2`n!JX*M3d@-;opSh{gQ-x08YFUj6#thD~KSWBmKKmV&%% z|N7s(d#Qx;L;kz-?iAT;B>(4a2Nv$XUy%O4@));E$StX;v=lhV0&b4Posz;TQl1#O zAMMEPy>5tbc`>5H$d2$V?euVUr3dZ^^*Qlzy76j~jSIOGC#Zi4s?Q~ocDS9}_wB@{ zP)G&g5A+E$20lQg5D^9H`I*{Q_Y-uqw3#+PzaiUh&M=Ki4VIuQRTr3%e&moXmCssY z+aUV=2mt5VHb3_)estWBcH+RoiV9N|KzNb8{qb$ZTY9pM3fo3FHN=ozzqX1B{K=hj zt>s)tbX8Z};af*6S;8rP8$-Ow?tO;WzpP3;NcvGkevs~mr-Uw*gaH8H+P3=IEgMK3 zzkG?R`@|65`7(f{79Kb$lKVMWKr@SulxIrrm?rWRIdXIPtN-2l9i$`FRL0&Vq%4C$|J1b)9JF<=WBvaO0ha z+Y}!k8ct*gGE!+7Y84FHRhMEOKXjPVXT`U=3u1Y5n~CY-w&CAlJ0i~$IV9WSa&Y~r z((Lm#-kt8|8K$<)>8GP}S~&}8Z1_Z1ecQ2fJ51~y%8ma{jGd8bo27$q-^vqJd}|uy zp8e7zI5+KORKBmbdv;=WZ1%%#okkB79{0`c5tlKRvATK6&P?iCM8flya0ZXAghF|T zT@wz`Y9@ILZ+EM`3nVt4>ssjCh`Xtbcf4$UcI2{YC>Zvh_UO`Y&gS#VNYEVh;G=8H zI_u9Z6WjSyk(;47yRm`3-f;E(7ubS!?*G3w&U^5YLT3Adf8R`;yi`b%@XU%0_j_e- zUc4pNQFGT~3)`+5eX;oflg>kNuc?#Yz9pvOmCIz`x^dH6T@|~DhNOqV48_M1>r+p+ zj_g!id;d}2Ojy>qmtH4BvAgcnjp&oAKP9eWiC$(Q#^=hJ-xr@ykBi@mHD!*7#iu0p!m<4?D3raBMgS^A;_ zuaI4?9cze%a-CgEvayt+nBQaEV)9+k$mPz5C%mHL?YZ<-jndp(9>z=)j zpKtwzqq~ToZu;MUI$bjw=Op&ElkdnCn+fhH&!an8@snM|Pu7x;b4S*t_z%b}etsHY zBM=rI;mPgr@*O<6f4&g@*O6O`_e7aEXkJtY1`n92%;wtE-EQ9|~GEzd?~kC!e(#JPR?ApRnUjx>CXX${~8DEY1~{sz@(ZdQf_hlB{DFf@pt`mN9r z(*mQS;G9jk&Z}ud3SHML0MHkl$sWHh&HBIPebLCq_`Tz9whO zhE_ZuvMvOb2t|YxEMloW&D(Nw!qH;BJI*bA_a&mHBdW4&IWgT+Z&?sOiMzPQ9 zpozafJvBY84$3jyluxED7#Zkdok~lE*7Z$oZ8$vO8k;#izCsPP)x@jue)aCxs~~~U zpH`b~-lt$41TaY7i6k%sAsC>6hOQ}V4#7qv9W;xcwD?Ua)U1J?>gbZ;Q($W;B}NP@4tMJ zi4Z(XvDa4;$?!vY!kBX)wjVw$%}Ij{a9y%`=&`lcvHT~m504apafDqEwVbBrJmr*S zWVTd}TXcgAmXeYJels>6gZhg4dU*r$$-!}usv%CoVG0058UQFt%BDvjc7Z)8Sa~5* zcGtax%k0jTu8=DPNCGKO0PWDolbJ+U+AN}0&v$Or%6jp$qrSc#z_2<19*0+Us&&nm>njex%swU1xgn&PMW}g0F-P7E)nnq7crS=DMr*c$e^P? zTMeCS_kimF6liGd8CK!&g;%LyV_;=KzXZ=8jB*UNlU8|_EC{~`T^y6oe3iMK+CYeXx?dBcxpb9ti`5) zX{AL*YPaTC0%7qz3ac4qaWXJuYHDiua1baL04)KqLWuPoJyZ_framtyScV`vfJ{BZ z!>s^00tDg4ED~Z=G`;{ps$Svh_=g{hppq|8k5X|!g+llC$J7)`1EoOq5?oQ;dqATE zYCtJ{7lqTrcbQxbkT~rXJ>;T+=(?t)^k#W!9_=y*CLsWm3N>wlp?CCQd;zFAV2?oa z?o&;GE-=gxh>U`)Y8SzYM~hIn9#$~$sNOf!GyoO~kH(t4^!&)FNZFJ_;J$&adM#f5 z5R_p+1_VzJmjv-<{cm<@G|Y zeAy16L^<`x-E){KvL7Hh>=YVKu*}y$#eWR`2Ue*kgcGY=%k7$~uv8 z3ECo%{m9LoM@=g*hGp?QtT!lsw0-yx0SFUBM;VG$v&}wMSDV$w$XL*#U<9PlUu|Dx z9={RNH$OS3V`5SO$}Qv)6k=svLQDXGgm{VL{4k$K7u4J#T@a^`4F2w+fHRd%O>;9p zyOb*FfA2mwW4+Jq!^oVp9t1S!<@s$>Y?b5Kup@XvAuRQ2KnW-}ykU(aV1|0-7z9Ey z!>15Z1rL&fj@)=ps1wXD_dHYodXvZB&7%*%*Qjx47#iHuun*=a${wBKM$hMQvMEkJ zQIcXAxHPJ50jN3wz09Y6wKh=mDl;PwS^twwOoD`Bl6y1iAOp?R7z(%%6Sv0djbl*b z_K}Pn;$QmlVY6WxHbP7-gS<_I=m^S8F&--C0saRC*yy)!-`B#!#?}{X-S)zn*uy(E z%Cc{_ps4{d`8CS}Xh&6-Xe}+xn@IYx_o3pz%gju^x{pe)b>H#CRAMaw(`hjanKp2r zQId%f4|k8yih?ri{x6zc=f1A*_hyqO3dJ0+3m2#ITd|gcf`AcIy4>x`f&xL6FQ+yu zW~eGk9u=Fy=$QcSg!S5ttG;sqOr@A-lk#KA+1VM#-L!3;JpKtlTl!E_RtB3h@R|2s z>}>o7w3QV|#9fv<1#OPxZ%Xi&+VAZ!)A`^Y#pb9XpY@wIjbL@ul}o~`6YxYxYE%!S zme&g^05vr#_pq?M05};H4{E>e-@iW!Lk3Zf7a|9gr7m3}D&GCjA3b5Rod)i*d;_3~wEX69s5@1hx|J7&aTz=z&fQv6sf zOxl+#dz*BRtUMTrMcbZbdT;6FAe2;;Pk!7*L*oY_8>}Bt$l@lzRew033kh<=Vqm^~ z%6qOXMOf%y6+p+sr@kuF1m->FOctuzP1p9Zj1`g}FK57w>c(W}aKb|)_o09eR!*@mD9WY94K8dclg3c8$IeV-X6HBgPk z`{`3N*g9++z^B=HI4#YxO>#(_IWsZT=q>pGkac!;b|CZ?P_6On-ZVEI;NOm(a)Zj) znKP>^#~~e!0kf?N3DVAVtbxf9&l!U#Yx0C0Hpu4d1I4x6;J${9<1Z#>-A*lgx z0iZ~{8*Ux;DRu%yy%A0MdW8eJ9)gwFuIlA``})qVIT4q8e&18P3YGQ9zR%YGmZ-xCG+ecFHve*U8ed6q{mL=vl+DAOXugz{z=g;`^3icMrd! zlrcdONU`W24HUAsl9kF5(BU2P@SGk$ek^wSw4yLG4bA>% z<>O;x*!ILtdN7Ce0s&5jXu3?e)OnuD@rjou*v(L$u-lA3{xzz4$gS#y5%?Ye1SXe= zh!ch#lTy3lLE{5dQUzrXRjjsS$+EJhJQI(-A|ETu%E6%zd7Oy@j~_h(kA%Z0Z_C?q zA~9TcNnV~tdn zm#emK_3?1qb?otg1B@7U2_}c+8q$jTB=ux9Av?}p(>YK9Q&(3HuzBCqlp`G~JYji( zccb#PYZgOay^3^SX&v0V_ud;{SR<(Isrq%*J~|`;nuH@n({?T1(9wZBxnNu|@Q~_P zJR`gxpo>Ao7#cEwSzy)q!dLfb_h>rWo5xF zK>SXtj%Bg!F6eKoHz35s`&KjEG*ykw-1_KG97>je=c~DX6{({AMacv=k<`#U%6s zuo}e2-`2)mHNZA+AykKLW``;-0O6Q+)nPO!Q`*&aI#A}H1Kiw1&9#?7yn=#xAh;l_ z4C4kQ_)&M^Soy?V=|W5bR&E|na0_4r%&e@Ul)-yA?;rO{B9>5gn$W_Gg^kvNHc|lB zlYmj(xZKf#<&gXgoT9>w42_J?Pm=S|)2jQuQ-t54dkH&9B(9^Pu&ppTFhL_re2>>P zPA(3P@J|qRyRNORt*56rb^E!yH4}vUATNXUt*@uoKQttW+FqT!ynKAoYX1NfOq^Q# zIO|AG4$BX!Im<9eIxzx?Z>kYDW(z?G>O#;8vTRcHC0eO7GdB7kGvU81 zi0<3^P%uWklPfPH|ZMC(pIg4W_Yxy(Itc?_|tvL%3g*Hf{dvrmGQ0)9b zbf{whMho@s^!&tLK-aLfz)2*1q9)$Dt7zk#IXd|Li(;%iI0>}E)4=UsHqHUPq|-SU zA6_|a`O`ToA$tDk{T0EF1m%P4-2E|j5y z(E7PPfv&DDy)>{Y)+_LCdvpecj)$auB~f}zwC;vjJ8pwhrZGls~Mf3`Cl}>by$^Y*FLP{ zqgaRn76?c;NH+-5-5mnbCEZ|>0@4lA&89n)?(XjH?)_W)`;K@1a^@It@B6-Dt#h4$ z3Rw7a@B%LzP67xt!NkObC>%*#?B~ycuWt@D_Ypa|d)j%7NkR5I7K0R-waS+-UO?1j zqWDLM$9RShF1A`G-_1qU)o}vef)kie%a=hw%fUSC6Fd;OvR9H{^Lf;Ken+3SR)T~m zuzl{{dxH?FoD7$ydGVBFIt6zsN#7p${>)TTxjN7pMyxthnZTt|SXu=+SCGtm1O8-ivTwt6(csGgc4Qr_ zDWUevb3_0B5fT!9W%LCX>Hg?;*rTjvuhgI@$dqh{$JGDk4ZQFSzYI{qsjE-GLw$~o zZ3h)|2mUM0f3DC_xG(`3I8}dBe^Y6F`zchy|*15(2h>m25^`;ibFYL_l(VYqp#1icJ??vPY+NC=2CAf zG6XI{kR&e{esYvS;&I0=@7E=&%BqY@j`8_(jgc1K8BMdB_uVP|?6$0GhWWpOU`t&sY%_eYW+E zyZEsQi=ft5zg(o4{3|Aa+UVb*NuvA;1)#1;S`K(A$|^H~oCMk%5YNRt3L>=utr;}A zyHEpEchWZ-o9e?wnXpP}usxC&3*wN^tFVJiHQ+u5>;Wu78`KUVWEfVci2!H(S`B?t zwx*=y<8B9$&{q4kzOVP@BbM3idA?N%3wsYiJlS^a+JEQ-m9WzwpGY-5`)kW#3t$HE zC17iYbC)F|X28~Hu%^$h9X|7z>Qjpn0U#+EV09X&SiqY$nal1&K?-WJu5Zz&tnKZG z*%hSuo{sfCt<>!CFz9*h55u@C)zu7`HsF@@NgjgBC!S$-VF0!z%hs=KrDIF!5N27Id)B z10_EJ_;%$az)-;qfGn7(;AL~^6EMcub_BecLtH7@LA0f z0r~S-=DxRj0j)$sMXTU|y0eo2!J;W57%m3z#Q?V09fec?h`I**wzD(H!j{|VPIrFx z;?0A!^sUOl8XLF-AQiW;q~y~F7f9A!X9tgn*d!V9ktDKIz{Kc9;Wz|{jin4=S?1X4 z-{G3$l%B$iMxt=xD3OdWn8TS3MW&RFs47|SiI|lcC{Upf&fgTf6NZ7;|Mb=zA1ncQ zv;)ybSKtq4=K$xd2iQI&`wIOCF9lo-x)sG7wH*_k~cwqEt#?cLkom?QLzp z#nW&ag`z>#JLpJG%f=t?2yH){4RG#1#KiO^p`npvfA}R^A5PBnX;KhwS%FSdQ4!XD zxp6Hm$T8t*4CcWBx2-8&aS++EnIfOXYCiTpXklju|JgHs5f=FV(A*V;XhL{2`lmnZ zOeoy*+%$}yGVfDweD^+Kuqfa(qQxvsu>GL#fWi{h-g0VxiIi7V6ino))TDa>G|A+6 ztXp$Ra+E`xYI3Ot^W_b?v|5~zi%ZTPP-rW%LDBZ4+p)zZcZ}N+aBR5G?cvi=umW5H zYafJ%?T1dN*`ShUP)R{AFj zBYJ>)0Rw~eyQwNswNG&T520clsC01I$<51!D-M=;|Et7juU@Ij%FeBsFOkQ!?6a5xq)Br+ijZS~cwD^sAL^m_<&Y2)FM>WS ztsCYNgxsqub8~-JP;uP(1%{3=1A)CQ85Q;v3@AApQ1>{ICafu=ELAw^SN&Vlv7N8Z z3inWMn1erXATl`(a2c*rE{M*GnBC*9w^>-)T_r=G)d}xfMWKM^h%t^qlda z+Wvqw!vJ2_fV6E6=ZwNJ!%#RKTk3f^BQryAy6EU}B>Y1gJ(_3!aGUSyfGXm2y54;^ zxwnqDLO*eYcG+a|l+Sh4)b?VJGFp;#EW`73CEm8ENN1h+KSdfDg+%FB?1px;!4C?9 zC}j}|iMEkty!rvk4()}KTZ~=ub``@06@p6_apJ}?BYUxL_{G^j%amh zNl{hx3_=f&c4v_QPc~da`JfOpTBt7qwzq(=RwZb?MWutnMrgH$@kx$GIUV5OkZ%Ro zA*4fcjzjBhs9e0rz5}xHA<~R~!nU4l03(n9)xnHprp7sJG<=`ER0nKQrR|e*b7@8> zMAR0*FHX%0ulKMdIw+_YO#M1pJ9~P-tTg*G2_=^(tJn7vC}_Dm%7N@b;U*8049}CT z=)K<%d5N;Y0q1wX{e(81I80kpusLDlR1BHh*&T&ZDzFFQ^14;z<<D^AaG&E_+no~J&Ok1Nb9%@{`g=R3)a#VZ^z`3sTjJ5s(D24FlWnT4 z(Boe3fBo;HO|fl5zSq=~C%x@GNy=HBt9N?eaA^J3k=>z}=hwdRy%v$dXWwUL(b{Y| zXga*w<=bYrT{`-wbBZi6EbgHq^tZy^(QamNV{+a9g^@8+nT0Q5jL5lOHCXy&usd7l zI9oPtB9lN*alY5{-L|zSl~;^%wl(>ult!t-%Yu{ZqRH}YE=SAh{t3bBFg9A1M7_9o zi~150kLVLmq^+%u!##iHgDuIho7uW;t_EUf`v>m|t z_a@;m)`h1F*HR0GL<9v)ZwoUsMZpc)!1S8i&u?1dx zF=(<)QjK7o34=(AjDUau07}wyNx|G1l?E+JlDu^arHP_SM`tG&xNE}lT7Nx0HYV%- zJ0JiL%q?VPe@l|VNa-H{xzNH(jDqFCz)t}0WgVaz9D-pN=Nw#dVCVST5|6_sb!6X0 zu`C5^17?zdnWje4y?giDfg)HGWo@sk%dc<@owO%xa77)|-c|V}zmGz0ZHKqQ_!>Rl z_AxCuCnRJ6glcL^g}zR!&)dbTh-0r>mita)i;k4^Csie5w4|!gT?)rnsOi#|Zsw$& zWy6gb|R6-BB?1SdVknga2_zxHVg)!DI{Nk$yEn*J*94?;mXa29hTK z1W$^k4FHxdufk_m>oIM+k3HTr=VY!8a--)Y7UtQm!#A`r%v&t85-AH@7*QPZWLQ zU0%dGq8)43+jS#iuUygH%Hlyp92BFXBT|Xq0 z?l}i*njJL>{!w$H>F6?YU_5rq)K@{G@@tVv?{taFhKl3s67)c70Ih;Dgm)JRfRbqfVYDj$@s z(7BDNKZNe{lLoXur4GGv)_&slC3HVp2A;we0B2cVt#pMpc+L}{BmLa(0GUBuHBg4a zixIS~x!3)gywgmVK4bq^y53`eCmIkdNL_vtVxz&9Bk0oI>OX&t0 zm*fq3m_8T}JiRzEC@tWyUFp-bfkN2$E=;Sy7~%ne2vs=P%ok8WyO{9#fg2N3F@Rfg zi+^F8L7!O%zwiPkG}>dqYytrKk{S4De@Rs_=)7rM9cmRbBU@d<2uh=_7vGpGM?0o24eqvSXEA zJ{AeO;i2cLs596du|fVj$N8a!@rWDiBdm|;e?>Zb3@_onP>P8w{e zB-Z(Pf237uAZngkKBVKRxVec+Qjd)ciYe8qo6P3L3xQBwl6~LLiB#dH(*rCUSWb!V zl1Ab~Iz-nlYU8Sj95$Rsrft-msVV@uRF_1M!gGWcVz$=R5!PZue~P*8{~TED02E>N z`5M9av9tgNn|Qo#V*so@M*}ViE6_COQy#-S4SG%`1aMKt53cR_U44C$j(LdxX7SRyTC_H;y%+bH=V1(%THEZbCwQuE1p?voV}MO6K+Pyu54gUS zFkxYv;N62bMidxpK^83PaW;>ZEdiGMMO3QLXQ5^V_c~1-ppFgl^Bbsqg{J_R6cpyV zb>eEqc6Q9Mj;L04Xi@mCrgAZOaj!xzG#)FR!3IUehm5P}rKL~v*)NHLMOA;N8OgPv zT6yLb_nwZ9WXU>ISs?}BUzXAD8JB<$|51n#bs7Dy+wTItJ=_yYY4%e1m z;aGdSFM7tZa~(9=FwKF6FD;&P&^C?}plLJkPAd7}D`*4RBjCbdX0{385GImw{NNf3 z?m=B$U8(Yv8oy|Gcxr(wG%+#J-yghk^VGi?HqwA5*ew7x2GC=-lX0VxlAoV2UFBU3xLm0_PzEjT(l%UubL3$0p7hjwBw))_X4kaK^am_MSkw6CL9tCE09Kd1Wo>CaoMe zrl^^rjd$`P(3tNxFp<{nMwyI9dSg;rtNHSL4Ph}+zD)I%;QKINYWdlX{ObgB(j$Te zC23^`artb~Cbdb$EV*J~8v(}ajI-;mx)$14V;ai8Z4Vz3%(zA+CL&}hEX=cqtQK@l z&fQkfw6j8}pEH*Vz>f=P3Iyl24RjQFq+B$3<-$|AGqXYLMne?YiM1GNQ(P4OFfA?I zpnD>p)q%CaJN<|FC7*|G5@ZGr-PzAgKuRigJSU#TbKqOBT%FNM8&10{&oOG{d*w9L z{lT_QW&14s#;>0)}$P?QV5sifg&}`aK&&~%TzIZBcCOeB&|uf)z4|BNl|k$Puf0mW2-I2 zQpkNsV_NZeF-b?=r7XF1Ih?A_Nk8B^H6xX;hCr(EtCs0-?(&TQ!Bd1{|G9+APlXWq zg!J?r;?L+=Lu%QDIW=)p{Jhr#p@YmbO?_rbSZKdq#QGsCT(S+fS2vw3RjYPJrEa=; zG%PRmy-&WHysL8p5A?&OcC2Vg7}l8$Wy09zpEwnYH-R$?hX}YiL(=x%);LU6n7}^7 z;XkFIl9Cb_)&`3LuLc@xVS^$V`T;Eo)@ha^m8Mu1tlpS8fW6WRe>L*qXRs!$!Wjc| z%+W3AafK^XbI|9EdHadD3Oy!MU z#Ds=o!H8o}52{Ti7bt3PZLQ!LQ3v7}Vh%@K+?PT3A>}P?!Bz!|hgf>u&-3 z%Ry&Rn1Mgb_ee96h=+M4voyE-xP{f+;p(w9 zUzEd#D?$S9Lz06TAV1Jiz%d1ci`Ic)AD{c`pHNj34hxryT}=I*nLnwmVhSQ|2WvNn zYO5LDvB3!;WZcPzt-T%$9_a-|FP=GE9$F`+lh+rFf3ufBdrTmD&ODtaQlIdl1s&UQhjG4_lPSN2}kkz>S-t=8v+8<}-YJr4JCNowDARqna= z;xP#_47eBIri=5xXvq`))vwUJ{}hTI^t?J>CP!jflCeHVx}A+iXp?pi<*Xv6HtWq! z4(KgNLhcUMV_KFi&(T}dO3(%$a(n6_8RoUx`u2&_d*XHVHGZz1XEl=l)Iu*TD!gIZ ziYvIF4{i6dlOr&-?TwfW+WItHzE<6TN<1`J_5_EwqDlgtYVvMe-5@=IzRqfm$!ua;nmg3^mNa~f*JeAe+Vrq)10`u*JM8^kgn=_~J&a-qS*?KIwt(P<| zo(D7RClwMm<$G=UjkYR1xQq_$TxE$P<~Ih{%JUvL<)&2^tt=o2j`Q;m3LqFtLd2(B zU+A#qo!PwRc~-U@bb0ktNm0SJmOWj}x;-fpS^cG*9(le}%>f$WLvE2>arIV{mh)OYcw8xR#VOroZmTL2 zX0lN_@7BNX=Nhg~FI!Z}{*L8a{{FyoR(5o5;?ij_{Oc-7~R??vxb$Z53 zM#JTKMUyi=y#Kkls4)G(V#^7xJ?UG~iscQ2vN85t*u&+f+bJxpSXG}F-c(EAVU%A4 zNO=6)Ii5XUUP8*TO?{dFPJumjb6K`mXML)lb+*h^fhf@5>E)A_Yp!>mjIiGrPKqj< zL^|4=CA^sTO)K@UGhpHB?U^}}m<}I!T zTit4C;iogxa&u@m13b0XGPVN2BX_(%Lc);tto7&jgfyO% z_W!w}uccUXrk1%{xID_&8mO%^N)tMNrD0J&b@%RFID)SsKujVsd-eU*dPZUgwV8o! zzFZObDifpn7RUty!e?m)Gy}db*r1Tpf%=~6vi0uYcPN#@^Lu#@lpxcl=$GCZ1{gxA zKp=-YGo;kpLvQbb6Lu3G7KY7v2B&*u=M!jxj9CNVtc9}7R}lP1nA8J55Cz9^IZ9tD zzN@i@8u;dyvmJIyMqsrQQe0H8Vs<8RD3PsP9f#*FbKDO)O-|hRd|r<6lLT?EZZ6kr zTfg->Vat3eUDl|tdD9*J<%NZ+3kxqZ4XIvh*7T8v^`>L2{%-4<+iijTpM4)>V%Ziu zQe^9E`F@gkA;!ysEz@*D>^Fzgya9E*Jx{+^9ekP@bvEO3Dx`-ME^fb`Ta`bWWG3?H zk!=84_H5?u@LQM*3#Ebo{WYF`_yp3467>_o0rqeYxy5=4!`2^1OO=Br-t7-asq=Sc3xlL{j_?@g+=iA5!h8;czw)4E8nyX7 zu61WS*!e0U;=!TJ_%#<^WPZ~|)|7M@a?rrtU@W`!~-)z!}=pK4+?45de-`(c&w3yW2x|blkbb)ebO};Kgn}w7=60N zOvRF0IDFC>sY#c}VQUER2RSs%q3MP8hC2AP9v#-20H$;rc%#^vkAPMMsTgps0@pK| z*PXNUHaJAyN#VWy_oBO^n5 z@}@6JJUSv3a%kufg9Wm6db_QCw+8wZTHQH4)0=umniN?vZt4CX7hr1|2*0hKqxs_x znp?T$BWrQkjK@+*6cB2Y2JK!}YpZNhw;Ls|W|wXn@Ab#Yc26+R)?}nkFShM8s&grK zQtr4H+m;|dAH0fT>TFV+DwSaaYe#zB!svCh6z@Lzy)jpeara(49;x~(jpsql)KpL))8r+d~8?z{?uPR8ud_b+Q^5uc*7@JWfMrSZA*?eF)tBayz6$PFg6j1a{1g%l3W znI!|u@;;J4LfGv}7Z1bUdZR0Nko<%|hXs+UW!)&v$Lgg*siH}}bDnpyuypDhG{oRA zm-$c2#WAI^xS;6DxZ~A^NXqSB(Y=i2`O^Z|4La`Cf0MFZs;JS(y(^K(BEcUsfS@^M zD-R?a=nVfGm=Nb0G2rdI(p?tDS*y}JG{v2y!j|yShNZ6&Qb`!3qMxQ3^RX0 zWzW%DoaQKEHDBw-x3*jE5?U2R!yslBxpDWYL;MUvejgygAs5Am1|A;s=L)MoV&S=e z{eX5ij$P+>tS8$-z7ZOI;37Vc5B0jp<;Pq8d9rAu|ChSv9>uj3yEoR6Jy*isJ?d39i>5&t-syp9cKzh%U zUGP<$Mu~+OaeOfo<2V%-S^C0CUaW}MjP}uZjSJX)nda{tJi<^;e3(s?m3%lkD=hz$ zjsknFj9S;kc+I7$t zr=-4Cxkq_rs!^)Z=!=9r<`eiDQ$D2Wm1)W{Z5D+oVV3iicxLjb``&TE>FdL+1wPY(DCt^GHp_lRRYiHkm9bH0 zbj@DkWVT=UP+CXyDcj@xe-7=3XWjoBiqEvJ*>v1AQ%6D>r9q(3o65 z7d5&+QG4y?o3Zrc6BU0tc}6_t{7w@?;X6W)Y!0ook&_u2J0>eadZ9QhW>b~+ zt3yeP<;Xfbr<3HKr-BV z7VQ4MhqI=6=igs3|M|h&9}E6J8KM(j0FKBj1fkg^=Q4E(I4`hfW z656Kb4|;5uM|--HtR};`B?2-g4wf@@mi>-tQ)h8aJ!QzguddgQ@i&V@LzRQww6w-Q za%CI|SpO(#b#f83(b3;*ndMD?CV%o~yRT7XmA~WRL!*FL>t%tg93x}n@tt$=uxs8m z8La<+7}p)k=$&tuzs>k@?R|i&R<)f)2O3t1!^wXzzV+Pr_0a(IVZ-s3WtgsL-S<8O zj|rwA1EXR#oD51h6ibl~n^p5XGb)J9?egvxX@S_K<#jr{B6M&K5ooNmLa$ra zl{!Y+cTKupmk2d(ueO-cor^o~gv~eF$$i^#WOmgin0Q#YMwXt(*lms-^Ql;9O|D+A zQpbAox~S`29rh!##AKLPDu(Ef)G2btp_*AikUQelI&5^L^bxDbn9d?ZklM^r+M0Hn zHVs%CbDMk%Jj&lg+doxbd8TyopdD@WBgijDZDp;hZmxW7O=Rp6anIa0rL)HY$EKe- z>&~~ml=+c>?r!6{eG;HPnO(gR(WBjTqseiKt8U&pFaeqgtWZOlwCKgU7)FhX`;CJ` z8M%gRpQiQ*Fs^OZ4hp}x@~h~5H!0#KqNk#q^p&&|qzD(tvX8ecNlZ>oZuqa;IF};C zjGjo*!FOM*(Y0oGL%Fk~<>Hb@V+Qw}*FA6T@$N=eUy-;W$q>g6u-2q{_&;mZOG*;n zKibX`ql}heG97ZO!zmI^tJ2^OlOzupaNa&BP5w_!0>L_L3LKymb??v+Gvep8>u{^tURRgEn(=d+1yUpbc$x@&D9+V zT}7%Bu3hoQ?a!{-ZI5wT{^;pMCTNY5<@yWiPmncCNKQCqKu|w*>Z_$ zq39n{oHn2d2@S`?cMDw=oQbbB8?nz*8$FJ{;aT-8KMR`nR(7w{)E_B68nO$h=96+4 zKW5pa;!HP1uXBqRw%)niEcpD65|@-}s6+^B<6(^(VPBGyVqJKE{ozROOI{Zz@)&%x zk&tm>zH`yV9W57!YtsYsG=bM{=fbmu*UXlHo*D(lrHk#~RJdt6J(+WvW69H(L-dIg z`bV?c4D?fzHyfryCw1;L^2ssCrI_5!W2J4~I?-dRKlc-QBG)rHJKg4>*<+kDx@xO| zMUr`Ty>jHPkED#)Vho=Sfik7aFE_`rYoF@FQ968Pn}QL3ljLjcr4Tq<5QiW$#5+$SC3#dIW;ilBG33&|4Y%1i`#*Bx+c(=j?Tim;>?>?aopRYOcbZ2 zkR~6`;o_I>{9O1BTzPc_M;VnYDxRevI>O+^p#lakkAoN8*-;;Zt5$6JME}oP)+wEH98xH~Qr-VtI_PbsKtcaP^>ET189{-$7`|kQK z8an#lOR}q$76C}}`vV>XY7rm4mHB_ka=rA_+|x?wkGnoLH_2}t-lbHN3O`sVw~Az# zX573$ueBIPvB!ZlN=rin()C>ApL<- zV;jbdIr-j@h6sf;`jaOk(P=-$N6Xwbo(*3t)eaMWcr^=(78r|8f~Kz> zuSZJQnsP|QI(n)qjaogM7h}}125~Bwbt#Ok2DaoI_2dlMQ$;rCLXY_8ajyfJ(24! z<6pez(n`p|$>Fd)t@Y!Qo>Y6lxy&oAS$|_dLi{Xgk11n8@a^tsXnoz@lI%0Y)$*#2 zV1-Ufe+{Qcgwt?{J+HiZg>yGpa_RBi@QPGw zCIh-~`OV5{5{}EpJm$CVS}*E$4Ou6fpJqEM`$QP&FShdGzRgb-57wL)Jll_Dv)oWQ zQRK=I3i;~ueV%$&n{Fnfpx|?7Yi#pte0DdViF1MsWTaK3&(n;Q5y@JzZq250>TAd8 zkbgxqt?^Xx(PJ~CIRl%Ee7As;xel=(Zf@(6?Z91R=iupj@Esxtw1F51qLJ5>*C;g@ z4AxPz#!B1ee5PA}Qnn@qA$W`q^5?tRW})42gL!^}%SKlAS|CklqWg)OtgI|(hlK-& zx(&QK3`{JJcVY}~-_gOQjE<vbX?Nyvgk$WYoUmgjnn`0{kxA{$|nb$#53PNDtD=oxZY z(mb=A;IHxV+N6S_Zk;oa*&mtN7FtazioI-EF0ML8$AgTVk;DKFroIe>BirmidokaX z78|GemXDVdGM9&nNK?E-Ykz;lp3E@aWtZ08`M?)rMvYQz02fQ!{lo6~!09f7-9C9| z7)xG0t(HcKC8=TDu(g9-|HHe&NIQAWCa-|kaw~NpX{}F^@qe}4zl*Vn?Zm>s@S5eO zc?_$5X|@A*+Umzlj)cUZgV}uf=H8CJw!d`r51s-;o38TKHi{s7PVxxJlD?&4Nd zw8wVi-5l6hrjuWvUdP>{?~VJsHd)YhWJZ{{d;i?c+sctI4XAGxmz0O;{u`4>pAe(> z)p}kE?&ST^w$?`WRY~piKD-_WJ+0HF6G}UDl$7UZivx@uz>x!Hah6VfUEX#h4I-)Q z*leQY7w7t!2*mAhTQ4*XghhHkf!VrWDB2ZX7nm{K2?ydtlxmDgrbaoVGQQHo0O7+< z`m|0aFp^T3aUoD73JOe^#PA?A^zos@3?b=OKikNrC7@hi75`xGXxc-S)96-p;qlao zjq5UPHY6-+I`odqHfP1;z<@yYcdQlZk@a0~ezOtz!Taa>MI zvfC#xe?pGeGcB#*?;GjrCY@Y;)4t>Cj~1V}vEfFpk;sbR;>)no?j2|!QIVG~qBb@% zX}REc-+HrkCOzM;t7mv2H`l6f6!=nvMo-3}bo);I4d3jJN1B8V@p`e? zA{oBO_0z1Tt@JvM#ZpI|(ZEa9aaA-)0>m{L{E#F5g%wkIwV6P8ON4Sn+MrD=%lQ%Y zG-=h%p!Usv!-K+uqaMa#zR07Pm{=Y@!zib#gI_8o2#!K>eIYcrYI~|(;_bf5l!~?Z zfPm3N@5`kx+6a121*64~W9q;-|EGhY68_towHNKKInCBmPWFB_?9&$~P7Ym%L{%^G zPf`@0z-=6$V=gx%wKjunzh)4b(I^+VicWA4B8^n;nRecjxRzLGon)m@+os9OBdcfC zGLlLDlNX{i$8fAq=v}|TQxSBg;5&}~ik1E7jF)sip8Yoti=CN2b#at^9qvU_9(Ey( zx)J(;m5~S5{#2lr+p)IM8t@^TY=(eW!voPVpg6=RZv_2ErHi+}zyD0=nbE?6`08-> z@J1_vXPg4sl@!%=*7W;h(tGdSa^&n`J;g;usj8|P8yc>xtSGN!qr|a54g;<=4A@G6 z?FIT_PIQnAz#zbEradGSM2o?}a;mCpb8{eyU|Jsa5l%UWAP*h4LOVkc?I^-|*M#_Q zyEZi=BQh)u=+;1)7b0Jaa5bU~7;A>K5THarfP{gC1xjrQvnqp^kPdRXw?`qhTDqD)%h=Z^~POdO3 zON=q(X|}jl`{$) zj}P$^J?L@Gr|;m#^3eX87A{14$#=(MRVER4f5Z1I#0qt6BsTUF>^~P?FEL5U8!!XTXyf8!56kU88Z(g5MVGJl)XHF!L|JE6dG5oppDb z{+mO%8UgWodDE0eC9oI*?T5v;Xbw#c#eB`R1}D--5<`y}5r&4-S#A~<`rAvIDxSN} z!Gyx_f$;3^&}sd4J1MpxiUfmXa=rUkhP5TZi}h^>~_uiJmu*!V00}n&^eK z2!!Di@L&Mw4352xzNGJr+0SfjB_x=}CnmBLvw^YzG16d60Zh5I?Nu4LcHthb1NPiH zxuwN4SQ*5(yDx_~Ki$=lmrs_@8Zs?~zEe~(OhCkBbJDB%C zsu$32N`N{wfgTbPf?BSYmNOL~;>UND+~pAm8v_zDvKQFcuysm+SJ%-Y?)o{?Hs6j@ zR#OwCsCl++z#*@5+SgN72B{!uO|-w?GsyL)zxIv@Be|EE9F4h2Lq$~uil;aZTadTS zf&~QRngW-IT6Ys(4Zy%qdUgYKsHrIxHuo~#%f0)0mUnMm(Y~bDjssP&s%n(OA}R?A zTo#nQSU_YB6w;dofBKS1uodwD#eK&gS}H1(O4YO!2;-lC&NLAKo73fBNeqJLKoF5- zyUKTmXl7;x+%9|q0!mA0;wkna`CKxQmxqW*z~rNuS+(n_r2*kKDv+(zG(0%C5V##M zyaT_U_tndwRt9;a>-Gdo=|%4p=i;uYq~wzH!JUtmmibo|7nivfrc^(lbt*V{=V|4+ zmJQ7-&Wa&3D)O{wuLph*4ZGtRwK~jfAI+p6owl#F-=6*P1ONWD$3<-MCQClDUd3IB zbJ+58;tQ7t2VX^gOsKgNyzYLp!OlKp-8Xsl5@@#azM2`9K#$y9<58oNknm@u$G(XC z53WAXSfs5{(b(JV>bs}pJJL_MrW@V5X66~DabE$jc%k63nl@z_B5V4 zss~dmsVmf>H&kurnTc9a#{fW$oaQ0Ie2;vKy$u z51-oh@?_Xjfg@M0ThU+QK%pYY5C+Q#n0>rt;L_00Ae}1(@tIZqwK6xjdl|#vL+Dix zFy-Jc)4K%rBG@P7kfZ?b^q1R6}9XGj387MqO(CM3Jd%V|vV zUG44bAcsNJ-%tViCiZMG8_2LGty_YfuwP12^_Vs~M&N@!E2frO?^AQstN7DzoZxmKM*2Io z#>nKrPpueM78yRZKGkyFO8KnEB;=$qV46*q zx`l8e_(sL6=RJA!XfSBpSKC(|9W?xy4AldkF2o`+F)`_>sZOr0n@wBd9>xnfANt_#`6;ETkH^s!!q;KHzUFxomH5*TRL_)+V~WoHlWDIg9io90yfN6tD?_ z^t7;`_w1v*uwzG*c%HJq3pS8Pz=G=eu?3vCc(}N(D9J(z2rk8`X)@B&fr}WKZ_LEx zde~hphO3gRDyOL#7ZZcBx+^4wld)#w1z1bS?KJrLy#d`2kmtL=-vk!QeLqNYB<11) zem?yA%F6HvqVY=GjI|7!PFQj?TtMVAAb;AbiL zXa(^!oxt$NCf9jPX`t5A*7k~x^cU&O|8W5<<9tl~F1tHS)@SQIO-)U~feT2O7;x0R z39AUW21LMz7W^WrfH4V7NcfJx0-GNA6(JF^w6d}@TVD@L<@GoS-#6k3=i~$-@{mei zQA=GTk-#_o#>^m!ewh*nv2x3GmT*e4nUB52_aC>w2@tOI z#C`qxd_aO84s&2s@*H+Cb?7||7dJ39RaaG|h_T<98i%~ZfdNJk_`ZGnrzCKuKo_W^ zAjBnl(3vV0DkuY|N>lAfTU&K>C-A~*z%~(>Ic6F#HsJbb4)HuylSZ8{ zTwGjw4#P2Ll4cVl*vm9jTIl}O<3_pWxoo>nvQ0Ev-rW8PRYJ2_#57%DtgL)+;DKne*=7`&dYtU+J{4nN z^9B+)`Veoht?@xyD1}Sp0+i2CTA2_K5cF${h>5jt45!&kgNGCwh%^g*;J#H9OCx7Q zQt4;IRpo!m;c-=Q-^m@U8KDe#VF6|!&7!%WWb4oy#^-VINzxJ&Y>L$J0AZFagND=+ zRsUwc7F2-P7;f(FU}pq=aht$jUsx!zTbD1K1rZMvWqw<(s7uaB_){R(G?sM0)GHh~{=afDgg}ae=VY`&Sl&_(s~%Gjg9jWqTYRn+Z;z zhx_|-G1FBas*~f4)8przKu^0cvI&)cY3Tnzf(~Td6;PSM3!w_nhQ08Z0iHkngJ2Fd zfREd`P*`!D5D`Jvq6+8m^SIlJj{pd}=^SQc6jq8zxK6mDq|C0UNKMZ>o{g@Xzx;t1 zNIb6Q9d^ZkPa3sAWtTJ+W>Gq;r9j?*=4sJs} zJs6Gw7on(CEB0=@J86g1Q{niaBB zqfqImpY%vcN(zEc5{;Y_R6-t4X=j~RkQ91tuNvu!B{WV4L9tkn!@~e8=E@+E~W-h)qMC4xG!@`UdEeifT@w zaHO;9&;LUcHCAPx6H-OO!Ql+b8KShJleNNcrNpYo#5kM`l%0m*XkeJ2Q(`O! zFRytrA52|9bG%SU)0zDKGyEr^F}a9k_|W?YAS05D=PcE2^h!4NQngFgx%WRO=6(9x zx2O)L9cO*5$56NXASyfeC5E6LHY6a&hkTIT!0`{Ojil4U^n3yo*J?Ezo1(UsWWm0$ z>T10{V5rh!&O9i_VuApp&wlK6eFJJ2L=pn(V*bInaY`T9P#zf z(uD&KyPUk!JgXN1ZkF0Zp@xTX07xPg3^#lWBBPYke`QUSR%`ssYQcm0{1FC5P!Jrw zfd z4F{Qsp2L@Ko{w+I=7ZT7!&}&h)^>I@#nA(XaQ}8>iW1(VFfCR8r4E{wCR$BvE;+)Y zLJHeWcoFam7esm>o?S>2u6gi;t<@IQ`vq4?_7bM@LDYTm1jBfH0`NPu-%wPf#{d(V z+rJIeXmp;MafCOc5sjo2BjKWWRwAD>3^WpGWcA`wmHv@m~h1gU_YVpM}>;ZA1A}~N)3;Q>mF{Qf=SNMrJKWTr0YHs#vl|1yo(6(6C zMnXlm!5s^_1D+nmhy}l@@`t1xf9~U$szB}+zk708dHE^ZtXm3R*wt0wz<-ppZp0&u z)P({DZ>huv;J88P)aSYc{n!o8gECl%U)X}?5RF4aF z_7lYEbmQATLYWe!LEiEnz9vzg7+4~~H0d02ioSSL!#ZwCXi}GE$dQ=Z#m-SKMM>P6 zrW0IuIKsu#h64Mt3jgfFH6z1w9Hu(T0X4~Lf@?mgs38w`YN`fsl>PmE=tG~ozT6%E z!+$3jVF8)3M1ND2b6(P_FRibu0jC!tS5cOZsI4R4!VljIpT#r`^EE2L9DIAJ+e|au zy_H_y_!=}UkbsS&<;m7K)NRVQie~Gwu$ya1&TfKv573llp({U1>O#YukP_DUl%}6%9*e zD03tvV~Yk>B$5mfO(IjWvD08GyOk9xC1oBXA(Vu6N}@6krO1#WlqtODZTG(4{=VaT z|9!{z>-D3pXX`U$rwUI86NK`y>!6PJ#d>`1C0Z9hXbsK6Hc^ zi`m_%Q?@PRjB4k_ut|Nv=~Hw4H@3e{{;^$p>(+yub%?FpmM|O?u9LaRYwZ|lUhjM# zv!9(!j-a>Y|3U~-0q27F*hV}}dE=x#SW5ZduhKrd8MC6;cRdA%Jv}{rd>#Y8^Y_;} zbm%jv*zlo1hZ@>0Lq`I^H0D`LpFjW7-VSWwB~Xk&0f`Y7B2`2vz1Y@!leaX<;>!^d z3UH+$-BkwPC1xSEan|?!v9@lISJiuoCCeHyYF)F@EhhIUs0vkli=6I#* z(2lucD-l$2%jTp3rLqZ@%QPxGZsTvk#uZEGt%Yr0eZr9OX=@9@vxXU6rW@ zNYia=aMxiTqu{pT4iP#besr^m1WWG4F5^DNa#c@5exoR5=NNx~e|PsQL8oHGb&Rpx zBmuBH?gM(@E$ntU8XGiceSV{cwB9|37;knA01=1yag#mzS`91gTWC-*o!Sb1BZ zTvtlrn{V$;4~h>pm;5fZFC!Y*3IW+&+JiDD5ypY_^WxxP1bfJKO8-blI^5u_!OL14 z6dcU5FE`fv2u3O7bhUj34i24*cdJ&xv=RI*I@+rE+yZD_L-0BML8J1PEy1IX@OBuE z3Tv-~90%{WTpY6yAz2$x0W~!9yolBrT*AnuIA(Ufo}S+QcQ)|1xHl$E95@cn1ty7k zbM|90$rPN(SKfHQ>Bn56(Vu{32Pd+Wvcr76P3rFvN8%68(xfdnV#NHJDHY=hR$v5= zJX#8N4b2$#*743jO%yB+tJyQmQ!VpcV)bLIUx=j`cGQSVo@Nb;;dZ3Kmf4T?3QAQd zX5+ccYkTtUg8y0eSe*>7vBbuWEqSL7`^_6)4bdU=f!Wya;4`Jglgmu5s{BzBqu=sC+p!0mn?X*O&XvZGxo zk#*qz-`6%!yiht|6G%JsP2JXe?8AU!wqP|Nev;Qb$27PzRBRC)Cqp7Lcr zaCM6oEkdRMvLp-*EMCx$VP#&YsWf0`GNIo$Y2cN8I)@?lG^|9D@c-2O%Payge{r> z$2jt=Qemv-Z-~=y93&TVmE3y>;zslMIob#V-8ZSgtN-S26yk{HL%_t~$x8pKQ}2eL ziuq_?O01i!Ys&tdv>zKwcADBXU(7Vr1Xp;CB^N0A2K)pB1;KL@pp#gB3q0Cxp!c<# z3QuU3rdNYUW1~fG^qej*YrIUkZy2{!-oA53IY6>XG%|q0eC-L}>rhBFHxCLS4ApIF z%M=`n=>LBiRxl!}th2zKK^EMJU|J;@$t)yhyWc_~Q z1BubGvA{sjwiVj)+2(~nc(94Y-%^l$1y#OV+`EcMdA$%*Fso@7RF{-|1|gEbH|0`T zQpCw?<5VP?-CbQnE??f;Vi>t22TyZ!)YDG)GrTXTb#=atPV_%%1sLPGTu5jXW;rm@ zAEzzmR?0w~Z733{IrHX8*mfa`(OkM!bhC@L)V_Hu6Aqbm7#BGNoY{lAXBVgut}&T5 z$X3BqkJ5{rL3&(#JcdWgs;e_mhXDkPQ<%K6XF#pJy&c1+5rB{C>m73nPkz({hKePE z5rXD~gOihQYyNsEDGa$@0~iX{!Bxhw5xMEZ_Jec!H+xl5?J92J=`34hU|->p&>LU!OgO6M0Is_VY#vL;63LreGZ1u z$HyBtwfA+v6!9%y43`HN2PYmt$Ja!3S5aNfc;%cNa}`s#f}n&3Z9mxbIXbT8rQ>K1 zeW?T~CceDlvAPV5&4QsAa3+YTjrRT#usQ>gHz@KEH+=7@l|FSS`9Vl<@JmeKqEe8R zbrhI>(T6Po-oe`RO2ZC6OwOC%(@bONGxLK$r<#|aFS!#eXgaSSBW!Va^7`GoVW%JU z09bryML&-7=sZ5Pu(vo{6EtY%=%%RUDLTkABMnMLy9#szs(~!R>Y5nvcN_PdTHPH% zXKK50COn@1mjapL^{8Hwi+;HS6E&V)kR*8J50Wgia#znOnytIY1@@An`f4TxO{Bqb zvof>R!(PE$dwU6C)?d7aYss6hAT3fV4{kqSi zwn2Wv_FBm(Dz>XqGRx;Q6FCR`_-ny6%>2kGpPLc(_Q~yko7yaxI@aoGhG0&DO)$w&MAk zx|~LTWD-&F{P*r%-j_;Eg>?ga1VZN3NMdobhEL@fBzvCUk}je`jzzd zPa1CP9+$OAa*^|+>)#_l2`Q5W_J0$zOOnpq*u3NOzkf^J>(ctTmek^#24+9`bQRsj zCBN;pzMQqQu+06HrL4I{y4CVrOE$lc#A3_v`*5ikF!^uuzFc><+razx((t9aA^74H z`QqN>i(hC9T&tG4BXwizjzhB+CM6n}1%^AVHIFn`tGc)DHZ)Yc&UatNH#A;2^X}r} zcWqrAvuX4o{RQD-k(G1b2TQ#$6934gsWp51oll&5`xd$6$R%=#;LOV03qQJ5@J#L2 zLHRXI?r(X~UV+=yhxL5of(wsI*ZO$7hR#YeO?Zs&tl_qeEcU(&IU<|MiN`adt1 z3qP^8H>B}a7;7b+u_iz6#1U>E&SyLp<@zC&0fpZ3Mob!(?PIE5W(_BvY6Q9CY~8v= zy5}=iScMhyJ)ZbctTdK0Bu39nv~H|ROUyd{+nHpQO^Qd}%OpSbQZQCDV=fF{=p|0XEGq$T@0`;Q?~|iauZ2N`wyZjtH-q1OBuD7Onu=#ZC?nRpbdb8wJC{QRHW+8E9QyXJfa?fluZXYpdf2spKYe_a6BM(HMiN*8d% zRa#=fhbZ@=UCevv%yH{)iE<*JWuh8rKkpm+m zg4~)<6MmPaVo^Dba7wA5po2D zq{#Ub%H!yGYcfDYF#RqD&)iU2!2*w8*DRg6=3r!2cX`u%yroEkL@Pz3UAuE_lZe9U zU(R=6`f*M;;zdhg8VN?cmjg&GSYt*yXly}iAm_vGa@j-CI3Vl*p3&*fL!L;WK#UoA z_|~_9fj4LPC=rFfE&B%}G*CT2mj%F|z*AP%)>UXVz;*%TlmF-unxdWnvO#dnqyg3k z#-ygGs0gkKP+Eh7R#nvksJ5VcSG65fRj{SJZ&0e*D!R02bTBj{zl>CHC=#d5ns8osO0mMWGPx4k#3x*%h-0ha-`)UdY4V0WyO73EvCYWLdfL6um*Ac@)wrTh} zr6Dl0?}&rB;6aJ-B2R!iPG$s84!SYX@D(3)nE+!TLF9Scr#|sj9&`(ZYbir9p;|Ud zgSfkoEBy4H0`mr(%L)$%ga>9#6;aXK5^9|Q6Lv((iK(c7g~|(E6F`fqj?SW3q0ZQ1 z#6bzQu*rCV+7r(Ny(M6`LnbaD7zI@nRqxRO$WZONtsVtFmMd4Bp&~?QBI!ph5ZQC% z14k4h-vYk{de&Jujta-b!~{D#y8&|;fi(M^Ih~4Ze)?s(I6cMgG7_Bq6l&x4BW25+ zqz*iKaMqTKld}nB2xJf~@^*xwHh_1H#O3D|x3~JDn?Sn{Fw@^2uOBbu0xJO^^+&!U zlyE2ufH*FwMScVzj{=?};15Pg@>n>f{ZcNARO%|DX&ZeH+vwn1T<}&KpDFIZGkD<_jj}|f*2YsK?DHoZyQi3vFM1>h6Y}vqTLz>dWq%${%}rBt#M(Z@Cik#o6N&@~vg4L&eMJS~RU6l*>_*#hdQNIND{oJgT9pZT3oD=rTl2F9o0Wo%t*x4x8v0VEflx2L z`lQKzKeQoHR-H0j{g{q31!75alxr8}$rtkdYZcI~;fNGxVt} z;N*N)zg|WB*PAo8FVQ_;%1?zn!>2{vya~=(Fkh9jc2a$J{r9ktv5nK)U0epS-9^iPCrdT&GVx$0f1*F)?b|G152!_aYYlBhKc+sD26FAF zUNl$L9G&3l^w4rOah>RgY9Y}6P&AaSD?c&7MQG`Vi3f}3IPK+?W?87RcC9_^FYLRo zypN!$s5G4cJlpNzZDnW8^j@v#R<0_Os$P!uRVspl;UFq6D=A5_ENsAE{|W6^iVEFG zysYsCU*Bn2+p>TIKPyHLFc{1k!>-bZPNCG=AFJNcw zG<`-<-5-yH{H)RV(hV<0S||He)zl^@C)v40h#Z=oEl|g|)zv=e*1)`vgA(C@hj(c? zqv`4`yfj*N_m0_EhDVm4fn6zG=h&P}l(i+Ve&R_LN;!&zY^}Rsl0r1m@s*nHq?3va?JscD|5xNSM@VS2Z z67RY9VfFuAvlh$Qc*+wjp5}RdPXaaN z`SUuc(xLRyXNgh@v=~KfE}r?`?e?LFt#?DF)P6HFM}_N91rEg8PkK9_VqwYTfMf)S+>v{I0T0XPwSPvLMDwW`fw5!?#ZBGVkHQgVw3j)d?pSZywLb^iqBH(eP?( z@-0|MxdD~nVcdnh6-q0JC{&u!^mhy5KK}h#_!rc+uA3kf3j`MJEv0yDzivR3>=({= zXtoDxnqlqlGjeU?fu#Rwr}crH2@z#FF&ga{0vS+nszm+r!Q(|<>ej{Q5WaRFYeI|# ze9_{-0cp#E1Xw`)Omk$ByS6}-aE0cG;?THS(*wt=w{PEW>5%w{;-+ZU9+kB!P=TkS zU5JG$I*E`EQpJ+$>OKg)#-qrm&fe|cEl=nQi%NsE3AeDqdT8?nEqV%;EIe7LS;9j7cb|N)5UvqkD`&=)Z0l*v z=|?0$qhFV^3!19f1XLDnVkT8b%)q^h-@2ZEJ!EzZ|BpsTG`7Z`Mm_GIgGfz^8z zA_hcrsGMxb%0U!IZn&jmVx(L$J#6Fx*p8tk_+xNT1tN$oS8*vN!A=$_VIGMv!Dxzx z1=K0R>l?AEq^pF%XwG}|i2PO%(Tvt(;LxaPZN-}l*Ujt};kRgXaM^_9=_Ga%8V6CN zghE9G>SM5V!xKGyeGvb0g^C1p&+xUn)O?-rMyJB>d(l9fpMNIu5)A532ukQP`5|D7 zM()Bde|_?doj8uL8%3SH%zH{Lp0-`pu>!7JWMobPfJKGOt1>JVGZ$-gL*~z)zkbNf zdg|vGYPnZwT@X)7&lSV{`T2&DJ^DV7FK?Nemn)(!%xOdq!TrH)sbk0vF+1RHRJTf` zR6&E1Z4Mr^x3CuoV4xS6wJS=+D}Cy!)Jxv)?LNo-e(z<|{7}pt&kyEdsC=VGZw3i@ife-;2hfy;#Jur=B_}bI6Y{iORlp-Jo zGIMf0t!Av+q^Fk`)SX>G{)^7VeHlf~&8VmKvd-{>Q{ThG;~<)#XEwwZJXkP=TT0^3 zQ6@9MvoUF2^zBK_iMe}Mj1F&dUBQu|q2U+!VzTub2xt*_pzh;8cnciimdI7U3ljsC zU`|X%!Vk!k3_N8QrO{~HnTMR5rct&7!*DM09|6IXH)~%GPEAf|X=!=%Hn3PMF**}R z9u08hc+?WNP~?wPg`(E*{#Oe4?0!Z@CpHxH7UB1y4@{WmAYq6RF**}54ids!=p{#g z4TwrHY7QEkDu5ipP zuzk!o^F{(yQ=eSXTYyg4+bV7n5OGEk1TG(qG@u7y(ohIPrzh(2sBpjmpz4x_G9PSf h`we^oB{UySM3i%G$h~Z(_9x^Oy3Q``G)=3s{{Zgq9Q*(P From eccefcea7b359bf07c95cb5acd5661cf4ed8da49 Mon Sep 17 00:00:00 2001 From: Thomas Nares Date: Mon, 28 Nov 2022 16:25:52 +0100 Subject: [PATCH 147/310] Add currency rates source --- faq/pricing.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/faq/pricing.md b/faq/pricing.md index f1f6ab139c..c572d3a56d 100644 --- a/faq/pricing.md +++ b/faq/pricing.md @@ -12,7 +12,7 @@ title: Pricing FAQ **A:** In PrestaShop, all currencies is associated with the exchange rate for Euro. -These exchange rates are updated every day by authorities in charge of these currencies. +These exchange rates are updated every day (at 2:00AM) by authorities in charge of these currencies. The API used to get those rates is [https://fixer.io/](https://fixer.io/) The PrestaShop company gathers these rates and expose them through API endpoint https://api.prestashop.com/xml/currencies.xml (URL available in the code through constant `_PS_CURRENCY_FEED_URL_`). From 3d64e489c850fa543fed6d31b1bc6910634c02c7 Mon Sep 17 00:00:00 2001 From: Thomas NARES Date: Thu, 1 Dec 2022 13:14:23 +0100 Subject: [PATCH 148/310] Apply suggestions from code review Co-authored-by: Krystian Podemski --- .../architecture/legacy/legacy-controllers.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/development/architecture/legacy/legacy-controllers.md b/development/architecture/legacy/legacy-controllers.md index dabd5ebbda..fc7f80c883 100644 --- a/development/architecture/legacy/legacy-controllers.md +++ b/development/architecture/legacy/legacy-controllers.md @@ -15,19 +15,19 @@ Legacy controllers work best when a Controller performs a single action, for exa %%{ init: { 'flowchart': { 'curve': 'stepAfter' } } }%% graph TB A(("Controller::run()")) --> B("init()
Initializes the controller") - B:::importantStep --> C{"checkAccess()
Check if the controller
is available for the
current user/viistor
"} + B:::importantStep --> C{"checkAccess()
Check if the controller
is available for the
current user/visitor
"} C:::decision -- false --> D("initCursedPage()
Assigns Smarty variables when access is forbidden") - D --> E("smartyOutputContent()
Display page content") + D --> E("smartyOutputContent()
Displays the page content") E:::importantStep - C -- true --> G("setMedia()
Sets controller CSS and JS files") + C -- true --> G("setMedia()
Sets controller's CSS and JS files") G:::notAlwaysRun --> H("postProcess()
Used to process user input") H:::importantStep --> I{"has redirect_after"} - I:::decision -- true --> J("redirect()
Redirects to redirect_after after
the process if there is no error
") + I:::decision -- true --> J("redirect()
If there is no error, redirects after the process to the "redirect_after"") I -- false --> K("initHeader()
Assigns Smarty variables
for the page header
") J --> K - K:::notAlwaysRun --> L{"viewAccess()
Check if the current user/visiter
has valid view permissions
"} + K:::notAlwaysRun --> L{"viewAccess()
Checks if the current user/visitor
has valid view permissions
"} L:::decision -- false --> M("Add access denied error message
Added to errors property") - L -- true --> N("initContent()
Assigns Smarty variables
for the page main content
") + L -- true --> N("initContent()
Assigns Smarty variables
for the main content of the page
") M --> O("initFooter()
Assigns Smarty variables for the page footer") N:::importantStep --> O O:::notAlwaysRun --> P{"is ajax"} From e1c907d2dc05a619f61ec301f8f3a494435a159b Mon Sep 17 00:00:00 2001 From: Thomas NARES Date: Thu, 1 Dec 2022 13:20:14 +0100 Subject: [PATCH 149/310] Update development/architecture/legacy/legacy-controllers.md --- development/architecture/legacy/legacy-controllers.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/development/architecture/legacy/legacy-controllers.md b/development/architecture/legacy/legacy-controllers.md index fc7f80c883..9c77d9cbb2 100644 --- a/development/architecture/legacy/legacy-controllers.md +++ b/development/architecture/legacy/legacy-controllers.md @@ -22,7 +22,7 @@ graph TB C -- true --> G("setMedia()
Sets controller's CSS and JS files") G:::notAlwaysRun --> H("postProcess()
Used to process user input") H:::importantStep --> I{"has redirect_after"} - I:::decision -- true --> J("redirect()
If there is no error, redirects after the process to the "redirect_after"") + I:::decision -- true --> J("redirect()
If there is no error, redirects after the process to the #quot;redirect_after#quot;") I -- false --> K("initHeader()
Assigns Smarty variables
for the page header
") J --> K K:::notAlwaysRun --> L{"viewAccess()
Checks if the current user/visitor
has valid view permissions
"} From 5880128abc4d79e6efa8730113517c5acc5b4ccb Mon Sep 17 00:00:00 2001 From: Thomas Nares Date: Thu, 3 Nov 2022 09:04:30 +0100 Subject: [PATCH 150/310] missing some hooks - wip --- modules/concepts/hooks/list-hooks/_index.md | 26 + .../actionAfter.md | 23 + .../actionBefore.md | 23 + ...actionListingFieldsModifier.md | 25 + .../list-hooks/actionAdminAfter.md | 23 + .../list-hooks/actionAdminBefore.md | 23 + ...rametersMetaControllerPostProcessBefore.md | 23 + ...inWebserviceControllerPostProcessBefore.md | 23 + ...ministrationControllerPostProcessBefore.md | 23 + ...sPerformanceControllerPostProcessBefore.md | 23 + .../actionAdminControllerSetMedia.md | 23 + ...lGeolocationControllerPostProcessBefore.md | 23 + ...LocalizationControllerPostProcessBefore.md | 23 + ...ionAdminLogsControllerPostProcessBefore.md | 23 + ...nMaintenanceControllerPostProcessBefore.md | 23 + .../actionAdminMetaAfterWriteRobotsFile.md | 26 + .../actionAdminOrdersTrackingNumberUpdate.md | 30 + ...nPreferencesControllerPostProcessBefore.md | 23 + ...ctionAdminProductsListingFieldsModifier.md | 31 + ...tionAdminProductsListingResultsModifier.md | 27 + ...dminSecurityControllerPostProcessBefore.md | 23 + ...gPreferencesControllerPostProcessBefore.md | 23 + ...rPreferencesControllerPostProcessBefore.md | 23 + ...tPreferencesControllerPostProcessBefore.md | 23 + .../hooks/list-hooks/actionAjaxDieBefore.md | 23 + .../actionAttributeCombinationDelete.md | 23 + .../actionAttributeCombinationSave.md | 23 + .../hooks/list-hooks/actionAttributeDelete.md | 23 + .../list-hooks/actionAttributeGroupDelete.md | 23 + .../list-hooks/actionAttributeGroupSave.md | 23 + .../hooks/list-hooks/actionAttributeSave.md | 23 + .../list-hooks/actionAuthenticationBefore.md | 23 + .../hooks/list-hooks/actionBeforeAjaxDie.md | 23 + .../list-hooks/actionBuildFrontEndObject.md | 25 + .../hooks/list-hooks/actionCarrierProcess.md | 23 + .../hooks/list-hooks/actionCarrierUpdate.md | 26 + .../hooks/list-hooks/actionCartSave.md | 23 + .../hooks/list-hooks/actionCategoryAdd.md | 23 + .../hooks/list-hooks/actionCategoryDelete.md | 23 + .../hooks/list-hooks/actionCategoryUpdate.md | 23 + .../hooks/list-hooks/actionCheckoutRender.md | 23 + .../hooks/list-hooks/actionClearCache.md | 23 + .../list-hooks/actionClearCompileCache.md | 23 + .../hooks/list-hooks/actionClearSf2Cache.md | 23 + .../list-hooks/actionCustomerAccountAdd.md | 25 + .../list-hooks/actionCustomerAccountUpdate.md | 25 + .../list-hooks/actionCustomerAddGroups.md | 23 + .../actionCustomerBeforeUpdateGroup.md | 23 + .../list-hooks/actionCustomerLogoutAfter.md | 23 + .../list-hooks/actionCustomerLogoutBefore.md | 23 + .../list-hooks/actionDeliveryPriceByPrice.md | 23 + .../list-hooks/actionDeliveryPriceByWeight.md | 23 + .../list-hooks/actionDispatcherBefore.md | 23 + .../list-hooks/actionDownloadAttachment.md | 23 + .../hooks/list-hooks/actionFeatureDelete.md | 23 + .../hooks/list-hooks/actionFeatureSave.md | 23 + .../list-hooks/actionFeatureValueDelete.md | 23 + .../list-hooks/actionFeatureValueSave.md | 23 + .../actionFrontControllerSetMedia.md | 23 + .../list-hooks/actionGetIDZoneByAddressID.md | 23 + .../actionGetProductPropertiesAfter.md | 27 + ...ctionGetProductPropertiesAfterUnitPrice.md | 27 + .../actionGetProductPropertiesBefore.md | 27 + .../hooks/list-hooks/actionHtaccessCreate.md | 23 + .../actionInvoiceNumberFormatted.md | 28 + .../actionMailAlterMessageBeforeSend.md | 25 + .../list-hooks/actionModuleInstallAfter.md | 23 + .../list-hooks/actionModuleInstallBefore.md | 23 + .../actionModuleUnRegisterHookBefore.md | 23 + .../list-hooks/actionModuleUninstallAfter.md | 23 + .../list-hooks/actionModuleUninstallBefore.md | 23 + .../actionObjectAddAfter.md | 24 + .../actionObjectAddBefore.md | 24 + .../actionObjectDeleteAfter.md | 24 + .../actionObjectDeleteBefore.md | 24 + .../actionObjectUpdateAfter.md | 24 + .../actionObjectUpdateBefore.md | 24 + .../hooks/list-hooks/actionObjectAddAfter.md | 24 + .../hooks/list-hooks/actionObjectAddBefore.md | 24 + .../actionObjectAttributeAddBefore.md | 24 + .../actionObjectAttributeGroupAddBefore.md | 24 + .../list-hooks/actionObjectDeleteAfter.md | 24 + .../list-hooks/actionObjectDeleteBefore.md | 24 + ...actionObjectProductCommentValidateAfter.md | 24 + .../list-hooks/actionObjectUpdateAfter.md | 24 + .../list-hooks/actionObjectUpdateBefore.md | 24 + .../hooks/list-hooks/actionOnImageCutAfter.md | 23 + .../list-hooks/actionOnImageResizeAfter.md | 23 + .../hooks/list-hooks/actionOrderEdited.md | 23 + .../hooks/list-hooks/actionOrderReturn.md | 23 + .../hooks/list-hooks/actionOrderSlipAdd.md | 280 ++ .../list-hooks/actionOutputHTMLBefore.md | 23 + .../list-hooks/actionPDFInvoiceRender.md | 23 + .../hooks/list-hooks/actionPasswordRenew.md | 23 + .../hooks/list-hooks/actionPaymentCCAdd.md | 23 + .../list-hooks/actionPaymentConfirmation.md | 531 ++++ .../hooks/list-hooks/actionProductAdd.md | 23 + .../actionProductAttributeDelete.md | 23 + .../actionProductAttributeUpdate.md | 23 + .../hooks/list-hooks/actionProductCancel.md | 54 + .../hooks/list-hooks/actionProductDelete.md | 23 + .../list-hooks/actionProductOutOfStock.md | 23 + .../hooks/list-hooks/actionProductSave.md | 23 + ...ctionProductSearchProviderRunQueryAfter.md | 26 + ...tionProductSearchProviderRunQueryBefore.md | 25 + .../hooks/list-hooks/actionProductUpdate.md | 23 + .../concepts/hooks/list-hooks/actionSearch.md | 29 + .../hooks/list-hooks/actionSetInvoice.md | 27 + .../list-hooks/actionShopDataDuplication.md | 104 + .../list-hooks/actionSubmitAccountBefore.md | 64 + .../hooks/list-hooks/actionUpdateLangAfter.md | 23 + .../actionValidateCustomerAddressForm.md | 116 + .../hooks/list-hooks/actionValidateOrder.md | 29 + .../hooks/list-hooks/actionWatermark.md | 23 + .../list-hooks/actionWishlistAddProduct.md | 28 + .../list-hooks/addWebserviceResources.md | 1597 ++++++++++++ .../additionalCustomerAddressFields.md | 106 + .../additionalCustomerFormFields.md | 51 + .../displayAdditionalCustomerAddressFields.md | 23 + .../list-hooks/displayAdminAfterHeader.md | 23 + .../hooks/list-hooks/displayAdminCustomers.md | 23 + .../list-hooks/displayAdminEndContent.md | 23 + .../hooks/list-hooks/displayAdminForm.md | 23 + .../list-hooks/displayAdminGridTableAfter.md | 28 + .../list-hooks/displayAdminGridTableBefore.md | 28 + .../hooks/list-hooks/displayAdminListAfter.md | 23 + .../list-hooks/displayAdminListBefore.md | 23 + .../list-hooks/displayAdminNavBarBeforeEnd.md | 23 + .../hooks/list-hooks/displayAdminOptions.md | 23 + .../hooks/list-hooks/displayAdminOrder.md | 23 + .../displayAdminOrderCreateExtraButtons.md | 23 + .../hooks/list-hooks/displayAdminOrderMain.md | 23 + .../list-hooks/displayAdminOrderMainBottom.md | 23 + .../hooks/list-hooks/displayAdminOrderSide.md | 23 + .../list-hooks/displayAdminOrderSideBottom.md | 23 + .../displayAdminProductsCombinationBottom.md | 23 + ...ayAdminProductsMainStepLeftColumnBottom.md | 23 + ...ayAdminProductsMainStepLeftColumnMiddle.md | 23 + ...yAdminProductsMainStepRightColumnBottom.md | 23 + .../displayAdminProductsOptionsStepBottom.md | 23 + .../displayAdminProductsOptionsStepTop.md | 23 + .../displayAdminProductsPriceStepBottom.md | 23 + ...isplayAdminProductsQuantitiesStepBottom.md | 23 + .../displayAdminProductsSeoStepBottom.md | 23 + .../displayAdminProductsShippingStepBottom.md | 23 + .../list-hooks/displayAdminStatsModules.md | 124 + .../list-hooks/displayAdminThemesListAfter.md | 23 + .../hooks/list-hooks/displayAdminView.md | 23 + .../list-hooks/displayAfterBodyOpeningTag.md | 23 + .../hooks/list-hooks/displayAfterCarrier.md | 23 + .../list-hooks/displayAfterProductThumbs.md | 23 + .../hooks/list-hooks/displayAfterTitleTag.md | 23 + .../list-hooks/displayBackOfficeCategory.md | 23 + .../hooks/list-hooks/displayBackOfficeTop.md | 23 + .../hooks/list-hooks/displayBanner.md | 23 + .../list-hooks/displayBeforeBodyClosingTag.md | 23 + .../hooks/list-hooks/displayBeforeCarrier.md | 23 + .../displayCMSDisputeInformation.md | 23 + .../hooks/list-hooks/displayCMSPrintButton.md | 23 + .../list-hooks/displayCarrierExtraContent.md | 23 + .../displayCartExtraProductActions.md | 23 + .../list-hooks/displayCartModalContent.md | 23 + .../list-hooks/displayCartModalFooter.md | 23 + .../displayCheckoutBeforeConfirmation.md | 23 + .../displayCheckoutSubtotalDetails.md | 23 + .../list-hooks/displayCheckoutSummaryTop.md | 23 + .../displayCrossSellingShoppingCart.md | 23 + .../list-hooks/displayCustomerAccount.md | 23 + .../list-hooks/displayCustomerAccountForm.md | 23 + .../displayCustomerAccountFormTop.md | 23 + .../displayCustomerLoginFormAfter.md | 23 + .../hooks/list-hooks/displayCustomization.md | 2294 +++++++++++++++++ .../displayDashboardToolbarIcons.md | 23 + .../displayDashboardToolbarTopMenu.md | 23 + .../hooks/list-hooks/displayDashboardTop.md | 23 + .../displayEmptyModuleCategoryExtraMessage.md | 23 + .../list-hooks/displayExpressCheckout.md | 23 + .../hooks/list-hooks/displayFeatureForm.md | 23 + .../hooks/list-hooks/displayFooter.md | 23 + .../hooks/list-hooks/displayFooterAfter.md | 23 + .../hooks/list-hooks/displayFooterBefore.md | 23 + .../hooks/list-hooks/displayFooterProduct.md | 23 + .../hooks/list-hooks/displayGDPRConsent.md | 23 + .../hooks/list-hooks/displayHeader.md | 23 + .../concepts/hooks/list-hooks/displayHome.md | 23 + .../list-hooks/displayInvoiceLegalFreeText.md | 23 + .../list-hooks/displayLeftColumnProduct.md | 23 + .../hooks/list-hooks/displayMaintenance.md | 23 + .../hooks/list-hooks/displayMyAccountBlock.md | 23 + .../concepts/hooks/list-hooks/displayNav1.md | 23 + .../concepts/hooks/list-hooks/displayNav2.md | 23 + .../hooks/list-hooks/displayNavFullWidth.md | 23 + .../displayNewsletterRegistration.md | 23 + .../hooks/list-hooks/displayNotFound.md | 23 + .../list-hooks/displayOrderConfirmation1.md | 23 + .../list-hooks/displayOrderConfirmation2.md | 23 + .../hooks/list-hooks/displayOrderDetail.md | 23 + .../hooks/list-hooks/displayOrderPreview.md | 23 + .../list-hooks/displayPaymentByBinaries.md | 23 + .../hooks/list-hooks/displayPaymentReturn.md | 80 + .../hooks/list-hooks/displayPaymentTop.md | 23 + .../displayPersonalInformationTop.md | 23 + .../hooks/list-hooks/displayProductActions.md | 23 + .../displayProductAdditionalInfo.md | 23 + .../list-hooks/displayProductListReviews.md | 23 + .../list-hooks/displayProductPriceBlock.md | 23 + .../hooks/list-hooks/displayReassurance.md | 23 + .../list-hooks/displayRightColumnProduct.md | 23 + .../hooks/list-hooks/displaySearch.md | 23 + .../hooks/list-hooks/displayShoppingCart.md | 23 + .../list-hooks/displayShoppingCartFooter.md | 23 + .../concepts/hooks/list-hooks/displayTop.md | 23 + .../hooks/list-hooks/filterProductSearch.md | 23 + .../hooks/list-hooks/legacyblockkpi.md | 23 + .../overrideMinimalPurchasePrice.md | 25 + .../hooks/list-hooks/termsAndConditions.md | 63 + 216 files changed, 10241 insertions(+) create mode 100644 modules/concepts/hooks/list-hooks/_index.md create mode 100644 modules/concepts/hooks/list-hooks/actionAfter.md create mode 100644 modules/concepts/hooks/list-hooks/actionBefore.md create mode 100644 modules/concepts/hooks/list-hooks/actionListingFieldsModifier.md create mode 100644 modules/concepts/hooks/list-hooks/actionAdminAfter.md create mode 100644 modules/concepts/hooks/list-hooks/actionAdminBefore.md create mode 100644 modules/concepts/hooks/list-hooks/actionAdminAdminShopParametersMetaControllerPostProcessBefore.md create mode 100644 modules/concepts/hooks/list-hooks/actionAdminAdminWebserviceControllerPostProcessBefore.md create mode 100644 modules/concepts/hooks/list-hooks/actionAdminAdministrationControllerPostProcessBefore.md create mode 100644 modules/concepts/hooks/list-hooks/actionAdminAdvancedParametersPerformanceControllerPostProcessBefore.md create mode 100644 modules/concepts/hooks/list-hooks/actionAdminControllerSetMedia.md create mode 100644 modules/concepts/hooks/list-hooks/actionAdminInternationalGeolocationControllerPostProcessBefore.md create mode 100644 modules/concepts/hooks/list-hooks/actionAdminInternationalLocalizationControllerPostProcessBefore.md create mode 100644 modules/concepts/hooks/list-hooks/actionAdminLogsControllerPostProcessBefore.md create mode 100644 modules/concepts/hooks/list-hooks/actionAdminMaintenanceControllerPostProcessBefore.md create mode 100644 modules/concepts/hooks/list-hooks/actionAdminMetaAfterWriteRobotsFile.md create mode 100644 modules/concepts/hooks/list-hooks/actionAdminOrdersTrackingNumberUpdate.md create mode 100644 modules/concepts/hooks/list-hooks/actionAdminPreferencesControllerPostProcessBefore.md create mode 100644 modules/concepts/hooks/list-hooks/actionAdminProductsListingFieldsModifier.md create mode 100644 modules/concepts/hooks/list-hooks/actionAdminProductsListingResultsModifier.md create mode 100644 modules/concepts/hooks/list-hooks/actionAdminSecurityControllerPostProcessBefore.md create mode 100644 modules/concepts/hooks/list-hooks/actionAdminShippingPreferencesControllerPostProcessBefore.md create mode 100644 modules/concepts/hooks/list-hooks/actionAdminShopParametersOrderPreferencesControllerPostProcessBefore.md create mode 100644 modules/concepts/hooks/list-hooks/actionAdminShopParametersProductPreferencesControllerPostProcessBefore.md create mode 100644 modules/concepts/hooks/list-hooks/actionAjaxDieBefore.md create mode 100644 modules/concepts/hooks/list-hooks/actionAttributeCombinationDelete.md create mode 100644 modules/concepts/hooks/list-hooks/actionAttributeCombinationSave.md create mode 100644 modules/concepts/hooks/list-hooks/actionAttributeDelete.md create mode 100644 modules/concepts/hooks/list-hooks/actionAttributeGroupDelete.md create mode 100644 modules/concepts/hooks/list-hooks/actionAttributeGroupSave.md create mode 100644 modules/concepts/hooks/list-hooks/actionAttributeSave.md create mode 100644 modules/concepts/hooks/list-hooks/actionAuthenticationBefore.md create mode 100644 modules/concepts/hooks/list-hooks/actionBeforeAjaxDie.md create mode 100644 modules/concepts/hooks/list-hooks/actionBuildFrontEndObject.md create mode 100644 modules/concepts/hooks/list-hooks/actionCarrierProcess.md create mode 100644 modules/concepts/hooks/list-hooks/actionCarrierUpdate.md create mode 100644 modules/concepts/hooks/list-hooks/actionCartSave.md create mode 100644 modules/concepts/hooks/list-hooks/actionCategoryAdd.md create mode 100644 modules/concepts/hooks/list-hooks/actionCategoryDelete.md create mode 100644 modules/concepts/hooks/list-hooks/actionCategoryUpdate.md create mode 100644 modules/concepts/hooks/list-hooks/actionCheckoutRender.md create mode 100644 modules/concepts/hooks/list-hooks/actionClearCache.md create mode 100644 modules/concepts/hooks/list-hooks/actionClearCompileCache.md create mode 100644 modules/concepts/hooks/list-hooks/actionClearSf2Cache.md create mode 100644 modules/concepts/hooks/list-hooks/actionCustomerAccountAdd.md create mode 100644 modules/concepts/hooks/list-hooks/actionCustomerAccountUpdate.md create mode 100644 modules/concepts/hooks/list-hooks/actionCustomerAddGroups.md create mode 100644 modules/concepts/hooks/list-hooks/actionCustomerBeforeUpdateGroup.md create mode 100644 modules/concepts/hooks/list-hooks/actionCustomerLogoutAfter.md create mode 100644 modules/concepts/hooks/list-hooks/actionCustomerLogoutBefore.md create mode 100644 modules/concepts/hooks/list-hooks/actionDeliveryPriceByPrice.md create mode 100644 modules/concepts/hooks/list-hooks/actionDeliveryPriceByWeight.md create mode 100644 modules/concepts/hooks/list-hooks/actionDispatcherBefore.md create mode 100644 modules/concepts/hooks/list-hooks/actionDownloadAttachment.md create mode 100644 modules/concepts/hooks/list-hooks/actionFeatureDelete.md create mode 100644 modules/concepts/hooks/list-hooks/actionFeatureSave.md create mode 100644 modules/concepts/hooks/list-hooks/actionFeatureValueDelete.md create mode 100644 modules/concepts/hooks/list-hooks/actionFeatureValueSave.md create mode 100644 modules/concepts/hooks/list-hooks/actionFrontControllerSetMedia.md create mode 100644 modules/concepts/hooks/list-hooks/actionGetIDZoneByAddressID.md create mode 100644 modules/concepts/hooks/list-hooks/actionGetProductPropertiesAfter.md create mode 100644 modules/concepts/hooks/list-hooks/actionGetProductPropertiesAfterUnitPrice.md create mode 100644 modules/concepts/hooks/list-hooks/actionGetProductPropertiesBefore.md create mode 100644 modules/concepts/hooks/list-hooks/actionHtaccessCreate.md create mode 100644 modules/concepts/hooks/list-hooks/actionInvoiceNumberFormatted.md create mode 100644 modules/concepts/hooks/list-hooks/actionMailAlterMessageBeforeSend.md create mode 100644 modules/concepts/hooks/list-hooks/actionModuleInstallAfter.md create mode 100644 modules/concepts/hooks/list-hooks/actionModuleInstallBefore.md create mode 100644 modules/concepts/hooks/list-hooks/actionModuleUnRegisterHookBefore.md create mode 100644 modules/concepts/hooks/list-hooks/actionModuleUninstallAfter.md create mode 100644 modules/concepts/hooks/list-hooks/actionModuleUninstallBefore.md create mode 100644 modules/concepts/hooks/list-hooks/actionObjectAddAfter.md create mode 100644 modules/concepts/hooks/list-hooks/actionObjectAddBefore.md create mode 100644 modules/concepts/hooks/list-hooks/actionObjectDeleteAfter.md create mode 100644 modules/concepts/hooks/list-hooks/actionObjectDeleteBefore.md create mode 100644 modules/concepts/hooks/list-hooks/actionObjectUpdateAfter.md create mode 100644 modules/concepts/hooks/list-hooks/actionObjectUpdateBefore.md create mode 100644 modules/concepts/hooks/list-hooks/actionObjectAddAfter.md create mode 100644 modules/concepts/hooks/list-hooks/actionObjectAddBefore.md create mode 100644 modules/concepts/hooks/list-hooks/actionObjectAttributeAddBefore.md create mode 100644 modules/concepts/hooks/list-hooks/actionObjectAttributeGroupAddBefore.md create mode 100644 modules/concepts/hooks/list-hooks/actionObjectDeleteAfter.md create mode 100644 modules/concepts/hooks/list-hooks/actionObjectDeleteBefore.md create mode 100644 modules/concepts/hooks/list-hooks/actionObjectProductCommentValidateAfter.md create mode 100644 modules/concepts/hooks/list-hooks/actionObjectUpdateAfter.md create mode 100644 modules/concepts/hooks/list-hooks/actionObjectUpdateBefore.md create mode 100644 modules/concepts/hooks/list-hooks/actionOnImageCutAfter.md create mode 100644 modules/concepts/hooks/list-hooks/actionOnImageResizeAfter.md create mode 100644 modules/concepts/hooks/list-hooks/actionOrderEdited.md create mode 100644 modules/concepts/hooks/list-hooks/actionOrderReturn.md create mode 100644 modules/concepts/hooks/list-hooks/actionOrderSlipAdd.md create mode 100644 modules/concepts/hooks/list-hooks/actionOutputHTMLBefore.md create mode 100644 modules/concepts/hooks/list-hooks/actionPDFInvoiceRender.md create mode 100644 modules/concepts/hooks/list-hooks/actionPasswordRenew.md create mode 100644 modules/concepts/hooks/list-hooks/actionPaymentCCAdd.md create mode 100644 modules/concepts/hooks/list-hooks/actionPaymentConfirmation.md create mode 100644 modules/concepts/hooks/list-hooks/actionProductAdd.md create mode 100644 modules/concepts/hooks/list-hooks/actionProductAttributeDelete.md create mode 100644 modules/concepts/hooks/list-hooks/actionProductAttributeUpdate.md create mode 100644 modules/concepts/hooks/list-hooks/actionProductCancel.md create mode 100644 modules/concepts/hooks/list-hooks/actionProductDelete.md create mode 100644 modules/concepts/hooks/list-hooks/actionProductOutOfStock.md create mode 100644 modules/concepts/hooks/list-hooks/actionProductSave.md create mode 100644 modules/concepts/hooks/list-hooks/actionProductSearchProviderRunQueryAfter.md create mode 100644 modules/concepts/hooks/list-hooks/actionProductSearchProviderRunQueryBefore.md create mode 100644 modules/concepts/hooks/list-hooks/actionProductUpdate.md create mode 100644 modules/concepts/hooks/list-hooks/actionSearch.md create mode 100644 modules/concepts/hooks/list-hooks/actionSetInvoice.md create mode 100644 modules/concepts/hooks/list-hooks/actionShopDataDuplication.md create mode 100644 modules/concepts/hooks/list-hooks/actionSubmitAccountBefore.md create mode 100644 modules/concepts/hooks/list-hooks/actionUpdateLangAfter.md create mode 100644 modules/concepts/hooks/list-hooks/actionValidateCustomerAddressForm.md create mode 100644 modules/concepts/hooks/list-hooks/actionValidateOrder.md create mode 100644 modules/concepts/hooks/list-hooks/actionWatermark.md create mode 100644 modules/concepts/hooks/list-hooks/actionWishlistAddProduct.md create mode 100644 modules/concepts/hooks/list-hooks/addWebserviceResources.md create mode 100644 modules/concepts/hooks/list-hooks/additionalCustomerAddressFields.md create mode 100644 modules/concepts/hooks/list-hooks/additionalCustomerFormFields.md create mode 100644 modules/concepts/hooks/list-hooks/displayAdditionalCustomerAddressFields.md create mode 100644 modules/concepts/hooks/list-hooks/displayAdminAfterHeader.md create mode 100644 modules/concepts/hooks/list-hooks/displayAdminCustomers.md create mode 100644 modules/concepts/hooks/list-hooks/displayAdminEndContent.md create mode 100644 modules/concepts/hooks/list-hooks/displayAdminForm.md create mode 100644 modules/concepts/hooks/list-hooks/displayAdminGridTableAfter.md create mode 100644 modules/concepts/hooks/list-hooks/displayAdminGridTableBefore.md create mode 100644 modules/concepts/hooks/list-hooks/displayAdminListAfter.md create mode 100644 modules/concepts/hooks/list-hooks/displayAdminListBefore.md create mode 100644 modules/concepts/hooks/list-hooks/displayAdminNavBarBeforeEnd.md create mode 100644 modules/concepts/hooks/list-hooks/displayAdminOptions.md create mode 100644 modules/concepts/hooks/list-hooks/displayAdminOrder.md create mode 100644 modules/concepts/hooks/list-hooks/displayAdminOrderCreateExtraButtons.md create mode 100644 modules/concepts/hooks/list-hooks/displayAdminOrderMain.md create mode 100644 modules/concepts/hooks/list-hooks/displayAdminOrderMainBottom.md create mode 100644 modules/concepts/hooks/list-hooks/displayAdminOrderSide.md create mode 100644 modules/concepts/hooks/list-hooks/displayAdminOrderSideBottom.md create mode 100644 modules/concepts/hooks/list-hooks/displayAdminProductsCombinationBottom.md create mode 100644 modules/concepts/hooks/list-hooks/displayAdminProductsMainStepLeftColumnBottom.md create mode 100644 modules/concepts/hooks/list-hooks/displayAdminProductsMainStepLeftColumnMiddle.md create mode 100644 modules/concepts/hooks/list-hooks/displayAdminProductsMainStepRightColumnBottom.md create mode 100644 modules/concepts/hooks/list-hooks/displayAdminProductsOptionsStepBottom.md create mode 100644 modules/concepts/hooks/list-hooks/displayAdminProductsOptionsStepTop.md create mode 100644 modules/concepts/hooks/list-hooks/displayAdminProductsPriceStepBottom.md create mode 100644 modules/concepts/hooks/list-hooks/displayAdminProductsQuantitiesStepBottom.md create mode 100644 modules/concepts/hooks/list-hooks/displayAdminProductsSeoStepBottom.md create mode 100644 modules/concepts/hooks/list-hooks/displayAdminProductsShippingStepBottom.md create mode 100644 modules/concepts/hooks/list-hooks/displayAdminStatsModules.md create mode 100644 modules/concepts/hooks/list-hooks/displayAdminThemesListAfter.md create mode 100644 modules/concepts/hooks/list-hooks/displayAdminView.md create mode 100644 modules/concepts/hooks/list-hooks/displayAfterBodyOpeningTag.md create mode 100644 modules/concepts/hooks/list-hooks/displayAfterCarrier.md create mode 100644 modules/concepts/hooks/list-hooks/displayAfterProductThumbs.md create mode 100644 modules/concepts/hooks/list-hooks/displayAfterTitleTag.md create mode 100644 modules/concepts/hooks/list-hooks/displayBackOfficeCategory.md create mode 100644 modules/concepts/hooks/list-hooks/displayBackOfficeTop.md create mode 100644 modules/concepts/hooks/list-hooks/displayBanner.md create mode 100644 modules/concepts/hooks/list-hooks/displayBeforeBodyClosingTag.md create mode 100644 modules/concepts/hooks/list-hooks/displayBeforeCarrier.md create mode 100644 modules/concepts/hooks/list-hooks/displayCMSDisputeInformation.md create mode 100644 modules/concepts/hooks/list-hooks/displayCMSPrintButton.md create mode 100644 modules/concepts/hooks/list-hooks/displayCarrierExtraContent.md create mode 100644 modules/concepts/hooks/list-hooks/displayCartExtraProductActions.md create mode 100644 modules/concepts/hooks/list-hooks/displayCartModalContent.md create mode 100644 modules/concepts/hooks/list-hooks/displayCartModalFooter.md create mode 100644 modules/concepts/hooks/list-hooks/displayCheckoutBeforeConfirmation.md create mode 100644 modules/concepts/hooks/list-hooks/displayCheckoutSubtotalDetails.md create mode 100644 modules/concepts/hooks/list-hooks/displayCheckoutSummaryTop.md create mode 100644 modules/concepts/hooks/list-hooks/displayCrossSellingShoppingCart.md create mode 100644 modules/concepts/hooks/list-hooks/displayCustomerAccount.md create mode 100644 modules/concepts/hooks/list-hooks/displayCustomerAccountForm.md create mode 100644 modules/concepts/hooks/list-hooks/displayCustomerAccountFormTop.md create mode 100644 modules/concepts/hooks/list-hooks/displayCustomerLoginFormAfter.md create mode 100644 modules/concepts/hooks/list-hooks/displayCustomization.md create mode 100644 modules/concepts/hooks/list-hooks/displayDashboardToolbarIcons.md create mode 100644 modules/concepts/hooks/list-hooks/displayDashboardToolbarTopMenu.md create mode 100644 modules/concepts/hooks/list-hooks/displayDashboardTop.md create mode 100644 modules/concepts/hooks/list-hooks/displayEmptyModuleCategoryExtraMessage.md create mode 100644 modules/concepts/hooks/list-hooks/displayExpressCheckout.md create mode 100644 modules/concepts/hooks/list-hooks/displayFeatureForm.md create mode 100644 modules/concepts/hooks/list-hooks/displayFooter.md create mode 100644 modules/concepts/hooks/list-hooks/displayFooterAfter.md create mode 100644 modules/concepts/hooks/list-hooks/displayFooterBefore.md create mode 100644 modules/concepts/hooks/list-hooks/displayFooterProduct.md create mode 100644 modules/concepts/hooks/list-hooks/displayGDPRConsent.md create mode 100644 modules/concepts/hooks/list-hooks/displayHeader.md create mode 100644 modules/concepts/hooks/list-hooks/displayHome.md create mode 100644 modules/concepts/hooks/list-hooks/displayInvoiceLegalFreeText.md create mode 100644 modules/concepts/hooks/list-hooks/displayLeftColumnProduct.md create mode 100644 modules/concepts/hooks/list-hooks/displayMaintenance.md create mode 100644 modules/concepts/hooks/list-hooks/displayMyAccountBlock.md create mode 100644 modules/concepts/hooks/list-hooks/displayNav1.md create mode 100644 modules/concepts/hooks/list-hooks/displayNav2.md create mode 100644 modules/concepts/hooks/list-hooks/displayNavFullWidth.md create mode 100644 modules/concepts/hooks/list-hooks/displayNewsletterRegistration.md create mode 100644 modules/concepts/hooks/list-hooks/displayNotFound.md create mode 100644 modules/concepts/hooks/list-hooks/displayOrderConfirmation1.md create mode 100644 modules/concepts/hooks/list-hooks/displayOrderConfirmation2.md create mode 100644 modules/concepts/hooks/list-hooks/displayOrderDetail.md create mode 100644 modules/concepts/hooks/list-hooks/displayOrderPreview.md create mode 100644 modules/concepts/hooks/list-hooks/displayPaymentByBinaries.md create mode 100644 modules/concepts/hooks/list-hooks/displayPaymentReturn.md create mode 100644 modules/concepts/hooks/list-hooks/displayPaymentTop.md create mode 100644 modules/concepts/hooks/list-hooks/displayPersonalInformationTop.md create mode 100644 modules/concepts/hooks/list-hooks/displayProductActions.md create mode 100644 modules/concepts/hooks/list-hooks/displayProductAdditionalInfo.md create mode 100644 modules/concepts/hooks/list-hooks/displayProductListReviews.md create mode 100644 modules/concepts/hooks/list-hooks/displayProductPriceBlock.md create mode 100644 modules/concepts/hooks/list-hooks/displayReassurance.md create mode 100644 modules/concepts/hooks/list-hooks/displayRightColumnProduct.md create mode 100644 modules/concepts/hooks/list-hooks/displaySearch.md create mode 100644 modules/concepts/hooks/list-hooks/displayShoppingCart.md create mode 100644 modules/concepts/hooks/list-hooks/displayShoppingCartFooter.md create mode 100644 modules/concepts/hooks/list-hooks/displayTop.md create mode 100644 modules/concepts/hooks/list-hooks/filterProductSearch.md create mode 100644 modules/concepts/hooks/list-hooks/legacyblockkpi.md create mode 100644 modules/concepts/hooks/list-hooks/overrideMinimalPurchasePrice.md create mode 100644 modules/concepts/hooks/list-hooks/termsAndConditions.md diff --git a/modules/concepts/hooks/list-hooks/_index.md b/modules/concepts/hooks/list-hooks/_index.md new file mode 100644 index 0000000000..7478d09c16 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/_index.md @@ -0,0 +1,26 @@ +--- +menuTitle: List of hooks bis +title: List of hooks bis +type: +chapter: false +--- + +# List of hooks bis + +{{% notice tip %}} +**Search tip:** Some hooks are generated dynamically, so their names are documented in a generic way. + +For example, `actionAdminCustomersFormModifier` is documented as `actionFormModifier`, so you won't find it if you search for the exact name. When you see a controller name or action in the hook name and you can't find it, try searching for a part of the hook name, like `FormModifier`. +{{% /notice %}} + +
+ + +

No hooks found

+
+ + + +
+{{% children showhidden="true" %}} +
\ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionAfter.md b/modules/concepts/hooks/list-hooks/actionAfter.md new file mode 100644 index 0000000000..e0176077ca --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionAfter.md @@ -0,0 +1,23 @@ +--- +menuTitle: actionAfter +title: actionAfter +hidden: true +files: + - classes/controller/AdminController.php +types: + - backoffice +hookTypes: + - legacy +--- + +# Hook : actionAfter + +Located in : + + - classes/controller/AdminController.php + +## Parameters + +```php +Hook::exec('action' . get_class($this) . ucfirst($this->action) . 'After', ['controller' => $this, 'return' => $return]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionBefore.md b/modules/concepts/hooks/list-hooks/actionBefore.md new file mode 100644 index 0000000000..5519ba6349 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionBefore.md @@ -0,0 +1,23 @@ +--- +menuTitle: actionBefore +title: actionBefore +hidden: true +files: + - classes/controller/AdminController.php +types: + - backoffice +hookTypes: + - legacy +--- + +# Hook : actionBefore + +Located in : + + - classes/controller/AdminController.php + +## Parameters + +```php +Hook::exec('action' . get_class($this) . ucfirst($this->action) . 'Before', ['controller' => $this]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionListingFieldsModifier.md b/modules/concepts/hooks/list-hooks/actionListingFieldsModifier.md new file mode 100644 index 0000000000..692062dfc0 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionListingFieldsModifier.md @@ -0,0 +1,25 @@ +--- +menuTitle: actionListingFieldsModifier +title: actionListingFieldsModifier +hidden: true +files: + - classes/controller/AdminController.php +types: + - backoffice +hookTypes: + - legacy +--- + +# Hook : actionListingFieldsModifier + +Located in : + + - classes/controller/AdminController.php + +## Parameters + +```php +Hook::exec('action' . $this->controller_name . 'ListingFieldsModifier', [ + 'fields' => &$this->fields_list, + ]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionAdminAfter.md b/modules/concepts/hooks/list-hooks/actionAdminAfter.md new file mode 100644 index 0000000000..3148d3a572 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionAdminAfter.md @@ -0,0 +1,23 @@ +--- +menuTitle: actionAdminAfter +title: actionAdminAfter +hidden: true +files: + - classes/controller/AdminController.php +types: + - backoffice +hookTypes: + - legacy +--- + +# Hook : actionAdminAfter + +Located in : + + - classes/controller/AdminController.php + +## Parameters + +```php +Hook::exec('actionAdmin' . ucfirst($this->action) . 'After', ['controller' => $this, 'return' => $return]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionAdminBefore.md b/modules/concepts/hooks/list-hooks/actionAdminBefore.md new file mode 100644 index 0000000000..48c3ae402a --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionAdminBefore.md @@ -0,0 +1,23 @@ +--- +menuTitle: actionAdminBefore +title: actionAdminBefore +hidden: true +files: + - classes/controller/AdminController.php +types: + - backoffice +hookTypes: + - legacy +--- + +# Hook : actionAdminBefore + +Located in : + + - classes/controller/AdminController.php + +## Parameters + +```php +Hook::exec('actionAdmin' . ucfirst($this->action) . 'Before', ['controller' => $this]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionAdminAdminShopParametersMetaControllerPostProcessBefore.md b/modules/concepts/hooks/list-hooks/actionAdminAdminShopParametersMetaControllerPostProcessBefore.md new file mode 100644 index 0000000000..c84d0b84ac --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionAdminAdminShopParametersMetaControllerPostProcessBefore.md @@ -0,0 +1,23 @@ +--- +menuTitle: actionAdminAdminShopParametersMetaControllerPostProcessBefore +title: actionAdminAdminShopParametersMetaControllerPostProcessBefore +hidden: true +files: + - src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/MetaController.php +types: + - backoffice +hookTypes: + - symfony +--- + +# Hook : actionAdminAdminShopParametersMetaControllerPostProcessBefore + +Located in : + + - src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/MetaController.php + +## Parameters + +```php +dispatchHook('actionAdminAdminShopParametersMetaControllerPostProcessBefore', ['controller' => $this]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionAdminAdminWebserviceControllerPostProcessBefore.md b/modules/concepts/hooks/list-hooks/actionAdminAdminWebserviceControllerPostProcessBefore.md new file mode 100644 index 0000000000..0896967049 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionAdminAdminWebserviceControllerPostProcessBefore.md @@ -0,0 +1,23 @@ +--- +menuTitle: actionAdminAdminWebserviceControllerPostProcessBefore +title: actionAdminAdminWebserviceControllerPostProcessBefore +hidden: true +files: + - src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/WebserviceController.php +types: + - backoffice +hookTypes: + - symfony +--- + +# Hook : actionAdminAdminWebserviceControllerPostProcessBefore + +Located in : + + - src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/WebserviceController.php + +## Parameters + +```php +dispatchHook('actionAdminAdminWebserviceControllerPostProcessBefore', ['controller' => $this]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionAdminAdministrationControllerPostProcessBefore.md b/modules/concepts/hooks/list-hooks/actionAdminAdministrationControllerPostProcessBefore.md new file mode 100644 index 0000000000..5247d7d162 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionAdminAdministrationControllerPostProcessBefore.md @@ -0,0 +1,23 @@ +--- +menuTitle: actionAdminAdministrationControllerPostProcessBefore +title: actionAdminAdministrationControllerPostProcessBefore +hidden: true +files: + - src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/AdministrationController.php +types: + - backoffice +hookTypes: + - symfony +--- + +# Hook : actionAdminAdministrationControllerPostProcessBefore + +Located in : + + - src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/AdministrationController.php + +## Parameters + +```php +dispatchHook('actionAdminAdministrationControllerPostProcessBefore', ['controller' => $this]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionAdminAdvancedParametersPerformanceControllerPostProcessBefore.md b/modules/concepts/hooks/list-hooks/actionAdminAdvancedParametersPerformanceControllerPostProcessBefore.md new file mode 100644 index 0000000000..795e9060ea --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionAdminAdvancedParametersPerformanceControllerPostProcessBefore.md @@ -0,0 +1,23 @@ +--- +menuTitle: actionAdminAdvancedParametersPerformanceControllerPostProcessBefore +title: actionAdminAdvancedParametersPerformanceControllerPostProcessBefore +hidden: true +files: + - src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/PerformanceController.php +types: + - backoffice +hookTypes: + - symfony +--- + +# Hook : actionAdminAdvancedParametersPerformanceControllerPostProcessBefore + +Located in : + + - src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/PerformanceController.php + +## Parameters + +```php +dispatchHook('actionAdminAdvancedParametersPerformanceControllerPostProcessBefore', ['controller' => $this]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionAdminControllerSetMedia.md b/modules/concepts/hooks/list-hooks/actionAdminControllerSetMedia.md new file mode 100644 index 0000000000..67f329be30 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionAdminControllerSetMedia.md @@ -0,0 +1,23 @@ +--- +menuTitle: actionAdminControllerSetMedia +title: actionAdminControllerSetMedia +hidden: true +files: + - classes/controller/AdminController.php +types: + - backoffice +hookTypes: + - legacy +--- + +# Hook : actionAdminControllerSetMedia + +Located in : + + - classes/controller/AdminController.php + +## Parameters + +```php +Hook::exec('actionAdminControllerSetMedia'); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionAdminInternationalGeolocationControllerPostProcessBefore.md b/modules/concepts/hooks/list-hooks/actionAdminInternationalGeolocationControllerPostProcessBefore.md new file mode 100644 index 0000000000..e43be3fc36 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionAdminInternationalGeolocationControllerPostProcessBefore.md @@ -0,0 +1,23 @@ +--- +menuTitle: actionAdminInternationalGeolocationControllerPostProcessBefore +title: actionAdminInternationalGeolocationControllerPostProcessBefore +hidden: true +files: + - src/PrestaShopBundle/Controller/Admin/Improve/International/GeolocationController.php +types: + - backoffice +hookTypes: + - symfony +--- + +# Hook : actionAdminInternationalGeolocationControllerPostProcessBefore + +Located in : + + - src/PrestaShopBundle/Controller/Admin/Improve/International/GeolocationController.php + +## Parameters + +```php +dispatchHook('actionAdminInternationalGeolocationControllerPostProcessBefore', ['controller' => $this]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionAdminInternationalLocalizationControllerPostProcessBefore.md b/modules/concepts/hooks/list-hooks/actionAdminInternationalLocalizationControllerPostProcessBefore.md new file mode 100644 index 0000000000..45c8df3639 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionAdminInternationalLocalizationControllerPostProcessBefore.md @@ -0,0 +1,23 @@ +--- +menuTitle: actionAdminInternationalLocalizationControllerPostProcessBefore +title: actionAdminInternationalLocalizationControllerPostProcessBefore +hidden: true +files: + - src/PrestaShopBundle/Controller/Admin/Improve/International/LocalizationController.php +types: + - backoffice +hookTypes: + - symfony +--- + +# Hook : actionAdminInternationalLocalizationControllerPostProcessBefore + +Located in : + + - src/PrestaShopBundle/Controller/Admin/Improve/International/LocalizationController.php + +## Parameters + +```php +dispatchHook('actionAdminInternationalLocalizationControllerPostProcessBefore', ['controller' => $this]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionAdminLogsControllerPostProcessBefore.md b/modules/concepts/hooks/list-hooks/actionAdminLogsControllerPostProcessBefore.md new file mode 100644 index 0000000000..d0ba008141 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionAdminLogsControllerPostProcessBefore.md @@ -0,0 +1,23 @@ +--- +menuTitle: actionAdminLogsControllerPostProcessBefore +title: actionAdminLogsControllerPostProcessBefore +hidden: true +files: + - src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/LogsController.php +types: + - backoffice +hookTypes: + - symfony +--- + +# Hook : actionAdminLogsControllerPostProcessBefore + +Located in : + + - src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/LogsController.php + +## Parameters + +```php +dispatchHook('actionAdminLogsControllerPostProcessBefore', ['controller' => $this]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionAdminMaintenanceControllerPostProcessBefore.md b/modules/concepts/hooks/list-hooks/actionAdminMaintenanceControllerPostProcessBefore.md new file mode 100644 index 0000000000..d785405fd6 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionAdminMaintenanceControllerPostProcessBefore.md @@ -0,0 +1,23 @@ +--- +menuTitle: actionAdminMaintenanceControllerPostProcessBefore +title: actionAdminMaintenanceControllerPostProcessBefore +hidden: true +files: + - src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/MaintenanceController.php +types: + - backoffice +hookTypes: + - symfony +--- + +# Hook : actionAdminMaintenanceControllerPostProcessBefore + +Located in : + + - src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/MaintenanceController.php + +## Parameters + +```php +dispatchHook('actionAdminMaintenanceControllerPostProcessBefore', ['controller' => $this]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionAdminMetaAfterWriteRobotsFile.md b/modules/concepts/hooks/list-hooks/actionAdminMetaAfterWriteRobotsFile.md new file mode 100644 index 0000000000..9bbfa65beb --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionAdminMetaAfterWriteRobotsFile.md @@ -0,0 +1,26 @@ +--- +menuTitle: actionAdminMetaAfterWriteRobotsFile +title: actionAdminMetaAfterWriteRobotsFile +hidden: true +files: + - classes/Tools.php +types: + - backoffice +hookTypes: + - legacy +--- + +# Hook : actionAdminMetaAfterWriteRobotsFile + +Located in : + + - classes/Tools.php + +## Parameters + +```php +Hook::exec('actionAdminMetaAfterWriteRobotsFile', [ + 'rb_data' => $robots_content, + 'write_fd' => &$write_fd, + ]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionAdminOrdersTrackingNumberUpdate.md b/modules/concepts/hooks/list-hooks/actionAdminOrdersTrackingNumberUpdate.md new file mode 100644 index 0000000000..fc26c8dca3 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionAdminOrdersTrackingNumberUpdate.md @@ -0,0 +1,30 @@ +--- +menuTitle: actionAdminOrdersTrackingNumberUpdate +title: actionAdminOrdersTrackingNumberUpdate +hidden: true +files: + - src/Adapter/Order/CommandHandler/UpdateOrderShippingDetailsHandler.php +types: + - backoffice +hookTypes: + - legacy +--- + +# Hook : actionAdminOrdersTrackingNumberUpdate + +Located in : + + - src/Adapter/Order/CommandHandler/UpdateOrderShippingDetailsHandler.php + +## Parameters + +```php +Hook::exec('actionAdminOrdersTrackingNumberUpdate', [ + 'order' => $order, + 'customer' => $customer, + 'carrier' => $carrier, + ], null, false, true, false, $order->id_shop); + } + } finally { + $this->contextStateManager->restorePreviousContext(); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionAdminPreferencesControllerPostProcessBefore.md b/modules/concepts/hooks/list-hooks/actionAdminPreferencesControllerPostProcessBefore.md new file mode 100644 index 0000000000..cf727d859b --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionAdminPreferencesControllerPostProcessBefore.md @@ -0,0 +1,23 @@ +--- +menuTitle: actionAdminPreferencesControllerPostProcessBefore +title: actionAdminPreferencesControllerPostProcessBefore +hidden: true +files: + - src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/PreferencesController.php +types: + - backoffice +hookTypes: + - symfony +--- + +# Hook : actionAdminPreferencesControllerPostProcessBefore + +Located in : + + - src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/PreferencesController.php + +## Parameters + +```php +dispatchHook('actionAdminPreferencesControllerPostProcessBefore', ['controller' => $this]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionAdminProductsListingFieldsModifier.md b/modules/concepts/hooks/list-hooks/actionAdminProductsListingFieldsModifier.md new file mode 100644 index 0000000000..456cb47e4c --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionAdminProductsListingFieldsModifier.md @@ -0,0 +1,31 @@ +--- +menuTitle: actionAdminProductsListingFieldsModifier +title: actionAdminProductsListingFieldsModifier +hidden: true +files: + - src/Adapter/Product/AdminProductDataProvider.php +types: + - backoffice +hookTypes: + - legacy +--- + +# Hook : actionAdminProductsListingFieldsModifier + +Located in : + + - src/Adapter/Product/AdminProductDataProvider.php + +## Parameters + +```php +Hook::exec('actionAdminProductsListingFieldsModifier', [ + '_ps_version' => AppKernel::VERSION, + 'sql_select' => &$sqlSelect, + 'sql_table' => &$sqlTable, + 'sql_where' => &$sqlWhere, + 'sql_group_by' => &$sqlGroupBy, + 'sql_order' => &$sqlOrder, + 'sql_limit' => &$sqlLimit, + ]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionAdminProductsListingResultsModifier.md b/modules/concepts/hooks/list-hooks/actionAdminProductsListingResultsModifier.md new file mode 100644 index 0000000000..73bf423016 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionAdminProductsListingResultsModifier.md @@ -0,0 +1,27 @@ +--- +menuTitle: actionAdminProductsListingResultsModifier +title: actionAdminProductsListingResultsModifier +hidden: true +files: + - src/Adapter/Product/AdminProductDataProvider.php +types: + - backoffice +hookTypes: + - legacy +--- + +# Hook : actionAdminProductsListingResultsModifier + +Located in : + + - src/Adapter/Product/AdminProductDataProvider.php + +## Parameters + +```php +Hook::exec('actionAdminProductsListingResultsModifier', [ + '_ps_version' => AppKernel::VERSION, + 'products' => &$products, + 'total' => $total, + ]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionAdminSecurityControllerPostProcessBefore.md b/modules/concepts/hooks/list-hooks/actionAdminSecurityControllerPostProcessBefore.md new file mode 100644 index 0000000000..bffc0fc0cc --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionAdminSecurityControllerPostProcessBefore.md @@ -0,0 +1,23 @@ +--- +menuTitle: actionAdminSecurityControllerPostProcessBefore +title: actionAdminSecurityControllerPostProcessBefore +hidden: true +files: + - src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/SecurityController.php +types: + - backoffice +hookTypes: + - symfony +--- + +# Hook : actionAdminSecurityControllerPostProcessBefore + +Located in : + + - src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/SecurityController.php + +## Parameters + +```php +dispatchHook('actionAdminSecurityControllerPostProcessBefore', ['controller' => $this]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionAdminShippingPreferencesControllerPostProcessBefore.md b/modules/concepts/hooks/list-hooks/actionAdminShippingPreferencesControllerPostProcessBefore.md new file mode 100644 index 0000000000..e3dcc94bcc --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionAdminShippingPreferencesControllerPostProcessBefore.md @@ -0,0 +1,23 @@ +--- +menuTitle: actionAdminShippingPreferencesControllerPostProcessBefore +title: actionAdminShippingPreferencesControllerPostProcessBefore +hidden: true +files: + - src/PrestaShopBundle/Controller/Admin/Improve/Shipping/PreferencesController.php +types: + - backoffice +hookTypes: + - symfony +--- + +# Hook : actionAdminShippingPreferencesControllerPostProcessBefore + +Located in : + + - src/PrestaShopBundle/Controller/Admin/Improve/Shipping/PreferencesController.php + +## Parameters + +```php +dispatchHook('actionAdminShippingPreferencesControllerPostProcessBefore', ['controller' => $this]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionAdminShopParametersOrderPreferencesControllerPostProcessBefore.md b/modules/concepts/hooks/list-hooks/actionAdminShopParametersOrderPreferencesControllerPostProcessBefore.md new file mode 100644 index 0000000000..6c468be66a --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionAdminShopParametersOrderPreferencesControllerPostProcessBefore.md @@ -0,0 +1,23 @@ +--- +menuTitle: actionAdminShopParametersOrderPreferencesControllerPostProcessBefore +title: actionAdminShopParametersOrderPreferencesControllerPostProcessBefore +hidden: true +files: + - src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/OrderPreferencesController.php +types: + - backoffice +hookTypes: + - symfony +--- + +# Hook : actionAdminShopParametersOrderPreferencesControllerPostProcessBefore + +Located in : + + - src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/OrderPreferencesController.php + +## Parameters + +```php +dispatchHook('actionAdminShopParametersOrderPreferencesControllerPostProcessBefore', ['controller' => $this]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionAdminShopParametersProductPreferencesControllerPostProcessBefore.md b/modules/concepts/hooks/list-hooks/actionAdminShopParametersProductPreferencesControllerPostProcessBefore.md new file mode 100644 index 0000000000..5b888629ad --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionAdminShopParametersProductPreferencesControllerPostProcessBefore.md @@ -0,0 +1,23 @@ +--- +menuTitle: actionAdminShopParametersProductPreferencesControllerPostProcessBefore +title: actionAdminShopParametersProductPreferencesControllerPostProcessBefore +hidden: true +files: + - src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/ProductPreferencesController.php +types: + - backoffice +hookTypes: + - symfony +--- + +# Hook : actionAdminShopParametersProductPreferencesControllerPostProcessBefore + +Located in : + + - src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/ProductPreferencesController.php + +## Parameters + +```php +dispatchHook('actionAdminShopParametersProductPreferencesControllerPostProcessBefore', ['controller' => $this]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionAjaxDieBefore.md b/modules/concepts/hooks/list-hooks/actionAjaxDieBefore.md new file mode 100644 index 0000000000..0f0c2a12d7 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionAjaxDieBefore.md @@ -0,0 +1,23 @@ +--- +menuTitle: actionAjaxDieBefore +title: actionAjaxDieBefore +hidden: true +files: + - classes/controller/Controller.php +types: + - frontoffice +hookTypes: + - legacy +--- + +# Hook : actionAjaxDieBefore + +Located in : + + - classes/controller/Controller.php + +## Parameters + +```php +Hook::exec('actionAjaxDieBefore', ['controller' => $controller, 'method' => $method, 'value' => $value]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionAttributeCombinationDelete.md b/modules/concepts/hooks/list-hooks/actionAttributeCombinationDelete.md new file mode 100644 index 0000000000..830d873d60 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionAttributeCombinationDelete.md @@ -0,0 +1,23 @@ +--- +menuTitle: actionAttributeCombinationDelete +title: actionAttributeCombinationDelete +hidden: true +files: + - classes/Combination.php +types: + - frontoffice +hookTypes: + - legacy +--- + +# Hook : actionAttributeCombinationDelete + +Located in : + + - classes/Combination.php + +## Parameters + +```php +Hook::exec('actionAttributeCombinationDelete', ['id_product_attribute' => (int) $this->id]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionAttributeCombinationSave.md b/modules/concepts/hooks/list-hooks/actionAttributeCombinationSave.md new file mode 100644 index 0000000000..9cea40632c --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionAttributeCombinationSave.md @@ -0,0 +1,23 @@ +--- +menuTitle: actionAttributeCombinationSave +title: actionAttributeCombinationSave +hidden: true +files: + - classes/Combination.php +types: + - frontoffice +hookTypes: + - legacy +--- + +# Hook : actionAttributeCombinationSave + +Located in : + + - classes/Combination.php + +## Parameters + +```php +Hook::exec('actionAttributeCombinationSave', ['id_product_attribute' => (int) $this->id, 'id_attributes' => $idsAttribute]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionAttributeDelete.md b/modules/concepts/hooks/list-hooks/actionAttributeDelete.md new file mode 100644 index 0000000000..e074a0ccdd --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionAttributeDelete.md @@ -0,0 +1,23 @@ +--- +menuTitle: actionAttributeDelete +title: actionAttributeDelete +hidden: true +files: + - classes/ProductAttribute.php +types: + - frontoffice +hookTypes: + - legacy +--- + +# Hook : actionAttributeDelete + +Located in : + + - classes/ProductAttribute.php + +## Parameters + +```php +Hook::exec('actionAttributeDelete', ['id_attribute' => $this->id]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionAttributeGroupDelete.md b/modules/concepts/hooks/list-hooks/actionAttributeGroupDelete.md new file mode 100644 index 0000000000..0997e4853a --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionAttributeGroupDelete.md @@ -0,0 +1,23 @@ +--- +menuTitle: actionAttributeGroupDelete +title: actionAttributeGroupDelete +hidden: true +files: + - classes/AttributeGroup.php +types: + - frontoffice +hookTypes: + - legacy +--- + +# Hook : actionAttributeGroupDelete + +Located in : + + - classes/AttributeGroup.php + +## Parameters + +```php +Hook::exec('actionAttributeGroupDelete', ['id_attribute_group' => $this->id]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionAttributeGroupSave.md b/modules/concepts/hooks/list-hooks/actionAttributeGroupSave.md new file mode 100644 index 0000000000..61a89eaba3 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionAttributeGroupSave.md @@ -0,0 +1,23 @@ +--- +menuTitle: actionAttributeGroupSave +title: actionAttributeGroupSave +hidden: true +files: + - classes/AttributeGroup.php +types: + - frontoffice +hookTypes: + - legacy +--- + +# Hook : actionAttributeGroupSave + +Located in : + + - classes/AttributeGroup.php + +## Parameters + +```php +Hook::exec('actionAttributeGroupSave', ['id_attribute_group' => $this->id]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionAttributeSave.md b/modules/concepts/hooks/list-hooks/actionAttributeSave.md new file mode 100644 index 0000000000..810c8ad565 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionAttributeSave.md @@ -0,0 +1,23 @@ +--- +menuTitle: actionAttributeSave +title: actionAttributeSave +hidden: true +files: + - classes/ProductAttribute.php +types: + - frontoffice +hookTypes: + - legacy +--- + +# Hook : actionAttributeSave + +Located in : + + - classes/ProductAttribute.php + +## Parameters + +```php +Hook::exec('actionAttributeSave', ['id_attribute' => $this->id]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionAuthenticationBefore.md b/modules/concepts/hooks/list-hooks/actionAuthenticationBefore.md new file mode 100644 index 0000000000..2e242904bf --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionAuthenticationBefore.md @@ -0,0 +1,23 @@ +--- +menuTitle: actionAuthenticationBefore +title: actionAuthenticationBefore +hidden: true +files: + - classes/form/CustomerLoginForm.php +types: + - frontoffice +hookTypes: + - legacy +--- + +# Hook : actionAuthenticationBefore + +Located in : + + - classes/form/CustomerLoginForm.php + +## Parameters + +```php +Hook::exec('actionAuthenticationBefore'); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionBeforeAjaxDie.md b/modules/concepts/hooks/list-hooks/actionBeforeAjaxDie.md new file mode 100644 index 0000000000..311a95a4cd --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionBeforeAjaxDie.md @@ -0,0 +1,23 @@ +--- +menuTitle: actionBeforeAjaxDie +title: actionBeforeAjaxDie +hidden: true +files: + - classes/controller/Controller.php +types: + - frontoffice +hookTypes: + - legacy +--- + +# Hook : actionBeforeAjaxDie + +Located in : + + - classes/controller/Controller.php + +## Parameters + +```php +Hook::exec('actionBeforeAjaxDie' . $controller . $method, ['value' => $value]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionBuildFrontEndObject.md b/modules/concepts/hooks/list-hooks/actionBuildFrontEndObject.md new file mode 100644 index 0000000000..2efc65d1be --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionBuildFrontEndObject.md @@ -0,0 +1,25 @@ +--- +menuTitle: actionBuildFrontEndObject +title: actionBuildFrontEndObject +hidden: true +files: + - classes/controller/FrontController.php +types: + - frontoffice +hookTypes: + - legacy +--- + +# Hook : actionBuildFrontEndObject + +Located in : + + - classes/controller/FrontController.php + +## Parameters + +```php +Hook::exec('actionBuildFrontEndObject', [ + 'obj' => &$object, + ]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionCarrierProcess.md b/modules/concepts/hooks/list-hooks/actionCarrierProcess.md new file mode 100644 index 0000000000..9cb8cd425e --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionCarrierProcess.md @@ -0,0 +1,23 @@ +--- +menuTitle: actionCarrierProcess +title: actionCarrierProcess +hidden: true +files: + - classes/checkout/CheckoutDeliveryStep.php +types: + - frontoffice +hookTypes: + - legacy +--- + +# Hook : actionCarrierProcess + +Located in : + + - classes/checkout/CheckoutDeliveryStep.php + +## Parameters + +```php +Hook::exec('actionCarrierProcess', ['cart' => $this->getCheckoutSession()->getCart()]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionCarrierUpdate.md b/modules/concepts/hooks/list-hooks/actionCarrierUpdate.md new file mode 100644 index 0000000000..0cc596a8dd --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionCarrierUpdate.md @@ -0,0 +1,26 @@ +--- +menuTitle: actionCarrierUpdate +title: actionCarrierUpdate +hidden: true +files: + - controllers/admin/AdminCarriersController.php +types: + - backoffice +hookTypes: + - legacy +--- + +# Hook : actionCarrierUpdate + +Located in : + + - controllers/admin/AdminCarriersController.php + +## Parameters + +```php +Hook::exec('actionCarrierUpdate', [ + 'id_carrier' => (int) $current_carrier->id, + 'carrier' => $new_carrier, + ]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionCartSave.md b/modules/concepts/hooks/list-hooks/actionCartSave.md new file mode 100644 index 0000000000..d645b8f4c9 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionCartSave.md @@ -0,0 +1,23 @@ +--- +menuTitle: actionCartSave +title: actionCartSave +hidden: true +files: + - classes/Cart.php +types: + - frontoffice +hookTypes: + - legacy +--- + +# Hook : actionCartSave + +Located in : + + - classes/Cart.php + +## Parameters + +```php +Hook::exec('actionCartSave', ['cart' => $this]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionCategoryAdd.md b/modules/concepts/hooks/list-hooks/actionCategoryAdd.md new file mode 100644 index 0000000000..ad46e8d3fe --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionCategoryAdd.md @@ -0,0 +1,23 @@ +--- +menuTitle: actionCategoryAdd +title: actionCategoryAdd +hidden: true +files: + - classes/Category.php +types: + - frontoffice +hookTypes: + - legacy +--- + +# Hook : actionCategoryAdd + +Located in : + + - classes/Category.php + +## Parameters + +```php +Hook::exec('actionCategoryAdd', ['category' => $this]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionCategoryDelete.md b/modules/concepts/hooks/list-hooks/actionCategoryDelete.md new file mode 100644 index 0000000000..d69c3fd2fd --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionCategoryDelete.md @@ -0,0 +1,23 @@ +--- +menuTitle: actionCategoryDelete +title: actionCategoryDelete +hidden: true +files: + - classes/Category.php +types: + - frontoffice +hookTypes: + - legacy +--- + +# Hook : actionCategoryDelete + +Located in : + + - classes/Category.php + +## Parameters + +```php +Hook::exec('actionCategoryDelete', ['category' => $this, 'deleted_children' => $deletedChildren]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionCategoryUpdate.md b/modules/concepts/hooks/list-hooks/actionCategoryUpdate.md new file mode 100644 index 0000000000..928aded0fd --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionCategoryUpdate.md @@ -0,0 +1,23 @@ +--- +menuTitle: actionCategoryUpdate +title: actionCategoryUpdate +hidden: true +files: + - controllers/admin/AdminProductsController.php +types: + - backoffice +hookTypes: + - legacy +--- + +# Hook : actionCategoryUpdate + +Located in : + + - controllers/admin/AdminProductsController.php + +## Parameters + +```php +Hook::exec('actionCategoryUpdate', ['category' => $category]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionCheckoutRender.md b/modules/concepts/hooks/list-hooks/actionCheckoutRender.md new file mode 100644 index 0000000000..99bc8b6e06 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionCheckoutRender.md @@ -0,0 +1,23 @@ +--- +menuTitle: actionCheckoutRender +title: actionCheckoutRender +hidden: true +files: + - controllers/front/OrderController.php +types: + - frontoffice +hookTypes: + - legacy +--- + +# Hook : actionCheckoutRender + +Located in : + + - controllers/front/OrderController.php + +## Parameters + +```php +Hook::exec('actionCheckoutRender', ['checkoutProcess' => &$this->checkoutProcess]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionClearCache.md b/modules/concepts/hooks/list-hooks/actionClearCache.md new file mode 100644 index 0000000000..07c9c860c2 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionClearCache.md @@ -0,0 +1,23 @@ +--- +menuTitle: actionClearCache +title: actionClearCache +hidden: true +files: + - classes/Tools.php +types: + - frontoffice +hookTypes: + - legacy +--- + +# Hook : actionClearCache + +Located in : + + - classes/Tools.php + +## Parameters + +```php +Hook::exec('actionClearCache'); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionClearCompileCache.md b/modules/concepts/hooks/list-hooks/actionClearCompileCache.md new file mode 100644 index 0000000000..1b55b04848 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionClearCompileCache.md @@ -0,0 +1,23 @@ +--- +menuTitle: actionClearCompileCache +title: actionClearCompileCache +hidden: true +files: + - classes/Tools.php +types: + - frontoffice +hookTypes: + - legacy +--- + +# Hook : actionClearCompileCache + +Located in : + + - classes/Tools.php + +## Parameters + +```php +Hook::exec('actionClearCompileCache'); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionClearSf2Cache.md b/modules/concepts/hooks/list-hooks/actionClearSf2Cache.md new file mode 100644 index 0000000000..2b13a3914a --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionClearSf2Cache.md @@ -0,0 +1,23 @@ +--- +menuTitle: actionClearSf2Cache +title: actionClearSf2Cache +hidden: true +files: + - src/Adapter/Cache/Clearer/SymfonyCacheClearer.php +types: + - frontoffice +hookTypes: + - legacy +--- + +# Hook : actionClearSf2Cache + +Located in : + + - src/Adapter/Cache/Clearer/SymfonyCacheClearer.php + +## Parameters + +```php +Hook::exec('actionClearSf2Cache'); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionCustomerAccountAdd.md b/modules/concepts/hooks/list-hooks/actionCustomerAccountAdd.md new file mode 100644 index 0000000000..49c36d00a3 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionCustomerAccountAdd.md @@ -0,0 +1,25 @@ +--- +menuTitle: actionCustomerAccountAdd +title: actionCustomerAccountAdd +hidden: true +files: + - classes/form/CustomerPersister.php +types: + - frontoffice +hookTypes: + - legacy +--- + +# Hook : actionCustomerAccountAdd + +Located in : + + - classes/form/CustomerPersister.php + +## Parameters + +```php +Hook::exec('actionCustomerAccountAdd', [ + 'newCustomer' => $customer, + ]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionCustomerAccountUpdate.md b/modules/concepts/hooks/list-hooks/actionCustomerAccountUpdate.md new file mode 100644 index 0000000000..488d517e27 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionCustomerAccountUpdate.md @@ -0,0 +1,25 @@ +--- +menuTitle: actionCustomerAccountUpdate +title: actionCustomerAccountUpdate +hidden: true +files: + - classes/form/CustomerPersister.php +types: + - frontoffice +hookTypes: + - legacy +--- + +# Hook : actionCustomerAccountUpdate + +Located in : + + - classes/form/CustomerPersister.php + +## Parameters + +```php +Hook::exec('actionCustomerAccountUpdate', [ + 'customer' => $customer, + ]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionCustomerAddGroups.md b/modules/concepts/hooks/list-hooks/actionCustomerAddGroups.md new file mode 100644 index 0000000000..d9435fb589 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionCustomerAddGroups.md @@ -0,0 +1,23 @@ +--- +menuTitle: actionCustomerAddGroups +title: actionCustomerAddGroups +hidden: true +files: + - classes/Customer.php +types: + - frontoffice +hookTypes: + - legacy +--- + +# Hook : actionCustomerAddGroups + +Located in : + + - classes/Customer.php + +## Parameters + +```php +Hook::exec('actionCustomerAddGroups', ['id_customer' => $this->id, 'groups' => $groups]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionCustomerBeforeUpdateGroup.md b/modules/concepts/hooks/list-hooks/actionCustomerBeforeUpdateGroup.md new file mode 100644 index 0000000000..627aa76cd6 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionCustomerBeforeUpdateGroup.md @@ -0,0 +1,23 @@ +--- +menuTitle: actionCustomerBeforeUpdateGroup +title: actionCustomerBeforeUpdateGroup +hidden: true +files: + - classes/Customer.php +types: + - frontoffice +hookTypes: + - legacy +--- + +# Hook : actionCustomerBeforeUpdateGroup + +Located in : + + - classes/Customer.php + +## Parameters + +```php +Hook::exec('actionCustomerBeforeUpdateGroup', ['id_customer' => $this->id, 'groups' => $list]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionCustomerLogoutAfter.md b/modules/concepts/hooks/list-hooks/actionCustomerLogoutAfter.md new file mode 100644 index 0000000000..0d3538da65 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionCustomerLogoutAfter.md @@ -0,0 +1,23 @@ +--- +menuTitle: actionCustomerLogoutAfter +title: actionCustomerLogoutAfter +hidden: true +files: + - classes/Customer.php +types: + - frontoffice +hookTypes: + - legacy +--- + +# Hook : actionCustomerLogoutAfter + +Located in : + + - classes/Customer.php + +## Parameters + +```php +Hook::exec('actionCustomerLogoutAfter', ['customer' => $this]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionCustomerLogoutBefore.md b/modules/concepts/hooks/list-hooks/actionCustomerLogoutBefore.md new file mode 100644 index 0000000000..854f82e76e --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionCustomerLogoutBefore.md @@ -0,0 +1,23 @@ +--- +menuTitle: actionCustomerLogoutBefore +title: actionCustomerLogoutBefore +hidden: true +files: + - classes/Customer.php +types: + - frontoffice +hookTypes: + - legacy +--- + +# Hook : actionCustomerLogoutBefore + +Located in : + + - classes/Customer.php + +## Parameters + +```php +Hook::exec('actionCustomerLogoutBefore', ['customer' => $this]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionDeliveryPriceByPrice.md b/modules/concepts/hooks/list-hooks/actionDeliveryPriceByPrice.md new file mode 100644 index 0000000000..a252868537 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionDeliveryPriceByPrice.md @@ -0,0 +1,23 @@ +--- +menuTitle: actionDeliveryPriceByPrice +title: actionDeliveryPriceByPrice +hidden: true +files: + - classes/Carrier.php +types: + - frontoffice +hookTypes: + - legacy +--- + +# Hook : actionDeliveryPriceByPrice + +Located in : + + - classes/Carrier.php + +## Parameters + +```php +Hook::exec('actionDeliveryPriceByPrice', ['id_carrier' => $id_carrier, 'order_total' => $order_total, 'id_zone' => $id_zone]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionDeliveryPriceByWeight.md b/modules/concepts/hooks/list-hooks/actionDeliveryPriceByWeight.md new file mode 100644 index 0000000000..7a0afe4a54 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionDeliveryPriceByWeight.md @@ -0,0 +1,23 @@ +--- +menuTitle: actionDeliveryPriceByWeight +title: actionDeliveryPriceByWeight +hidden: true +files: + - classes/Carrier.php +types: + - frontoffice +hookTypes: + - legacy +--- + +# Hook : actionDeliveryPriceByWeight + +Located in : + + - classes/Carrier.php + +## Parameters + +```php +Hook::exec('actionDeliveryPriceByWeight', ['id_carrier' => $id_carrier, 'total_weight' => $total_weight, 'id_zone' => $id_zone]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionDispatcherBefore.md b/modules/concepts/hooks/list-hooks/actionDispatcherBefore.md new file mode 100644 index 0000000000..fce3f69bdb --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionDispatcherBefore.md @@ -0,0 +1,23 @@ +--- +menuTitle: actionDispatcherBefore +title: actionDispatcherBefore +hidden: true +files: + - classes/Dispatcher.php +types: + - frontoffice +hookTypes: + - legacy +--- + +# Hook : actionDispatcherBefore + +Located in : + + - classes/Dispatcher.php + +## Parameters + +```php +Hook::exec('actionDispatcherBefore', ['controller_type' => $this->front_controller]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionDownloadAttachment.md b/modules/concepts/hooks/list-hooks/actionDownloadAttachment.md new file mode 100644 index 0000000000..abc7a838a6 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionDownloadAttachment.md @@ -0,0 +1,23 @@ +--- +menuTitle: actionDownloadAttachment +title: actionDownloadAttachment +hidden: true +files: + - controllers/front/AttachmentController.php +types: + - frontoffice +hookTypes: + - legacy +--- + +# Hook : actionDownloadAttachment + +Located in : + + - controllers/front/AttachmentController.php + +## Parameters + +```php +Hook::exec('actionDownloadAttachment', ['attachment' => &$attachment]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionFeatureDelete.md b/modules/concepts/hooks/list-hooks/actionFeatureDelete.md new file mode 100644 index 0000000000..07017008ec --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionFeatureDelete.md @@ -0,0 +1,23 @@ +--- +menuTitle: actionFeatureDelete +title: actionFeatureDelete +hidden: true +files: + - classes/Feature.php +types: + - frontoffice +hookTypes: + - legacy +--- + +# Hook : actionFeatureDelete + +Located in : + + - classes/Feature.php + +## Parameters + +```php +Hook::exec('actionFeatureDelete', ['id_feature' => $this->id]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionFeatureSave.md b/modules/concepts/hooks/list-hooks/actionFeatureSave.md new file mode 100644 index 0000000000..60c1227c40 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionFeatureSave.md @@ -0,0 +1,23 @@ +--- +menuTitle: actionFeatureSave +title: actionFeatureSave +hidden: true +files: + - classes/Feature.php +types: + - frontoffice +hookTypes: + - legacy +--- + +# Hook : actionFeatureSave + +Located in : + + - classes/Feature.php + +## Parameters + +```php +Hook::exec('actionFeatureSave', ['id_feature' => $this->id]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionFeatureValueDelete.md b/modules/concepts/hooks/list-hooks/actionFeatureValueDelete.md new file mode 100644 index 0000000000..fc1244e5ab --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionFeatureValueDelete.md @@ -0,0 +1,23 @@ +--- +menuTitle: actionFeatureValueDelete +title: actionFeatureValueDelete +hidden: true +files: + - classes/FeatureValue.php +types: + - frontoffice +hookTypes: + - legacy +--- + +# Hook : actionFeatureValueDelete + +Located in : + + - classes/FeatureValue.php + +## Parameters + +```php +Hook::exec('actionFeatureValueDelete', ['id_feature_value' => $this->id]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionFeatureValueSave.md b/modules/concepts/hooks/list-hooks/actionFeatureValueSave.md new file mode 100644 index 0000000000..eab6cd8e34 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionFeatureValueSave.md @@ -0,0 +1,23 @@ +--- +menuTitle: actionFeatureValueSave +title: actionFeatureValueSave +hidden: true +files: + - classes/FeatureValue.php +types: + - frontoffice +hookTypes: + - legacy +--- + +# Hook : actionFeatureValueSave + +Located in : + + - classes/FeatureValue.php + +## Parameters + +```php +Hook::exec('actionFeatureValueSave', ['id_feature_value' => $this->id]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionFrontControllerSetMedia.md b/modules/concepts/hooks/list-hooks/actionFrontControllerSetMedia.md new file mode 100644 index 0000000000..5dc05c0a19 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionFrontControllerSetMedia.md @@ -0,0 +1,23 @@ +--- +menuTitle: actionFrontControllerSetMedia +title: actionFrontControllerSetMedia +hidden: true +files: + - classes/controller/FrontController.php +types: + - frontoffice +hookTypes: + - legacy +--- + +# Hook : actionFrontControllerSetMedia + +Located in : + + - classes/controller/FrontController.php + +## Parameters + +```php +Hook::exec('actionFrontControllerSetMedia', []); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionGetIDZoneByAddressID.md b/modules/concepts/hooks/list-hooks/actionGetIDZoneByAddressID.md new file mode 100644 index 0000000000..9dcccaffc8 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionGetIDZoneByAddressID.md @@ -0,0 +1,23 @@ +--- +menuTitle: actionGetIDZoneByAddressID +title: actionGetIDZoneByAddressID +hidden: true +files: + - classes/Address.php +types: + - frontoffice +hookTypes: + - legacy +--- + +# Hook : actionGetIDZoneByAddressID + +Located in : + + - classes/Address.php + +## Parameters + +```php +Hook::exec('actionGetIDZoneByAddressID', ['id_address' => $id_address]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionGetProductPropertiesAfter.md b/modules/concepts/hooks/list-hooks/actionGetProductPropertiesAfter.md new file mode 100644 index 0000000000..982d52c6c2 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionGetProductPropertiesAfter.md @@ -0,0 +1,27 @@ +--- +menuTitle: actionGetProductPropertiesAfter +title: actionGetProductPropertiesAfter +hidden: true +files: + - classes/Product.php +types: + - frontoffice +hookTypes: + - legacy +--- + +# Hook : actionGetProductPropertiesAfter + +Located in : + + - classes/Product.php + +## Parameters + +```php +Hook::exec('actionGetProductPropertiesAfter', [ + 'id_lang' => $id_lang, + 'product' => &$row, + 'context' => $context, + ]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionGetProductPropertiesAfterUnitPrice.md b/modules/concepts/hooks/list-hooks/actionGetProductPropertiesAfterUnitPrice.md new file mode 100644 index 0000000000..53bd4c5215 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionGetProductPropertiesAfterUnitPrice.md @@ -0,0 +1,27 @@ +--- +menuTitle: actionGetProductPropertiesAfterUnitPrice +title: actionGetProductPropertiesAfterUnitPrice +hidden: true +files: + - classes/Product.php +types: + - frontoffice +hookTypes: + - legacy +--- + +# Hook : actionGetProductPropertiesAfterUnitPrice + +Located in : + + - classes/Product.php + +## Parameters + +```php +Hook::exec('actionGetProductPropertiesAfterUnitPrice', [ + 'id_lang' => $id_lang, + 'product' => &$row, + 'context' => $context, + ]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionGetProductPropertiesBefore.md b/modules/concepts/hooks/list-hooks/actionGetProductPropertiesBefore.md new file mode 100644 index 0000000000..c26d7a9093 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionGetProductPropertiesBefore.md @@ -0,0 +1,27 @@ +--- +menuTitle: actionGetProductPropertiesBefore +title: actionGetProductPropertiesBefore +hidden: true +files: + - classes/Product.php +types: + - frontoffice +hookTypes: + - legacy +--- + +# Hook : actionGetProductPropertiesBefore + +Located in : + + - classes/Product.php + +## Parameters + +```php +Hook::exec('actionGetProductPropertiesBefore', [ + 'id_lang' => $id_lang, + 'product' => &$row, + 'context' => $context, + ]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionHtaccessCreate.md b/modules/concepts/hooks/list-hooks/actionHtaccessCreate.md new file mode 100644 index 0000000000..d18c82893a --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionHtaccessCreate.md @@ -0,0 +1,23 @@ +--- +menuTitle: actionHtaccessCreate +title: actionHtaccessCreate +hidden: true +files: + - classes/Tools.php +types: + - frontoffice +hookTypes: + - legacy +--- + +# Hook : actionHtaccessCreate + +Located in : + + - classes/Tools.php + +## Parameters + +```php +Hook::exec('actionHtaccessCreate'); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionInvoiceNumberFormatted.md b/modules/concepts/hooks/list-hooks/actionInvoiceNumberFormatted.md new file mode 100644 index 0000000000..bdf12763f5 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionInvoiceNumberFormatted.md @@ -0,0 +1,28 @@ +--- +menuTitle: actionInvoiceNumberFormatted +title: actionInvoiceNumberFormatted +hidden: true +files: + - classes/order/OrderInvoice.php +types: + - frontoffice +hookTypes: + - legacy +--- + +# Hook : actionInvoiceNumberFormatted + +Located in : + + - classes/order/OrderInvoice.php + +## Parameters + +```php +Hook::exec('actionInvoiceNumberFormatted', [ + get_class($this) => $this, + 'id_lang' => (int) $id_lang, + 'id_shop' => (int) $id_shop, + 'number' => (int) $this->number, + ]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionMailAlterMessageBeforeSend.md b/modules/concepts/hooks/list-hooks/actionMailAlterMessageBeforeSend.md new file mode 100644 index 0000000000..8f079d06b3 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionMailAlterMessageBeforeSend.md @@ -0,0 +1,25 @@ +--- +menuTitle: actionMailAlterMessageBeforeSend +title: actionMailAlterMessageBeforeSend +hidden: true +files: + - classes/Mail.php +types: + - frontoffice +hookTypes: + - legacy +--- + +# Hook : actionMailAlterMessageBeforeSend + +Located in : + + - classes/Mail.php + +## Parameters + +```php +Hook::exec('actionMailAlterMessageBeforeSend', [ + 'message' => &$message, + ]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionModuleInstallAfter.md b/modules/concepts/hooks/list-hooks/actionModuleInstallAfter.md new file mode 100644 index 0000000000..9a404ef81f --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionModuleInstallAfter.md @@ -0,0 +1,23 @@ +--- +menuTitle: actionModuleInstallAfter +title: actionModuleInstallAfter +hidden: true +files: + - classes/module/Module.php +types: + - frontoffice +hookTypes: + - legacy +--- + +# Hook : actionModuleInstallAfter + +Located in : + + - classes/module/Module.php + +## Parameters + +```php +Hook::exec('actionModuleInstallAfter', ['object' => $this]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionModuleInstallBefore.md b/modules/concepts/hooks/list-hooks/actionModuleInstallBefore.md new file mode 100644 index 0000000000..4edbe6002a --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionModuleInstallBefore.md @@ -0,0 +1,23 @@ +--- +menuTitle: actionModuleInstallBefore +title: actionModuleInstallBefore +hidden: true +files: + - classes/module/Module.php +types: + - frontoffice +hookTypes: + - legacy +--- + +# Hook : actionModuleInstallBefore + +Located in : + + - classes/module/Module.php + +## Parameters + +```php +Hook::exec('actionModuleInstallBefore', ['object' => $this]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionModuleUnRegisterHookBefore.md b/modules/concepts/hooks/list-hooks/actionModuleUnRegisterHookBefore.md new file mode 100644 index 0000000000..0d6dd83a86 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionModuleUnRegisterHookBefore.md @@ -0,0 +1,23 @@ +--- +menuTitle: actionModuleUnRegisterHookBefore +title: actionModuleUnRegisterHookBefore +hidden: true +files: + - classes/Hook.php +types: + - frontoffice +hookTypes: + - legacy +--- + +# Hook : actionModuleUnRegisterHookBefore + +Located in : + + - classes/Hook.php + +## Parameters + +```php +Hook::exec('actionModuleUnRegisterHookBefore', ['object' => $module_instance, 'hook_name' => $hook_name]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionModuleUninstallAfter.md b/modules/concepts/hooks/list-hooks/actionModuleUninstallAfter.md new file mode 100644 index 0000000000..9a6465e88f --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionModuleUninstallAfter.md @@ -0,0 +1,23 @@ +--- +menuTitle: actionModuleUninstallAfter +title: actionModuleUninstallAfter +hidden: true +files: + - classes/module/Module.php +types: + - frontoffice +hookTypes: + - legacy +--- + +# Hook : actionModuleUninstallAfter + +Located in : + + - classes/module/Module.php + +## Parameters + +```php +Hook::exec('actionModuleUninstallAfter', ['object' => $this]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionModuleUninstallBefore.md b/modules/concepts/hooks/list-hooks/actionModuleUninstallBefore.md new file mode 100644 index 0000000000..d684244632 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionModuleUninstallBefore.md @@ -0,0 +1,23 @@ +--- +menuTitle: actionModuleUninstallBefore +title: actionModuleUninstallBefore +hidden: true +files: + - classes/module/Module.php +types: + - frontoffice +hookTypes: + - legacy +--- + +# Hook : actionModuleUninstallBefore + +Located in : + + - classes/module/Module.php + +## Parameters + +```php +Hook::exec('actionModuleUninstallBefore', ['object' => $this]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionObjectAddAfter.md b/modules/concepts/hooks/list-hooks/actionObjectAddAfter.md new file mode 100644 index 0000000000..ca68474454 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionObjectAddAfter.md @@ -0,0 +1,24 @@ +--- +menuTitle: actionObjectAddAfter +title: actionObjectAddAfter +hidden: true +files: + - classes/ObjectModel.php +types: + - backoffice + - frontoffice +hookTypes: + - legacy +--- + +# Hook : actionObjectAddAfter + +Located in : + + - classes/ObjectModel.php + +## Parameters + +```php +Hook::exec('actionObject' . $this->getFullyQualifiedName() . 'AddAfter', ['object' => $this]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionObjectAddBefore.md b/modules/concepts/hooks/list-hooks/actionObjectAddBefore.md new file mode 100644 index 0000000000..98d74e205e --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionObjectAddBefore.md @@ -0,0 +1,24 @@ +--- +menuTitle: actionObjectAddBefore +title: actionObjectAddBefore +hidden: true +files: + - classes/ObjectModel.php +types: + - backoffice + - frontoffice +hookTypes: + - legacy +--- + +# Hook : actionObjectAddBefore + +Located in : + + - classes/ObjectModel.php + +## Parameters + +```php +Hook::exec('actionObject' . $this->getFullyQualifiedName() . 'AddBefore', ['object' => $this]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionObjectDeleteAfter.md b/modules/concepts/hooks/list-hooks/actionObjectDeleteAfter.md new file mode 100644 index 0000000000..224669360a --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionObjectDeleteAfter.md @@ -0,0 +1,24 @@ +--- +menuTitle: actionObjectDeleteAfter +title: actionObjectDeleteAfter +hidden: true +files: + - classes/ObjectModel.php +types: + - backoffice + - frontoffice +hookTypes: + - legacy +--- + +# Hook : actionObjectDeleteAfter + +Located in : + + - classes/ObjectModel.php + +## Parameters + +```php +Hook::exec('actionObject' . $this->getFullyQualifiedName() . 'DeleteAfter', ['object' => $this]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionObjectDeleteBefore.md b/modules/concepts/hooks/list-hooks/actionObjectDeleteBefore.md new file mode 100644 index 0000000000..ce8ad44866 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionObjectDeleteBefore.md @@ -0,0 +1,24 @@ +--- +menuTitle: actionObjectDeleteBefore +title: actionObjectDeleteBefore +hidden: true +files: + - classes/ObjectModel.php +types: + - backoffice + - frontoffice +hookTypes: + - legacy +--- + +# Hook : actionObjectDeleteBefore + +Located in : + + - classes/ObjectModel.php + +## Parameters + +```php +Hook::exec('actionObject' . $this->getFullyQualifiedName() . 'DeleteBefore', ['object' => $this]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionObjectUpdateAfter.md b/modules/concepts/hooks/list-hooks/actionObjectUpdateAfter.md new file mode 100644 index 0000000000..9e131d1570 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionObjectUpdateAfter.md @@ -0,0 +1,24 @@ +--- +menuTitle: actionObjectUpdateAfter +title: actionObjectUpdateAfter +hidden: true +files: + - classes/ObjectModel.php +types: + - backoffice + - frontoffice +hookTypes: + - legacy +--- + +# Hook : actionObjectUpdateAfter + +Located in : + + - classes/ObjectModel.php + +## Parameters + +```php +Hook::exec('actionObject' . $this->getFullyQualifiedName() . 'UpdateAfter', ['object' => $this]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionObjectUpdateBefore.md b/modules/concepts/hooks/list-hooks/actionObjectUpdateBefore.md new file mode 100644 index 0000000000..5042e5f9ba --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionObjectUpdateBefore.md @@ -0,0 +1,24 @@ +--- +menuTitle: actionObjectUpdateBefore +title: actionObjectUpdateBefore +hidden: true +files: + - classes/ObjectModel.php +types: + - backoffice + - frontoffice +hookTypes: + - legacy +--- + +# Hook : actionObjectUpdateBefore + +Located in : + + - classes/ObjectModel.php + +## Parameters + +```php +Hook::exec('actionObject' . $this->getFullyQualifiedName() . 'UpdateBefore', ['object' => $this]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionObjectAddAfter.md b/modules/concepts/hooks/list-hooks/actionObjectAddAfter.md new file mode 100644 index 0000000000..957c2cfc8b --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionObjectAddAfter.md @@ -0,0 +1,24 @@ +--- +menuTitle: actionObjectAddAfter +title: actionObjectAddAfter +hidden: true +files: + - classes/ObjectModel.php +types: + - backoffice + - frontoffice +hookTypes: + - legacy +--- + +# Hook : actionObjectAddAfter + +Located in : + + - classes/ObjectModel.php + +## Parameters + +```php +Hook::exec('actionObjectAddAfter', ['object' => $this]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionObjectAddBefore.md b/modules/concepts/hooks/list-hooks/actionObjectAddBefore.md new file mode 100644 index 0000000000..4f11373f27 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionObjectAddBefore.md @@ -0,0 +1,24 @@ +--- +menuTitle: actionObjectAddBefore +title: actionObjectAddBefore +hidden: true +files: + - classes/ObjectModel.php +types: + - backoffice + - frontoffice +hookTypes: + - legacy +--- + +# Hook : actionObjectAddBefore + +Located in : + + - classes/ObjectModel.php + +## Parameters + +```php +Hook::exec('actionObjectAddBefore', ['object' => $this]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionObjectAttributeAddBefore.md b/modules/concepts/hooks/list-hooks/actionObjectAttributeAddBefore.md new file mode 100644 index 0000000000..9985de9247 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionObjectAttributeAddBefore.md @@ -0,0 +1,24 @@ +--- +menuTitle: actionObjectAttributeAddBefore +title: actionObjectAttributeAddBefore +hidden: true +files: + - controllers/admin/AdminAttributesGroupsController.php +types: + - backoffice + - frontoffice +hookTypes: + - legacy +--- + +# Hook : actionObjectAttributeAddBefore + +Located in : + + - controllers/admin/AdminAttributesGroupsController.php + +## Parameters + +```php +Hook::exec('actionObjectAttributeAddBefore'); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionObjectAttributeGroupAddBefore.md b/modules/concepts/hooks/list-hooks/actionObjectAttributeGroupAddBefore.md new file mode 100644 index 0000000000..e932b0b7ad --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionObjectAttributeGroupAddBefore.md @@ -0,0 +1,24 @@ +--- +menuTitle: actionObjectAttributeGroupAddBefore +title: actionObjectAttributeGroupAddBefore +hidden: true +files: + - controllers/admin/AdminAttributesGroupsController.php +types: + - backoffice + - frontoffice +hookTypes: + - legacy +--- + +# Hook : actionObjectAttributeGroupAddBefore + +Located in : + + - controllers/admin/AdminAttributesGroupsController.php + +## Parameters + +```php +Hook::exec('actionObjectAttributeGroupAddBefore'); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionObjectDeleteAfter.md b/modules/concepts/hooks/list-hooks/actionObjectDeleteAfter.md new file mode 100644 index 0000000000..ba49362186 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionObjectDeleteAfter.md @@ -0,0 +1,24 @@ +--- +menuTitle: actionObjectDeleteAfter +title: actionObjectDeleteAfter +hidden: true +files: + - classes/ObjectModel.php +types: + - backoffice + - frontoffice +hookTypes: + - legacy +--- + +# Hook : actionObjectDeleteAfter + +Located in : + + - classes/ObjectModel.php + +## Parameters + +```php +Hook::exec('actionObjectDeleteAfter', ['object' => $this]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionObjectDeleteBefore.md b/modules/concepts/hooks/list-hooks/actionObjectDeleteBefore.md new file mode 100644 index 0000000000..2201c39583 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionObjectDeleteBefore.md @@ -0,0 +1,24 @@ +--- +menuTitle: actionObjectDeleteBefore +title: actionObjectDeleteBefore +hidden: true +files: + - classes/ObjectModel.php +types: + - backoffice + - frontoffice +hookTypes: + - legacy +--- + +# Hook : actionObjectDeleteBefore + +Located in : + + - classes/ObjectModel.php + +## Parameters + +```php +Hook::exec('actionObjectDeleteBefore', ['object' => $this]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionObjectProductCommentValidateAfter.md b/modules/concepts/hooks/list-hooks/actionObjectProductCommentValidateAfter.md new file mode 100644 index 0000000000..79b6d0b7ce --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionObjectProductCommentValidateAfter.md @@ -0,0 +1,24 @@ +--- +menuTitle: actionObjectProductCommentValidateAfter +title: actionObjectProductCommentValidateAfter +hidden: true +files: + - modules/productcomments/ProductComment.php +types: + - backoffice + - frontoffice +hookTypes: + - legacy +--- + +# Hook : actionObjectProductCommentValidateAfter + +Located in : + + - modules/productcomments/ProductComment.php + +## Parameters + +```php +Hook::exec('actionObjectProductCommentValidateAfter', ['object' => $this]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionObjectUpdateAfter.md b/modules/concepts/hooks/list-hooks/actionObjectUpdateAfter.md new file mode 100644 index 0000000000..c6ae847920 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionObjectUpdateAfter.md @@ -0,0 +1,24 @@ +--- +menuTitle: actionObjectUpdateAfter +title: actionObjectUpdateAfter +hidden: true +files: + - classes/ObjectModel.php +types: + - backoffice + - frontoffice +hookTypes: + - legacy +--- + +# Hook : actionObjectUpdateAfter + +Located in : + + - classes/ObjectModel.php + +## Parameters + +```php +Hook::exec('actionObjectUpdateAfter', ['object' => $this]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionObjectUpdateBefore.md b/modules/concepts/hooks/list-hooks/actionObjectUpdateBefore.md new file mode 100644 index 0000000000..ccc93560d1 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionObjectUpdateBefore.md @@ -0,0 +1,24 @@ +--- +menuTitle: actionObjectUpdateBefore +title: actionObjectUpdateBefore +hidden: true +files: + - classes/ObjectModel.php +types: + - backoffice + - frontoffice +hookTypes: + - legacy +--- + +# Hook : actionObjectUpdateBefore + +Located in : + + - classes/ObjectModel.php + +## Parameters + +```php +Hook::exec('actionObjectUpdateBefore', ['object' => $this]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionOnImageCutAfter.md b/modules/concepts/hooks/list-hooks/actionOnImageCutAfter.md new file mode 100644 index 0000000000..804a65bda7 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionOnImageCutAfter.md @@ -0,0 +1,23 @@ +--- +menuTitle: actionOnImageCutAfter +title: actionOnImageCutAfter +hidden: true +files: + - classes/ImageManager.php +types: + - frontoffice +hookTypes: + - legacy +--- + +# Hook : actionOnImageCutAfter + +Located in : + + - classes/ImageManager.php + +## Parameters + +```php +Hook::exec('actionOnImageCutAfter', ['dst_file' => $dstFile, 'file_type' => $fileType]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionOnImageResizeAfter.md b/modules/concepts/hooks/list-hooks/actionOnImageResizeAfter.md new file mode 100644 index 0000000000..ebaaa3c225 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionOnImageResizeAfter.md @@ -0,0 +1,23 @@ +--- +menuTitle: actionOnImageResizeAfter +title: actionOnImageResizeAfter +hidden: true +files: + - classes/ImageManager.php +types: + - frontoffice +hookTypes: + - legacy +--- + +# Hook : actionOnImageResizeAfter + +Located in : + + - classes/ImageManager.php + +## Parameters + +```php +Hook::exec('actionOnImageResizeAfter', ['dst_file' => $destinationFile, 'file_type' => $fileType]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionOrderEdited.md b/modules/concepts/hooks/list-hooks/actionOrderEdited.md new file mode 100644 index 0000000000..03cfa78bd5 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionOrderEdited.md @@ -0,0 +1,23 @@ +--- +menuTitle: actionOrderEdited +title: actionOrderEdited +hidden: true +files: + - src/Adapter/Order/CommandHandler/UpdateProductInOrderHandler.php +types: + - frontoffice +hookTypes: + - legacy +--- + +# Hook : actionOrderEdited + +Located in : + + - src/Adapter/Order/CommandHandler/UpdateProductInOrderHandler.php + +## Parameters + +```php +Hook::exec('actionOrderEdited', ['order' => $order]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionOrderReturn.md b/modules/concepts/hooks/list-hooks/actionOrderReturn.md new file mode 100644 index 0000000000..5c7cccfa58 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionOrderReturn.md @@ -0,0 +1,23 @@ +--- +menuTitle: actionOrderReturn +title: actionOrderReturn +hidden: true +files: + - controllers/front/OrderFollowController.php +types: + - frontoffice +hookTypes: + - legacy +--- + +# Hook : actionOrderReturn + +Located in : + + - controllers/front/OrderFollowController.php + +## Parameters + +```php +Hook::exec('actionOrderReturn', ['orderReturn' => $orderReturn]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionOrderSlipAdd.md b/modules/concepts/hooks/list-hooks/actionOrderSlipAdd.md new file mode 100644 index 0000000000..fcafdbaae0 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionOrderSlipAdd.md @@ -0,0 +1,280 @@ +--- +menuTitle: actionOrderSlipAdd +title: actionOrderSlipAdd +hidden: true +files: + - src/Adapter/Order/Refund/OrderSlipCreator.php +types: + - frontoffice +hookTypes: + - legacy +--- + +# Hook : actionOrderSlipAdd + +Located in : + + - src/Adapter/Order/Refund/OrderSlipCreator.php + +## Parameters + +```php +Hook::exec('actionOrderSlipAdd', [ + 'order' => $order, + 'productList' => $orderRefundSummary->getProductRefunds(), + 'qtyList' => $fullQuantityList, + ], null, false, true, false, $order->id_shop); + + $customer = new Customer((int) $order->id_customer); + + // @todo: use private method to send mail + $params = [ + '{lastname}' => $customer->lastname, + '{firstname}' => $customer->firstname, + '{id_order}' => $order->id, + '{order_name}' => $order->getUniqReference(), + ]; + + $orderLanguage = $order->getAssociatedLanguage(); + + // @todo: use a dedicated Mail class (see #13945) + // @todo: remove this @and have a proper error handling + @Mail::Send( + (int) $orderLanguage->getId(), + 'credit_slip', + $this->translator->trans( + 'New credit slip regarding your order', + [], + 'Emails.Subject', + $orderLanguage->locale + ), + $params, + $customer->email, + $customer->firstname . ' ' . $customer->lastname, + null, + null, + null, + null, + _PS_MAIL_DIR_, + true, + (int) $order->id_shop + ); + + /** @var OrderDetail $orderDetail */ + foreach ($orderRefundSummary->getOrderDetails() as $orderDetail) { + if ($this->configuration->get('PS_ADVANCED_STOCK_MANAGEMENT')) { + StockAvailable::synchronize($orderDetail->product_id); + } + } + } else { + throw new InvalidCancelProductException(InvalidCancelProductException::INVALID_AMOUNT); + } + } + + /** + * This is a copy of OrderSlip::create except the OrderDetail modification has been removed + * since it's now managed in the handler, this allows to update order details even without + * generating a credit slip + * + * @todo this copy uses array data but could probably be refactored to use OrderDetailRefund objects + * + * @param Order $order + * @param array $product_list + * @param float $shipping_cost + * @param float $amount + * @param bool $amount_choosen + * @param bool $add_tax + * @param int $precision + * + * @return bool + * + * @throws PrestaShopDatabaseException + * @throws PrestaShopException + */ + private function createOrderSlip( + Order $order, + array $product_list, + float $shipping_cost = 0, + float $amount = 0, + bool $amount_choosen = false, + bool $add_tax = true, + int $precision = 6 + ) { + $currency = new Currency((int) $order->id_currency); + $orderSlip = new OrderSlip(); + $orderSlip->id_customer = (int) $order->id_customer; + $orderSlip->id_order = (int) $order->id; + $orderSlip->conversion_rate = $currency->conversion_rate; + + $orderSlip->total_shipping_tax_excl = 0; + $orderSlip->total_shipping_tax_incl = 0; + $orderSlip->partial = 0; + + if ($shipping_cost > 0) { + $orderSlip->shipping_cost = true; + $carrier = new Carrier((int) $order->id_carrier); + // @todo: define if we use invoice or delivery address, or we use configuration PS_TAX_ADDRESS_TYPE + $address = Address::initialize($order->id_address_delivery, false); + $tax_calculator = $carrier->getTaxCalculator($address); + + if ($add_tax) { + $orderSlip->total_shipping_tax_excl = $shipping_cost; + if ($tax_calculator instanceof TaxCalculator) { + $orderSlip->total_shipping_tax_incl = Tools::ps_round($tax_calculator->addTaxes($orderSlip->total_shipping_tax_excl), $precision); + } else { + $orderSlip->total_shipping_tax_incl = $orderSlip->total_shipping_tax_excl; + } + } else { + $orderSlip->total_shipping_tax_incl = $shipping_cost; + if ($tax_calculator instanceof TaxCalculator) { + $orderSlip->total_shipping_tax_excl = Tools::ps_round($tax_calculator->removeTaxes($orderSlip->total_shipping_tax_incl), $precision); + } else { + $orderSlip->total_shipping_tax_excl = $orderSlip->total_shipping_tax_incl; + } + } + } else { + $orderSlip->shipping_cost = false; + } + + $orderSlip->amount = 0; + $orderSlip->total_products_tax_excl = 0; + $orderSlip->total_products_tax_incl = 0; + $total_products = []; + foreach ($product_list as &$product) { + $order_detail = new OrderDetail((int) $product['id_order_detail']); + $price = (float) $product['unit_price']; + $quantity = (int) $product['quantity']; + + // @todo: define if we use invoice or delivery address, or we use configuration PS_TAX_ADDRESS_TYPE + $address = Address::initialize($order->id_address_invoice, false); + $id_address = (int) $address->id; + $id_tax_rules_group = (int) $order_detail->id_tax_rules_group; + $tax_calculator = $order_detail->getTaxCalculator(); + + if ($add_tax) { + $orderSlip->total_products_tax_excl += $price * $quantity; + } else { + $orderSlip->total_products_tax_incl += $price * $quantity; + } + + if (in_array($this->configuration->get('PS_ROUND_TYPE'), [Order::ROUND_ITEM, Order::ROUND_LINE])) { + if (!isset($total_products[$id_tax_rules_group])) { + $total_products[$id_tax_rules_group] = 0; + } + } else { + if (!isset($total_products[$id_tax_rules_group . '_' . $id_address])) { + $total_products[$id_tax_rules_group . '_' . $id_address] = 0; + } + } + + if ($add_tax) { + $product_tax_incl_line = Tools::ps_round($tax_calculator->addTaxes($price) * $quantity, $precision); + } else { + $product_tax_incl_line = Tools::ps_round($tax_calculator->removeTaxes($price) * $quantity, $precision); + } + switch ($this->configuration->get('PS_ROUND_TYPE')) { + case Order::ROUND_ITEM: + if ($add_tax) { + $product_tax_incl = Tools::ps_round($tax_calculator->addTaxes($price), $precision) * $quantity; + } else { + $product_tax_incl = Tools::ps_round($tax_calculator->removeTaxes($price), $precision) * $quantity; + } + $total_products[$id_tax_rules_group] += $product_tax_incl; + break; + case Order::ROUND_LINE: + $product_tax_incl = $product_tax_incl_line; + $total_products[$id_tax_rules_group] += $product_tax_incl; + break; + case Order::ROUND_TOTAL: + $product_tax_incl = $product_tax_incl_line; + $total_products[$id_tax_rules_group . '_' . $id_address] += $price * $quantity; + break; + default: + $product_tax_incl = 0; + } + + if ($add_tax) { + $product['unit_price_tax_excl'] = $price; + $product['unit_price_tax_incl'] = Tools::ps_round($tax_calculator->addTaxes($price), $precision); + $product['total_price_tax_excl'] = Tools::ps_round($price * $quantity, $precision); + $product['total_price_tax_incl'] = Tools::ps_round($product_tax_incl, $precision); + } else { + $product['unit_price_tax_incl'] = $price; + $product['unit_price_tax_excl'] = Tools::ps_round($tax_calculator->removeTaxes($price), $precision); + $product['total_price_tax_incl'] = Tools::ps_round($price * $quantity, $precision); + $product['total_price_tax_excl'] = Tools::ps_round($product_tax_incl, $precision); + } + } + + unset($product); + + foreach ($total_products as $key => $price) { + if ($this->configuration->get('PS_ROUND_TYPE') == Order::ROUND_TOTAL) { + $tmp = explode('_', $key); + $address = Address::initialize((int) $tmp[1], true); + $tax_calculator = TaxManagerFactory::getManager($address, (int) $tmp[0])->getTaxCalculator(); + + if ($add_tax) { + $orderSlip->total_products_tax_incl += Tools::ps_round($tax_calculator->addTaxes($price), $precision); + } else { + $orderSlip->total_products_tax_excl += Tools::ps_round($tax_calculator->removeTaxes($price), $precision); + } + } else { + if ($add_tax) { + $orderSlip->total_products_tax_incl += $price; + } else { + $orderSlip->total_products_tax_excl += $price; + } + } + } + + if ($add_tax) { + $orderSlip->total_products_tax_incl -= $amount && !$amount_choosen ? $amount : 0; + $orderSlip->amount = $amount_choosen ? $amount : $orderSlip->total_products_tax_excl; + } else { + $orderSlip->total_products_tax_excl -= $amount && !$amount_choosen ? $amount : 0; + $orderSlip->amount = $amount_choosen ? $amount : $orderSlip->total_products_tax_incl; + } + $orderSlip->shipping_cost_amount = $orderSlip->total_shipping_tax_incl; + + if ((float) $amount && !$amount_choosen) { + $orderSlip->order_slip_type = VoucherRefundType::PRODUCT_PRICES_EXCLUDING_VOUCHER_REFUND; + } + if (((float) $amount && $amount_choosen) || $orderSlip->shipping_cost_amount > 0) { + $orderSlip->order_slip_type = VoucherRefundType::SPECIFIC_AMOUNT_REFUND; + } + + if (!$orderSlip->add()) { + return false; + } + + $res = true; + + foreach ($product_list as $product) { + $res &= $this->addProductOrderSlip((int) $orderSlip->id, $product); + } + + return (bool) $res; + } + + /** + * @param array $product + * + * @return bool + * + * @throws PrestaShopDatabaseException + */ + private function addProductOrderSlip(int $orderSlipId, array $product): bool + { + return (bool) Db::getInstance()->insert('order_slip_detail', [ + 'id_order_slip' => $orderSlipId, + 'id_order_detail' => (int) $product['id_order_detail'], + 'product_quantity' => $product['quantity'], + 'unit_price_tax_excl' => $product['unit_price_tax_excl'], + 'unit_price_tax_incl' => $product['unit_price_tax_incl'], + 'total_price_tax_excl' => $product['total_price_tax_excl'], + 'total_price_tax_incl' => $product['total_price_tax_incl'], + 'amount_tax_excl' => $product['total_price_tax_excl'], + 'amount_tax_incl' => $product['total_price_tax_incl'], + ]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionOutputHTMLBefore.md b/modules/concepts/hooks/list-hooks/actionOutputHTMLBefore.md new file mode 100644 index 0000000000..1fb36e1533 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionOutputHTMLBefore.md @@ -0,0 +1,23 @@ +--- +menuTitle: actionOutputHTMLBefore +title: actionOutputHTMLBefore +hidden: true +files: + - classes/controller/FrontController.php +types: + - frontoffice +hookTypes: + - legacy +--- + +# Hook : actionOutputHTMLBefore + +Located in : + + - classes/controller/FrontController.php + +## Parameters + +```php +Hook::exec('actionOutputHTMLBefore', ['html' => &$html]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionPDFInvoiceRender.md b/modules/concepts/hooks/list-hooks/actionPDFInvoiceRender.md new file mode 100644 index 0000000000..fa30fac4db --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionPDFInvoiceRender.md @@ -0,0 +1,23 @@ +--- +menuTitle: actionPDFInvoiceRender +title: actionPDFInvoiceRender +hidden: true +files: + - src/Adapter/PDF/OrderInvoicePdfGenerator.php +types: + - frontoffice +hookTypes: + - legacy +--- + +# Hook : actionPDFInvoiceRender + +Located in : + + - src/Adapter/PDF/OrderInvoicePdfGenerator.php + +## Parameters + +```php +Hook::exec('actionPDFInvoiceRender', ['order_invoice_list' => $order_invoice_list]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionPasswordRenew.md b/modules/concepts/hooks/list-hooks/actionPasswordRenew.md new file mode 100644 index 0000000000..33609ec37f --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionPasswordRenew.md @@ -0,0 +1,23 @@ +--- +menuTitle: actionPasswordRenew +title: actionPasswordRenew +hidden: true +files: + - controllers/front/PasswordController.php +types: + - frontoffice +hookTypes: + - legacy +--- + +# Hook : actionPasswordRenew + +Located in : + + - controllers/front/PasswordController.php + +## Parameters + +```php +Hook::exec('actionPasswordRenew', ['customer' => $customer, 'password' => $password]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionPaymentCCAdd.md b/modules/concepts/hooks/list-hooks/actionPaymentCCAdd.md new file mode 100644 index 0000000000..7f784ac466 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionPaymentCCAdd.md @@ -0,0 +1,23 @@ +--- +menuTitle: actionPaymentCCAdd +title: actionPaymentCCAdd +hidden: true +files: + - classes/order/OrderPayment.php +types: + - frontoffice +hookTypes: + - legacy +--- + +# Hook : actionPaymentCCAdd + +Located in : + + - classes/order/OrderPayment.php + +## Parameters + +```php +Hook::exec('actionPaymentCCAdd', ['paymentCC' => $this]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionPaymentConfirmation.md b/modules/concepts/hooks/list-hooks/actionPaymentConfirmation.md new file mode 100644 index 0000000000..3a44c7244c --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionPaymentConfirmation.md @@ -0,0 +1,531 @@ +--- +menuTitle: actionPaymentConfirmation +title: actionPaymentConfirmation +hidden: true +files: + - classes/order/OrderHistory.php +types: + - frontoffice +hookTypes: + - legacy +--- + +# Hook : actionPaymentConfirmation + +Located in : + + - classes/order/OrderHistory.php + +## Parameters + +```php +Hook::exec('actionPaymentConfirmation', ['id_order' => (int) $order->id], null, false, true, false, $order->id_shop); + } + + // executes hook + Hook::exec('actionOrderStatusUpdate', [ + 'newOrderStatus' => $new_os, + 'oldOrderStatus' => $old_os, + 'id_order' => (int) $order->id, + ], null, false, true, false, $order->id_shop); + + if (Validate::isLoadedObject($order) && $new_os instanceof OrderState) { + $context = Context::getContext(); + + // An email is sent the first time a virtual item is validated + $virtual_products = $order->getVirtualProducts(); + if ($virtual_products && !$old_os->logable && $new_os->logable) { + $assign = []; + foreach ($virtual_products as $key => $virtual_product) { + $id_product_download = ProductDownload::getIdFromIdProduct($virtual_product['product_id']); + $product_download = new ProductDownload($id_product_download); + // If this virtual item has an associated file, we'll provide the link to download the file in the email + if ($product_download->display_filename != '') { + $assign[$key]['name'] = $product_download->display_filename; + $dl_link = $product_download->getTextLink(false, $virtual_product['download_hash']) + . '&id_order=' . (int) $order->id + . '&secure_key=' . $order->secure_key; + $assign[$key]['link'] = $dl_link; + if (isset($virtual_product['download_deadline']) && $virtual_product['download_deadline'] != '0000-00-00 00:00:00') { + $assign[$key]['deadline'] = Tools::displayDate($virtual_product['download_deadline']); + } + if ($product_download->nb_downloadable != 0) { + $assign[$key]['downloadable'] = (int) $product_download->nb_downloadable; + } + } + } + + $customer = new Customer((int) $order->id_customer); + $links = []; + foreach ($assign as $product) { + $complementaryText = []; + if (isset($product['deadline'])) { + $complementaryText[] = $this->trans('expires on %s.', [$product['deadline']], 'Admin.Orderscustomers.Notification'); + } + if (isset($product['downloadable'])) { + $complementaryText[] = $this->trans('downloadable %d time(s)', [(int) $product['downloadable']], 'Admin.Orderscustomers.Notification'); + } + $links[] = [ + 'text' => Tools::htmlentitiesUTF8($product['name']), + 'url' => $product['link'], + 'complementary_text' => implode(' ', $complementaryText), + ]; + } + + $context = Context::getContext(); + $partialRenderer = new MailPartialTemplateRenderer($context->smarty); + + $links_txt = $partialRenderer->render('download_product_virtual_products.txt', $context->language, $links, true); + $links_html = $partialRenderer->render('download_product_virtual_products.tpl', $context->language, $links); + + $data = [ + '{lastname}' => $customer->lastname, + '{firstname}' => $customer->firstname, + '{id_order}' => (int) $order->id, + '{order_name}' => $order->getUniqReference(), + '{nbProducts}' => count($virtual_products), + '{virtualProducts}' => $links_html, + '{virtualProductsTxt}' => $links_txt, + ]; + // If there is at least one downloadable file + if (!empty($assign)) { + $orderLanguage = new Language((int) $order->id_lang); + Mail::Send( + (int) $order->id_lang, + 'download_product', + Context::getContext()->getTranslator()->trans( + 'The virtual product that you bought is available for download', + [], + 'Emails.Subject', + $orderLanguage->locale + ), + $data, + $customer->email, + $customer->firstname . ' ' . $customer->lastname, + null, + null, + null, + null, + _PS_MAIL_DIR_, + false, + (int) $order->id_shop + ); + } + } + + /** @since 1.5.0 : gets the stock manager */ + $manager = null; + if (Configuration::get('PS_ADVANCED_STOCK_MANAGEMENT')) { + $manager = StockManagerFactory::getManager(); + } + + $error_or_canceled_statuses = [Configuration::get('PS_OS_ERROR'), Configuration::get('PS_OS_CANCELED')]; + + $employee = null; + if (!(int) $this->id_employee || !Validate::isLoadedObject(($employee = new Employee((int) $this->id_employee)))) { + if (!Validate::isLoadedObject($old_os) && $context != null) { + // First OrderHistory, there is no $old_os, so $employee is null before here + $employee = $context->employee; // filled if from BO and order created (because no old_os) + if ($employee) { + $this->id_employee = $employee->id; + } + } else { + $employee = null; + } + } + + // foreach products of the order + foreach ($order->getProductsDetail() as $product) { + if (Validate::isLoadedObject($old_os)) { + // if becoming logable => adds sale + if ($new_os->logable && !$old_os->logable) { + ProductSale::addProductSale($product['product_id'], $product['product_quantity']); + // @since 1.5.0 - Stock Management + if (!Pack::isPack($product['product_id']) && + in_array($old_os->id, $error_or_canceled_statuses) && + !StockAvailable::dependsOnStock($product['id_product'], (int) $order->id_shop)) { + StockAvailable::updateQuantity($product['product_id'], $product['product_attribute_id'], -(int) $product['product_quantity'], $order->id_shop); + } + } elseif (!$new_os->logable && $old_os->logable) { + // if becoming unlogable => removes sale + ProductSale::removeProductSale($product['product_id'], $product['product_quantity']); + + // @since 1.5.0 - Stock Management + if (!Pack::isPack($product['product_id']) && + in_array($new_os->id, $error_or_canceled_statuses) && + !StockAvailable::dependsOnStock($product['id_product'])) { + StockAvailable::updateQuantity($product['product_id'], $product['product_attribute_id'], (int) $product['product_quantity'], $order->id_shop); + } + } elseif (!$new_os->logable && !$old_os->logable && + in_array($new_os->id, $error_or_canceled_statuses) && + !in_array($old_os->id, $error_or_canceled_statuses) && + !StockAvailable::dependsOnStock($product['id_product']) + ) { + // if waiting for payment => payment error/canceled + StockAvailable::updateQuantity($product['product_id'], $product['product_attribute_id'], (int) $product['product_quantity'], $order->id_shop); + } + } + // From here, there is 2 cases : $old_os exists, and we can test shipped state evolution, + // Or old_os does not exists, and we should consider that initial shipped state is 0 (to allow decrease of stocks) + + // @since 1.5.0 : if the order is being shipped and this products uses the advanced stock management : + // decrements the physical stock using $id_warehouse + if ($new_os->shipped == 1 && (!Validate::isLoadedObject($old_os) || $old_os->shipped == 0) && + Configuration::get('PS_ADVANCED_STOCK_MANAGEMENT') && + Warehouse::exists($product['id_warehouse']) && + $manager != null && + (int) $product['advanced_stock_management'] == 1) { + // gets the warehouse + $warehouse = new Warehouse($product['id_warehouse']); + + // decrements the stock (if it's a pack, the StockManager does what is needed) + $manager->removeProduct( + $product['product_id'], + $product['product_attribute_id'], + $warehouse, + ($product['product_quantity'] - $product['product_quantity_refunded'] - $product['product_quantity_return']), + (int) Configuration::get('PS_STOCK_CUSTOMER_ORDER_REASON'), + true, + (int) $order->id + ); + } elseif ($new_os->shipped == 0 && Validate::isLoadedObject($old_os) && $old_os->shipped == 1 && + Configuration::get('PS_ADVANCED_STOCK_MANAGEMENT') && + Warehouse::exists($product['id_warehouse']) && + $manager != null && + (int) $product['advanced_stock_management'] == 1 + ) { + // @since.1.5.0 : if the order was shipped, and is not anymore, we need to restock products + + // if the product is a pack, we restock every products in the pack using the last negative stock mvts + if (Pack::isPack($product['product_id'])) { + $pack_products = Pack::getItems($product['product_id'], Configuration::get('PS_LANG_DEFAULT', null, null, $order->id_shop)); + foreach ($pack_products as $pack_product) { + if ($pack_product->advanced_stock_management == 1) { + $mvts = StockMvt::getNegativeStockMvts($order->id, $pack_product->id, 0, $pack_product->pack_quantity * $product['product_quantity']); + foreach ($mvts as $mvt) { + $manager->addProduct( + $pack_product->id, + 0, + new Warehouse($mvt['id_warehouse']), + $mvt['physical_quantity'], + null, + $mvt['price_te'], + true, + null + ); + } + if (!StockAvailable::dependsOnStock($product['id_product'])) { + StockAvailable::updateQuantity($pack_product->id, 0, (int) $pack_product->pack_quantity * $product['product_quantity'], $order->id_shop); + } + } + } + } else { + // else, it's not a pack, re-stock using the last negative stock mvts + + $mvts = StockMvt::getNegativeStockMvts( + $order->id, + $product['product_id'], + $product['product_attribute_id'], + ($product['product_quantity'] - $product['product_quantity_refunded'] - $product['product_quantity_return']) + ); + + foreach ($mvts as $mvt) { + $manager->addProduct( + $product['product_id'], + $product['product_attribute_id'], + new Warehouse($mvt['id_warehouse']), + $mvt['physical_quantity'], + null, + $mvt['price_te'], + true + ); + } + } + } + + // Save movement if : + // not Configuration::get('PS_ADVANCED_STOCK_MANAGEMENT') + // new_os->shipped != old_os->shipped + if (Validate::isLoadedObject($old_os) && Validate::isLoadedObject($new_os) && $new_os->shipped != $old_os->shipped && !Configuration::get('PS_ADVANCED_STOCK_MANAGEMENT')) { + $product_quantity = (int) ($product['product_quantity'] - $product['product_quantity_refunded'] - $product['product_quantity_return']); + + if ($product_quantity > 0) { + $current_shop_context_type = Context::getContext()->shop->getContextType(); + if ($current_shop_context_type !== Shop::CONTEXT_SHOP) { + //change to order shop context + $current_shop_group_id = Context::getContext()->shop->getContextShopGroupID(); + Context::getContext()->shop->setContext(Shop::CONTEXT_SHOP, $order->id_shop); + } + (new StockManager())->saveMovement( + (int) $product['product_id'], + (int) $product['product_attribute_id'], + (int) $product_quantity * ($new_os->shipped == 1 ? -1 : 1), + [ + 'id_order' => $order->id, + 'id_stock_mvt_reason' => ($new_os->shipped == 1 ? Configuration::get('PS_STOCK_CUSTOMER_ORDER_REASON') : Configuration::get('PS_STOCK_CUSTOMER_ORDER_CANCEL_REASON')), + ] + ); + //back to current shop context + if ($current_shop_context_type !== Shop::CONTEXT_SHOP && isset($current_shop_group_id)) { + Context::getContext()->shop->setContext($current_shop_context_type, $current_shop_group_id); + } + } + } + } + } + + $this->id_order_state = (int) $new_order_state; + + // changes invoice number of order ? + if (!Validate::isLoadedObject($new_os) || !Validate::isLoadedObject($order)) { + throw new PrestaShopException($this->trans('Invalid new order status', [], 'Admin.Orderscustomers.Notification')); + } + + // the order is valid if and only if the invoice is available and the order is not cancelled + $order->current_state = $this->id_order_state; + $order->valid = $new_os->logable; + $order->update(); + + if ($new_os->invoice && !$order->invoice_number) { + $order->setInvoice($use_existing_payment); + } elseif ($new_os->delivery && !$order->delivery_number) { + $order->setDeliverySlip(); + } + + // set orders as paid + if ($new_os->paid == 1) { + if ($order->total_paid != 0) { + $payment_method = Module::getInstanceByName($order->module); + } + + $invoices = $order->getInvoicesCollection(); + foreach ($invoices as $invoice) { + /** @var OrderInvoice $invoice */ + $rest_paid = $invoice->getRestPaid(); + if ($rest_paid > 0) { + $payment = new OrderPayment(); + $payment->order_reference = Tools::substr($order->reference, 0, 9); + $payment->id_currency = $order->id_currency; + $payment->amount = $rest_paid; + $payment->payment_method = isset($payment_method) && $payment_method instanceof Module ? $payment_method->displayName : null; + $payment->conversion_rate = $order->conversion_rate; + $payment->save(); + + // Update total_paid_real value for backward compatibility reasons + $order->total_paid_real += $rest_paid; + $order->save(); + + Db::getInstance()->insert( + 'order_invoice_payment', + [ + 'id_order_invoice' => (int) $invoice->id, + 'id_order_payment' => (int) $payment->id, + 'id_order' => (int) $order->id, + ] + ); + } + } + } + + // updates delivery date even if it was already set by another state change + if ($new_os->delivery) { + $order->setDelivery(); + } + + // executes hook + Hook::exec('actionOrderStatusPostUpdate', [ + 'newOrderStatus' => $new_os, + 'oldOrderStatus' => $old_os, + 'id_order' => (int) $order->id, + ], null, false, true, false, $order->id_shop); + + // sync all stock + (new StockManagerAdapter())->updatePhysicalProductQuantity( + (int) $order->id_shop, + (int) Configuration::get('PS_OS_ERROR'), + (int) Configuration::get('PS_OS_CANCELED'), + null, + (int) $order->id + ); + + ShopUrl::resetMainDomainCache(); + } + + /** + * @param bool $autodate Optional + * @param array|bool $template_vars Optional + * @param Context|null $context Deprecated + * + * @return bool + */ + public function addWithemail($autodate = true, $template_vars = false, Context $context = null) + { + $order = new Order($this->id_order); + + if (!$this->add($autodate)) { + return false; + } + Order::cleanHistoryCache(); + + if (!$this->sendEmail($order, $template_vars)) { + return false; + } + + return true; + } + + /** + * @param Order $order + * @param array|false $template_vars + * + * @return bool + */ + public function sendEmail($order, $template_vars = false) + { + $result = Db::getInstance()->getRow(' + SELECT osl.`template`, c.`lastname`, c.`firstname`, osl.`name` AS osname, c.`email`, os.`module_name`, os.`id_order_state`, os.`pdf_invoice`, os.`pdf_delivery` + FROM `' . _DB_PREFIX_ . 'order_history` oh + LEFT JOIN `' . _DB_PREFIX_ . 'orders` o ON oh.`id_order` = o.`id_order` + LEFT JOIN `' . _DB_PREFIX_ . 'customer` c ON o.`id_customer` = c.`id_customer` + LEFT JOIN `' . _DB_PREFIX_ . 'order_state` os ON oh.`id_order_state` = os.`id_order_state` + LEFT JOIN `' . _DB_PREFIX_ . 'order_state_lang` osl ON (os.`id_order_state` = osl.`id_order_state` AND osl.`id_lang` = o.`id_lang`) + WHERE oh.`id_order_history` = ' . (int) $this->id . ' AND os.`send_email` = 1'); + if (isset($result['template']) && Validate::isEmail($result['email'])) { + ShopUrl::cacheMainDomainForShop($order->id_shop); + + $topic = $result['osname']; + $carrierUrl = ''; + if (Validate::isLoadedObject($carrier = new Carrier((int) $order->id_carrier, $order->id_lang))) { + $carrierUrl = $carrier->url; + } + $data = [ + '{lastname}' => $result['lastname'], + '{firstname}' => $result['firstname'], + '{id_order}' => (int) $this->id_order, + '{order_name}' => $order->getUniqReference(), + '{followup}' => str_replace('@', $order->getShippingNumber() ?? '', $carrierUrl), + '{shipping_number}' => $order->getShippingNumber(), + ]; + + if ($result['module_name']) { + $module = Module::getInstanceByName($result['module_name']); + if (Validate::isLoadedObject($module) && isset($module->extra_mail_vars) && is_array($module->extra_mail_vars)) { + $data = array_merge($data, $module->extra_mail_vars); + } + } + + if (is_array($template_vars)) { + $data = array_merge($data, $template_vars); + } + + $context = Context::getContext(); + $data['{total_paid}'] = Tools::getContextLocale($context)->formatPrice((float) $order->total_paid, Currency::getIsoCodeById((int) $order->id_currency)); + + if (Validate::isLoadedObject($order)) { + // Attach invoice and / or delivery-slip if they exists and status is set to attach them + if (($result['pdf_invoice'] || $result['pdf_delivery'])) { + $currentLanguage = $context->language; + $orderLanguage = new Language((int) $order->id_lang); + $context->language = $orderLanguage; + $context->getTranslator()->setLocale($orderLanguage->locale); + $invoice = $order->getInvoicesCollection(); + $file_attachement = []; + + if ($result['pdf_invoice'] && (int) Configuration::get('PS_INVOICE') && $order->invoice_number) { + Hook::exec('actionPDFInvoiceRender', ['order_invoice_list' => $invoice]); + $pdf = new PDF($invoice, PDF::TEMPLATE_INVOICE, $context->smarty); + $file_attachement['invoice']['content'] = $pdf->render(false); + $file_attachement['invoice']['name'] = $pdf->getFilename(); + $file_attachement['invoice']['mime'] = 'application/pdf'; + } + if ($result['pdf_delivery'] && $order->delivery_number) { + $pdf = new PDF($invoice, PDF::TEMPLATE_DELIVERY_SLIP, $context->smarty); + $file_attachement['delivery']['content'] = $pdf->render(false); + $file_attachement['delivery']['name'] = $pdf->getFilename(); + $file_attachement['delivery']['mime'] = 'application/pdf'; + } + + $context->language = $currentLanguage; + $context->getTranslator()->setLocale($currentLanguage->locale); + } else { + $file_attachement = null; + } + + if (!Mail::Send( + (int) $order->id_lang, + $result['template'], + $topic, + $data, + $result['email'], + $result['firstname'] . ' ' . $result['lastname'], + null, + null, + $file_attachement, + null, + _PS_MAIL_DIR_, + false, + (int) $order->id_shop + )) { + return false; + } + } + + ShopUrl::resetMainDomainCache(); + } + + return true; + } + + public function add($autodate = true, $null_values = false) + { + if (!parent::add($autodate)) { + return false; + } + + $order = new Order((int) $this->id_order); + // Update id_order_state attribute in Order + $order->current_state = $this->id_order_state; + $order->update(); + + Hook::exec('actionOrderHistoryAddAfter', ['order_history' => $this], null, false, true, false, $order->id_shop); + + return true; + } + + /** + * @return int + */ + public function isValidated() + { + return (int) Db::getInstance()->getValue(' + SELECT COUNT(oh.`id_order_history`) AS nb + FROM `' . _DB_PREFIX_ . 'order_state` os + LEFT JOIN `' . _DB_PREFIX_ . 'order_history` oh ON (os.`id_order_state` = oh.`id_order_state`) + WHERE oh.`id_order` = ' . (int) $this->id_order . ' + AND os.`logable` = 1'); + } + + /** + * Add method for webservice create resource Order History + * If sendemail=1 GET parameter is present sends email to customer otherwise does not. + * + * @return bool + */ + public function addWs() + { + $sendemail = (bool) Tools::getValue('sendemail', false); + $this->changeIdOrderState($this->id_order_state, $this->id_order); + + if ($sendemail) { + //Mail::Send requires link object on context and is not set when getting here + $context = Context::getContext(); + if ($context->link == null) { + $protocol_link = (Tools::usingSecureMode() && Configuration::get('PS_SSL_ENABLED')) ? 'https://' : 'http://'; + $protocol_content = (Tools::usingSecureMode() && Configuration::get('PS_SSL_ENABLED')) ? 'https://' : 'http://'; + $context->link = new Link($protocol_link, $protocol_content); + } + + return $this->addWithemail(); + } else { + return $this->add(); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionProductAdd.md b/modules/concepts/hooks/list-hooks/actionProductAdd.md new file mode 100644 index 0000000000..a68e22c9a1 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionProductAdd.md @@ -0,0 +1,23 @@ +--- +menuTitle: actionProductAdd +title: actionProductAdd +hidden: true +files: + - controllers/admin/AdminProductsController.php +types: + - backoffice +hookTypes: + - legacy +--- + +# Hook : actionProductAdd + +Located in : + + - controllers/admin/AdminProductsController.php + +## Parameters + +```php +Hook::exec('actionProductAdd', ['id_product_old' => $id_product_old, 'id_product' => (int) $product->id, 'product' => $product]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionProductAttributeDelete.md b/modules/concepts/hooks/list-hooks/actionProductAttributeDelete.md new file mode 100644 index 0000000000..641c9a7157 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionProductAttributeDelete.md @@ -0,0 +1,23 @@ +--- +menuTitle: actionProductAttributeDelete +title: actionProductAttributeDelete +hidden: true +files: + - classes/Product.php +types: + - frontoffice +hookTypes: + - legacy +--- + +# Hook : actionProductAttributeDelete + +Located in : + + - classes/Product.php + +## Parameters + +```php +Hook::exec('actionProductAttributeDelete', ['id_product_attribute' => 0, 'id_product' => (int) $this->id, 'deleteAllAttributes' => true]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionProductAttributeUpdate.md b/modules/concepts/hooks/list-hooks/actionProductAttributeUpdate.md new file mode 100644 index 0000000000..d09a97ef41 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionProductAttributeUpdate.md @@ -0,0 +1,23 @@ +--- +menuTitle: actionProductAttributeUpdate +title: actionProductAttributeUpdate +hidden: true +files: + - classes/Product.php +types: + - frontoffice +hookTypes: + - legacy +--- + +# Hook : actionProductAttributeUpdate + +Located in : + + - classes/Product.php + +## Parameters + +```php +Hook::exec('actionProductAttributeUpdate', ['id_product_attribute' => (int) $id_product_attribute]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionProductCancel.md b/modules/concepts/hooks/list-hooks/actionProductCancel.md new file mode 100644 index 0000000000..827517f6d8 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionProductCancel.md @@ -0,0 +1,54 @@ +--- +menuTitle: actionProductCancel +title: actionProductCancel +hidden: true +files: + - src/Adapter/Order/CommandHandler/IssueStandardRefundHandler.php +types: + - frontoffice +hookTypes: + - legacy +--- + +# Hook : actionProductCancel + +Located in : + + - src/Adapter/Order/CommandHandler/IssueStandardRefundHandler.php + +## Parameters + +```php +Hook::exec('actionProductCancel', ['order' => $order, 'id_order_detail' => (int) $orderDetailId, 'cancel_quantity' => $productRefund['quantity'], 'action' => CancellationActionType::STANDARD_REFUND], null, false, true, false, $order->id_shop); + } + + // Update order carrier weight + $orderCarrier = new OrderCarrier((int) $order->getIdOrderCarrier()); + if (Validate::isLoadedObject($orderCarrier)) { + $orderCarrier->weight = (float) $order->getTotalWeight(); + if ($orderCarrier->update()) { + $order->weight = sprintf('%.3f %s', $orderCarrier->weight, $this->configuration->get('PS_WEIGHT_UNIT')); + } + } + + // Create order slip + if ($command->generateCreditSlip()) { + $this->orderSlipCreator->create($order, $orderRefundSummary); + } + + // Update refund details (standard refund only happen for an order not delivered, so it can't return products) + $this->refundUpdater->updateRefundData( + $orderRefundSummary, + false, + true + ); + + // Generate voucher if needed + if ($command->generateVoucher() && $orderRefundSummary->getRefundedAmount() > 0) { + $this->voucherGenerator->generateVoucher( + $order, + $orderRefundSummary->getRefundedAmount(), + Context::getContext()->currency->iso_code, + $orderRefundSummary->isTaxIncluded() + ); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionProductDelete.md b/modules/concepts/hooks/list-hooks/actionProductDelete.md new file mode 100644 index 0000000000..ed751bf882 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionProductDelete.md @@ -0,0 +1,23 @@ +--- +menuTitle: actionProductDelete +title: actionProductDelete +hidden: true +files: + - classes/Product.php +types: + - frontoffice +hookTypes: + - legacy +--- + +# Hook : actionProductDelete + +Located in : + + - classes/Product.php + +## Parameters + +```php +Hook::exec('actionProductDelete', ['id_product' => (int) $this->id, 'product' => $this]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionProductOutOfStock.md b/modules/concepts/hooks/list-hooks/actionProductOutOfStock.md new file mode 100644 index 0000000000..328ae58457 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionProductOutOfStock.md @@ -0,0 +1,23 @@ +--- +menuTitle: actionProductOutOfStock +title: actionProductOutOfStock +hidden: true +files: + - themes/classic/templates/catalog/_partials/product-details.tpl +types: + - frontoffice +hookTypes: + - smarty +--- + +# Hook : actionProductOutOfStock + +Located in : + + - themes/classic/templates/catalog/_partials/product-details.tpl + +## Parameters + +```php +{hook h='actionProductOutOfStock' product=$product} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionProductSave.md b/modules/concepts/hooks/list-hooks/actionProductSave.md new file mode 100644 index 0000000000..b107aa1f6b --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionProductSave.md @@ -0,0 +1,23 @@ +--- +menuTitle: actionProductSave +title: actionProductSave +hidden: true +files: + - classes/Product.php +types: + - frontoffice +hookTypes: + - legacy +--- + +# Hook : actionProductSave + +Located in : + + - classes/Product.php + +## Parameters + +```php +Hook::exec('actionProductSave', ['id_product' => (int) $this->id, 'product' => $this]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionProductSearchProviderRunQueryAfter.md b/modules/concepts/hooks/list-hooks/actionProductSearchProviderRunQueryAfter.md new file mode 100644 index 0000000000..06a226f6a5 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionProductSearchProviderRunQueryAfter.md @@ -0,0 +1,26 @@ +--- +menuTitle: actionProductSearchProviderRunQueryAfter +title: actionProductSearchProviderRunQueryAfter +hidden: true +files: + - classes/controller/ProductListingFrontController.php +types: + - frontoffice +hookTypes: + - legacy +--- + +# Hook : actionProductSearchProviderRunQueryAfter + +Located in : + + - classes/controller/ProductListingFrontController.php + +## Parameters + +```php +Hook::exec('actionProductSearchProviderRunQueryAfter', [ + 'query' => $query, + 'result' => $result, + ]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionProductSearchProviderRunQueryBefore.md b/modules/concepts/hooks/list-hooks/actionProductSearchProviderRunQueryBefore.md new file mode 100644 index 0000000000..e28d4cbc8b --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionProductSearchProviderRunQueryBefore.md @@ -0,0 +1,25 @@ +--- +menuTitle: actionProductSearchProviderRunQueryBefore +title: actionProductSearchProviderRunQueryBefore +hidden: true +files: + - classes/controller/ProductListingFrontController.php +types: + - frontoffice +hookTypes: + - legacy +--- + +# Hook : actionProductSearchProviderRunQueryBefore + +Located in : + + - classes/controller/ProductListingFrontController.php + +## Parameters + +```php +Hook::exec('actionProductSearchProviderRunQueryBefore', [ + 'query' => $query, + ]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionProductUpdate.md b/modules/concepts/hooks/list-hooks/actionProductUpdate.md new file mode 100644 index 0000000000..67534af0d4 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionProductUpdate.md @@ -0,0 +1,23 @@ +--- +menuTitle: actionProductUpdate +title: actionProductUpdate +hidden: true +files: + - src/Adapter/Product/AdminProductWrapper.php +types: + - backoffice +hookTypes: + - legacy +--- + +# Hook : actionProductUpdate + +Located in : + + - src/Adapter/Product/AdminProductWrapper.php + +## Parameters + +```php +Hook::exec('actionProductUpdate', ['id_product' => (int) $product->id, 'product' => $product]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionSearch.md b/modules/concepts/hooks/list-hooks/actionSearch.md new file mode 100644 index 0000000000..a091b74110 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionSearch.md @@ -0,0 +1,29 @@ +--- +menuTitle: actionSearch +title: actionSearch +hidden: true +files: + - src/Adapter/Search/SearchProductSearchProvider.php +types: + - frontoffice +hookTypes: + - legacy +--- + +# Hook : actionSearch + +Located in : + + - src/Adapter/Search/SearchProductSearchProvider.php + +## Parameters + +```php +Hook::exec('actionSearch', [ + 'searched_query' => $queryString, + 'total' => $count, + + // deprecated since 1.7.x + 'expr' => $queryString, + ]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionSetInvoice.md b/modules/concepts/hooks/list-hooks/actionSetInvoice.md new file mode 100644 index 0000000000..5f0e7e02aa --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionSetInvoice.md @@ -0,0 +1,27 @@ +--- +menuTitle: actionSetInvoice +title: actionSetInvoice +hidden: true +files: + - classes/order/Order.php +types: + - frontoffice +hookTypes: + - legacy +--- + +# Hook : actionSetInvoice + +Located in : + + - classes/order/Order.php + +## Parameters + +```php +Hook::exec('actionSetInvoice', [ + get_class($this) => $this, + get_class($order_invoice) => $order_invoice, + 'use_existing_payment' => (bool) $use_existing_payment, + ]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionShopDataDuplication.md b/modules/concepts/hooks/list-hooks/actionShopDataDuplication.md new file mode 100644 index 0000000000..b4cec2c92f --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionShopDataDuplication.md @@ -0,0 +1,104 @@ +--- +menuTitle: actionShopDataDuplication +title: actionShopDataDuplication +hidden: true +files: + - classes/shop/Shop.php +types: + - frontoffice +hookTypes: + - legacy +--- + +# Hook : actionShopDataDuplication + +Located in : + + - classes/shop/Shop.php + +## Parameters + +```php +Hook::exec('actionShopDataDuplication', [ + 'old_id_shop' => (int) $old_id, + 'new_id_shop' => (int) $this->id, + ], $m['id_module']); + } + } + } + } + + /** + * @param int $id + * + * @return array + */ + public static function getCategories($id = 0, $only_id = true) + { + // build query + $query = new DbQuery(); + if ($only_id) { + $query->select('cs.`id_category`'); + } else { + $query->select('DISTINCT cs.`id_category`, cl.`name`, cl.`link_rewrite`'); + } + $query->from('category_shop', 'cs'); + $query->leftJoin('category_lang', 'cl', 'cl.`id_category` = cs.`id_category` AND cl.`id_lang` = ' . (int) Context::getContext()->language->id); + $query->where('cs.`id_shop` = ' . (int) $id); + $result = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS($query); + + if ($only_id) { + $array = []; + foreach ($result as $row) { + $array[] = $row['id_category']; + } + $array = array_unique($array); + } else { + return $result; + } + + return $array; + } + + /** + * @param string $entity + * @param int $id_shop + * + * @return array|bool + */ + public static function getEntityIds($entity, $id_shop, $active = false, $delete = false) + { + if (!Shop::isTableAssociated($entity)) { + return false; + } + + return Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS( + 'SELECT entity.`id_' . bqSQL($entity) . '` + FROM `' . _DB_PREFIX_ . bqSQL($entity) . '_shop`es + LEFT JOIN ' . _DB_PREFIX_ . bqSQL($entity) . ' entity + ON (entity.`id_' . bqSQL($entity) . '` = es.`id_' . bqSQL($entity) . '`) + WHERE es.`id_shop` = ' . (int) $id_shop . + ($active ? ' AND entity.`active` = 1' : '') . + ($delete ? ' AND entity.deleted = 0' : '') + ); + } + + /** + * @param string $host + * + * @return array + * + * @throws PrestaShopDatabaseException + */ + private static function findShopByHost($host) + { + $sql = 'SELECT s.id_shop, CONCAT(su.physical_uri, su.virtual_uri) AS uri, su.domain, su.main + FROM ' . _DB_PREFIX_ . 'shop_url su + LEFT JOIN ' . _DB_PREFIX_ . 'shop s ON (s.id_shop = su.id_shop) + WHERE (su.domain = \'' . pSQL($host) . '\' OR su.domain_ssl = \'' . pSQL($host) . '\') + AND s.active = 1 + AND s.deleted = 0 + ORDER BY LENGTH(CONCAT(su.physical_uri, su.virtual_uri)) DESC'; + + $result = Db::getInstance()->executeS($sql); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionSubmitAccountBefore.md b/modules/concepts/hooks/list-hooks/actionSubmitAccountBefore.md new file mode 100644 index 0000000000..5ff788e0a0 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionSubmitAccountBefore.md @@ -0,0 +1,64 @@ +--- +menuTitle: actionSubmitAccountBefore +title: actionSubmitAccountBefore +hidden: true +files: + - controllers/front/RegistrationController.php +types: + - frontoffice +hookTypes: + - legacy +--- + +# Hook : actionSubmitAccountBefore + +Located in : + + - controllers/front/RegistrationController.php + +## Parameters + +```php +Hook::exec('actionSubmitAccountBefore', [], null, true), + function ($carry, $item) { + return $carry && $item; + }, + true + ); + + // If no problem occured in the hook, let's get the user redirected + if ($hookResult && $register_form->submit() && !$this->ajax) { + // First option - redirect the customer to desired URL specified in 'back' parameter + // Before that, we need to check if 'back' is legit URL that is on OUR domain, with the right protocol + $back = rawurldecode(Tools::getValue('back')); + if (Tools::urlBelongsToShop($back)) { + return $this->redirectWithNotifications($back); + } + + // Second option - we will redirect him to authRedirection if set + if ($this->authRedirection) { + return $this->redirectWithNotifications($this->authRedirection); + } + + // Third option - we will redirect him to home URL + return $this->redirectWithNotifications(__PS_BASE_URI__); + } + } + + $this->context->smarty->assign([ + 'register_form' => $register_form->getProxy(), + 'hook_create_account_top' => Hook::exec('displayCustomerAccountFormTop'), + ]); + $this->setTemplate('customer/registration'); + + parent::initContent(); + } + + public function getBreadcrumbLinks() + { + $breadcrumb = parent::getBreadcrumbLinks(); + + $breadcrumb['links'][] = [ + 'title' => $this->trans('Create an account', [], 'Shop.Theme.Customeraccount'), + 'url' => $this->context->link->getPageLink('registration'), +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionUpdateLangAfter.md b/modules/concepts/hooks/list-hooks/actionUpdateLangAfter.md new file mode 100644 index 0000000000..3b50006c66 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionUpdateLangAfter.md @@ -0,0 +1,23 @@ +--- +menuTitle: actionUpdateLangAfter +title: actionUpdateLangAfter +hidden: true +files: + - classes/Language.php +types: + - frontoffice +hookTypes: + - legacy +--- + +# Hook : actionUpdateLangAfter + +Located in : + + - classes/Language.php + +## Parameters + +```php +Hook::exec('actionUpdateLangAfter', ['lang' => $language]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionValidateCustomerAddressForm.md b/modules/concepts/hooks/list-hooks/actionValidateCustomerAddressForm.md new file mode 100644 index 0000000000..222019d115 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionValidateCustomerAddressForm.md @@ -0,0 +1,116 @@ +--- +menuTitle: actionValidateCustomerAddressForm +title: actionValidateCustomerAddressForm +hidden: true +files: + - classes/form/CustomerAddressForm.php +types: + - frontoffice +hookTypes: + - legacy +--- + +# Hook : actionValidateCustomerAddressForm + +Located in : + + - classes/form/CustomerAddressForm.php + +## Parameters + +```php +Hook::exec('actionValidateCustomerAddressForm', ['form' => $this])) !== '') { + $is_valid &= (bool) $hookReturn; + } + + return $is_valid && parent::validate(); + } + + public function submit() + { + if (!$this->validate()) { + return false; + } + + $address = new Address( + Tools::getValue('id_address'), + $this->language->id + ); + + foreach ($this->formFields as $formField) { + $address->{$formField->getName()} = $formField->getValue(); + } + + if (!isset($this->formFields['id_state'])) { + $address->id_state = 0; + } + + if (empty($address->alias)) { + $address->alias = $this->translator->trans('My Address', [], 'Shop.Theme.Checkout'); + } + + Hook::exec('actionSubmitCustomerAddressForm', ['address' => &$address]); + + $this->setAddress($address); + + return $this->getPersister()->save( + $address, + $this->getValue('token') + ); + } + + /** + * @return Address + */ + public function getAddress() + { + return $this->address; + } + + /** + * @return CustomerAddressPersister + */ + protected function getPersister() + { + return $this->persister; + } + + protected function setAddress(Address $address) + { + $this->address = $address; + } + + public function getTemplateVariables() + { + $context = Context::getContext(); + + if (!$this->formFields) { + // This is usually done by fillWith but the form may be + // rendered before fillWith is called. + // I don't want to assign formFields in the constructor + // because it accesses the DB and a constructor should not + // have side effects. + $this->formFields = $this->formatter->getFormat(); + } + + $this->setValue('token', $this->persister->getToken()); + $formFields = array_map( + function (FormField $item) { + return $item->toArray(); + }, + $this->formFields + ); + + if (empty($formFields['firstname']['value'])) { + $formFields['firstname']['value'] = $context->customer->firstname; + } + + if (empty($formFields['lastname']['value'])) { + $formFields['lastname']['value'] = $context->customer->lastname; + } + + return [ + 'id_address' => (isset($this->address->id)) ? $this->address->id : 0, + 'action' => $this->action, + 'errors' => $this->getErrors(), +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionValidateOrder.md b/modules/concepts/hooks/list-hooks/actionValidateOrder.md new file mode 100644 index 0000000000..5758f1452f --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionValidateOrder.md @@ -0,0 +1,29 @@ +--- +menuTitle: actionValidateOrder +title: actionValidateOrder +hidden: true +files: + - classes/PaymentModule.php +types: + - frontoffice +hookTypes: + - legacy +--- + +# Hook : actionValidateOrder + +Located in : + + - classes/PaymentModule.php + +## Parameters + +```php +Hook::exec('actionValidateOrder', [ + 'cart' => $this->context->cart, + 'order' => $order, + 'customer' => $this->context->customer, + 'currency' => $this->context->currency, + 'orderStatus' => $order_status, + ]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionWatermark.md b/modules/concepts/hooks/list-hooks/actionWatermark.md new file mode 100644 index 0000000000..df72b1ca0b --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionWatermark.md @@ -0,0 +1,23 @@ +--- +menuTitle: actionWatermark +title: actionWatermark +hidden: true +files: + - controllers/admin/AdminProductsController.php +types: + - backoffice +hookTypes: + - legacy +--- + +# Hook : actionWatermark + +Located in : + + - controllers/admin/AdminProductsController.php + +## Parameters + +```php +Hook::exec('actionWatermark', ['id_image' => $id_image, 'id_product' => $id_product]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionWishlistAddProduct.md b/modules/concepts/hooks/list-hooks/actionWishlistAddProduct.md new file mode 100644 index 0000000000..c00eb81005 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionWishlistAddProduct.md @@ -0,0 +1,28 @@ +--- +menuTitle: actionWishlistAddProduct +title: actionWishlistAddProduct +hidden: true +files: + - modules/blockwishlist/controllers/front/action.php +types: + - frontoffice +hookTypes: + - legacy +--- + +# Hook : actionWishlistAddProduct + +Located in : + + - modules/blockwishlist/controllers/front/action.php + +## Parameters + +```php +Hook::exec('actionWishlistAddProduct', [ + 'idWishlist' => $idWishList, + 'customerId' => $this->context->customer->id, + 'idProduct' => $id_product, + 'idProductAttribute' => $id_product_attribute, + ]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/addWebserviceResources.md b/modules/concepts/hooks/list-hooks/addWebserviceResources.md new file mode 100644 index 0000000000..13cd52cec2 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/addWebserviceResources.md @@ -0,0 +1,1597 @@ +--- +menuTitle: addWebserviceResources +title: addWebserviceResources +hidden: true +files: + - classes/webservice/WebserviceRequest.php +types: + - frontoffice +hookTypes: + - legacy +--- + +# Hook : addWebserviceResources + +Located in : + + - classes/webservice/WebserviceRequest.php + +## Parameters + +```php +Hook::exec('addWebserviceResources', ['resources' => $resources], null, true, false); + if (is_countable($extra_resources) && count($extra_resources)) { + foreach ($extra_resources as $new_resources) { + if (is_countable($new_resources) && count($new_resources)) { + $resources = array_merge($resources, $new_resources); + } + } + } + ksort($resources); + + return $resources; + } + + /** + * This method is used for calculate the price for products on the output details. + * + * @param array $field + * @param ObjectModel $entity_object + * + * @return array field parameters + */ + public function getPriceForProduct($field, $entity_object) + { + if (is_int($entity_object->id)) { + $arr_return = $this->specificPriceForProduct($entity_object, ['default_price' => '']); + $field['value'] = $arr_return['default_price']['value']; + } + + return $field; + } + + /** + * This method is used for calculate the price for products on a virtual fields. + * + * @param ObjectModel $entity_object + * @param array $parameters + * + * @return array + */ + public function specificPriceForProduct($entity_object, $parameters) + { + foreach (array_keys($parameters) as $name) { + $parameters[$name]['object_id'] = $entity_object->id; + } + $arr_return = $this->specificPriceCalculation($parameters); + + return $arr_return; + } + + public function specificPriceCalculation($parameters) + { + $arr_return = []; + foreach ($parameters as $name => $value) { + $id_shop = (int) Context::getContext()->shop->id; + $id_country = (int) (isset($value['country']) ? $value['country'] : (Configuration::get('PS_COUNTRY_DEFAULT'))); + $id_state = (int) (isset($value['state']) ? $value['state'] : 0); + $id_currency = (int) (isset($value['currency']) ? $value['currency'] : Configuration::get('PS_CURRENCY_DEFAULT')); + $id_group = (int) (isset($value['group']) ? $value['group'] : (int) Configuration::get('PS_CUSTOMER_GROUP')); + $quantity = (int) (isset($value['quantity']) ? $value['quantity'] : 1); + $use_tax = (bool) (isset($value['use_tax']) ? $value['use_tax'] : Configuration::get('PS_TAX')); + $decimals = (int) (isset($value['decimals']) ? $value['decimals'] : Configuration::get('PS_PRICE_ROUND_MODE')); + $id_product_attribute = (int) (isset($value['product_attribute']) ? $value['product_attribute'] : null); + $only_reduc = (bool) (isset($value['only_reduction']) ? $value['only_reduction'] : false); + $use_reduc = (bool) (isset($value['use_reduction']) ? $value['use_reduction'] : true); + $use_ecotax = (bool) (isset($value['use_ecotax']) ? $value['use_ecotax'] : Configuration::get('PS_USE_ECOTAX')); + $specific_price_output = null; + $id_county = (string) (isset($value['county']) ? $value['county'] : 0); + $return_value = Product::priceCalculation( + $id_shop, + $value['object_id'], + $id_product_attribute, + $id_country, + $id_state, + $id_county, + $id_currency, + $id_group, + $quantity, + $use_tax, + $decimals, + $only_reduc, + $use_reduc, + $use_ecotax, + $specific_price_output, + false + ); + $arr_return[$name] = ['sqlId' => strtolower($name), 'value' => sprintf('%f', $return_value)]; + } + + return $arr_return; + } + + /** + * This method is used for calculate the price for products on a virtual fields. + * + * @param ObjectModel $entity_object + * @param array $parameters + * + * @return array + */ + public function specificPriceForCombination($entity_object, $parameters) + { + foreach (array_keys($parameters) as $name) { + $parameters[$name]['object_id'] = $entity_object->id_product; + $parameters[$name]['product_attribute'] = $entity_object->id; + } + $arr_return = $this->specificPriceCalculation($parameters); + + return $arr_return; + } + + /** + * Start Webservice request + * Check webservice activation + * Check authentication + * Check resource + * Check HTTP Method + * Execute the action + * Display the result. + * + * @param string $key + * @param string $method + * @param string $url + * @param array $params + * @param string $bad_class_name + * @param string $inputXml + * + * @return array Returns an array of results (headers, content, type of resource...) + */ + public function fetch($key, $method, $url, $params, $bad_class_name, $inputXml = null) + { + // Time logger + $this->_startTime = microtime(true); + $this->objects = []; + + // Error handler + set_error_handler([$this, 'webserviceErrorHandler']); + ini_set('html_errors', 'off'); + + // Two global vars, for compatibility with the PS core + global $webservice_call, $display_errors; + $webservice_call = true; + $display_errors = strtolower(ini_get('display_errors')) != 'off'; + // __PS_BASE_URI__ is from Shop::$current_base_uri + $this->wsUrl = Tools::getHttpHost(true) . __PS_BASE_URI__ . 'api/'; + // set the output object which manage the content and header structure and information + $this->objOutput = new WebserviceOutputBuilder($this->wsUrl); + + $this->_key = trim($key); + + if (isset($params['output_format'])) { + $this->outputFormat = $params['output_format']; + } + // Set the render object to build the output on the asked format (XML, JSON, CSV, ...) + $this->objOutput->setObjectRender($this->getOutputObject($this->outputFormat)); + $this->params = $params; + // Check webservice activation and request authentication + if ($this->webserviceChecks()) { + if ($bad_class_name) { + $this->setError(500, 'Class "' . htmlspecialchars($bad_class_name) . '" not found. Please update the class_name field in the webservice_account table.', 126); + } + // parse request url + $this->method = $method; + $this->urlSegment = explode('/', $url); + $this->urlFragments = $params; + $this->_inputXml = $inputXml; + $this->depth = isset($this->urlFragments['depth']) ? (int) $this->urlFragments['depth'] : $this->depth; + + try { + // Method below set a particular fonction to use on the price field for products entity + // @see WebserviceRequest::getPriceForProduct() method + // @see WebserviceOutputBuilder::setSpecificField() method + //$this->objOutput->setSpecificField($this, 'getPriceForProduct', 'price', 'products'); + if (isset($this->urlFragments['price'])) { + $this->objOutput->setVirtualField($this, 'specificPriceForCombination', 'combinations', $this->urlFragments['price']); + $this->objOutput->setVirtualField($this, 'specificPriceForProduct', 'products', $this->urlFragments['price']); + } + } catch (Exception $e) { + $this->setError(500, $e->getMessage(), $e->getCode()); + } + + if (isset($this->urlFragments['language'])) { + $this->_available_languages = $this->filterLanguage(); + } else { + $this->_available_languages = Language::getIDs(); + } + + if (empty($this->_available_languages)) { + $this->setError(400, 'language is not available', 81); + } + + // Need to set available languages for the render object. + // Thus we can filter i18n field for the output + // @see WebserviceOutputXML::renderField() method for example + $this->objOutput->objectRender->setLanguages($this->_available_languages); + + // check method and resource + if (empty($this->errors) && $this->checkResource() && $this->checkHTTPMethod()) { + // The resource list is necessary for build the output + $this->objOutput->setWsResources($this->resourceList); + + // if the resource is a core entity... + if (!isset($this->resourceList[$this->urlSegment[0]]['specific_management']) || !$this->resourceList[$this->urlSegment[0]]['specific_management']) { + // load resource configuration + if ($this->urlSegment[0] != '') { + /** @var ObjectModel $object */ + $object = new $this->resourceList[$this->urlSegment[0]]['class'](); + if (isset($this->resourceList[$this->urlSegment[0]]['parameters_attribute'])) { + $this->resourceConfiguration = $object->getWebserviceParameters($this->resourceList[$this->urlSegment[0]]['parameters_attribute']); + } else { + $this->resourceConfiguration = $object->getWebserviceParameters(); + } + } + $success = false; + // execute the action + switch ($this->method) { + case 'GET': + case 'HEAD': + if ($this->executeEntityGetAndHead()) { + $success = true; + } + + break; + case 'POST': + if ($this->executeEntityPost()) { + $success = true; + } + + break; + case 'PUT': + if ($this->executeEntityPut()) { + $success = true; + } + + break; + case 'PATCH': + if ($this->executeEntityPatch()) { + $success = true; + } + + break; + case 'DELETE': + $this->executeEntityDelete(); + + break; + } + // Need to set an object for the WebserviceOutputBuilder object in any case + // because schema need to get webserviceParameters of this object + if (isset($object)) { + $this->objects['empty'] = $object; + } + } else { + // if the management is specific + $specificObjectName = 'WebserviceSpecificManagement' . ucfirst(Tools::toCamelCase($this->urlSegment[0])); + if (!class_exists($specificObjectName)) { + $this->setError(501, sprintf('The specific management class is not implemented for the "%s" entity.', $this->urlSegment[0]), 124); + } else { + $this->setObjectSpecificManagement(new $specificObjectName()); + $this->objectSpecificManagement->setObjectOutput($this->objOutput); + if ($this instanceof WebserviceRequest) { + $this->objectSpecificManagement->setWsObject($this); + } + + try { + $this->objectSpecificManagement->manage(); + } catch (WebserviceException $e) { + if ($e->getType() == WebserviceException::DID_YOU_MEAN) { + $this->setErrorDidYouMean($e->getStatus(), $e->getMessage(), $e->getWrongValue(), $e->getAvailableValues(), $e->getCode()); + } elseif ($e->getType() == WebserviceException::SIMPLE) { + $this->setError($e->getStatus(), $e->getMessage(), $e->getCode()); + } + } + } + } + } + } + $return = $this->returnOutput(); + unset( + $webservice_call, + $display_errors + ); + + return $return; + } + + protected function webserviceChecks() + { + return $this->isActivated() && $this->authenticate() && $this->groupShopExists($this->params) && $this->shopExists($this->params) && $this->shopHasRight($this->_key); + } + + /** + * Set a webservice error. + * + * @param int $status + * @param string $label + * @param int $code + */ + public function setError($status, $label, $code) + { + global $display_errors; + if (!isset($display_errors)) { + $display_errors = strtolower(ini_get('display_errors')) != 'off'; + } + if (isset($this->objOutput)) { + $this->objOutput->setStatus($status); + } + $this->errors[] = [$code, $label]; + } + + /** + * Set a webservice error and propose a new value near from the available values. + * + * @param int $num + * @param string $label + * @param string $value + * @param array $available_values + * @param int $code + */ + public function setErrorDidYouMean($num, $label, $value, $available_values, $code) + { + $this->setError($num, $label . '. Did you mean: "' . $this->getClosest($value, $available_values) . '"?' . (count($available_values) > 1 ? ' The full list is: "' . implode('", "', $available_values) . '"' : ''), $code); + } + + /** + * Return the nearest value picked in the values list. + * + * @param string $input + * @param array $words + * + * @return string + */ + protected function getClosest($input, $words) + { + $shortest = -1; + $closest = ''; + foreach ($words as $word) { + $lev = levenshtein($input, $word); + if ($lev == 0) { + $closest = $word; + $shortest = 0; + + break; + } + if ($lev <= $shortest || $shortest < 0) { + $closest = $word; + $shortest = $lev; + } + } + + return $closest; + } + + /** + * Used to replace the default PHP error handler, in order to display PHP errors in a XML format. + * + * @param int $errno contains the level of the error raised, as an integer + * @param string $errstr contains the error message, as a string + * @param string $errfile errfile, which contains the filename that the error was raised in, as a string + * @param int $errline errline, which contains the line number the error was raised at, as an integer + * + * @return bool Always return true to avoid the default PHP error handler + */ + public function webserviceErrorHandler($errno, $errstr, $errfile, $errline) + { + $display_errors = strtolower(ini_get('display_errors')) != 'off'; + if (!(error_reporting() & $errno) || $display_errors) { + return true; + } + + $errortype = [ + E_ERROR => 'Error', + E_WARNING => 'Warning', + E_PARSE => 'Parse', + E_NOTICE => 'Notice', + E_CORE_ERROR => 'Core Error', + E_CORE_WARNING => 'Core Warning', + E_COMPILE_ERROR => 'Compile Error', + E_COMPILE_WARNING => 'Compile Warning', + E_USER_ERROR => 'Error', + E_USER_WARNING => 'User warning', + E_USER_NOTICE => 'User notice', + E_STRICT => 'Runtime Notice', + E_RECOVERABLE_ERROR => 'Recoverable error', + ]; + $type = $errortype[$errno] ?? 'Unknown error'; + Tools::error_log('[PHP ' . $type . ' #' . $errno . '] ' . $errstr . ' (' . $errfile . ', line ' . $errline . ')'); + + switch ($errno) { + case E_ERROR: + WebserviceRequest::getInstance()->setError(500, '[PHP Error #' . $errno . '] ' . $errstr . ' (' . $errfile . ', line ' . $errline . ')', 2); + + break; + case E_WARNING: + WebserviceRequest::getInstance()->setError(500, '[PHP Warning #' . $errno . '] ' . $errstr . ' (' . $errfile . ', line ' . $errline . ')', 3); + + break; + case E_PARSE: + WebserviceRequest::getInstance()->setError(500, '[PHP Parse #' . $errno . '] ' . $errstr . ' (' . $errfile . ', line ' . $errline . ')', 4); + + break; + case E_NOTICE: + WebserviceRequest::getInstance()->setError(500, '[PHP Notice #' . $errno . '] ' . $errstr . ' (' . $errfile . ', line ' . $errline . ')', 5); + + break; + case E_CORE_ERROR: + WebserviceRequest::getInstance()->setError(500, '[PHP Core #' . $errno . '] ' . $errstr . ' (' . $errfile . ', line ' . $errline . ')', 6); + + break; + case E_CORE_WARNING: + WebserviceRequest::getInstance()->setError(500, '[PHP Core warning #' . $errno . '] ' . $errstr . ' (' . $errfile . ', line ' . $errline . ')', 7); + + break; + case E_COMPILE_ERROR: + WebserviceRequest::getInstance()->setError(500, '[PHP Compile #' . $errno . '] ' . $errstr . ' (' . $errfile . ', line ' . $errline . ')', 8); + + break; + case E_COMPILE_WARNING: + WebserviceRequest::getInstance()->setError(500, '[PHP Compile warning #' . $errno . '] ' . $errstr . ' (' . $errfile . ', line ' . $errline . ')', 9); + + break; + case E_USER_ERROR: + WebserviceRequest::getInstance()->setError(500, '[PHP Error #' . $errno . '] ' . $errstr . ' (' . $errfile . ', line ' . $errline . ')', 10); + + break; + case E_USER_WARNING: + WebserviceRequest::getInstance()->setError(500, '[PHP User warning #' . $errno . '] ' . $errstr . ' (' . $errfile . ', line ' . $errline . ')', 11); + + break; + case E_USER_NOTICE: + WebserviceRequest::getInstance()->setError(500, '[PHP User notice #' . $errno . '] ' . $errstr . ' (' . $errfile . ', line ' . $errline . ')', 12); + + break; + case E_STRICT: + WebserviceRequest::getInstance()->setError(500, '[PHP Strict #' . $errno . '] ' . $errstr . ' (' . $errfile . ', line ' . $errline . ')', 13); + + break; + case E_RECOVERABLE_ERROR: + WebserviceRequest::getInstance()->setError(500, '[PHP Recoverable error #' . $errno . '] ' . $errstr . ' (' . $errfile . ', line ' . $errline . ')', 14); + + break; + default: + WebserviceRequest::getInstance()->setError(500, '[PHP Unknown error #' . $errno . '] ' . $errstr . ' (' . $errfile . ', line ' . $errline . ')', 15); + } + + return true; + } + + /** + * Check if there is one or more error. + * + * @return bool + */ + protected function hasErrors() + { + return (bool) $this->errors; + } + + /** + * Check request authentication. + * + * @return bool + */ + protected function authenticate() + { + if ($this->hasErrors()) { + return false; + } + + if (null === $this->_key) { + $this->setError(401, 'Please enter the authentication key as the login. No password required', 16); + } else { + if (empty($this->_key)) { + $this->setError(401, 'Authentication key is empty', 17); + } elseif (strlen($this->_key) != '32') { + $this->setError(401, 'Invalid authentication key format', 18); + } else { + if (WebserviceKey::isKeyActive($this->_key)) { + $this->keyPermissions = WebserviceKey::getPermissionForAccount($this->_key); + } else { + $this->setError(401, 'Authentification key is not active', 20); + } + + if (!$this->keyPermissions) { + $this->setError(401, 'No permission for this authentication key', 21); + } + } + } + if ($this->hasErrors()) { + header('WWW-Authenticate: Basic realm="Welcome to PrestaShop Webservice, please enter the authentication key as the login. No password required."'); + $this->objOutput->setStatus(401); + + return false; + } else { + // only now we can say the access is authenticated + $this->_authenticated = true; + + return true; + } + } + + /** + * Check webservice activation. + * + * @return bool + */ + protected function isActivated() + { + if (!Configuration::get('PS_WEBSERVICE')) { + $this->setError(503, 'The PrestaShop webservice is disabled. Please activate it in the PrestaShop Back Office', 22); + + return false; + } + + return true; + } + + /** + * @param string $key + * + * @return bool + */ + protected function shopHasRight($key) + { + $sql = 'SELECT 1 + FROM ' . _DB_PREFIX_ . 'webservice_account wsa LEFT JOIN ' . _DB_PREFIX_ . 'webservice_account_shop wsas ON (wsa.id_webservice_account = wsas.id_webservice_account) + WHERE wsa.key = \'' . pSQL($key) . '\''; + $OR = []; + foreach (self::$shopIDs as $id_shop) { + $OR[] = ' wsas.id_shop = ' . (int) $id_shop . ' '; + } + $sql .= ' AND (' . implode('OR', $OR) . ') '; + if (!Db::getInstance()->getValue($sql)) { + $this->setError(403, 'No permission for this key on this shop', 132); + + return false; + } + + return true; + } + + /** + * @param array $params + * + * @return bool + */ + protected function shopExists($params) + { + if (is_countable(self::$shopIDs) && count(self::$shopIDs)) { + return true; + } + + if (isset($params['id_shop'])) { + if ($params['id_shop'] != 'all' && is_numeric($params['id_shop'])) { + Shop::setContext(Shop::CONTEXT_SHOP, (int) $params['id_shop']); + self::$shopIDs[] = (int) $params['id_shop']; + + return true; + } elseif ($params['id_shop'] == 'all') { + Shop::setContext(Shop::CONTEXT_ALL); + self::$shopIDs = Shop::getShops(true, null, true); + + return true; + } + } else { + self::$shopIDs[] = Context::getContext()->shop->id; + + return true; + } + $this->setError(404, 'This shop id does not exist', 999); + + return false; + } + + /** + * @param array $params + * + * @return bool + */ + protected function groupShopExists($params) + { + $idShopGroup = null; + if (isset($params['id_shop_group']) && is_numeric($params['id_shop_group'])) { + $idShopGroup = (int) $params['id_shop_group']; + } elseif (isset($params['id_group_shop']) && is_numeric($params['id_group_shop'])) { + $idShopGroup = (int) $params['id_group_shop']; + } + + if (null !== $idShopGroup) { + Shop::setContext(Shop::CONTEXT_GROUP, $idShopGroup); + self::$shopIDs = Shop::getShops(true, $idShopGroup, true); + if (!is_countable(self::$shopIDs) || count(self::$shopIDs) == 0) { + // @FIXME Set ErrorCode ! + $this->setError(500, 'This shop group doesn\'t have shops', 999); + + return false; + } + } + // id_shop_group isn't mandatory + return true; + } + + /** + * Check HTTP method. + * + * @return bool + */ + protected function checkHTTPMethod() + { + if (!in_array($this->method, ['GET', 'PUT', 'POST', 'PATCH', 'DELETE', 'HEAD'])) { + $this->setError(405, 'Method ' . $this->method . ' is not valid', 23); + } elseif (isset($this->urlSegment[0], $this->resourceList[$this->urlSegment[0]]['forbidden_method']) && in_array($this->method, $this->resourceList[$this->urlSegment[0]]['forbidden_method'])) { + $this->setError(405, 'Method ' . $this->method . ' is not allowed for the resource ' . $this->urlSegment[0], 101); + } elseif ($this->urlSegment[0] && !in_array($this->method, $this->keyPermissions[$this->urlSegment[0]])) { + $this->setError(405, 'Method ' . $this->method . ' is not allowed for the resource ' . $this->urlSegment[0] . ' with this authentication key', 25); + } else { + return true; + } + + return false; + } + + /** + * Check resource validity. + * + * @return bool + */ + protected function checkResource() + { + $this->resourceList = $this->getResources(); + $resourceNames = array_keys($this->resourceList); + if ($this->urlSegment[0] == '') { + $this->resourceConfiguration['objectsNodeName'] = 'resources'; + } elseif (in_array($this->urlSegment[0], $resourceNames)) { + if (!in_array($this->urlSegment[0], array_keys($this->keyPermissions))) { + $this->setError(401, 'Resource of type "' . $this->urlSegment[0] . '" is not allowed with this authentication key', 26); + + return false; + } + } else { + $this->setErrorDidYouMean(400, 'Resource of type "' . $this->urlSegment[0] . '" does not exists', $this->urlSegment[0], $resourceNames, 27); + + return false; + } + + return true; + } + + protected function setObjects() + { + $objects = []; + $arr_avoid_id = []; + $ids = []; + if (isset($this->urlFragments['id'])) { + preg_match('#^\[(.*)\]$#Ui', $this->urlFragments['id'], $matches); + if (count($matches) > 1) { + $ids = explode(',', $matches[1]); + } + } else { + $ids[] = (int) $this->urlSegment[1]; + } + if (!empty($ids)) { + foreach ($ids as $id) { + $object = new $this->resourceConfiguration['retrieveData']['className']((int) $id); + if (!$object->id) { + $arr_avoid_id[] = $id; + } else { + $objects[] = $object; + } + } + } + + if (!empty($arr_avoid_id) || empty($ids)) { + $this->setError(404, 'Id(s) not exists: ' . implode(', ', $arr_avoid_id), 87); + $this->_outputEnabled = true; + } + } + + protected function parseDisplayFields($str) + { + $bracket_level = 0; + $part = []; + $tmp = ''; + $str_len = strlen($str); + for ($i = 0; $i < $str_len; ++$i) { + if ($str[$i] == ',' && $bracket_level == 0) { + $part[] = $tmp; + $tmp = ''; + } else { + $tmp .= $str[$i]; + } + if ($str[$i] == '[') { + ++$bracket_level; + } + if ($str[$i] == ']') { + --$bracket_level; + } + } + if ($tmp != '') { + $part[] = $tmp; + } + $fields = []; + foreach ($part as $str) { + $field_name = trim(substr($str, 0, (strpos($str, '[') === false ? strlen($str) : strpos($str, '[')))); + if (!isset($fields[$field_name])) { + $fields[$field_name] = null; + } + if (strpos($str, '[') !== false) { + $sub_fields = substr($str, strpos($str, '[') + 1, strlen($str) - strpos($str, '[') - 2); + $tmp_array = []; + if (strpos($sub_fields, ',') !== false) { + $tmp_array = explode(',', $sub_fields); + } else { + $tmp_array = [$sub_fields]; + } + $fields[$field_name] = (is_array($fields[$field_name])) ? array_merge($fields[$field_name], $tmp_array) : $tmp_array; + } + } + + return $fields; + } + + public function setFieldsToDisplay() + { + // set the fields to display in the list : "full", "minimum", "field_1", "field_1,field_2,field_3" + if (isset($this->urlFragments['display'])) { + $this->fieldsToDisplay = $this->urlFragments['display']; + if ($this->fieldsToDisplay != 'full' && $this->fieldsToDisplay != 'minimum') { + preg_match('#^\[(.*)\]$#Ui', $this->fieldsToDisplay, $matches); + if (count($matches)) { + $error = false; + $fieldsToTest = $this->parseDisplayFields($matches[1]); + foreach ($fieldsToTest as $field_name => $part) { + // in case it is not an association + if (!is_array($part)) { + // We have to allow new specific field for price calculation too + $error = (!isset($this->resourceConfiguration['fields'][$field_name]) && !isset($this->urlFragments['price'][$field_name])); + } else { + // if this association does not exists + if (!array_key_exists($field_name, $this->resourceConfiguration['associations'])) { + $error = true; + } + + foreach ($part as $field) { + if ($field != 'id' && !array_key_exists($field, $this->resourceConfiguration['associations'][$field_name]['fields'])) { + $error = true; + + break; + } + } + } + if ($error) { + $this->setError(400, 'Unable to display this field "' . $field_name . (is_array($part) ? ' (details : ' . var_export($part, true) . ')' : '') . '". However, these are available: ' . implode(', ', array_keys($this->resourceConfiguration['fields'])), 35); + + return false; + } + } + $this->fieldsToDisplay = $fieldsToTest; + } else { + $this->setError(400, 'The \'display\' syntax is wrong. You can set \'full\' or \'[field_1,field_2,field_3,...]\'. These are available: ' . implode(', ', array_keys($this->resourceConfiguration['fields'])), 36); + + return false; + } + } + } + + return true; + } + + protected function manageFilters() + { + // filtered fields which can not use filters : hidden_fields + $available_filters = []; + // filtered i18n fields which can use filters + $i18n_available_filters = []; + foreach ($this->resourceConfiguration['fields'] as $fieldName => $field) { + if ((!isset($this->resourceConfiguration['hidden_fields']) || + (isset($this->resourceConfiguration['hidden_fields']) && !in_array($fieldName, $this->resourceConfiguration['hidden_fields'])))) { + if ((!isset($field['i18n']) || + (isset($field['i18n']) && !$field['i18n']))) { + $available_filters[] = $fieldName; + } else { + $i18n_available_filters[] = $fieldName; + } + } + } + + // Date feature : date=1 + if (!empty($this->urlFragments['date'])) { + if (!in_array('date_add', $available_filters)) { + $available_filters[] = 'date_add'; + } + if (!in_array('date_upd', $available_filters)) { + $available_filters[] = 'date_upd'; + } + if (!array_key_exists('date_add', $this->resourceConfiguration['fields'])) { + $this->resourceConfiguration['fields']['date_add'] = ['sqlId' => 'date_add']; + } + if (!array_key_exists('date_upd', $this->resourceConfiguration['fields'])) { + $this->resourceConfiguration['fields']['date_upd'] = ['sqlId' => 'date_upd']; + } + } else { + foreach ($available_filters as $key => $value) { + if ($value == 'date_add' || $value == 'date_upd') { + unset($available_filters[$key]); + } + } + } + + //construct SQL filter + $sql_filter = ''; + $sql_join = ''; + if ($this->urlFragments) { + $schema = 'schema'; + // if we have to display the schema + if (isset($this->urlFragments[$schema])) { + if ($this->urlFragments[$schema] == 'blank' || $this->urlFragments[$schema] == 'synopsis') { + $this->schemaToDisplay = $this->urlFragments[$schema]; + + return true; + } else { + $this->setError(400, 'Please select a schema of type \'synopsis\' to get the whole schema informations (which fields are required, which kind of content...) or \'blank\' to get an empty schema to fill before using POST request', 28); + + return false; + } + } else { + // if there are filters + if (isset($this->urlFragments['filter'])) { + foreach ($this->urlFragments['filter'] as $field => $url_param) { + if ($field != 'sort' && $field != 'limit') { + if (!in_array($field, $available_filters)) { + // if there are linked tables + if (isset($this->resourceConfiguration['linked_tables'][$field])) { + // contruct SQL join for linked tables + $sql_join .= 'LEFT JOIN `' . bqSQL(_DB_PREFIX_ . $this->resourceConfiguration['linked_tables'][$field]['table']) . '` `' . bqSQL($field) . '` ON (main.`' . bqSQL($this->resourceConfiguration['fields']['id']['sqlId']) . '` = `' . bqSQL($field) . '`.`' . bqSQL($this->resourceConfiguration['fields']['id']['sqlId']) . '`)' . "\n"; + + // construct SQL filter for linked tables + foreach ($url_param as $field2 => $value) { + if (isset($this->resourceConfiguration['linked_tables'][$field]['fields'][$field2])) { + $linked_field = $this->resourceConfiguration['linked_tables'][$field]['fields'][$field2]; + $sql_filter .= $this->getSQLRetrieveFilter($linked_field['sqlId'], $value, $field . '.'); + } else { + $list = array_keys($this->resourceConfiguration['linked_tables'][$field]['fields']); + $this->setErrorDidYouMean(400, 'This filter does not exist for this linked table', $field2, $list, 29); + + return false; + } + } + } elseif ($url_param != '' && in_array($field, $i18n_available_filters)) { + if (!is_array($url_param)) { + $url_param = [$url_param]; + } + $sql_join .= 'LEFT JOIN `' . bqSQL(_DB_PREFIX_ . $this->resourceConfiguration['retrieveData']['table']) . '_lang` AS main_i18n ON (main.`' . bqSQL($this->resourceConfiguration['fields']['id']['sqlId']) . '` = main_i18n.`' . bqSQL($this->resourceConfiguration['fields']['id']['sqlId']) . '`)' . "\n"; + foreach ($url_param as $field2 => $value) { + $linked_field = $this->resourceConfiguration['fields'][$field]; + $sql_filter .= $this->getSQLRetrieveFilter($linked_field['sqlId'], $value, 'main_i18n.'); + $language_filter = '[' . implode('|', $this->_available_languages) . ']'; + $sql_filter .= $this->getSQLRetrieveFilter('id_lang', $language_filter, 'main_i18n.'); + } + } elseif (is_array($url_param)) { + // if there are filters on linked tables but there are no linked table + if (isset($this->resourceConfiguration['linked_tables'])) { + $this->setErrorDidYouMean(400, 'This linked table does not exist', $field, array_keys($this->resourceConfiguration['linked_tables']), 30); + } else { + $this->setError(400, 'There is no existing linked table for this resource', 31); + } + + return false; + } else { + $this->setErrorDidYouMean(400, 'This filter does not exist', $field, $available_filters, 32); + + return false; + } + } elseif ($url_param == '') { + $this->setError(400, 'The filter "' . $field . '" is malformed.', 33); + + return false; + } else { + if (isset($this->resourceConfiguration['fields'][$field]['getter'])) { + $this->setError(400, 'The field "' . $field . '" is dynamic. It is not possible to filter GET query with this field.', 34); + + return false; + } else { + if (isset($this->resourceConfiguration['retrieveData']['tableAlias'])) { + $sql_filter .= $this->getSQLRetrieveFilter($this->resourceConfiguration['fields'][$field]['sqlId'], $url_param, $this->resourceConfiguration['retrieveData']['tableAlias'] . '.'); + } else { + $sql_filter .= $this->getSQLRetrieveFilter($this->resourceConfiguration['fields'][$field]['sqlId'], $url_param); + } + } + } + } + } + } + } + } + + if (!$this->setFieldsToDisplay()) { + return false; + } + // construct SQL Sort + $sql_sort = ''; + if (isset($this->urlFragments['sort'])) { + preg_match('#^\[(.*)\]$#Ui', $this->urlFragments['sort'], $matches); + if (count($matches) > 1) { + $sorts = explode(',', $matches[1]); + } else { + $sorts = [$this->urlFragments['sort']]; + } + + $sql_sort .= ' ORDER BY '; + + foreach ($sorts as $sort) { + $delimiterPosition = strrpos($sort, '_'); + $fieldName = $direction = ''; + if ($delimiterPosition !== false) { + $fieldName = substr($sort, 0, $delimiterPosition); + $direction = strtoupper(substr($sort, $delimiterPosition + 1)); + } + if ($delimiterPosition === false || !in_array($direction, ['ASC', 'DESC'])) { + $this->setError(400, 'The "sort" value has to be formed as this example: "field_ASC" or \'[field_1_DESC,field_2_ASC,field_3_ASC,...]\' ("field" has to be an available field)', 37); + + return false; + } elseif (!in_array($fieldName, $available_filters) && !in_array($fieldName, $i18n_available_filters)) { + $this->setError(400, 'Unable to filter by this field. However, these are available: ' . implode(', ', $available_filters) . ', for i18n fields:' . implode(', ', $i18n_available_filters), 38); + + return false; + } elseif (in_array($fieldName, $i18n_available_filters)) { + // for sort on i18n field + if (!preg_match('#main_i18n#', $sql_join)) { + $sql_join .= 'LEFT JOIN `' . _DB_PREFIX_ . bqSQL($this->resourceConfiguration['retrieveData']['table']) . '_lang` AS main_i18n ON (main.`' . bqSQL($this->resourceConfiguration['fields']['id']['sqlId']) . '` = main_i18n.`' . bqSQL($this->resourceConfiguration['fields']['id']['sqlId']) . '`)' . "\n"; + } + $sql_sort .= 'main_i18n.`' . bqSQL($this->resourceConfiguration['fields'][$fieldName]['sqlId']) . '` ' . $direction . ', '; // ORDER BY main_i18n.`field` ASC|DESC + } else { + /** @var ObjectModel $object */ + $object = new $this->resourceConfiguration['retrieveData']['className'](); + $assoc = Shop::getAssoTable($this->resourceConfiguration['retrieveData']['table']); + if ($assoc !== false && $assoc['type'] == 'shop' && ($object->isMultiShopField($this->resourceConfiguration['fields'][$fieldName]['sqlId']) || $fieldName == 'id')) { + $table_alias = 'multi_shop_' . $this->resourceConfiguration['retrieveData']['table']; + } else { + $table_alias = ''; + } + $sql_sort .= (isset($this->resourceConfiguration['retrieveData']['tableAlias']) ? '`' . bqSQL($this->resourceConfiguration['retrieveData']['tableAlias']) . '`.' : '`' . bqSQL($table_alias) . '`.') . '`' . pSQL($this->resourceConfiguration['fields'][$fieldName]['sqlId']) . '` ' . $direction . ', '; // ORDER BY `field` ASC|DESC + } + } + $sql_sort = rtrim($sql_sort, ', ') . "\n"; + } + + //construct SQL Limit + $sql_limit = ''; + if (isset($this->urlFragments['limit'])) { + $limitArgs = explode(',', $this->urlFragments['limit']); + if (count($limitArgs) > 2) { + $this->setError(400, 'The "limit" value has to be formed as this example: "5,25" or "10"', 39); + + return false; + } else { + $sql_limit .= ' LIMIT ' . (int) ($limitArgs[0]) . (isset($limitArgs[1]) ? ', ' . (int) ($limitArgs[1]) : '') . "\n"; // LIMIT X|X, Y + } + } + $filters['sql_join'] = $sql_join; + $filters['sql_filter'] = $sql_filter; + $filters['sql_sort'] = $sql_sort; + $filters['sql_limit'] = $sql_limit; + + return $filters; + } + + public function getFilteredObjectList() + { + $objects = []; + $filters = $this->manageFilters(); + + /* If we only need to display the synopsis, analyzing the first row is sufficient */ + if (isset($this->urlFragments['schema']) && in_array($this->urlFragments['schema'], ['blank', 'synopsis'])) { + $filters = ['sql_join' => '', 'sql_filter' => '', 'sql_sort' => '', 'sql_limit' => ' LIMIT 1']; + } + + $this->resourceConfiguration['retrieveData']['params'][] = $filters['sql_join']; + $this->resourceConfiguration['retrieveData']['params'][] = $filters['sql_filter']; + $this->resourceConfiguration['retrieveData']['params'][] = $filters['sql_sort']; + $this->resourceConfiguration['retrieveData']['params'][] = $filters['sql_limit']; + //list entities + + $tmp = new $this->resourceConfiguration['retrieveData']['className'](); + $sqlObjects = call_user_func_array([$tmp, $this->resourceConfiguration['retrieveData']['retrieveMethod']], $this->resourceConfiguration['retrieveData']['params']); + if ($sqlObjects) { + foreach ($sqlObjects as $sqlObject) { + if ($this->fieldsToDisplay == 'minimum') { + $obj = new $this->resourceConfiguration['retrieveData']['className'](); + $obj->id = (int) $sqlObject[$this->resourceConfiguration['fields']['id']['sqlId']]; + $objects[] = $obj; + } else { + $objects[] = new $this->resourceConfiguration['retrieveData']['className']((int) $sqlObject[$this->resourceConfiguration['fields']['id']['sqlId']]); + } + } + + return $objects; + } + } + + public function getFilteredObjectDetails() + { + if (!$this->setFieldsToDisplay()) { + return false; + } + + $objects = []; + if (!isset($this->urlFragments['display'])) { + $this->fieldsToDisplay = 'full'; + } + + //get entity details + $object = new $this->resourceConfiguration['retrieveData']['className']((int) $this->urlSegment[1]); + if ($object->id) { + $objects[] = $object; + // Check if Object is accessible for this/those id_shop + $assoc = Shop::getAssoTable($this->resourceConfiguration['retrieveData']['table']); + if ($assoc !== false) { + $check_shop_group = false; + + $sql = 'SELECT 1 + FROM `' . bqSQL(_DB_PREFIX_ . $this->resourceConfiguration['retrieveData']['table']); + if ($assoc['type'] != 'fk_shop') { + $sql .= '_' . $assoc['type']; + } else { + $def = ObjectModel::getDefinition($this->resourceConfiguration['retrieveData']['className']); + if (isset($def['fields']['id_shop_group'])) { + $check_shop_group = true; + } + } + $sql .= '`'; + + $OR = []; + foreach (self::$shopIDs as $id_shop) { + $OR[] = ' (id_shop = ' . (int) $id_shop . ($check_shop_group ? ' OR (id_shop = 0 AND id_shop_group=' . (int) Shop::getGroupFromShop((int) $id_shop) . ')' : '') . ') '; + } + + $check = ' WHERE (' . implode('OR', $OR) . ') AND `' . bqSQL($this->resourceConfiguration['fields']['id']['sqlId']) . '` = ' . (int) $this->urlSegment[1]; + if (!Db::getInstance()->getValue($sql . $check)) { + $this->setError(404, 'This ' . $this->resourceConfiguration['retrieveData']['className'] . ' (' . (int) $this->urlSegment[1] . ') does not exists on this shop', 131); + } + } + + return $objects; + } + if (!count($this->errors)) { + $this->objOutput->setStatus(404); + $this->_outputEnabled = false; + + return false; + } + } + + /** + * Execute GET and HEAD requests. + * + * Build filter + * Build fields display + * Build sort + * Build limit + * + * @return bool + */ + public function executeEntityGetAndHead() + { + if ($this->resourceConfiguration['objectsNodeName'] != 'resources') { + if (!isset($this->urlSegment[1]) || !strlen($this->urlSegment[1])) { + $return = $this->getFilteredObjectList(); + } else { + $return = $this->getFilteredObjectDetails(); + } + + if (!$return) { + return false; + } else { + $this->_outputEnabled = true; + $this->objects = $return; + } + } + + return true; + } + + /** + * Execute POST method on a PrestaShop entity. + * + * @return bool + */ + public function executeEntityPost() + { + return $this->saveEntityFromXml(201); + } + + /** + * Execute PUT method on a PrestaShop entity. + * + * @return bool + */ + public function executeEntityPut() + { + return $this->saveEntityFromXml(200); + } + + /** + * Execute PATCH method on a PrestaShop entity. + * + * @return bool + */ + public function executeEntityPatch(): bool + { + return $this->saveEntityFromXml(200); + } + + /** + * Execute DELETE method on a PrestaShop entity. + * + * @return void + */ + public function executeEntityDelete() + { + $objects = []; + $arr_avoid_id = []; + $ids = []; + if (isset($this->urlFragments['id'])) { + preg_match('#^\[(.*)\]$#Ui', $this->urlFragments['id'], $matches); + if (count($matches) > 1) { + $ids = explode(',', $matches[1]); + } + } else { + $ids[] = (int) $this->urlSegment[1]; + } + if (!empty($ids)) { + foreach ($ids as $id) { + $object = new $this->resourceConfiguration['retrieveData']['className']((int) $id); + if (!$object->id) { + $arr_avoid_id[] = $id; + } else { + $objects[] = $object; + } + } + } + + $postponeNTreeRegeneration = false; + + if (!empty($arr_avoid_id) || empty($ids)) { + $this->setError(404, 'Id(s) not exists: ' . implode(', ', $arr_avoid_id), 87); + $this->_outputEnabled = true; + } else { + foreach ($objects as $object) { + if ($object instanceof Category) { + $object->doNotRegenerateNTree = true; + $postponeNTreeRegeneration = true; + } + + /* @var ObjectModel $object */ + if (isset($this->resourceConfiguration['objectMethods']['delete'])) { + $result = $object->{$this->resourceConfiguration['objectMethods']['delete']}(); + } else { + $result = $object->delete(); + } + + if (!$result) { + $arr_avoid_id[] = $object->id; + } + } + if (!empty($arr_avoid_id)) { + $this->setError(500, 'Id(s) wasn\'t deleted: ' . implode(', ', $arr_avoid_id), 88); + $this->_outputEnabled = true; + } else { + $this->_outputEnabled = false; + } + } + + if ($postponeNTreeRegeneration) { + Category::regenerateEntireNtree(); + } + } + + /** + * save Entity Object from XML. + * + * @param int $successReturnCode + * + * @return bool + */ + protected function saveEntityFromXml($successReturnCode) + { + try { + $xml = new SimpleXMLElement($this->_inputXml); + } catch (Exception $error) { + $this->setError(500, 'XML error : ' . $error->getMessage() . "\n" . 'XML length : ' . strlen($this->_inputXml) . "\n" . 'Original XML : ' . $this->_inputXml, 127); + + return false; + } + + $xmlEntities = $xml->children(); + $object = null; + + $ids = []; + foreach ($xmlEntities as $entity) { + // To cast in string allow to check null values + if ((string) $entity->id != '') { + $ids[] = (int) $entity->id; + } + } + if ($this->method == 'PUT' || $this->method == 'PATCH') { + $ids2 = array_unique($ids); + if (count($ids2) != count($ids)) { + $this->setError(400, 'id is duplicate in request', 89); + + return false; + } + if (count($xmlEntities) != count($ids)) { + $this->setError(400, 'id is required when modifying a resource', 90); + + return false; + } + } elseif ($this->method == 'POST' && count($ids) > 0) { + $this->setError(400, 'id is forbidden when adding a new resource', 91); + + return false; + } + + $postponeNTreeRegeneration = false; + foreach ($xmlEntities as $xmlEntity) { + /** @var SimpleXMLElement $xmlEntity */ + $attributes = $xmlEntity->children(); + + /* @var ObjectModel $object */ + if ($this->method == 'POST') { + $object = new $this->resourceConfiguration['retrieveData']['className'](); + } elseif ($this->method == 'PUT' || $this->method == 'PATCH') { + $object = new $this->resourceConfiguration['retrieveData']['className']((int) $attributes->id); + if (!$object->id) { + $this->setError(404, 'Invalid ID', 92); + + return false; + } + } + + if ($object instanceof Category) { + $object->doNotRegenerateNTree = true; + $postponeNTreeRegeneration = true; + } + + $this->objects[] = $object; + $i18n = false; + // attributes + foreach ($this->resourceConfiguration['fields'] as $fieldName => $fieldProperties) { + // only process fields actually in the input XML + if ($this->method == 'PATCH' && !isset($attributes->$fieldName)) { + continue; + } + $sqlId = $fieldProperties['sqlId']; + if ($fieldName == 'id') { + $sqlId = $fieldName; + } + if (isset($attributes->$fieldName, $fieldProperties['sqlId']) && (!isset($fieldProperties['i18n']) || !$fieldProperties['i18n'])) { + if (isset($fieldProperties['setter'])) { + // if we have to use a specific setter + if (!$fieldProperties['setter']) { + // if it's forbidden to set this field + $this->setError(400, 'parameter "' . $fieldName . '" not writable. Please remove this attribute of this XML', 93); + + return false; + } else { + $object->{$fieldProperties['setter']}((string) $attributes->$fieldName); + } + } elseif (property_exists($object, $sqlId)) { + $object->$sqlId = (string) $attributes->$fieldName; + } else { + $this->setError(400, 'Parameter "' . $fieldName . '" can\'t be set to the object "' . $this->resourceConfiguration['retrieveData']['className'] . '"', 123); + } + } elseif (isset($fieldProperties['required']) && $fieldProperties['required'] && !$fieldProperties['i18n']) { + $this->setError(400, 'parameter "' . $fieldName . '" required', 41); + + return false; + } elseif ((!isset($fieldProperties['required']) || !$fieldProperties['required']) && property_exists($object, $sqlId)) { + $object->$sqlId = null; + } + if (isset($fieldProperties['i18n']) && $fieldProperties['i18n']) { + $i18n = true; + if (isset($attributes->$fieldName, $attributes->$fieldName->language)) { + foreach ($attributes->$fieldName->language as $lang) { + /* @var SimpleXMLElement $lang */ + $object->{$fieldName}[(int) $lang->attributes()->id] = (string) $lang; + } + } else { + $object->{$fieldName} = (string) $attributes->$fieldName; + } + } + } + + // Apply the modifiers if they exist + foreach ($this->resourceConfiguration['fields'] as $fieldName => $fieldProperties) { + if (isset($fieldProperties['modifier']['modifier']) && $fieldProperties['modifier']['http_method'] & constant('WebserviceRequest::HTTP_' . $this->method)) { + $object->{$fieldProperties['modifier']['modifier']}(); + } + } + + if (!$this->hasErrors()) { + if ($i18n && ($retValidateFieldsLang = $object->validateFieldsLang(false, true)) !== true) { + $this->setError(400, 'Validation error: "' . $retValidateFieldsLang . '"', 84); + + return false; + } elseif (($retValidateFields = $object->validateFields(false, true)) !== true) { + $this->setError(400, 'Validation error: "' . $retValidateFields . '"', 85); + + return false; + } else { + // Call alternative method for add/update + $objectMethod = ($this->method == 'POST' ? 'add' : 'update'); + if (isset($this->resourceConfiguration['objectMethods']) && array_key_exists($objectMethod, $this->resourceConfiguration['objectMethods'])) { + $objectMethod = $this->resourceConfiguration['objectMethods'][$objectMethod]; + } + $result = $object->{$objectMethod}(); + if ($result) { + if (isset($attributes->associations)) { + foreach ($attributes->associations->children() as $association) { + /** @var SimpleXMLElement $association */ + // associations + if (isset($this->resourceConfiguration['associations'][$association->getName()])) { + $assocItems = $association->children(); + $values = []; + foreach ($assocItems as $assocItem) { + /** @var SimpleXMLElement $assocItem */ + $fields = $assocItem->children(); + $entry = []; + foreach ($fields as $fieldName => $fieldValue) { + $entry[$fieldName] = (string) $fieldValue; + } + $values[] = $entry; + } + $setter = $this->resourceConfiguration['associations'][$association->getName()]['setter']; + if (null !== $setter && $setter && method_exists($object, $setter) && !$object->$setter($values)) { + $this->setError(500, 'Error occurred while setting the ' . $association->getName() . ' value', 85); + + return false; + } + } elseif ($association->getName() != 'i18n') { + $this->setError(400, 'The association "' . $association->getName() . '" does not exists', 86); + + return false; + } + } + } + $assoc = Shop::getAssoTable($this->resourceConfiguration['retrieveData']['table']); + if ($assoc !== false && $assoc['type'] != 'fk_shop') { + // PUT nor POST is destructive, no deletion + $sql = 'INSERT IGNORE INTO `' . bqSQL(_DB_PREFIX_ . $this->resourceConfiguration['retrieveData']['table'] . '_' . $assoc['type']) . '` (id_shop, `' . bqSQL($this->resourceConfiguration['fields']['id']['sqlId']) . '`) VALUES '; + foreach (self::$shopIDs as $id) { + $sql .= '(' . (int) $id . ',' . (int) $object->id . ')'; + if ($id != end(self::$shopIDs)) { + $sql .= ', '; + } + } + Db::getInstance()->execute($sql); + } + } else { + $this->setError(500, 'Unable to save resource', 46); + } + } + } + } + + if ($postponeNTreeRegeneration) { + Category::regenerateEntireNtree(); + } + + if (!$this->hasErrors()) { + $this->objOutput->setStatus($successReturnCode); + + return true; + } + + return false; + } + + /** + * @param string $sqlId + * @param string $filterValue + * @param string $tableAlias default value is 'main.' + * + * @return string + */ + protected function getSQLRetrieveFilter($sqlId, $filterValue, $tableAlias = 'main.') + { + return SQLUtils::getSQLRetrieveFilter($sqlId, $filterValue, $tableAlias); + } + + public function filterLanguage() + { + $arr_languages = []; + $length_values = strlen($this->urlFragments['language']); + // if just one language is asked + if (is_numeric($this->urlFragments['language'])) { + $arr_languages[] = (int) $this->urlFragments['language']; + } elseif (strpos($this->urlFragments['language'], '[') === 0 + // if a range or a list is asked + && strpos($this->urlFragments['language'], ']') === $length_values - 1) { + if (strpos($this->urlFragments['language'], '|') !== false + xor strpos($this->urlFragments['language'], ',') !== false) { + $params_values = str_replace([']', '['], '', $this->urlFragments['language']); + // it's a list + if (strpos($params_values, '|') !== false) { + $list_enabled_lang = explode('|', $params_values); + $arr_languages = $list_enabled_lang; + } elseif (strpos($params_values, ',') !== false) { + // it's a range + $range_enabled_lang = explode(',', $params_values); + if (count($range_enabled_lang) != 2) { + $this->setError(400, 'A range value for a language must contains only 2 values', 78); + + return false; + } + for ($i = $range_enabled_lang[0]; $i <= $range_enabled_lang[1]; ++$i) { + $arr_languages[] = $i; + } + } + } elseif (preg_match('#\[(\d)+\]#Ui', $this->urlFragments['language'], $match_lang)) { + $arr_languages[] = $match_lang[1]; + } + } else { + $this->setError(400, 'language value is wrong', 79); + + return false; + } + + $result = array_map('is_numeric', $arr_languages); + if (array_search(false, $result, true)) { + $this->setError(400, 'Language ID must be numeric', 80); + + return false; + } + + foreach ($arr_languages as $key => $id_lang) { + if (!Language::getLanguage($id_lang)) { + unset($arr_languages[$key]); + } + } + + return $arr_languages; + } + + /** + * Thanks to the (WebserviceOutputBuilder) WebserviceKey::objOutput + * Method build the output depend on the WebserviceRequest::outputFormat + * and set HTTP header parameters. + * + * @return array with displaying informations (used in the dispatcher) + */ + protected function returnOutput() + { + $return = []; + + // Write headers + $this->objOutput + ->setHeaderParams('Access-Time', (string) time()) + ->setHeaderParams('X-Powered-By', 'PrestaShop Webservice') + ->setHeaderParams('Execution-Time', (string) round(microtime(true) - $this->_startTime, 3)) + ; + + $return['type'] = strtolower($this->outputFormat); + + // write this header only now (avoid hackers happiness...) + if ($this->_authenticated) { + $this->objOutput->setHeaderParams('PSWS-Version', _PS_VERSION_); + } + + // If Specific Management is asked + if ($this->objectSpecificManagement instanceof WebserviceSpecificManagementInterface) { + try { + $return['content'] = $this->objectSpecificManagement->getContent(); + } catch (WebserviceException $e) { + if ($e->getType() == WebserviceException::DID_YOU_MEAN) { + $this->setErrorDidYouMean($e->getStatus(), $e->getMessage(), $e->getWrongValue(), $e->getAvailableValues(), $e->getCode()); + } elseif ($e->getType() == WebserviceException::SIMPLE) { + $this->setError($e->getStatus(), $e->getMessage(), $e->getCode()); + } + } + } + + // for use a general output + if (!$this->hasErrors() && $this->objectSpecificManagement == null) { + if (empty($this->objects)) { + try { + $return['content'] = $this->objOutput->getResourcesList($this->keyPermissions); + } catch (WebserviceException $e) { + if ($e->getType() == WebserviceException::DID_YOU_MEAN) { + $this->setErrorDidYouMean($e->getStatus(), $e->getMessage(), $e->getWrongValue(), $e->getAvailableValues(), $e->getCode()); + } elseif ($e->getType() == WebserviceException::SIMPLE) { + $this->setError($e->getStatus(), $e->getMessage(), $e->getCode()); + } + } + } else { + try { + if (isset($this->urlSegment[1]) && !empty($this->urlSegment[1])) { + $type_of_view = WebserviceOutputBuilder::VIEW_DETAILS; + } else { + $type_of_view = WebserviceOutputBuilder::VIEW_LIST; + } + + if (in_array($this->method, ['PUT', 'POST', 'PATCH'])) { + $type_of_view = WebserviceOutputBuilder::VIEW_DETAILS; + $this->fieldsToDisplay = 'full'; + } + + $return['content'] = $this->objOutput->getContent($this->objects, $this->schemaToDisplay, $this->fieldsToDisplay, $this->depth, $type_of_view); + } catch (WebserviceException $e) { + if ($e->getType() == WebserviceException::DID_YOU_MEAN) { + $this->setErrorDidYouMean($e->getStatus(), $e->getMessage(), $e->getWrongValue(), $e->getAvailableValues(), $e->getCode()); + } elseif ($e->getType() == WebserviceException::SIMPLE) { + $this->setError($e->getStatus(), $e->getMessage(), $e->getCode()); + } + } catch (Exception $e) { + $this->setError(500, $e->getMessage(), $e->getCode()); + } + } + } + + // if the output is not enable, delete the content + // the type content too + if (!$this->_outputEnabled) { + unset($return['type']); + if (isset($return['content'])) { + unset($return['content']); + } + } elseif (isset($return['content'])) { + $return['content_sha1'] = sha1($return['content']); + $this->objOutput->setHeaderParams('Content-Sha1', $return['content_sha1']); + } + + // if errors happens when creating returned xml, + // the usual xml content is replaced by the nice error handler content + if ($this->hasErrors()) { + $this->_outputEnabled = true; + $return['content'] = $this->objOutput->getErrors($this->errors); + } + + if (!isset($return['content']) || strlen($return['content']) <= 0) { + $this->objOutput->setHeaderParams('Content-Type', ''); + } + + $return['headers'] = $this->objOutput->buildHeader(); + restore_error_handler(); + + return $return; + } + + /** + * @return array + */ + public static function getallheaders() + { + $retarr = []; + + if (function_exists('apache_request_headers')) { + $headers = apache_request_headers(); + } else { + $headers = array_merge($_ENV, $_SERVER); + foreach ($headers as $key => $val) { + //we need this header + if (strpos(strtolower($key), 'content-type') !== false) { + continue; + } + if (strtoupper(substr($key, 0, 5)) != 'HTTP_') { + unset($headers[$key]); + } + } + } + //Normalize this array to Cased-Like-This structure. + foreach ($headers as $key => $value) { + $key = preg_replace('/^HTTP_/i', '', $key); + $key = str_replace(' ', '-', ucwords(strtolower(str_replace(['-', '_'], ' ', $key)))); + $retarr[$key] = $value; + } + ksort($retarr); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/additionalCustomerAddressFields.md b/modules/concepts/hooks/list-hooks/additionalCustomerAddressFields.md new file mode 100644 index 0000000000..bfa2d950f8 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/additionalCustomerAddressFields.md @@ -0,0 +1,106 @@ +--- +menuTitle: additionalCustomerAddressFields +title: additionalCustomerAddressFields +hidden: true +files: + - classes/form/CustomerAddressFormatter.php +types: + - frontoffice +hookTypes: + - legacy +--- + +# Hook : additionalCustomerAddressFields + +Located in : + + - classes/form/CustomerAddressFormatter.php + +## Parameters + +```php +Hook::exec('additionalCustomerAddressFields', ['fields' => &$format], null, true); + if (is_array($additionalAddressFormFields)) { + foreach ($additionalAddressFormFields as $moduleName => $additionnalFormFields) { + if (!is_array($additionnalFormFields)) { + continue; + } + + foreach ($additionnalFormFields as $formField) { + $formField->moduleName = $moduleName; + $format[$moduleName . '_' . $formField->getName()] = $formField; + } + } + } + + return $this->addConstraints( + $this->addMaxLength( + $format + ) + ); + } + + private function addConstraints(array $format) + { + foreach ($format as $field) { + if (!empty($this->definition[$field->getName()]['validate'])) { + $field->addConstraint( + $this->definition[$field->getName()]['validate'] + ); + } + } + + return $format; + } + + private function addMaxLength(array $format) + { + foreach ($format as $field) { + if (!empty($this->definition[$field->getName()]['size'])) { + $field->setMaxLength( + $this->definition[$field->getName()]['size'] + ); + } + } + + return $format; + } + + private function getFieldLabel($field) + { + // Country:name => Country, Country:iso_code => Country, + // same label regardless of which field is used for mapping. + $field = explode(':', $field)[0]; + + switch ($field) { + case 'alias': + return $this->translator->trans('Alias', [], 'Shop.Forms.Labels'); + case 'firstname': + return $this->translator->trans('First name', [], 'Shop.Forms.Labels'); + case 'lastname': + return $this->translator->trans('Last name', [], 'Shop.Forms.Labels'); + case 'address1': + return $this->translator->trans('Address', [], 'Shop.Forms.Labels'); + case 'address2': + return $this->translator->trans('Address Complement', [], 'Shop.Forms.Labels'); + case 'postcode': + return $this->translator->trans('Zip/Postal Code', [], 'Shop.Forms.Labels'); + case 'city': + return $this->translator->trans('City', [], 'Shop.Forms.Labels'); + case 'Country': + return $this->translator->trans('Country', [], 'Shop.Forms.Labels'); + case 'State': + return $this->translator->trans('State', [], 'Shop.Forms.Labels'); + case 'phone': + return $this->translator->trans('Phone', [], 'Shop.Forms.Labels'); + case 'phone_mobile': + return $this->translator->trans('Mobile phone', [], 'Shop.Forms.Labels'); + case 'company': + return $this->translator->trans('Company', [], 'Shop.Forms.Labels'); + case 'vat_number': + return $this->translator->trans('VAT number', [], 'Shop.Forms.Labels'); + case 'dni': + return $this->translator->trans('Identification number', [], 'Shop.Forms.Labels'); + case 'other': + return $this->translator->trans('Other', [], 'Shop.Forms.Labels'); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/additionalCustomerFormFields.md b/modules/concepts/hooks/list-hooks/additionalCustomerFormFields.md new file mode 100644 index 0000000000..e45f3f1b8c --- /dev/null +++ b/modules/concepts/hooks/list-hooks/additionalCustomerFormFields.md @@ -0,0 +1,51 @@ +--- +menuTitle: additionalCustomerFormFields +title: additionalCustomerFormFields +hidden: true +files: + - classes/form/CustomerFormatter.php +types: + - frontoffice +hookTypes: + - legacy +--- + +# Hook : additionalCustomerFormFields + +Located in : + + - classes/form/CustomerFormatter.php + +## Parameters + +```php +Hook::exec('additionalCustomerFormFields', ['fields' => &$format], null, true); + + if (is_array($additionalCustomerFormFields)) { + foreach ($additionalCustomerFormFields as $moduleName => $additionnalFormFields) { + if (!is_array($additionnalFormFields)) { + continue; + } + + foreach ($additionnalFormFields as $formField) { + $formField->moduleName = $moduleName; + $format[$moduleName . '_' . $formField->getName()] = $formField; + } + } + } + + // TODO: TVA etc.? + + return $this->addConstraints($format); + } + + private function addConstraints(array $format) + { + $constraints = Customer::$definition['fields']; + + foreach ($format as $field) { + if (!empty($constraints[$field->getName()]['validate'])) { + $field->addConstraint( + $constraints[$field->getName()]['validate'] + ); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayAdditionalCustomerAddressFields.md b/modules/concepts/hooks/list-hooks/displayAdditionalCustomerAddressFields.md new file mode 100644 index 0000000000..af5b058bd2 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/displayAdditionalCustomerAddressFields.md @@ -0,0 +1,23 @@ +--- +menuTitle: displayAdditionalCustomerAddressFields +title: displayAdditionalCustomerAddressFields +hidden: true +files: + - themes/classic/templates/customer/_partials/block-address.tpl +types: + - frontoffice +hookTypes: + - smarty +--- + +# Hook : displayAdditionalCustomerAddressFields + +Located in : + + - themes/classic/templates/customer/_partials/block-address.tpl + +## Parameters + +```php +{hook h='displayAdditionalCustomerAddressFields' address=$address} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayAdminAfterHeader.md b/modules/concepts/hooks/list-hooks/displayAdminAfterHeader.md new file mode 100644 index 0000000000..9592c18de9 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/displayAdminAfterHeader.md @@ -0,0 +1,23 @@ +--- +menuTitle: displayAdminAfterHeader +title: displayAdminAfterHeader +hidden: true +files: + - admin784x07v4swfhm9fgvc0/themes/new-theme/template/light_display_layout.tpl +types: + - backoffice +hookTypes: + - smarty +--- + +# Hook : displayAdminAfterHeader + +Located in : + + - admin784x07v4swfhm9fgvc0/themes/new-theme/template/light_display_layout.tpl + +## Parameters + +```php +{hook h='displayAdminAfterHeader'} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayAdminCustomers.md b/modules/concepts/hooks/list-hooks/displayAdminCustomers.md new file mode 100644 index 0000000000..44535b3d3c --- /dev/null +++ b/modules/concepts/hooks/list-hooks/displayAdminCustomers.md @@ -0,0 +1,23 @@ +--- +menuTitle: displayAdminCustomers +title: displayAdminCustomers +hidden: true +files: + - src/PrestaShopBundle/Resources/views/Admin/Sell/Customer/view.html.twig +types: + - backoffice +hookTypes: + - twig +--- + +# Hook : displayAdminCustomers + +Located in : + + - src/PrestaShopBundle/Resources/views/Admin/Sell/Customer/view.html.twig + +## Parameters + +```php +{{ renderhook('displayAdminCustomers', {'id_customer': customerInformation.customerId.value}) }} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayAdminEndContent.md b/modules/concepts/hooks/list-hooks/displayAdminEndContent.md new file mode 100644 index 0000000000..ca84ee8bde --- /dev/null +++ b/modules/concepts/hooks/list-hooks/displayAdminEndContent.md @@ -0,0 +1,23 @@ +--- +menuTitle: displayAdminEndContent +title: displayAdminEndContent +hidden: true +files: + - admin784x07v4swfhm9fgvc0/themes/new-theme/template/light_display_layout.tpl +types: + - backoffice +hookTypes: + - smarty +--- + +# Hook : displayAdminEndContent + +Located in : + + - admin784x07v4swfhm9fgvc0/themes/new-theme/template/light_display_layout.tpl + +## Parameters + +```php +{hook h='displayAdminEndContent'} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayAdminForm.md b/modules/concepts/hooks/list-hooks/displayAdminForm.md new file mode 100644 index 0000000000..d4b85ccf3c --- /dev/null +++ b/modules/concepts/hooks/list-hooks/displayAdminForm.md @@ -0,0 +1,23 @@ +--- +menuTitle: displayAdminForm +title: displayAdminForm +hidden: true +files: + - admin784x07v4swfhm9fgvc0/themes/default/template/helpers/form/form.tpl +types: + - backoffice +hookTypes: + - smarty +--- + +# Hook : displayAdminForm + +Located in : + + - admin784x07v4swfhm9fgvc0/themes/default/template/helpers/form/form.tpl + +## Parameters + +```php +{hook h='displayAdminForm' fieldset=$f} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayAdminGridTableAfter.md b/modules/concepts/hooks/list-hooks/displayAdminGridTableAfter.md new file mode 100644 index 0000000000..7c81cf9fd8 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/displayAdminGridTableAfter.md @@ -0,0 +1,28 @@ +--- +menuTitle: displayAdminGridTableAfter +title: displayAdminGridTableAfter +hidden: true +files: + - src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Blocks/table.html.twig +types: + - backoffice +hookTypes: + - twig +--- + +# Hook : displayAdminGridTableAfter + +Located in : + + - src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Blocks/table.html.twig + +## Parameters + +```php +{{ renderhook('displayAdminGridTableAfter', { + 'grid': grid, + 'legacy_controller': app.request.attributes.get('_legacy_controller'), + 'controller': app.request.attributes.get('_controller') + }) +}} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayAdminGridTableBefore.md b/modules/concepts/hooks/list-hooks/displayAdminGridTableBefore.md new file mode 100644 index 0000000000..bd03f74f40 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/displayAdminGridTableBefore.md @@ -0,0 +1,28 @@ +--- +menuTitle: displayAdminGridTableBefore +title: displayAdminGridTableBefore +hidden: true +files: + - src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Blocks/table.html.twig +types: + - backoffice +hookTypes: + - twig +--- + +# Hook : displayAdminGridTableBefore + +Located in : + + - src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Blocks/table.html.twig + +## Parameters + +```php +{{ renderhook('displayAdminGridTableBefore', { + 'grid': grid, + 'legacy_controller': app.request.attributes.get('_legacy_controller'), + 'controller': app.request.attributes.get('_controller') + }) +}} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayAdminListAfter.md b/modules/concepts/hooks/list-hooks/displayAdminListAfter.md new file mode 100644 index 0000000000..f143e66bc3 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/displayAdminListAfter.md @@ -0,0 +1,23 @@ +--- +menuTitle: displayAdminListAfter +title: displayAdminListAfter +hidden: true +files: + - admin784x07v4swfhm9fgvc0/themes/default/template/helpers/list/list_footer.tpl +types: + - backoffice +hookTypes: + - smarty +--- + +# Hook : displayAdminListAfter + +Located in : + + - admin784x07v4swfhm9fgvc0/themes/default/template/helpers/list/list_footer.tpl + +## Parameters + +```php +{hook h='displayAdminListAfter'} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayAdminListBefore.md b/modules/concepts/hooks/list-hooks/displayAdminListBefore.md new file mode 100644 index 0000000000..b5bb4fa8f6 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/displayAdminListBefore.md @@ -0,0 +1,23 @@ +--- +menuTitle: displayAdminListBefore +title: displayAdminListBefore +hidden: true +files: + - admin784x07v4swfhm9fgvc0/themes/default/template/helpers/list/list_header.tpl +types: + - backoffice +hookTypes: + - smarty +--- + +# Hook : displayAdminListBefore + +Located in : + + - admin784x07v4swfhm9fgvc0/themes/default/template/helpers/list/list_header.tpl + +## Parameters + +```php +{hook h='displayAdminListBefore'} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayAdminNavBarBeforeEnd.md b/modules/concepts/hooks/list-hooks/displayAdminNavBarBeforeEnd.md new file mode 100644 index 0000000000..6765ad501e --- /dev/null +++ b/modules/concepts/hooks/list-hooks/displayAdminNavBarBeforeEnd.md @@ -0,0 +1,23 @@ +--- +menuTitle: displayAdminNavBarBeforeEnd +title: displayAdminNavBarBeforeEnd +hidden: true +files: + - admin784x07v4swfhm9fgvc0/themes/new-theme/template/components/layout/nav_bar.tpl +types: + - backoffice +hookTypes: + - smarty +--- + +# Hook : displayAdminNavBarBeforeEnd + +Located in : + + - admin784x07v4swfhm9fgvc0/themes/new-theme/template/components/layout/nav_bar.tpl + +## Parameters + +```php +{hook h='displayAdminNavBarBeforeEnd'} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayAdminOptions.md b/modules/concepts/hooks/list-hooks/displayAdminOptions.md new file mode 100644 index 0000000000..d2482c4962 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/displayAdminOptions.md @@ -0,0 +1,23 @@ +--- +menuTitle: displayAdminOptions +title: displayAdminOptions +hidden: true +files: + - admin784x07v4swfhm9fgvc0/themes/default/template/helpers/options/options.tpl +types: + - backoffice +hookTypes: + - smarty +--- + +# Hook : displayAdminOptions + +Located in : + + - admin784x07v4swfhm9fgvc0/themes/default/template/helpers/options/options.tpl + +## Parameters + +```php +{hook h='displayAdminOptions'} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayAdminOrder.md b/modules/concepts/hooks/list-hooks/displayAdminOrder.md new file mode 100644 index 0000000000..b3e020d7d7 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/displayAdminOrder.md @@ -0,0 +1,23 @@ +--- +menuTitle: displayAdminOrder +title: displayAdminOrder +hidden: true +files: + - src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/view.html.twig +types: + - backoffice +hookTypes: + - twig +--- + +# Hook : displayAdminOrder + +Located in : + + - src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/view.html.twig + +## Parameters + +```php +{{ renderhook('displayAdminOrder', {'id_order': orderForViewing.id}) }} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayAdminOrderCreateExtraButtons.md b/modules/concepts/hooks/list-hooks/displayAdminOrderCreateExtraButtons.md new file mode 100644 index 0000000000..0ca935d458 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/displayAdminOrderCreateExtraButtons.md @@ -0,0 +1,23 @@ +--- +menuTitle: displayAdminOrderCreateExtraButtons +title: displayAdminOrderCreateExtraButtons +hidden: true +files: + - src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/Create/summary.html.twig +types: + - backoffice +hookTypes: + - twig +--- + +# Hook : displayAdminOrderCreateExtraButtons + +Located in : + + - src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/Create/summary.html.twig + +## Parameters + +```php +{{ renderhook('displayAdminOrderCreateExtraButtons') }} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayAdminOrderMain.md b/modules/concepts/hooks/list-hooks/displayAdminOrderMain.md new file mode 100644 index 0000000000..5cfa5e30f2 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/displayAdminOrderMain.md @@ -0,0 +1,23 @@ +--- +menuTitle: displayAdminOrderMain +title: displayAdminOrderMain +hidden: true +files: + - src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/view.html.twig +types: + - backoffice +hookTypes: + - twig +--- + +# Hook : displayAdminOrderMain + +Located in : + + - src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/view.html.twig + +## Parameters + +```php +{{ renderhook('displayAdminOrderMain', {'id_order': orderForViewing.id}) }} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayAdminOrderMainBottom.md b/modules/concepts/hooks/list-hooks/displayAdminOrderMainBottom.md new file mode 100644 index 0000000000..e308987755 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/displayAdminOrderMainBottom.md @@ -0,0 +1,23 @@ +--- +menuTitle: displayAdminOrderMainBottom +title: displayAdminOrderMainBottom +hidden: true +files: + - src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/view.html.twig +types: + - backoffice +hookTypes: + - twig +--- + +# Hook : displayAdminOrderMainBottom + +Located in : + + - src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/view.html.twig + +## Parameters + +```php +{{ renderhook('displayAdminOrderMainBottom', {'id_order': orderForViewing.id}) }} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayAdminOrderSide.md b/modules/concepts/hooks/list-hooks/displayAdminOrderSide.md new file mode 100644 index 0000000000..9a80dac84a --- /dev/null +++ b/modules/concepts/hooks/list-hooks/displayAdminOrderSide.md @@ -0,0 +1,23 @@ +--- +menuTitle: displayAdminOrderSide +title: displayAdminOrderSide +hidden: true +files: + - src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/view.html.twig +types: + - backoffice +hookTypes: + - twig +--- + +# Hook : displayAdminOrderSide + +Located in : + + - src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/view.html.twig + +## Parameters + +```php +{{ renderhook('displayAdminOrderSide', {'id_order': orderForViewing.id}) }} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayAdminOrderSideBottom.md b/modules/concepts/hooks/list-hooks/displayAdminOrderSideBottom.md new file mode 100644 index 0000000000..bebb52fc8e --- /dev/null +++ b/modules/concepts/hooks/list-hooks/displayAdminOrderSideBottom.md @@ -0,0 +1,23 @@ +--- +menuTitle: displayAdminOrderSideBottom +title: displayAdminOrderSideBottom +hidden: true +files: + - src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/view.html.twig +types: + - backoffice +hookTypes: + - twig +--- + +# Hook : displayAdminOrderSideBottom + +Located in : + + - src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/view.html.twig + +## Parameters + +```php +{{ renderhook('displayAdminOrderSideBottom', {'id_order': orderForViewing.id}) }} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayAdminProductsCombinationBottom.md b/modules/concepts/hooks/list-hooks/displayAdminProductsCombinationBottom.md new file mode 100644 index 0000000000..2dc3a4d5af --- /dev/null +++ b/modules/concepts/hooks/list-hooks/displayAdminProductsCombinationBottom.md @@ -0,0 +1,23 @@ +--- +menuTitle: displayAdminProductsCombinationBottom +title: displayAdminProductsCombinationBottom +hidden: true +files: + - src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Forms/form_combination.html.twig +types: + - backoffice +hookTypes: + - twig +--- + +# Hook : displayAdminProductsCombinationBottom + +Located in : + + - src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Forms/form_combination.html.twig + +## Parameters + +```php +{{ renderhook('displayAdminProductsCombinationBottom', { 'id_product': form.vars.value.id_product, 'id_product_attribute': form.vars.value.id_product_attribute }) }} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayAdminProductsMainStepLeftColumnBottom.md b/modules/concepts/hooks/list-hooks/displayAdminProductsMainStepLeftColumnBottom.md new file mode 100644 index 0000000000..07e0cf3eb4 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/displayAdminProductsMainStepLeftColumnBottom.md @@ -0,0 +1,23 @@ +--- +menuTitle: displayAdminProductsMainStepLeftColumnBottom +title: displayAdminProductsMainStepLeftColumnBottom +hidden: true +files: + - src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/essentials.html.twig +types: + - backoffice +hookTypes: + - twig +--- + +# Hook : displayAdminProductsMainStepLeftColumnBottom + +Located in : + + - src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/essentials.html.twig + +## Parameters + +```php +{{ renderhook('displayAdminProductsMainStepLeftColumnBottom', { 'id_product': productId }) }} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayAdminProductsMainStepLeftColumnMiddle.md b/modules/concepts/hooks/list-hooks/displayAdminProductsMainStepLeftColumnMiddle.md new file mode 100644 index 0000000000..8ecafdc68b --- /dev/null +++ b/modules/concepts/hooks/list-hooks/displayAdminProductsMainStepLeftColumnMiddle.md @@ -0,0 +1,23 @@ +--- +menuTitle: displayAdminProductsMainStepLeftColumnMiddle +title: displayAdminProductsMainStepLeftColumnMiddle +hidden: true +files: + - src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/essentials.html.twig +types: + - backoffice +hookTypes: + - twig +--- + +# Hook : displayAdminProductsMainStepLeftColumnMiddle + +Located in : + + - src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/essentials.html.twig + +## Parameters + +```php +{{ renderhook('displayAdminProductsMainStepLeftColumnMiddle', { 'id_product': productId }) }} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayAdminProductsMainStepRightColumnBottom.md b/modules/concepts/hooks/list-hooks/displayAdminProductsMainStepRightColumnBottom.md new file mode 100644 index 0000000000..c27ec2d38b --- /dev/null +++ b/modules/concepts/hooks/list-hooks/displayAdminProductsMainStepRightColumnBottom.md @@ -0,0 +1,23 @@ +--- +menuTitle: displayAdminProductsMainStepRightColumnBottom +title: displayAdminProductsMainStepRightColumnBottom +hidden: true +files: + - src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/essentials.html.twig +types: + - backoffice +hookTypes: + - twig +--- + +# Hook : displayAdminProductsMainStepRightColumnBottom + +Located in : + + - src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/essentials.html.twig + +## Parameters + +```php +{{ renderhook('displayAdminProductsMainStepRightColumnBottom', { 'id_product': productId }) }} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayAdminProductsOptionsStepBottom.md b/modules/concepts/hooks/list-hooks/displayAdminProductsOptionsStepBottom.md new file mode 100644 index 0000000000..0f0aed60af --- /dev/null +++ b/modules/concepts/hooks/list-hooks/displayAdminProductsOptionsStepBottom.md @@ -0,0 +1,23 @@ +--- +menuTitle: displayAdminProductsOptionsStepBottom +title: displayAdminProductsOptionsStepBottom +hidden: true +files: + - src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/options.html.twig +types: + - backoffice +hookTypes: + - twig +--- + +# Hook : displayAdminProductsOptionsStepBottom + +Located in : + + - src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/options.html.twig + +## Parameters + +```php +{{ renderhook('displayAdminProductsOptionsStepBottom', { 'id_product': productId }) }} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayAdminProductsOptionsStepTop.md b/modules/concepts/hooks/list-hooks/displayAdminProductsOptionsStepTop.md new file mode 100644 index 0000000000..ca91b03fff --- /dev/null +++ b/modules/concepts/hooks/list-hooks/displayAdminProductsOptionsStepTop.md @@ -0,0 +1,23 @@ +--- +menuTitle: displayAdminProductsOptionsStepTop +title: displayAdminProductsOptionsStepTop +hidden: true +files: + - src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/options.html.twig +types: + - backoffice +hookTypes: + - twig +--- + +# Hook : displayAdminProductsOptionsStepTop + +Located in : + + - src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/options.html.twig + +## Parameters + +```php +{{ renderhook('displayAdminProductsOptionsStepTop', { 'id_product': productId }) }} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayAdminProductsPriceStepBottom.md b/modules/concepts/hooks/list-hooks/displayAdminProductsPriceStepBottom.md new file mode 100644 index 0000000000..7ec1cc4e57 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/displayAdminProductsPriceStepBottom.md @@ -0,0 +1,23 @@ +--- +menuTitle: displayAdminProductsPriceStepBottom +title: displayAdminProductsPriceStepBottom +hidden: true +files: + - src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/pricing.html.twig +types: + - backoffice +hookTypes: + - twig +--- + +# Hook : displayAdminProductsPriceStepBottom + +Located in : + + - src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/pricing.html.twig + +## Parameters + +```php +{{ renderhook('displayAdminProductsPriceStepBottom', { 'id_product': productId }) }} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayAdminProductsQuantitiesStepBottom.md b/modules/concepts/hooks/list-hooks/displayAdminProductsQuantitiesStepBottom.md new file mode 100644 index 0000000000..1aae7bad74 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/displayAdminProductsQuantitiesStepBottom.md @@ -0,0 +1,23 @@ +--- +menuTitle: displayAdminProductsQuantitiesStepBottom +title: displayAdminProductsQuantitiesStepBottom +hidden: true +files: + - src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/combinations.html.twig +types: + - backoffice +hookTypes: + - twig +--- + +# Hook : displayAdminProductsQuantitiesStepBottom + +Located in : + + - src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/combinations.html.twig + +## Parameters + +```php +{{ renderhook('displayAdminProductsQuantitiesStepBottom', { 'id_product': productId }) }} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayAdminProductsSeoStepBottom.md b/modules/concepts/hooks/list-hooks/displayAdminProductsSeoStepBottom.md new file mode 100644 index 0000000000..606d4297e7 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/displayAdminProductsSeoStepBottom.md @@ -0,0 +1,23 @@ +--- +menuTitle: displayAdminProductsSeoStepBottom +title: displayAdminProductsSeoStepBottom +hidden: true +files: + - src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Forms/form_seo.html.twig +types: + - backoffice +hookTypes: + - twig +--- + +# Hook : displayAdminProductsSeoStepBottom + +Located in : + + - src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Forms/form_seo.html.twig + +## Parameters + +```php +{{ renderhook('displayAdminProductsSeoStepBottom', { 'id_product': productId }) }} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayAdminProductsShippingStepBottom.md b/modules/concepts/hooks/list-hooks/displayAdminProductsShippingStepBottom.md new file mode 100644 index 0000000000..891a6da7fe --- /dev/null +++ b/modules/concepts/hooks/list-hooks/displayAdminProductsShippingStepBottom.md @@ -0,0 +1,23 @@ +--- +menuTitle: displayAdminProductsShippingStepBottom +title: displayAdminProductsShippingStepBottom +hidden: true +files: + - src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Forms/form_shipping.html.twig +types: + - backoffice +hookTypes: + - twig +--- + +# Hook : displayAdminProductsShippingStepBottom + +Located in : + + - src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Forms/form_shipping.html.twig + +## Parameters + +```php +{{ renderhook('displayAdminProductsShippingStepBottom', { 'id_product': id_product }) }} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayAdminStatsModules.md b/modules/concepts/hooks/list-hooks/displayAdminStatsModules.md new file mode 100644 index 0000000000..ee1f9f44ac --- /dev/null +++ b/modules/concepts/hooks/list-hooks/displayAdminStatsModules.md @@ -0,0 +1,124 @@ +--- +menuTitle: displayAdminStatsModules +title: displayAdminStatsModules +hidden: true +files: + - controllers/admin/AdminStatsTabController.php +types: + - backoffice +hookTypes: + - legacy +--- + +# Hook : displayAdminStatsModules + +Located in : + + - controllers/admin/AdminStatsTabController.php + +## Parameters + +```php +Hook::exec('displayAdminStatsModules', [], $module_instance->id); + } + } + + $tpl->assign([ + 'module_name' => $module_name, + 'module_instance' => isset($module_instance) ? $module_instance : null, + 'hook' => isset($hook) ? $hook : null, + ]); + + return $tpl->fetch(); + } + + public function postProcess() + { + $this->context = Context::getContext(); + + $this->processDateRange(); + + if (Tools::getValue('submitSettings')) { + if ($this->access('edit')) { + self::$currentIndex .= '&module=' . Tools::getValue('module'); + Configuration::updateValue('PS_STATS_RENDER', Tools::getValue('PS_STATS_RENDER', Configuration::get('PS_STATS_RENDER'))); + Configuration::updateValue('PS_STATS_GRID_RENDER', Tools::getValue('PS_STATS_GRID_RENDER', Configuration::get('PS_STATS_GRID_RENDER'))); + Configuration::updateValue('PS_STATS_OLD_CONNECT_AUTO_CLEAN', Tools::getValue('PS_STATS_OLD_CONNECT_AUTO_CLEAN', Configuration::get('PS_STATS_OLD_CONNECT_AUTO_CLEAN'))); + } else { + $this->errors[] = $this->trans('You do not have permission to edit this.', [], 'Admin.Notifications.Error'); + } + } + } + + public function processDateRange() + { + if (Tools::isSubmit('submitDatePicker')) { + if ((!Validate::isDate($from = Tools::getValue('datepickerFrom')) || !Validate::isDate($to = Tools::getValue('datepickerTo'))) || (strtotime($from) > strtotime($to))) { + $this->errors[] = $this->trans('The specified date is invalid.', [], 'Admin.Stats.Notification'); + } + } + if (Tools::isSubmit('submitDateDay')) { + $from = date('Y-m-d'); + $to = date('Y-m-d'); + } + if (Tools::isSubmit('submitDateDayPrev')) { + $yesterday = time() - 60 * 60 * 24; + $from = date('Y-m-d', $yesterday); + $to = date('Y-m-d', $yesterday); + } + if (Tools::isSubmit('submitDateMonth')) { + $from = date('Y-m-01'); + $to = date('Y-m-t'); + } + if (Tools::isSubmit('submitDateMonthPrev')) { + $m = (date('m') == 1 ? 12 : date('m') - 1); + $y = ($m == 12 ? date('Y') - 1 : date('Y')); + $from = $y . '-' . $m . '-01'; + $to = $y . '-' . $m . date('-t', mktime(12, 0, 0, $m, 15, $y)); + } + if (Tools::isSubmit('submitDateYear')) { + $from = date('Y-01-01'); + $to = date('Y-12-31'); + } + if (Tools::isSubmit('submitDateYearPrev')) { + $from = (date('Y') - 1) . date('-01-01'); + $to = (date('Y') - 1) . date('-12-31'); + } + if (isset($from, $to) && !count($this->errors)) { + $this->context->employee->stats_date_from = $from; + $this->context->employee->stats_date_to = $to; + $this->context->employee->update(); + if (!$this->isXmlHttpRequest()) { + Tools::redirectAdmin($_SERVER['REQUEST_URI']); + } + } + } + + public function ajaxProcessSetDashboardDateRange() + { + $this->processDateRange(); + + if ($this->isXmlHttpRequest()) { + if (is_array($this->errors) && count($this->errors)) { + die(json_encode( + [ + 'has_errors' => true, + 'errors' => [$this->errors], + 'date_from' => $this->context->employee->stats_date_from, + 'date_to' => $this->context->employee->stats_date_to, ] + )); + } else { + die(json_encode( + [ + 'has_errors' => false, + 'date_from' => $this->context->employee->stats_date_from, + 'date_to' => $this->context->employee->stats_date_to, ] + )); + } + } + } + + protected function getDate() + { + $year = isset($this->context->cookie->stats_year) ? $this->context->cookie->stats_year : date('Y'); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayAdminThemesListAfter.md b/modules/concepts/hooks/list-hooks/displayAdminThemesListAfter.md new file mode 100644 index 0000000000..b4228eb354 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/displayAdminThemesListAfter.md @@ -0,0 +1,23 @@ +--- +menuTitle: displayAdminThemesListAfter +title: displayAdminThemesListAfter +hidden: true +files: + - src/PrestaShopBundle/Resources/views/Admin/Improve/Design/Theme/index.html.twig +types: + - backoffice +hookTypes: + - twig +--- + +# Hook : displayAdminThemesListAfter + +Located in : + + - src/PrestaShopBundle/Resources/views/Admin/Improve/Design/Theme/index.html.twig + +## Parameters + +```php +{{ renderhook('displayAdminThemesListAfter', { 'current_theme_name': currentlyUsedTheme.get('name') }) }} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayAdminView.md b/modules/concepts/hooks/list-hooks/displayAdminView.md new file mode 100644 index 0000000000..6fa0596d61 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/displayAdminView.md @@ -0,0 +1,23 @@ +--- +menuTitle: displayAdminView +title: displayAdminView +hidden: true +files: + - admin784x07v4swfhm9fgvc0/themes/default/template/helpers/view/view.tpl +types: + - backoffice +hookTypes: + - smarty +--- + +# Hook : displayAdminView + +Located in : + + - admin784x07v4swfhm9fgvc0/themes/default/template/helpers/view/view.tpl + +## Parameters + +```php +{hook h='displayAdminView'} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayAfterBodyOpeningTag.md b/modules/concepts/hooks/list-hooks/displayAfterBodyOpeningTag.md new file mode 100644 index 0000000000..e2d41865e1 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/displayAfterBodyOpeningTag.md @@ -0,0 +1,23 @@ +--- +menuTitle: displayAfterBodyOpeningTag +title: displayAfterBodyOpeningTag +hidden: true +files: + - themes/classic/templates/layouts/layout-both-columns.tpl +types: + - frontoffice +hookTypes: + - smarty +--- + +# Hook : displayAfterBodyOpeningTag + +Located in : + + - themes/classic/templates/layouts/layout-both-columns.tpl + +## Parameters + +```php +{hook h='displayAfterBodyOpeningTag'} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayAfterCarrier.md b/modules/concepts/hooks/list-hooks/displayAfterCarrier.md new file mode 100644 index 0000000000..60ec8e6b8f --- /dev/null +++ b/modules/concepts/hooks/list-hooks/displayAfterCarrier.md @@ -0,0 +1,23 @@ +--- +menuTitle: displayAfterCarrier +title: displayAfterCarrier +hidden: true +files: + - classes/checkout/CheckoutDeliveryStep.php +types: + - frontoffice +hookTypes: + - legacy +--- + +# Hook : displayAfterCarrier + +Located in : + + - classes/checkout/CheckoutDeliveryStep.php + +## Parameters + +```php +Hook::exec('displayAfterCarrier', ['cart' => $this->getCheckoutSession()->getCart()]), +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayAfterProductThumbs.md b/modules/concepts/hooks/list-hooks/displayAfterProductThumbs.md new file mode 100644 index 0000000000..b94b80ab53 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/displayAfterProductThumbs.md @@ -0,0 +1,23 @@ +--- +menuTitle: displayAfterProductThumbs +title: displayAfterProductThumbs +hidden: true +files: + - themes/classic/templates/catalog/_partials/product-cover-thumbnails.tpl +types: + - frontoffice +hookTypes: + - smarty +--- + +# Hook : displayAfterProductThumbs + +Located in : + + - themes/classic/templates/catalog/_partials/product-cover-thumbnails.tpl + +## Parameters + +```php +{hook h='displayAfterProductThumbs' product=$product} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayAfterTitleTag.md b/modules/concepts/hooks/list-hooks/displayAfterTitleTag.md new file mode 100644 index 0000000000..2c29b75f7f --- /dev/null +++ b/modules/concepts/hooks/list-hooks/displayAfterTitleTag.md @@ -0,0 +1,23 @@ +--- +menuTitle: displayAfterTitleTag +title: displayAfterTitleTag +hidden: true +files: + - themes/classic/templates/_partials/head.tpl +types: + - frontoffice +hookTypes: + - smarty +--- + +# Hook : displayAfterTitleTag + +Located in : + + - themes/classic/templates/_partials/head.tpl + +## Parameters + +```php +{hook h='displayAfterTitleTag'} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayBackOfficeCategory.md b/modules/concepts/hooks/list-hooks/displayBackOfficeCategory.md new file mode 100644 index 0000000000..61b7425c76 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/displayBackOfficeCategory.md @@ -0,0 +1,23 @@ +--- +menuTitle: displayBackOfficeCategory +title: displayBackOfficeCategory +hidden: true +files: + - src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Categories/Blocks/form.html.twig +types: + - backoffice +hookTypes: + - twig +--- + +# Hook : displayBackOfficeCategory + +Located in : + + - src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Categories/Blocks/form.html.twig + +## Parameters + +```php +{{ renderhook('displayBackOfficeCategory') }} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayBackOfficeTop.md b/modules/concepts/hooks/list-hooks/displayBackOfficeTop.md new file mode 100644 index 0000000000..7488184da0 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/displayBackOfficeTop.md @@ -0,0 +1,23 @@ +--- +menuTitle: displayBackOfficeTop +title: displayBackOfficeTop +hidden: true +files: + - classes/controller/AdminController.php +types: + - backoffice +hookTypes: + - legacy +--- + +# Hook : displayBackOfficeTop + +Located in : + + - classes/controller/AdminController.php + +## Parameters + +```php +Hook::exec('displayBackOfficeTop'), +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayBanner.md b/modules/concepts/hooks/list-hooks/displayBanner.md new file mode 100644 index 0000000000..21fbe1ddfd --- /dev/null +++ b/modules/concepts/hooks/list-hooks/displayBanner.md @@ -0,0 +1,23 @@ +--- +menuTitle: displayBanner +title: displayBanner +hidden: true +files: + - themes/classic/templates/_partials/header.tpl +types: + - frontoffice +hookTypes: + - smarty +--- + +# Hook : displayBanner + +Located in : + + - themes/classic/templates/_partials/header.tpl + +## Parameters + +```php +{hook h='displayBanner'} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayBeforeBodyClosingTag.md b/modules/concepts/hooks/list-hooks/displayBeforeBodyClosingTag.md new file mode 100644 index 0000000000..89f71b393e --- /dev/null +++ b/modules/concepts/hooks/list-hooks/displayBeforeBodyClosingTag.md @@ -0,0 +1,23 @@ +--- +menuTitle: displayBeforeBodyClosingTag +title: displayBeforeBodyClosingTag +hidden: true +files: + - themes/classic/templates/layouts/layout-both-columns.tpl +types: + - frontoffice +hookTypes: + - smarty +--- + +# Hook : displayBeforeBodyClosingTag + +Located in : + + - themes/classic/templates/layouts/layout-both-columns.tpl + +## Parameters + +```php +{hook h='displayBeforeBodyClosingTag'} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayBeforeCarrier.md b/modules/concepts/hooks/list-hooks/displayBeforeCarrier.md new file mode 100644 index 0000000000..09d0fc5b94 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/displayBeforeCarrier.md @@ -0,0 +1,23 @@ +--- +menuTitle: displayBeforeCarrier +title: displayBeforeCarrier +hidden: true +files: + - classes/checkout/CheckoutDeliveryStep.php +types: + - frontoffice +hookTypes: + - legacy +--- + +# Hook : displayBeforeCarrier + +Located in : + + - classes/checkout/CheckoutDeliveryStep.php + +## Parameters + +```php +Hook::exec('displayBeforeCarrier', ['cart' => $this->getCheckoutSession()->getCart()]), +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayCMSDisputeInformation.md b/modules/concepts/hooks/list-hooks/displayCMSDisputeInformation.md new file mode 100644 index 0000000000..fedfe69510 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/displayCMSDisputeInformation.md @@ -0,0 +1,23 @@ +--- +menuTitle: displayCMSDisputeInformation +title: displayCMSDisputeInformation +hidden: true +files: + - themes/classic/templates/cms/page.tpl +types: + - frontoffice +hookTypes: + - smarty +--- + +# Hook : displayCMSDisputeInformation + +Located in : + + - themes/classic/templates/cms/page.tpl + +## Parameters + +```php +{hook h='displayCMSDisputeInformation'} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayCMSPrintButton.md b/modules/concepts/hooks/list-hooks/displayCMSPrintButton.md new file mode 100644 index 0000000000..b7e7b82642 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/displayCMSPrintButton.md @@ -0,0 +1,23 @@ +--- +menuTitle: displayCMSPrintButton +title: displayCMSPrintButton +hidden: true +files: + - themes/classic/templates/cms/page.tpl +types: + - frontoffice +hookTypes: + - smarty +--- + +# Hook : displayCMSPrintButton + +Located in : + + - themes/classic/templates/cms/page.tpl + +## Parameters + +```php +{hook h='displayCMSPrintButton'} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayCarrierExtraContent.md b/modules/concepts/hooks/list-hooks/displayCarrierExtraContent.md new file mode 100644 index 0000000000..57f72a93f7 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/displayCarrierExtraContent.md @@ -0,0 +1,23 @@ +--- +menuTitle: displayCarrierExtraContent +title: displayCarrierExtraContent +hidden: true +files: + - classes/checkout/DeliveryOptionsFinder.php +types: + - frontoffice +hookTypes: + - legacy +--- + +# Hook : displayCarrierExtraContent + +Located in : + + - classes/checkout/DeliveryOptionsFinder.php + +## Parameters + +```php +Hook::exec('displayCarrierExtraContent', ['carrier' => $carrier], $moduleId); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayCartExtraProductActions.md b/modules/concepts/hooks/list-hooks/displayCartExtraProductActions.md new file mode 100644 index 0000000000..51a295837d --- /dev/null +++ b/modules/concepts/hooks/list-hooks/displayCartExtraProductActions.md @@ -0,0 +1,23 @@ +--- +menuTitle: displayCartExtraProductActions +title: displayCartExtraProductActions +hidden: true +files: + - themes/classic/templates/checkout/_partials/cart-detailed-product-line.tpl +types: + - frontoffice +hookTypes: + - smarty +--- + +# Hook : displayCartExtraProductActions + +Located in : + + - themes/classic/templates/checkout/_partials/cart-detailed-product-line.tpl + +## Parameters + +```php +{hook h='displayCartExtraProductActions' product=$product} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayCartModalContent.md b/modules/concepts/hooks/list-hooks/displayCartModalContent.md new file mode 100644 index 0000000000..9e3b791f63 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/displayCartModalContent.md @@ -0,0 +1,23 @@ +--- +menuTitle: displayCartModalContent +title: displayCartModalContent +hidden: true +files: + - themes/classic/modules/ps_shoppingcart/modal.tpl +types: + - frontoffice +hookTypes: + - smarty +--- + +# Hook : displayCartModalContent + +Located in : + + - themes/classic/modules/ps_shoppingcart/modal.tpl + +## Parameters + +```php +{hook h='displayCartModalContent' product=$product} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayCartModalFooter.md b/modules/concepts/hooks/list-hooks/displayCartModalFooter.md new file mode 100644 index 0000000000..13c17de21f --- /dev/null +++ b/modules/concepts/hooks/list-hooks/displayCartModalFooter.md @@ -0,0 +1,23 @@ +--- +menuTitle: displayCartModalFooter +title: displayCartModalFooter +hidden: true +files: + - themes/classic/modules/ps_shoppingcart/modal.tpl +types: + - frontoffice +hookTypes: + - smarty +--- + +# Hook : displayCartModalFooter + +Located in : + + - themes/classic/modules/ps_shoppingcart/modal.tpl + +## Parameters + +```php +{hook h='displayCartModalFooter' product=$product} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayCheckoutBeforeConfirmation.md b/modules/concepts/hooks/list-hooks/displayCheckoutBeforeConfirmation.md new file mode 100644 index 0000000000..d0001ed11f --- /dev/null +++ b/modules/concepts/hooks/list-hooks/displayCheckoutBeforeConfirmation.md @@ -0,0 +1,23 @@ +--- +menuTitle: displayCheckoutBeforeConfirmation +title: displayCheckoutBeforeConfirmation +hidden: true +files: + - themes/classic/templates/checkout/_partials/steps/payment.tpl +types: + - frontoffice +hookTypes: + - smarty +--- + +# Hook : displayCheckoutBeforeConfirmation + +Located in : + + - themes/classic/templates/checkout/_partials/steps/payment.tpl + +## Parameters + +```php +{hook h='displayCheckoutBeforeConfirmation'} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayCheckoutSubtotalDetails.md b/modules/concepts/hooks/list-hooks/displayCheckoutSubtotalDetails.md new file mode 100644 index 0000000000..7e0dd85e92 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/displayCheckoutSubtotalDetails.md @@ -0,0 +1,23 @@ +--- +menuTitle: displayCheckoutSubtotalDetails +title: displayCheckoutSubtotalDetails +hidden: true +files: + - themes/classic/templates/checkout/_partials/cart-detailed-totals.tpl +types: + - frontoffice +hookTypes: + - smarty +--- + +# Hook : displayCheckoutSubtotalDetails + +Located in : + + - themes/classic/templates/checkout/_partials/cart-detailed-totals.tpl + +## Parameters + +```php +{hook h='displayCheckoutSubtotalDetails' subtotal=$subtotal} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayCheckoutSummaryTop.md b/modules/concepts/hooks/list-hooks/displayCheckoutSummaryTop.md new file mode 100644 index 0000000000..f1de9652d5 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/displayCheckoutSummaryTop.md @@ -0,0 +1,23 @@ +--- +menuTitle: displayCheckoutSummaryTop +title: displayCheckoutSummaryTop +hidden: true +files: + - themes/classic/templates/checkout/_partials/cart-summary-top.tpl +types: + - frontoffice +hookTypes: + - smarty +--- + +# Hook : displayCheckoutSummaryTop + +Located in : + + - themes/classic/templates/checkout/_partials/cart-summary-top.tpl + +## Parameters + +```php +{hook h='displayCheckoutSummaryTop'} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayCrossSellingShoppingCart.md b/modules/concepts/hooks/list-hooks/displayCrossSellingShoppingCart.md new file mode 100644 index 0000000000..8bf28c3556 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/displayCrossSellingShoppingCart.md @@ -0,0 +1,23 @@ +--- +menuTitle: displayCrossSellingShoppingCart +title: displayCrossSellingShoppingCart +hidden: true +files: + - themes/classic/templates/checkout/cart.tpl +types: + - frontoffice +hookTypes: + - smarty +--- + +# Hook : displayCrossSellingShoppingCart + +Located in : + + - themes/classic/templates/checkout/cart.tpl + +## Parameters + +```php +{hook h='displayCrossSellingShoppingCart'} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayCustomerAccount.md b/modules/concepts/hooks/list-hooks/displayCustomerAccount.md new file mode 100644 index 0000000000..2858d68677 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/displayCustomerAccount.md @@ -0,0 +1,23 @@ +--- +menuTitle: displayCustomerAccount +title: displayCustomerAccount +hidden: true +files: + - themes/classic/templates/customer/my-account.tpl +types: + - frontoffice +hookTypes: + - smarty +--- + +# Hook : displayCustomerAccount + +Located in : + + - themes/classic/templates/customer/my-account.tpl + +## Parameters + +```php +{hook h='displayCustomerAccount'} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayCustomerAccountForm.md b/modules/concepts/hooks/list-hooks/displayCustomerAccountForm.md new file mode 100644 index 0000000000..344d6531f9 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/displayCustomerAccountForm.md @@ -0,0 +1,23 @@ +--- +menuTitle: displayCustomerAccountForm +title: displayCustomerAccountForm +hidden: true +files: + - classes/form/CustomerForm.php +types: + - frontoffice +hookTypes: + - legacy +--- + +# Hook : displayCustomerAccountForm + +Located in : + + - classes/form/CustomerForm.php + +## Parameters + +```php +Hook::exec('displayCustomerAccountForm'), +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayCustomerAccountFormTop.md b/modules/concepts/hooks/list-hooks/displayCustomerAccountFormTop.md new file mode 100644 index 0000000000..dbda592c49 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/displayCustomerAccountFormTop.md @@ -0,0 +1,23 @@ +--- +menuTitle: displayCustomerAccountFormTop +title: displayCustomerAccountFormTop +hidden: true +files: + - controllers/front/RegistrationController.php +types: + - frontoffice +hookTypes: + - legacy +--- + +# Hook : displayCustomerAccountFormTop + +Located in : + + - controllers/front/RegistrationController.php + +## Parameters + +```php +Hook::exec('displayCustomerAccountFormTop'), +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayCustomerLoginFormAfter.md b/modules/concepts/hooks/list-hooks/displayCustomerLoginFormAfter.md new file mode 100644 index 0000000000..94cd554f2d --- /dev/null +++ b/modules/concepts/hooks/list-hooks/displayCustomerLoginFormAfter.md @@ -0,0 +1,23 @@ +--- +menuTitle: displayCustomerLoginFormAfter +title: displayCustomerLoginFormAfter +hidden: true +files: + - themes/classic/templates/customer/authentication.tpl +types: + - frontoffice +hookTypes: + - smarty +--- + +# Hook : displayCustomerLoginFormAfter + +Located in : + + - themes/classic/templates/customer/authentication.tpl + +## Parameters + +```php +{hook h='displayCustomerLoginFormAfter'} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayCustomization.md b/modules/concepts/hooks/list-hooks/displayCustomization.md new file mode 100644 index 0000000000..1b56c7f62b --- /dev/null +++ b/modules/concepts/hooks/list-hooks/displayCustomization.md @@ -0,0 +1,2294 @@ +--- +menuTitle: displayCustomization +title: displayCustomization +hidden: true +files: + - classes/Product.php +types: + - frontoffice +hookTypes: + - legacy +--- + +# Hook : displayCustomization + +Located in : + + - classes/Product.php + +## Parameters + +```php +Hook::exec('displayCustomization', ['customization' => $row], (int) $row['id_module']); + } + $customized_datas[(int) $row['id_product']][(int) $row['id_product_attribute']][(int) $row['id_address_delivery']][(int) $row['id_customization']]['datas'][(int) $row['type']][] = $row; + } + + if (!$result = Db::getInstance()->executeS( + 'SELECT `id_product`, `id_product_attribute`, `id_customization`, `id_address_delivery`, `quantity`, `quantity_refunded`, `quantity_returned` + FROM `' . _DB_PREFIX_ . 'customization` + WHERE `id_cart` = ' . (int) $id_cart . + ((int) $id_customization ? ' AND `id_customization` = ' . (int) $id_customization : '') . + ($only_in_cart ? ' AND `in_cart` = 1' : '') + )) { + return false; + } + + foreach ($result as $row) { + $customized_datas[(int) $row['id_product']][(int) $row['id_product_attribute']][(int) $row['id_address_delivery']][(int) $row['id_customization']]['quantity'] = (int) $row['quantity']; + $customized_datas[(int) $row['id_product']][(int) $row['id_product_attribute']][(int) $row['id_address_delivery']][(int) $row['id_customization']]['quantity_refunded'] = (int) $row['quantity_refunded']; + $customized_datas[(int) $row['id_product']][(int) $row['id_product_attribute']][(int) $row['id_address_delivery']][(int) $row['id_customization']]['quantity_returned'] = (int) $row['quantity_returned']; + $customized_datas[(int) $row['id_product']][(int) $row['id_product_attribute']][(int) $row['id_address_delivery']][(int) $row['id_customization']]['id_customization'] = (int) $row['id_customization']; + } + + return $customized_datas; + } + + /** + * @param array $products + * @param array $customized_datas + */ + public static function addCustomizationPrice(&$products, &$customized_datas) + { + if (!$customized_datas) { + return; + } + + foreach ($products as &$product_update) { + if (!Customization::isFeatureActive()) { + $product_update['customizationQuantityTotal'] = 0; + $product_update['customizationQuantityRefunded'] = 0; + $product_update['customizationQuantityReturned'] = 0; + } else { + $customization_quantity = 0; + $customization_quantity_refunded = 0; + $customization_quantity_returned = 0; + + /* Compatibility */ + $product_id = isset($product_update['id_product']) ? (int) $product_update['id_product'] : (int) $product_update['product_id']; + $product_attribute_id = isset($product_update['id_product_attribute']) ? (int) $product_update['id_product_attribute'] : (int) $product_update['product_attribute_id']; + $id_address_delivery = (int) $product_update['id_address_delivery']; + $product_quantity = isset($product_update['cart_quantity']) ? (int) $product_update['cart_quantity'] : (int) $product_update['product_quantity']; + $price = isset($product_update['price']) ? $product_update['price'] : $product_update['product_price']; + if (isset($product_update['price_wt']) && $product_update['price_wt']) { + $price_wt = $product_update['price_wt']; + } else { + $price_wt = $price * (1 + ((isset($product_update['tax_rate']) ? $product_update['tax_rate'] : $product_update['rate']) * 0.01)); + } + + if (!isset($customized_datas[$product_id][$product_attribute_id][$id_address_delivery])) { + $id_address_delivery = 0; + } + if (isset($customized_datas[$product_id][$product_attribute_id][$id_address_delivery])) { + foreach ($customized_datas[$product_id][$product_attribute_id][$id_address_delivery] as $customization) { + if ((int) $product_update['id_customization'] && $customization['id_customization'] != $product_update['id_customization']) { + continue; + } + $customization_quantity += (int) $customization['quantity']; + $customization_quantity_refunded += (int) $customization['quantity_refunded']; + $customization_quantity_returned += (int) $customization['quantity_returned']; + } + } + + $product_update['customizationQuantityTotal'] = $customization_quantity; + $product_update['customizationQuantityRefunded'] = $customization_quantity_refunded; + $product_update['customizationQuantityReturned'] = $customization_quantity_returned; + + if ($customization_quantity) { + $product_update['total_wt'] = $price_wt * ($product_quantity - $customization_quantity); + $product_update['total_customization_wt'] = $price_wt * $customization_quantity; + $product_update['total'] = $price * ($product_quantity - $customization_quantity); + $product_update['total_customization'] = $price * $customization_quantity; + } + } + } + } + + /** + * Add customization price for a single product + * + * @param array $product Product data + * @param array $customized_datas Customized data + */ + public static function addProductCustomizationPrice(&$product, &$customized_datas) + { + if (!$customized_datas) { + return; + } + + $products = [$product]; + self::addCustomizationPrice($products, $customized_datas); + $product = $products[0]; + } + + /** + * Customization fields label management + * + * @param string $field + * @param string $value + * + * @return array|false + */ + protected function _checkLabelField($field, $value) + { + if (!Validate::isLabel($value)) { + return false; + } + $tmp = explode('_', $field); + if (count($tmp) < 4) { + return false; + } + + return $tmp; + } + + /** + * @return bool + */ + protected function _deleteOldLabels() + { + $max = [ + Product::CUSTOMIZE_FILE => (int) $this->uploadable_files, + Product::CUSTOMIZE_TEXTFIELD => (int) $this->text_fields, + ]; + + /* Get customization field ids */ + if (( + $result = Db::getInstance()->executeS( + 'SELECT `id_customization_field`, `type` + FROM `' . _DB_PREFIX_ . 'customization_field` + WHERE `id_product` = ' . (int) $this->id . ' + ORDER BY `id_customization_field`' + ) + ) === false) { + return false; + } + + if (empty($result)) { + return true; + } + + $customization_fields = [ + Product::CUSTOMIZE_FILE => [], + Product::CUSTOMIZE_TEXTFIELD => [], + ]; + + foreach ($result as $row) { + $customization_fields[(int) $row['type']][] = (int) $row['id_customization_field']; + } + + $extra_file = count($customization_fields[Product::CUSTOMIZE_FILE]) - $max[Product::CUSTOMIZE_FILE]; + $extra_text = count($customization_fields[Product::CUSTOMIZE_TEXTFIELD]) - $max[Product::CUSTOMIZE_TEXTFIELD]; + + /* If too much inside the database, deletion */ + if ($extra_file > 0 && count($customization_fields[Product::CUSTOMIZE_FILE]) - $extra_file >= 0 && + (!Db::getInstance()->execute( + 'DELETE `' . _DB_PREFIX_ . 'customization_field`,`' . _DB_PREFIX_ . 'customization_field_lang` + FROM `' . _DB_PREFIX_ . 'customization_field` JOIN `' . _DB_PREFIX_ . 'customization_field_lang` + WHERE `' . _DB_PREFIX_ . 'customization_field`.`id_product` = ' . (int) $this->id . ' + AND `' . _DB_PREFIX_ . 'customization_field`.`type` = ' . Product::CUSTOMIZE_FILE . ' + AND `' . _DB_PREFIX_ . 'customization_field_lang`.`id_customization_field` = `' . _DB_PREFIX_ . 'customization_field`.`id_customization_field` + AND `' . _DB_PREFIX_ . 'customization_field`.`id_customization_field` >= ' . (int) $customization_fields[Product::CUSTOMIZE_FILE][count($customization_fields[Product::CUSTOMIZE_FILE]) - $extra_file] + ))) { + return false; + } + + if ($extra_text > 0 && count($customization_fields[Product::CUSTOMIZE_TEXTFIELD]) - $extra_text >= 0 && + (!Db::getInstance()->execute( + 'DELETE `' . _DB_PREFIX_ . 'customization_field`,`' . _DB_PREFIX_ . 'customization_field_lang` + FROM `' . _DB_PREFIX_ . 'customization_field` JOIN `' . _DB_PREFIX_ . 'customization_field_lang` + WHERE `' . _DB_PREFIX_ . 'customization_field`.`id_product` = ' . (int) $this->id . ' + AND `' . _DB_PREFIX_ . 'customization_field`.`type` = ' . Product::CUSTOMIZE_TEXTFIELD . ' + AND `' . _DB_PREFIX_ . 'customization_field_lang`.`id_customization_field` = `' . _DB_PREFIX_ . 'customization_field`.`id_customization_field` + AND `' . _DB_PREFIX_ . 'customization_field`.`id_customization_field` >= ' . (int) $customization_fields[Product::CUSTOMIZE_TEXTFIELD][count($customization_fields[Product::CUSTOMIZE_TEXTFIELD]) - $extra_text] + ))) { + return false; + } + + // Refresh cache of feature detachable + Configuration::updateGlobalValue('PS_CUSTOMIZATION_FEATURE_ACTIVE', Customization::isCurrentlyUsed()); + + return true; + } + + /** + * @param array $languages An array of language data + * @param int $type Product::CUSTOMIZE_FILE or Product::CUSTOMIZE_TEXTFIELD + * + * @return bool + */ + protected function _createLabel($languages, $type) + { + // Label insertion + if (!Db::getInstance()->execute(' + INSERT INTO `' . _DB_PREFIX_ . 'customization_field` (`id_product`, `type`, `required`) + VALUES (' . (int) $this->id . ', ' . (int) $type . ', 0)') || + !$id_customization_field = (int) Db::getInstance()->Insert_ID()) { + return false; + } + + // Multilingual label name creation + $values = ''; + + foreach ($languages as $language) { + foreach (Shop::getContextListShopID() as $id_shop) { + $values .= '(' . (int) $id_customization_field . ', ' . (int) $language['id_lang'] . ', ' . (int) $id_shop . ',\'\'), '; + } + } + + $values = rtrim($values, ', '); + if (!Db::getInstance()->execute(' + INSERT INTO `' . _DB_PREFIX_ . 'customization_field_lang` (`id_customization_field`, `id_lang`, `id_shop`, `name`) + VALUES ' . $values)) { + return false; + } + + // Set cache of feature detachable to true + Configuration::updateGlobalValue('PS_CUSTOMIZATION_FEATURE_ACTIVE', '1'); + + return true; + } + + /** + * @param int $uploadable_files + * @param int $text_fields + * + * @return bool + */ + public function createLabels($uploadable_files, $text_fields) + { + $languages = Language::getLanguages(); + if ((int) $uploadable_files > 0) { + for ($i = 0; $i < (int) $uploadable_files; ++$i) { + if (!$this->_createLabel($languages, Product::CUSTOMIZE_FILE)) { + return false; + } + } + } + + if ((int) $text_fields > 0) { + for ($i = 0; $i < (int) $text_fields; ++$i) { + if (!$this->_createLabel($languages, Product::CUSTOMIZE_TEXTFIELD)) { + return false; + } + } + } + + return true; + } + + /** + * @return bool + */ + public function updateLabels() + { + $has_required_fields = 0; + foreach ($_POST as $field => $value) { + /* Label update */ + if (strncmp($field, 'label_', 6) == 0) { + if (!$tmp = $this->_checkLabelField($field, $value)) { + return false; + } + /* Multilingual label name update */ + if (Shop::isFeatureActive()) { + foreach (Shop::getContextListShopID() as $id_shop) { + if (!Db::getInstance()->execute('INSERT INTO `' . _DB_PREFIX_ . 'customization_field_lang` + (`id_customization_field`, `id_lang`, `id_shop`, `name`) VALUES (' . (int) $tmp[2] . ', ' . (int) $tmp[3] . ', ' . (int) $id_shop . ', \'' . pSQL($value) . '\') + ON DUPLICATE KEY UPDATE `name` = \'' . pSQL($value) . '\'')) { + return false; + } + } + } elseif (!Db::getInstance()->execute(' + INSERT INTO `' . _DB_PREFIX_ . 'customization_field_lang` + (`id_customization_field`, `id_lang`, `name`) VALUES (' . (int) $tmp[2] . ', ' . (int) $tmp[3] . ', \'' . pSQL($value) . '\') + ON DUPLICATE KEY UPDATE `name` = \'' . pSQL($value) . '\'')) { + return false; + } + + $is_required = isset($_POST['require_' . (int) $tmp[1] . '_' . (int) $tmp[2]]) ? 1 : 0; + $has_required_fields |= $is_required; + /* Require option update */ + if (!Db::getInstance()->execute( + 'UPDATE `' . _DB_PREFIX_ . 'customization_field` + SET `required` = ' . (int) $is_required . ' + WHERE `id_customization_field` = ' . (int) $tmp[2] + )) { + return false; + } + } + } + + if ($has_required_fields && !ObjectModel::updateMultishopTable('product', ['customizable' => 2], 'a.id_product = ' . (int) $this->id)) { + return false; + } + + if (!$this->_deleteOldLabels()) { + return false; + } + + return true; + } + + /** + * @param int|false $id_lang Language identifier + * @param int|null $id_shop Shop identifier + * + * @return array|bool + */ + public function getCustomizationFields($id_lang = false, $id_shop = null) + { + if (!Customization::isFeatureActive()) { + return false; + } + + if (Shop::isFeatureActive() && !$id_shop) { + $id_shop = (int) Context::getContext()->shop->id; + } + + // Hide the modules fields in the front-office + // When a module adds a customization programmatically, it should set the `is_module` to 1 + $context = Context::getContext(); + $front = isset($context->controller->controller_type) && in_array($context->controller->controller_type, ['front']); + + if (!$result = Db::getInstance()->executeS( + 'SELECT cf.`id_customization_field`, cf.`type`, cf.`required`, cfl.`name`, cfl.`id_lang` + FROM `' . _DB_PREFIX_ . 'customization_field` cf + NATURAL JOIN `' . _DB_PREFIX_ . 'customization_field_lang` cfl + WHERE cf.`id_product` = ' . (int) $this->id . ($id_lang ? ' AND cfl.`id_lang` = ' . (int) $id_lang : '') . + ($id_shop ? ' AND cfl.`id_shop` = ' . (int) $id_shop : '') . + ($front ? ' AND !cf.`is_module`' : '') . ' + AND cf.`is_deleted` = 0 + ORDER BY cf.`id_customization_field`') + ) { + return false; + } + + if ($id_lang) { + return $result; + } + + $customization_fields = []; + foreach ($result as $row) { + $customization_fields[(int) $row['type']][(int) $row['id_customization_field']][(int) $row['id_lang']] = $row; + } + + return $customization_fields; + } + + /** + * check if product has an activated and required customizationFields. + * + * @return bool + * + * @throws PrestaShopDatabaseException + */ + public function hasActivatedRequiredCustomizableFields() + { + if (!Customization::isFeatureActive()) { + return false; + } + + return (bool) Db::getInstance()->executeS( + ' + SELECT 1 + FROM `' . _DB_PREFIX_ . 'customization_field` + WHERE `id_product` = ' . (int) $this->id . ' + AND `required` = 1 + AND `is_deleted` = 0' + ); + } + + /** + * @return array + */ + public function getCustomizationFieldIds() + { + if (!Customization::isFeatureActive()) { + return []; + } + + return Db::getInstance()->executeS(' + SELECT `id_customization_field`, `type`, `required` + FROM `' . _DB_PREFIX_ . 'customization_field` + WHERE `id_product` = ' . (int) $this->id); + } + + /** + * @return array + */ + public function getNonDeletedCustomizationFieldIds() + { + if (!Customization::isFeatureActive()) { + return []; + } + + $results = Db::getInstance()->executeS(' + SELECT `id_customization_field` + FROM `' . _DB_PREFIX_ . 'customization_field` + WHERE `is_deleted` = 0 + AND `id_product` = ' . (int) $this->id + ); + + return array_map(function ($result) { + return (int) $result['id_customization_field']; + }, $results); + } + + /** + * @param int $fieldType |null + * + * @return int + * + * @throws PrestaShopDatabaseException + */ + public function countCustomizationFields(?int $fieldType = null): int + { + $query = ' + SELECT COUNT(`id_customization_field`) as customizations_count + FROM `' . _DB_PREFIX_ . 'customization_field` + WHERE `is_deleted` = 0 + AND `id_product` = ' . (int) $this->id + ; + + if (null !== $fieldType) { + $query .= sprintf(' AND type = %d', $fieldType); + } + + $results = Db::getInstance()->executeS($query); + + if (empty($results)) { + return 0; + } + + return (int) reset($results)['customizations_count']; + } + + /** + * @return array + */ + public function getRequiredCustomizableFields() + { + if (!Customization::isFeatureActive()) { + return []; + } + + return Product::getRequiredCustomizableFieldsStatic($this->id); + } + + /** + * @param int $id Product identifier + * + * @return array + */ + public static function getRequiredCustomizableFieldsStatic($id) + { + if (!$id || !Customization::isFeatureActive()) { + return []; + } + + return Db::getInstance()->executeS( + ' + SELECT `id_customization_field`, `type` + FROM `' . _DB_PREFIX_ . 'customization_field` + WHERE `id_product` = ' . (int) $id . ' + AND `required` = 1 AND `is_deleted` = 0' + ); + } + + /** + * @param Context|null $context + * + * @return bool + */ + public function hasAllRequiredCustomizableFields(Context $context = null) + { + if (!Customization::isFeatureActive()) { + return true; + } + if (!$context) { + $context = Context::getContext(); + } + + $fields = $context->cart->getProductCustomization($this->id, null, true); + $required_fields = $this->getRequiredCustomizableFields(); + + $fields_present = []; + foreach ($fields as $field) { + $fields_present[] = ['id_customization_field' => $field['index'], 'type' => $field['type']]; + } + + foreach ($required_fields as $required_field) { + if (!in_array($required_field, $fields_present)) { + return false; + } + } + + return true; + } + + /** + * Return the list of old temp products. + * + * @return array + */ + public static function getOldTempProducts() + { + $sql = 'SELECT id_product FROM `' . _DB_PREFIX_ . 'product` WHERE state=' . Product::STATE_TEMP . ' AND date_upd < NOW() - INTERVAL 1 DAY'; + + return Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS($sql, true, false); + } + + /** + * Checks if the product is in at least one of the submited categories. + * + * @param int $id_product Product identifier + * @param array $categories array of category arrays + * + * @return bool is the product in at least one category + */ + public static function idIsOnCategoryId($id_product, $categories) + { + if (!((int) $id_product > 0) || !is_array($categories) || empty($categories)) { + return false; + } + $sql = 'SELECT id_product FROM `' . _DB_PREFIX_ . 'category_product` WHERE `id_product` = ' . (int) $id_product . ' AND `id_category` IN ('; + foreach ($categories as $category) { + $sql .= (int) $category['id_category'] . ','; + } + $sql = rtrim($sql, ',') . ')'; + + $hash = md5($sql); + if (!isset(self::$_incat[$hash])) { + if (!Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue($sql)) { + return false; + } + self::$_incat[$hash] = (Db::getInstance(_PS_USE_SQL_SLAVE_)->numRows() > 0 ? true : false); + } + + return self::$_incat[$hash]; + } + + /** + * @return string + */ + public function getNoPackPrice() + { + $context = Context::getContext(); + + return Tools::getContextLocale($context)->formatPrice(Pack::noPackPrice((int) $this->id), $context->currency->iso_code); + } + + /** + * @param int $id_customer Customer identifier + * + * @return bool + */ + public function checkAccess($id_customer) + { + return Product::checkAccessStatic((int) $this->id, (int) $id_customer); + } + + /** + * @param int $id_product Product identifier + * @param int|bool $id_customer Customer identifier + * + * @return bool + */ + public static function checkAccessStatic($id_product, $id_customer) + { + if (!Group::isFeatureActive()) { + return true; + } + + $cache_id = 'Product::checkAccess_' . (int) $id_product . '-' . (int) $id_customer . (!$id_customer ? '-' . (int) Group::getCurrent()->id : ''); + if (!Cache::isStored($cache_id)) { + if (!$id_customer) { + $result = (bool) Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue(' + SELECT ctg.`id_group` + FROM `' . _DB_PREFIX_ . 'category_product` cp + INNER JOIN `' . _DB_PREFIX_ . 'category_group` ctg ON (ctg.`id_category` = cp.`id_category`) + WHERE cp.`id_product` = ' . (int) $id_product . ' AND ctg.`id_group` = ' . (int) Group::getCurrent()->id); + } else { + $result = (bool) Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue(' + SELECT cg.`id_group` + FROM `' . _DB_PREFIX_ . 'category_product` cp + INNER JOIN `' . _DB_PREFIX_ . 'category_group` ctg ON (ctg.`id_category` = cp.`id_category`) + INNER JOIN `' . _DB_PREFIX_ . 'customer_group` cg ON (cg.`id_group` = ctg.`id_group`) + WHERE cp.`id_product` = ' . (int) $id_product . ' AND cg.`id_customer` = ' . (int) $id_customer); + } + + Cache::store($cache_id, $result); + + return $result; + } + + return Cache::retrieve($cache_id); + } + + /** + * Add a stock movement for current product. + * + * Since 1.5, this method only permit to add/remove available quantities of the current product in the current shop + * + * @see StockManager if you want to manage real stock + * @see StockAvailable if you want to manage available quantities for sale on your shop(s) + * @deprecated since 1.5.0 + * + * @param int $quantity + * @param int $id_reason StockMvtReason identifier - useless + * @param int|null $id_product_attribute Attribute identifier + * @param int|null $id_order Order identifier - DEPRECATED + * @param int|null $id_employee Employee identifier - DEPRECATED + * + * @return bool + */ + public function addStockMvt($quantity, $id_reason, $id_product_attribute = null, $id_order = null, $id_employee = null) + { + if (!$this->id || !$id_reason) { + return false; + } + + if ($id_product_attribute == null) { + $id_product_attribute = 0; + } + + $reason = new StockMvtReason((int) $id_reason); + if (!Validate::isLoadedObject($reason)) { + return false; + } + + $quantity = abs((int) $quantity) * $reason->sign; + + return StockAvailable::updateQuantity($this->id, $id_product_attribute, $quantity); + } + + /** + * @deprecated since 1.5.0 + * + * @param int $id_lang Language identifier + * + * @return array + */ + public function getStockMvts($id_lang) + { + Tools::displayAsDeprecated(); + + return Db::getInstance()->executeS(' + SELECT sm.id_stock_mvt, sm.date_add, sm.quantity, sm.id_order, + CONCAT(pl.name, \' \', GROUP_CONCAT(IFNULL(al.name, \'\'), \'\')) product_name, CONCAT(e.lastname, \' \', e.firstname) employee, mrl.name reason + FROM `' . _DB_PREFIX_ . 'stock_mvt` sm + LEFT JOIN `' . _DB_PREFIX_ . 'product_lang` pl ON ( + sm.id_product = pl.id_product + AND pl.id_lang = ' . (int) $id_lang . Shop::addSqlRestrictionOnLang('pl') . ' + ) + LEFT JOIN `' . _DB_PREFIX_ . 'stock_mvt_reason_lang` mrl ON ( + sm.id_stock_mvt_reason = mrl.id_stock_mvt_reason + AND mrl.id_lang = ' . (int) $id_lang . ' + ) + LEFT JOIN `' . _DB_PREFIX_ . 'employee` e ON ( + e.id_employee = sm.id_employee + ) + LEFT JOIN `' . _DB_PREFIX_ . 'product_attribute_combination` pac ON ( + pac.id_product_attribute = sm.id_product_attribute + ) + LEFT JOIN `' . _DB_PREFIX_ . 'attribute_lang` al ON ( + al.id_attribute = pac.id_attribute + AND al.id_lang = ' . (int) $id_lang . ' + ) + WHERE sm.id_product=' . (int) $this->id . ' + GROUP BY sm.id_stock_mvt + '); + } + + /** + * @param int $id_product Product identifier + * + * @return array + */ + public static function getUrlRewriteInformations($id_product) + { + return Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS(' + SELECT pl.`id_lang`, pl.`link_rewrite`, p.`ean13`, cl.`link_rewrite` AS category_rewrite + FROM `' . _DB_PREFIX_ . 'product` p + LEFT JOIN `' . _DB_PREFIX_ . 'product_lang` pl ON (p.`id_product` = pl.`id_product`' . Shop::addSqlRestrictionOnLang('pl') . ') + ' . Shop::addSqlAssociation('product', 'p') . ' + LEFT JOIN `' . _DB_PREFIX_ . 'lang` l ON (pl.`id_lang` = l.`id_lang`) + LEFT JOIN `' . _DB_PREFIX_ . 'category_lang` cl ON (cl.`id_category` = product_shop.`id_category_default` AND cl.`id_lang` = pl.`id_lang`' . Shop::addSqlRestrictionOnLang('cl') . ') + WHERE p.`id_product` = ' . (int) $id_product . ' + AND l.`active` = 1 + '); + } + + /** + * @return int TaxRulesGroup identifier + */ + public function getIdTaxRulesGroup() + { + return $this->id_tax_rules_group; + } + + /** + * @param int $id_product Product identifier + * @param Context|null $context + * + * @return int TaxRulesGroup identifier + */ + public static function getIdTaxRulesGroupByIdProduct($id_product, Context $context = null) + { + if (!$context) { + $context = Context::getContext(); + } + $key = 'product_id_tax_rules_group_' . (int) $id_product . '_' . (int) $context->shop->id; + if (!Cache::isStored($key)) { + $result = Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue(' + SELECT `id_tax_rules_group` + FROM `' . _DB_PREFIX_ . 'product_shop` + WHERE `id_product` = ' . (int) $id_product . ' AND id_shop=' . (int) $context->shop->id); + Cache::store($key, (int) $result); + + return (int) $result; + } + + return Cache::retrieve($key); + } + + /** + * Returns tax rate. + * + * @param Address|null $address + * + * @return float The total taxes rate applied to the product + */ + public function getTaxesRate(Address $address = null) + { + if (!$address || !$address->id_country) { + $address = Address::initialize(); + } + + $tax_manager = TaxManagerFactory::getManager($address, $this->id_tax_rules_group); + $tax_calculator = $tax_manager->getTaxCalculator(); + + return $tax_calculator->getTotalRate(); + } + + /** + * Webservice getter : get product features association. + * + * @return array + */ + public function getWsProductFeatures() + { + $rows = $this->getFeatures(); + foreach ($rows as $keyrow => $row) { + foreach ($row as $keyfeature => $feature) { + if ($keyfeature == 'id_feature') { + $rows[$keyrow]['id'] = $feature; + unset($rows[$keyrow]['id_feature']); + } + unset( + $rows[$keyrow]['id_product'], + $rows[$keyrow]['custom'] + ); + } + asort($rows[$keyrow]); + } + + return $rows; + } + + /** + * Webservice setter : set product features association. + * + * @param array $product_features Feature data + * + * @return bool + */ + public function setWsProductFeatures($product_features) + { + Db::getInstance()->execute( + ' + DELETE FROM `' . _DB_PREFIX_ . 'feature_product` + WHERE `id_product` = ' . (int) $this->id + ); + foreach ($product_features as $product_feature) { + $this->addFeaturesToDB($product_feature['id'], $product_feature['id_feature_value']); + } + + return true; + } + + /** + * Webservice getter : get virtual field default combination. + * + * @return int Default Attribute identifier + */ + public function getWsDefaultCombination() + { + return Product::getDefaultAttribute($this->id); + } + + /** + * Webservice setter : set virtual field default combination. + * + * @param int $id_combination Default Attribute identifier + * + * @return bool + */ + public function setWsDefaultCombination($id_combination) + { + $this->deleteDefaultAttributes(); + + return $this->setDefaultAttribute((int) $id_combination); + } + + /** + * Webservice getter : get category ids of current product for association. + * + * @return array + */ + public function getWsCategories() + { + $result = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS( + 'SELECT cp.`id_category` AS id + FROM `' . _DB_PREFIX_ . 'category_product` cp + LEFT JOIN `' . _DB_PREFIX_ . 'category` c ON (c.id_category = cp.id_category) + ' . Shop::addSqlAssociation('category', 'c') . ' + WHERE cp.`id_product` = ' . (int) $this->id + ); + + return $result; + } + + /** + * Webservice setter : set category ids of current product for association. + * + * @param array $category_ids category ids + * + * @return bool + */ + public function setWsCategories($category_ids) + { + $ids = []; + foreach ($category_ids as $value) { + if ($value instanceof Category) { + $ids[] = (int) $value->id; + } elseif (is_array($value) && array_key_exists('id', $value)) { + $ids[] = (int) $value['id']; + } else { + $ids[] = (int) $value; + } + } + $ids = array_unique($ids); + + $positions = Db::getInstance()->executeS( + 'SELECT `id_category`, `position` + FROM `' . _DB_PREFIX_ . 'category_product` + WHERE `id_product` = ' . (int) $this->id + ); + + $max_positions = Db::getInstance()->executeS( + 'SELECT `id_category`, max(`position`) as maximum + FROM `' . _DB_PREFIX_ . 'category_product` + GROUP BY id_category' + ); + + $positions_lookup = []; + $max_position_lookup = []; + + foreach ($positions as $row) { + $positions_lookup[(int) $row['id_category']] = (int) $row['position']; + } + foreach ($max_positions as $row) { + $max_position_lookup[(int) $row['id_category']] = (int) $row['maximum']; + } + + $return = true; + if ($this->deleteCategories() && !empty($ids)) { + $sql_values = []; + foreach ($ids as $id) { + $pos = 1; + if (array_key_exists((int) $id, $positions_lookup)) { + $pos = (int) $positions_lookup[(int) $id]; + } elseif (array_key_exists((int) $id, $max_position_lookup)) { + $pos = (int) $max_position_lookup[(int) $id] + 1; + } + + $sql_values[] = '(' . (int) $id . ', ' . (int) $this->id . ', ' . $pos . ')'; + } + + $return = Db::getInstance()->execute( + ' + INSERT INTO `' . _DB_PREFIX_ . 'category_product` (`id_category`, `id_product`, `position`) + VALUES ' . implode(',', $sql_values) + ); + } + + Hook::exec('actionProductUpdate', ['id_product' => (int) $this->id]); + + return $return; + } + + /** + * Webservice getter : get product accessories ids of current product for association. + * + * @return array + */ + public function getWsAccessories() + { + $result = Db::getInstance()->executeS( + 'SELECT p.`id_product` AS id + FROM `' . _DB_PREFIX_ . 'accessory` a + LEFT JOIN `' . _DB_PREFIX_ . 'product` p ON (p.id_product = a.id_product_2) + ' . Shop::addSqlAssociation('product', 'p') . ' + WHERE a.`id_product_1` = ' . (int) $this->id + ); + + return $result; + } + + /** + * Webservice setter : set product accessories ids of current product for association. + * + * @param array $accessories product ids + * + * @return bool + */ + public function setWsAccessories($accessories) + { + $this->deleteAccessories(); + foreach ($accessories as $accessory) { + Db::getInstance()->execute('INSERT INTO `' . _DB_PREFIX_ . 'accessory` (`id_product_1`, `id_product_2`) VALUES (' . (int) $this->id . ', ' . (int) $accessory['id'] . ')'); + } + + return true; + } + + /** + * Webservice getter : get combination ids of current product for association. + * + * @return array + */ + public function getWsCombinations() + { + $result = Db::getInstance()->executeS( + 'SELECT pa.`id_product_attribute` as id + FROM `' . _DB_PREFIX_ . 'product_attribute` pa + ' . Shop::addSqlAssociation('product_attribute', 'pa') . ' + WHERE pa.`id_product` = ' . (int) $this->id + ); + + return $result; + } + + /** + * Webservice setter : set combination ids of current product for association. + * + * @param array $combinations combination ids + * + * @return bool + */ + public function setWsCombinations($combinations) + { + // No hook exec + $ids_new = []; + foreach ($combinations as $combination) { + $ids_new[] = (int) $combination['id']; + } + + $ids_orig = []; + $original = Db::getInstance()->executeS( + 'SELECT pa.`id_product_attribute` as id + FROM `' . _DB_PREFIX_ . 'product_attribute` pa + ' . Shop::addSqlAssociation('product_attribute', 'pa') . ' + WHERE pa.`id_product` = ' . (int) $this->id + ); + + if (is_array($original)) { + foreach ($original as $id) { + $ids_orig[] = $id['id']; + } + } + + $all_ids = []; + $all = Db::getInstance()->executeS('SELECT pa.`id_product_attribute` as id FROM `' . _DB_PREFIX_ . 'product_attribute` pa ' . Shop::addSqlAssociation('product_attribute', 'pa')); + if (is_array($all)) { + foreach ($all as $id) { + $all_ids[] = $id['id']; + } + } + + $to_add = []; + foreach ($ids_new as $id) { + if (!in_array($id, $ids_orig)) { + $to_add[] = $id; + } + } + + $to_delete = []; + foreach ($ids_orig as $id) { + if (!in_array($id, $ids_new)) { + $to_delete[] = $id; + } + } + + // Delete rows + if (count($to_delete) > 0) { + foreach ($to_delete as $id) { + $combination = new Combination($id); + $combination->delete(); + } + } + + foreach ($to_add as $id) { + // Update id_product if exists else create + if (in_array($id, $all_ids)) { + Db::getInstance()->execute('UPDATE `' . _DB_PREFIX_ . 'product_attribute` SET id_product = ' . (int) $this->id . ' WHERE id_product_attribute=' . $id); + } else { + Db::getInstance()->execute('INSERT INTO `' . _DB_PREFIX_ . 'product_attribute` (`id_product`) VALUES (' . (int) $this->id . ')'); + } + } + + return true; + } + + /** + * Webservice getter : get product option ids of current product for association. + * + * @return array + */ + public function getWsProductOptionValues() + { + $result = Db::getInstance()->executeS('SELECT DISTINCT pac.id_attribute as id + FROM `' . _DB_PREFIX_ . 'product_attribute` pa + ' . Shop::addSqlAssociation('product_attribute', 'pa') . ' + LEFT JOIN `' . _DB_PREFIX_ . 'product_attribute_combination` pac ON (pac.id_product_attribute = pa.id_product_attribute) + WHERE pa.id_product = ' . (int) $this->id); + + return $result; + } + + /** + * Webservice getter : get virtual field position in category. + * + * @return int|string + */ + public function getWsPositionInCategory() + { + $result = Db::getInstance()->executeS( + 'SELECT `position` + FROM `' . _DB_PREFIX_ . 'category_product` + WHERE `id_category` = ' . (int) $this->id_category_default . ' + AND `id_product` = ' . (int) $this->id); + if (count($result) > 0) { + return $result[0]['position']; + } + + return ''; + } + + /** + * Webservice setter : set virtual field position in category. + * + * @param int $position + * + * @return bool + */ + public function setWsPositionInCategory($position) + { + if ($position <= 0) { + WebserviceRequest::getInstance()->setError( + 500, + $this->trans( + 'You cannot set 0 or a negative position, the minimum is 1.', + [], + 'Admin.Catalog.Notification' + ), + 134 + ); + + return false; + } + + $result = Db::getInstance()->executeS( + 'SELECT `id_product` ' . + 'FROM `' . _DB_PREFIX_ . 'category_product` ' . + 'WHERE `id_category` = ' . (int) $this->id_category_default . ' ' . + 'ORDER BY `position`' + ); + + if ($position > count($result)) { + WebserviceRequest::getInstance()->setError( + 500, + $this->trans( + 'You cannot set a position greater than the total number of products in the category, starting at 1.', + [], + 'Admin.Catalog.Notification' + ), + 135 + ); + + return false; + } + + // result is indexed by recordset order and not position. positions start at index 1 so we need an empty element + array_unshift($result, null); + foreach ($result as &$value) { + $value = $value['id_product']; + } + + $current_position = $this->getWsPositionInCategory(); + + if ($current_position && isset($result[$current_position])) { + $save = $result[$current_position]; + unset($result[$current_position]); + array_splice($result, (int) $position, 0, $save); + } + + foreach ($result as $position => $id_product) { + Db::getInstance()->update('category_product', [ + 'position' => $position, + ], '`id_category` = ' . (int) $this->id_category_default . ' AND `id_product` = ' . (int) $id_product); + } + + return true; + } + + /** + * Webservice getter : get virtual field id_default_image in category. + * + * @return int|string|null + */ + public function getCoverWs() + { + $result = $this->getCover($this->id); + + return $result ? $result['id_image'] : null; + } + + /** + * Webservice setter : set virtual field id_default_image in category. + * + * @param int $id_image + * + * @return bool + */ + public function setCoverWs($id_image) + { + Db::getInstance()->execute('UPDATE `' . _DB_PREFIX_ . 'image_shop` image_shop, `' . _DB_PREFIX_ . 'image` i + SET image_shop.`cover` = NULL + WHERE i.`id_product` = ' . (int) $this->id . ' AND i.id_image = image_shop.id_image + AND image_shop.id_shop=' . (int) Context::getContext()->shop->id); + + Db::getInstance()->execute('UPDATE `' . _DB_PREFIX_ . 'image_shop` + SET `cover` = 1 WHERE `id_image` = ' . (int) $id_image); + + return true; + } + + /** + * Webservice getter : get image ids of current product for association. + * + * @return array + */ + public function getWsImages() + { + return Db::getInstance()->executeS(' + SELECT i.`id_image` as id + FROM `' . _DB_PREFIX_ . 'image` i + ' . Shop::addSqlAssociation('image', 'i') . ' + WHERE i.`id_product` = ' . (int) $this->id . ' + ORDER BY i.`position`'); + } + + /** + * Webservice getter : Get StockAvailable identifier and Attribute identifier + * + * @return array + */ + public function getWsStockAvailables() + { + return Db::getInstance()->executeS('SELECT `id_stock_available` id, `id_product_attribute` + FROM `' . _DB_PREFIX_ . 'stock_available` + WHERE `id_product`=' . (int) $this->id . StockAvailable::addSqlShopRestriction()); + } + + /** + * Webservice getter: Get product attachments ids of current product for association + * + * @return array + */ + public function getWsAttachments(): array + { + return Db::getInstance()->executeS( + 'SELECT a.`id_attachment` AS id ' . + 'FROM `' . _DB_PREFIX_ . 'product_attachment` pa ' . + 'INNER JOIN `' . _DB_PREFIX_ . 'attachment` a ON (pa.id_attachment = a.id_attachment) ' . + Shop::addSqlAssociation('attachment', 'a') . ' ' . + 'WHERE pa.`id_product` = ' . (int) $this->id + ); + } + + /** + * Webservice setter: set product attachments ids of current product for association + * + * @param array $attachments ids + */ + public function setWsAttachments(array $attachments): bool + { + $this->deleteAttachments(true); + foreach ($attachments as $attachment) { + Db::getInstance()->execute('INSERT INTO `' . _DB_PREFIX_ . 'product_attachment` + (`id_product`, `id_attachment`) VALUES (' . (int) $this->id . ', ' . (int) $attachment['id'] . ')'); + } + Product::updateCacheAttachment((int) $this->id); + + return true; + } + + public function getWsTags() + { + return Db::getInstance()->executeS(' + SELECT `id_tag` as id + FROM `' . _DB_PREFIX_ . 'product_tag` + WHERE `id_product` = ' . (int) $this->id); + } + + /** + * Webservice setter : set tag ids of current product for association. + * + * @param array $tag_ids Tag identifiers + * + * @return bool + */ + public function setWsTags($tag_ids) + { + $ids = []; + foreach ($tag_ids as $value) { + $ids[] = $value['id']; + } + if ($this->deleteWsTags()) { + if ($ids) { + $sql_values = []; + $ids = array_map('intval', $ids); + foreach ($ids as $position => $id) { + $id_lang = Db::getInstance()->getValue('SELECT `id_lang` FROM `' . _DB_PREFIX_ . 'tag` WHERE `id_tag`=' . (int) $id); + $sql_values[] = '(' . (int) $this->id . ', ' . (int) $id . ', ' . (int) $id_lang . ')'; + } + $result = Db::getInstance()->execute( + ' + INSERT INTO `' . _DB_PREFIX_ . 'product_tag` (`id_product`, `id_tag`, `id_lang`) + VALUES ' . implode(',', $sql_values) + ); + + return $result; + } + } + + return true; + } + + /** + * Delete products tags entries without delete tags for webservice usage. + * + * @return bool Deletion result + */ + public function deleteWsTags() + { + return Db::getInstance()->delete('product_tag', 'id_product = ' . (int) $this->id); + } + + /** + * @return string + */ + public function getWsManufacturerName() + { + return Manufacturer::getNameById((int) $this->id_manufacturer); + } + + /** + * @return bool + */ + public static function resetEcoTax() + { + return ObjectModel::updateMultishopTable('product', [ + 'ecotax' => 0, + ]); + } + + /** + * Set Group reduction if needed. + */ + public function setGroupReduction() + { + return GroupReduction::setProductReduction($this->id); + } + + /** + * Checks if reference exists. + * + * @param string $reference Product reference + * + * @return bool + */ + public function existsRefInDatabase($reference) + { + $row = Db::getInstance()->getRow(' + SELECT `reference` + FROM `' . _DB_PREFIX_ . 'product` p + WHERE p.reference = "' . pSQL($reference) . '"', false); + + return isset($row['reference']); + } + + /** + * Get all product attributes ids. + * + * @since 1.5.0 + * + * @param int $id_product Product identifier + * @param bool $shop_only + * + * @return array Attribute identifiers list + */ + public static function getProductAttributesIds($id_product, $shop_only = false) + { + return Db::getInstance()->executeS(' + SELECT pa.id_product_attribute + FROM `' . _DB_PREFIX_ . 'product_attribute` pa' . + ($shop_only ? Shop::addSqlAssociation('product_attribute', 'pa') : '') . ' + WHERE pa.`id_product` = ' . (int) $id_product); + } + + /** + * Get label by lang and value by lang too. + * + * @param int $id_product Product identifier + * @param int $id_product_attribute Attribute identifier + * + * @return array + */ + public static function getAttributesParams($id_product, $id_product_attribute) + { + if ($id_product_attribute == 0) { + return []; + } + $id_lang = (int) Context::getContext()->language->id; + $cache_id = 'Product::getAttributesParams_' . (int) $id_product . '-' . (int) $id_product_attribute . '-' . (int) $id_lang; + + if (!Cache::isStored($cache_id)) { + $result = Db::getInstance()->executeS(' + SELECT a.`id_attribute`, a.`id_attribute_group`, al.`name`, agl.`name` as `group`, pa.`reference`, pa.`ean13`, pa.`isbn`, pa.`upc`, pa.`mpn` + FROM `' . _DB_PREFIX_ . 'attribute` a + LEFT JOIN `' . _DB_PREFIX_ . 'attribute_lang` al + ON (al.`id_attribute` = a.`id_attribute` AND al.`id_lang` = ' . (int) $id_lang . ') + LEFT JOIN `' . _DB_PREFIX_ . 'product_attribute_combination` pac + ON (pac.`id_attribute` = a.`id_attribute`) + LEFT JOIN `' . _DB_PREFIX_ . 'product_attribute` pa + ON (pa.`id_product_attribute` = pac.`id_product_attribute`) + ' . Shop::addSqlAssociation('product_attribute', 'pa') . ' + LEFT JOIN `' . _DB_PREFIX_ . 'attribute_group_lang` agl + ON (a.`id_attribute_group` = agl.`id_attribute_group` AND agl.`id_lang` = ' . (int) $id_lang . ') + WHERE pa.`id_product` = ' . (int) $id_product . ' + AND pac.`id_product_attribute` = ' . (int) $id_product_attribute . ' + AND agl.`id_lang` = ' . (int) $id_lang); + Cache::store($cache_id, $result); + } else { + $result = Cache::retrieve($cache_id); + } + + return $result; + } + + /** + * @param int $id_product Product identifier + * + * @return array + */ + public static function getAttributesInformationsByProduct($id_product) + { + $result = Db::getInstance()->executeS(' + SELECT DISTINCT a.`id_attribute`, a.`id_attribute_group`, al.`name` as `attribute`, agl.`name` as `group`,pa.`reference`, pa.`ean13`, pa.`isbn`, pa.`upc`, pa.`mpn` + FROM `' . _DB_PREFIX_ . 'attribute` a + LEFT JOIN `' . _DB_PREFIX_ . 'attribute_lang` al + ON (a.`id_attribute` = al.`id_attribute` AND al.`id_lang` = ' . (int) Context::getContext()->language->id . ') + LEFT JOIN `' . _DB_PREFIX_ . 'attribute_group_lang` agl + ON (a.`id_attribute_group` = agl.`id_attribute_group` AND agl.`id_lang` = ' . (int) Context::getContext()->language->id . ') + LEFT JOIN `' . _DB_PREFIX_ . 'product_attribute_combination` pac + ON (a.`id_attribute` = pac.`id_attribute`) + LEFT JOIN `' . _DB_PREFIX_ . 'product_attribute` pa + ON (pac.`id_product_attribute` = pa.`id_product_attribute`) + ' . Shop::addSqlAssociation('product_attribute', 'pa') . ' + ' . Shop::addSqlAssociation('attribute', 'pac') . ' + WHERE pa.`id_product` = ' . (int) $id_product); + + return $result; + } + + /** + * @return bool + */ + public function hasCombinations() + { + if (null === $this->id || 0 >= $this->id) { + return false; + } + $attributes = self::getAttributesInformationsByProduct($this->id); + + return !empty($attributes); + } + + /** + * Get an id_product_attribute by an id_product and one or more + * id_attribute. + * + * e.g: id_product 8 with id_attribute 4 (size medium) and + * id_attribute 5 (color blue) returns id_product_attribute 9 which + * is the dress size medium and color blue. + * + * @param int $idProduct Product identifier + * @param int|int[] $idAttributes Attribute identifier(s) + * @param bool $findBest + * + * @return int + * + * @throws PrestaShopException + */ + public static function getIdProductAttributeByIdAttributes($idProduct, $idAttributes, $findBest = false) + { + $idProduct = (int) $idProduct; + + if (!is_array($idAttributes) && is_numeric($idAttributes)) { + $idAttributes = [(int) $idAttributes]; + } + + if (!is_array($idAttributes) || empty($idAttributes)) { + throw new PrestaShopException(sprintf('Invalid parameter $idAttributes with value: "%s"', print_r($idAttributes, true))); + } + + $idAttributesImploded = implode(',', array_map('intval', $idAttributes)); + $idProductAttribute = Db::getInstance()->getValue( + 'SELECT pac.`id_product_attribute` + FROM `' . _DB_PREFIX_ . 'product_attribute_combination` pac + INNER JOIN `' . _DB_PREFIX_ . 'product_attribute` pa ON pa.id_product_attribute = pac.id_product_attribute + WHERE pa.id_product = ' . $idProduct . ' + AND pac.id_attribute IN (' . $idAttributesImploded . ') + GROUP BY pac.`id_product_attribute` + HAVING COUNT(pa.id_product) = ' . count($idAttributes) + ); + + if ($idProductAttribute === false && $findBest) { + //find the best possible combination + //first we order $idAttributes by the group position + $orderred = []; + $result = Db::getInstance()->executeS( + 'SELECT a.`id_attribute` + FROM `' . _DB_PREFIX_ . 'attribute` a + INNER JOIN `' . _DB_PREFIX_ . 'attribute_group` g ON a.`id_attribute_group` = g.`id_attribute_group` + WHERE a.`id_attribute` IN (' . $idAttributesImploded . ') + ORDER BY g.`position` ASC' + ); + + foreach ($result as $row) { + $orderred[] = $row['id_attribute']; + } + + while ($idProductAttribute === false && count($orderred) > 1) { + array_pop($orderred); + $idProductAttribute = Db::getInstance()->getValue( + 'SELECT pac.`id_product_attribute` + FROM `' . _DB_PREFIX_ . 'product_attribute_combination` pac + INNER JOIN `' . _DB_PREFIX_ . 'product_attribute` pa ON pa.id_product_attribute = pac.id_product_attribute + WHERE pa.id_product = ' . (int) $idProduct . ' + AND pac.id_attribute IN (' . implode(',', array_map('intval', $orderred)) . ') + GROUP BY pac.id_product_attribute + HAVING COUNT(pa.id_product) = ' . count($orderred) + ); + } + } + + if (empty($idProductAttribute)) { + throw new PrestaShopObjectNotFoundException('Cannot retrieve the id_product_attribute'); + } + + return (int) $idProductAttribute; + } + + /** + * Get the combination url anchor of the product. + * + * @param int $id_product_attribute Attribute identifier + * @param bool $with_id + * + * @return string + */ + public function getAnchor($id_product_attribute, $with_id = false) + { + $attributes = Product::getAttributesParams($this->id, $id_product_attribute); + $anchor = '#'; + $sep = Configuration::get('PS_ATTRIBUTE_ANCHOR_SEPARATOR'); + foreach ($attributes as &$a) { + foreach ($a as &$b) { + $b = str_replace($sep, '_', Tools::link_rewrite((string) $b)); + } + $anchor .= '/' . ($with_id && isset($a['id_attribute']) && $a['id_attribute'] ? (int) $a['id_attribute'] . $sep : '') . $a['group'] . $sep . $a['name']; + } + + return $anchor; + } + + /** + * Gets the name of a given product, in the given lang. + * + * @since 1.5.0 + * + * @param int $id_product Product identifier + * @param int|null $id_product_attribute Attribute identifier + * @param int|null $id_lang Language identifier + * + * @return string + */ + public static function getProductName($id_product, $id_product_attribute = null, $id_lang = null) + { + // use the lang in the context if $id_lang is not defined + if (!$id_lang) { + $id_lang = (int) Context::getContext()->language->id; + } + + // creates the query object + $query = new DbQuery(); + + // selects different names, if it is a combination + if ($id_product_attribute) { + $query->select('IFNULL(CONCAT(pl.name, \' : \', GROUP_CONCAT(DISTINCT agl.`name`, \' - \', al.name SEPARATOR \', \')),pl.name) as name'); + } else { + $query->select('DISTINCT pl.name as name'); + } + + // adds joins & where clauses for combinations + if ($id_product_attribute) { + $query->from('product_attribute', 'pa'); + $query->join(Shop::addSqlAssociation('product_attribute', 'pa')); + $query->innerJoin('product_lang', 'pl', 'pl.id_product = pa.id_product AND pl.id_lang = ' . (int) $id_lang . Shop::addSqlRestrictionOnLang('pl')); + $query->leftJoin('product_attribute_combination', 'pac', 'pac.id_product_attribute = pa.id_product_attribute'); + $query->leftJoin('attribute', 'atr', 'atr.id_attribute = pac.id_attribute'); + $query->leftJoin('attribute_lang', 'al', 'al.id_attribute = atr.id_attribute AND al.id_lang = ' . (int) $id_lang); + $query->leftJoin('attribute_group_lang', 'agl', 'agl.id_attribute_group = atr.id_attribute_group AND agl.id_lang = ' . (int) $id_lang); + $query->where('pa.id_product = ' . (int) $id_product . ' AND pa.id_product_attribute = ' . (int) $id_product_attribute); + } else { + // or just adds a 'where' clause for a simple product + + $query->from('product_lang', 'pl'); + $query->where('pl.id_product = ' . (int) $id_product); + $query->where('pl.id_lang = ' . (int) $id_lang . Shop::addSqlRestrictionOnLang('pl')); + } + + return Db::getInstance()->getValue($query); + } + + /** + * @param bool $autodate + * @param bool $null_values + * + * @return bool + */ + public function addWs($autodate = true, $null_values = false) + { + $success = $this->add($autodate, $null_values); + if ($success && Configuration::get('PS_SEARCH_INDEXATION')) { + Search::indexation(false, $this->id); + } + + return $success; + } + + /** + * @param bool $null_values + * + * @return bool + */ + public function updateWs($null_values = false) + { + if (null === $this->price) { + $this->price = Product::getPriceStatic((int) $this->id, false, null, 6, null, false, true, 1, false, null, null, null, $this->specificPrice); + } + + if (null === $this->unit_price_ratio) { + $this->unit_price_ratio = ($this->unit_price != 0 ? $this->price / $this->unit_price : 0); + } + + $success = parent::update($null_values); + if ($success && Configuration::get('PS_SEARCH_INDEXATION')) { + Search::indexation(false, $this->id); + } + Hook::exec('actionProductUpdate', ['id_product' => (int) $this->id]); + + return $success; + } + + /** + * For a given product, returns its real quantity. + * + * @since 1.5.0 + * + * @param int $id_product Product identifier + * @param int $id_product_attribute Attribute identifier + * @param int $id_warehouse Warehouse identifier + * @param int|null $id_shop Shop identifier + * + * @return int real_quantity + */ + public static function getRealQuantity($id_product, $id_product_attribute = 0, $id_warehouse = 0, $id_shop = null) + { + static $manager = null; + + if (Configuration::get('PS_ADVANCED_STOCK_MANAGEMENT') && null === $manager) { + $manager = StockManagerFactory::getManager(); + } + + if (Configuration::get('PS_ADVANCED_STOCK_MANAGEMENT') && Product::usesAdvancedStockManagement($id_product) && + StockAvailable::dependsOnStock($id_product, $id_shop)) { + return $manager->getProductRealQuantities($id_product, $id_product_attribute, $id_warehouse, true); + } else { + return StockAvailable::getQuantityAvailableByProduct($id_product, $id_product_attribute, $id_shop); + } + } + + /** + * For a given product, tells if it uses the advanced stock management. + * + * @since 1.5.0 + * + * @param int $id_product Product identifier + * + * @return bool + */ + public static function usesAdvancedStockManagement($id_product) + { + $query = new DbQuery(); + $query->select('product_shop.advanced_stock_management'); + $query->from('product', 'p'); + $query->join(Shop::addSqlAssociation('product', 'p')); + $query->where('p.id_product = ' . (int) $id_product); + + return (bool) Db::getInstance()->getValue($query); + } + + /** + * This method allows to flush price cache. + * + * @since 1.5.0 + */ + public static function flushPriceCache() + { + self::$_prices = []; + self::$_pricesLevel2 = []; + } + + /** + * Get list of parent categories. + * + * @since 1.5.0 + * + * @param int|null $id_lang Language identifier + * + * @return array + */ + public function getParentCategories($id_lang = null) + { + if (!$id_lang) { + $id_lang = Context::getContext()->language->id; + } + + $interval = Category::getInterval($this->id_category_default); + $sql = new DbQuery(); + $sql->from('category', 'c'); + $sql->leftJoin('category_lang', 'cl', 'c.id_category = cl.id_category AND id_lang = ' . (int) $id_lang . Shop::addSqlRestrictionOnLang('cl')); + $sql->where('c.nleft <= ' . (int) $interval['nleft'] . ' AND c.nright >= ' . (int) $interval['nright']); + $sql->orderBy('c.nleft'); + + return Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS($sql); + } + + /** + * Fill the variables used for stock management. + */ + public function loadStockData() + { + if (false === Validate::isLoadedObject($this)) { + return; + } + + // Default product quantity is available quantity to sell in current shop + $this->quantity = StockAvailable::getQuantityAvailableByProduct($this->id, 0); + $this->out_of_stock = StockAvailable::outOfStock($this->id); + $this->depends_on_stock = StockAvailable::dependsOnStock($this->id); + $this->location = StockAvailable::getLocation($this->id) ?: ''; + + if (Context::getContext()->shop->getContext() == Shop::CONTEXT_GROUP && Context::getContext()->shop->getContextShopGroup()->share_stock == 1) { + $this->advanced_stock_management = $this->useAdvancedStockManagement(); + } + } + + /** + * Get Advanced Stock Management status for this product + * + * @return bool 0 for disabled, 1 for enabled + */ + public function useAdvancedStockManagement() + { + return (bool) Db::getInstance()->getValue( + 'SELECT `advanced_stock_management` + FROM ' . _DB_PREFIX_ . 'product_shop + WHERE id_product=' . (int) $this->id . Shop::addSqlRestriction() + ); + } + + /** + * Set Advanced Stock Management status for this product + * + * @param bool $value false for disabled, true for enabled + */ + public function setAdvancedStockManagement($value) + { + $this->advanced_stock_management = (bool) $value; + if (Context::getContext()->shop->getContext() == Shop::CONTEXT_GROUP + && Context::getContext()->shop->getContextShopGroup()->share_stock == 1) { + Db::getInstance()->execute( + ' + UPDATE `' . _DB_PREFIX_ . 'product_shop` + SET `advanced_stock_management`=' . (int) $value . ' + WHERE id_product=' . (int) $this->id . Shop::addSqlRestriction() + ); + } else { + $this->setFieldsToUpdate(['advanced_stock_management' => true]); + $this->save(); + } + } + + /** + * Get the default category according to the shop. + * + * @return array{id_category_default: int}|int + */ + public function getDefaultCategory() + { + $default_category = Db::getInstance()->getValue( + 'SELECT product_shop.`id_category_default` + FROM `' . _DB_PREFIX_ . 'product` p + ' . Shop::addSqlAssociation('product', 'p') . ' + WHERE p.`id_product` = ' . (int) $this->id + ); + + if (!$default_category) { + return ['id_category_default' => Context::getContext()->shop->id_category]; + } else { + return (int) $default_category; + } + } + + /** + * Get Shop identifiers + * + * @param int $id_product Product identifier + * + * @return array + */ + public static function getShopsByProduct($id_product) + { + return Db::getInstance()->executeS(' + SELECT `id_shop` + FROM `' . _DB_PREFIX_ . 'product_shop` + WHERE `id_product` = ' . (int) $id_product); + } + + /** + * Remove all downloadable files for product and its attributes. + * + * @return bool + */ + public function deleteDownload() + { + $result = true; + $collection_download = new PrestaShopCollection('ProductDownload'); + $collection_download->where('id_product', '=', $this->id); + /** @var ProductDownload $product_download */ + foreach ($collection_download as $product_download) { + $result &= $product_download->delete($product_download->checkFile()); + } + + return $result; + } + + /** + * Get the product type (simple, virtual, pack). + * + * @since in 1.5.0 + * + * @return int + */ + public function getType() + { + if (!$this->id) { + return Product::PTYPE_SIMPLE; + } + if (Pack::isPack($this->id)) { + return Product::PTYPE_PACK; + } + if ($this->is_virtual) { + return Product::PTYPE_VIRTUAL; + } + + return Product::PTYPE_SIMPLE; + } + + /** + * @return bool + */ + public function hasAttributesInOtherShops() + { + return (bool) Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue( + ' + SELECT pa.id_product_attribute + FROM `' . _DB_PREFIX_ . 'product_attribute` pa + LEFT JOIN `' . _DB_PREFIX_ . 'product_attribute_shop` pas ON (pa.`id_product_attribute` = pas.`id_product_attribute`) + WHERE pa.`id_product` = ' . (int) $this->id + ); + } + + /** + * @return string TaxRulesGroup identifier most used + */ + public static function getIdTaxRulesGroupMostUsed() + { + return Db::getInstance()->getValue( + ' + SELECT id_tax_rules_group + FROM ( + SELECT COUNT(*) n, product_shop.id_tax_rules_group + FROM ' . _DB_PREFIX_ . 'product p + ' . Shop::addSqlAssociation('product', 'p') . ' + JOIN ' . _DB_PREFIX_ . 'tax_rules_group trg ON (product_shop.id_tax_rules_group = trg.id_tax_rules_group) + WHERE trg.active = 1 AND trg.deleted = 0 + GROUP BY product_shop.id_tax_rules_group + ORDER BY n DESC + LIMIT 1 + ) most_used' + ); + } + + /** + * For a given ean13 reference, returns the corresponding id. + * + * @param string $ean13 + * + * @return int|string Product identifier + */ + public static function getIdByEan13($ean13) + { + if (empty($ean13)) { + return 0; + } + + if (!Validate::isEan13($ean13)) { + return 0; + } + + $query = new DbQuery(); + $query->select('p.id_product'); + $query->from('product', 'p'); + $query->where('p.ean13 = \'' . pSQL($ean13) . '\''); + + return Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue($query); + } + + /** + * For a given reference, returns the corresponding id. + * + * @param string $reference + * + * @return int|string Product identifier + */ + public static function getIdByReference($reference) + { + if (empty($reference)) { + return 0; + } + + if (!Validate::isReference($reference)) { + return 0; + } + + $query = new DbQuery(); + $query->select('p.id_product'); + $query->from('product', 'p'); + $query->where('p.reference = \'' . pSQL($reference) . '\''); + + return Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue($query); + } + + /** + * @return string simple, pack, virtual + */ + public function getWsType() + { + $type_information = [ + Product::PTYPE_SIMPLE => 'simple', + Product::PTYPE_PACK => 'pack', + Product::PTYPE_VIRTUAL => 'virtual', + ]; + + return $type_information[$this->getType()]; + } + + /** + * Create the link rewrite if not exists or invalid on product creation + * + * @return bool + */ + public function modifierWsLinkRewrite() + { + if (empty($this->link_rewrite)) { + $this->link_rewrite = []; + } + + foreach ($this->name as $id_lang => $name) { + if (empty($this->link_rewrite[$id_lang])) { + $this->link_rewrite[$id_lang] = Tools::link_rewrite($name); + } elseif (!Validate::isLinkRewrite($this->link_rewrite[$id_lang])) { + $this->link_rewrite[$id_lang] = Tools::link_rewrite($this->link_rewrite[$id_lang]); + } + } + + return true; + } + + /** + * @return array + */ + public function getWsProductBundle() + { + return Db::getInstance()->executeS('SELECT id_product_item as id, id_product_attribute_item as id_product_attribute, quantity FROM ' . _DB_PREFIX_ . 'pack WHERE id_product_pack = ' . (int) $this->id); + } + + /** + * @param string $type_str simple, pack, virtual + * + * @return bool + */ + public function setWsType($type_str) + { + $reverse_type_information = [ + 'simple' => Product::PTYPE_SIMPLE, + 'pack' => Product::PTYPE_PACK, + 'virtual' => Product::PTYPE_VIRTUAL, + ]; + + if (!isset($reverse_type_information[$type_str])) { + return false; + } + + $type = $reverse_type_information[$type_str]; + + if (Pack::isPack((int) $this->id) && $type != Product::PTYPE_PACK) { + Pack::deleteItems($this->id); + } + + $this->cache_is_pack = ($type == Product::PTYPE_PACK); + $this->is_virtual = ($type == Product::PTYPE_VIRTUAL); + $this->product_type = $this->getDynamicProductType(); + + return true; + } + + /** + * @param array $items + * + * @return bool + */ + public function setWsProductBundle($items) + { + if ($this->is_virtual) { + return false; + } + + Pack::deleteItems($this->id); + + foreach ($items as $item) { + // Combination of a product is optional, and can be omitted. + if (!isset($item['product_attribute_id'])) { + $item['product_attribute_id'] = 0; + } + if ((int) $item['id'] > 0) { + Pack::addItem($this->id, (int) $item['id'], (int) $item['quantity'], (int) $item['product_attribute_id']); + } + } + + return true; + } + + /** + * @param int $id_attribute Attribute identifier + * @param int $id_shop Shop identifier + * + * @return string Attribute identifier + */ + public function isColorUnavailable($id_attribute, $id_shop) + { + return Db::getInstance()->getValue( + ' + SELECT sa.id_product_attribute + FROM ' . _DB_PREFIX_ . 'stock_available sa + WHERE id_product=' . (int) $this->id . ' AND quantity <= 0 + ' . StockAvailable::addSqlShopRestriction(null, $id_shop, 'sa') . ' + AND EXISTS ( + SELECT 1 + FROM ' . _DB_PREFIX_ . 'product_attribute pa + JOIN ' . _DB_PREFIX_ . 'product_attribute_shop product_attribute_shop + ON (product_attribute_shop.id_product_attribute = pa.id_product_attribute AND product_attribute_shop.id_shop=' . (int) $id_shop . ') + JOIN ' . _DB_PREFIX_ . 'product_attribute_combination pac + ON (pac.id_product_attribute AND product_attribute_shop.id_product_attribute) + WHERE sa.id_product_attribute = pa.id_product_attribute AND pa.id_product=' . (int) $this->id . ' AND pac.id_attribute=' . (int) $id_attribute . ' + )' + ); + } + + /** + * @param int $id_product Product identifier + * @param bool $full + * + * @return string + */ + public static function getColorsListCacheId($id_product, $full = true) + { + $cache_id = 'productlist_colors'; + if ($id_product) { + $cache_id .= '|' . (int) $id_product; + } + + if ($full) { + $cache_id .= '|' . (int) Context::getContext()->shop->id . '|' . (int) Context::getContext()->cookie->id_lang; + } + + return $cache_id; + } + + /** + * @param int $id_product Product identifier + * @param int $pack_stock_type value of Pack stock type, see constants defined in Pack class + * + * @return bool + */ + public static function setPackStockType($id_product, $pack_stock_type) + { + return Db::getInstance()->execute('UPDATE ' . _DB_PREFIX_ . 'product p + ' . Shop::addSqlAssociation('product', 'p') . ' SET product_shop.pack_stock_type = ' . (int) $pack_stock_type . ' WHERE p.`id_product` = ' . (int) $id_product); + } + + /** + * Gets a list of IDs from a list of IDs/Refs. The result will avoid duplicates, and checks if given IDs/Refs exists in DB. + * Useful when a product list should be checked before a bulk operation on them (Only 1 query => performances). + * + * @param int|string|int[]|string[] $ids_or_refs Product identifier(s) or reference(s) + * + * @return array|false Product identifiers, without duplicate and only existing ones + */ + public static function getExistingIdsFromIdsOrRefs($ids_or_refs) + { + // separate IDs and Refs + $ids = []; + $refs = []; + $whereStatements = []; + foreach ((is_array($ids_or_refs) ? $ids_or_refs : [$ids_or_refs]) as $id_or_ref) { + if (is_numeric($id_or_ref)) { + $ids[] = (int) $id_or_ref; + } elseif (is_string($id_or_ref)) { + $refs[] = '\'' . pSQL($id_or_ref) . '\''; + } + } + + // construct WHERE statement with OR combination + if (count($ids) > 0) { + $whereStatements[] = ' p.id_product IN (' . implode(',', $ids) . ') '; + } + if (count($refs) > 0) { + $whereStatements[] = ' p.reference IN (' . implode(',', $refs) . ') '; + } + if (!count($whereStatements)) { + return false; + } + + $results = Db::getInstance()->executeS(' + SELECT DISTINCT `id_product` + FROM `' . _DB_PREFIX_ . 'product` p + WHERE ' . implode(' OR ', $whereStatements)); + + // simplify array since there is 1 useless dimension. + // FIXME : find a better way to avoid this, directly in SQL? + foreach ($results as $k => $v) { + $results[$k] = (int) $v['id_product']; + } + + return $results; + } + + /** + * Get object of redirect_type. + * + * @return string|false category, product, false if unknown redirect_type + */ + public function getRedirectType() + { + switch ($this->redirect_type) { + case RedirectType::TYPE_CATEGORY_PERMANENT: + case RedirectType::TYPE_CATEGORY_TEMPORARY: + return 'category'; + + case RedirectType::TYPE_PRODUCT_PERMANENT: + case RedirectType::TYPE_PRODUCT_TEMPORARY: + return 'product'; + } + + return false; + } + + /** + * Return an array of customization fields IDs. + * + * @return array|false + */ + public function getUsedCustomizationFieldsIds() + { + return Db::getInstance()->executeS( + 'SELECT cd.`index` FROM `' . _DB_PREFIX_ . 'customized_data` cd + LEFT JOIN `' . _DB_PREFIX_ . 'customization_field` cf ON cf.`id_customization_field` = cd.`index` + WHERE cf.`id_product` = ' . (int) $this->id + ); + } + + /** + * Remove unused customization for the product. + * + * @param array $customizationIds - Array of customization fields IDs + * + * @return bool + * + * @throws PrestaShopDatabaseException + */ + public function deleteUnusedCustomizationFields($customizationIds) + { + $return = true; + if (is_array($customizationIds) && !empty($customizationIds)) { + $toDeleteIds = implode(',', $customizationIds); + $return &= Db::getInstance()->execute('DELETE FROM `' . _DB_PREFIX_ . 'customization_field` WHERE + `id_product` = ' . (int) $this->id . ' AND `id_customization_field` IN (' . $toDeleteIds . ')'); + + $return &= Db::getInstance()->execute('DELETE FROM `' . _DB_PREFIX_ . 'customization_field_lang` WHERE + `id_customization_field` IN (' . $toDeleteIds . ')'); + } + + if (!$return) { + throw new PrestaShopDatabaseException('An error occurred while deletion the customization fields'); + } + + return $return; + } + + /** + * Update the customization fields to be deleted if not used. + * + * @param array $customizationIds - Array of excluded customization fields IDs + * + * @return bool + * + * @throws PrestaShopDatabaseException + */ + public function softDeleteCustomizationFields($customizationIds) + { + $updateQuery = 'UPDATE `' . _DB_PREFIX_ . 'customization_field` cf + SET cf.`is_deleted` = 1 + WHERE + cf.`id_product` = ' . (int) $this->id . ' + AND cf.`is_deleted` = 0 '; + + if (is_array($customizationIds) && !empty($customizationIds)) { + $updateQuery .= 'AND cf.`id_customization_field` NOT IN (' . implode(',', array_map('intval', $customizationIds)) . ')'; + } + + $return = Db::getInstance()->execute($updateQuery); + + if (!$return) { + throw new PrestaShopDatabaseException('An error occurred while soft deletion the customization fields'); + } + + return $return; + } + + /** + * Update default supplier data + * + * @param int $idSupplier + * @param float $wholesalePrice + * @param string $supplierReference + * + * @return bool + */ + public function updateDefaultSupplierData(int $idSupplier, string $supplierReference, float $wholesalePrice): bool + { + if (!$this->id) { + return false; + } + + $sql = 'UPDATE `' . _DB_PREFIX_ . 'product` ' . + 'SET ' . + 'id_supplier = %d, ' . + 'supplier_reference = "%s", ' . + 'wholesale_price = "%s" ' . + 'WHERE id_product = %d'; + + return Db::getInstance()->execute( + sprintf( + $sql, + $idSupplier, + pSQL($supplierReference), + $wholesalePrice, + $this->id + ) + ); + } + + /** + * Get Product ecotax + * + * @param int $precision + * @param bool $include_tax + * @param bool $formated + * + * @return string|float + */ + public function getEcotax($precision = null, $include_tax = true, $formated = false) + { + $context = Context::getContext(); + $currency = $context->currency; + $precision = $precision ?? $currency->precision; + $ecotax_rate = $include_tax ? (float) Tax::getProductEcotaxRate() : 0; + $ecotax = Tools::ps_round( + (float) $this->ecotax * (1 + $ecotax_rate / 100), + $precision, + null + ); + + return $formated ? $context->getCurrentLocale()->formatPrice($ecotax, $currency->iso_code) : $ecotax; + } + + /** + * @return string + */ + public function getProductType(): string + { + // Default value is the one saved, but in case it is not set we use dynamic definition + if (!empty($this->product_type) && in_array($this->product_type, ProductType::AVAILABLE_TYPES)) { + return $this->product_type; + } + + return $this->getDynamicProductType(); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayDashboardToolbarIcons.md b/modules/concepts/hooks/list-hooks/displayDashboardToolbarIcons.md new file mode 100644 index 0000000000..64eafad31c --- /dev/null +++ b/modules/concepts/hooks/list-hooks/displayDashboardToolbarIcons.md @@ -0,0 +1,23 @@ +--- +menuTitle: displayDashboardToolbarIcons +title: displayDashboardToolbarIcons +hidden: true +files: + - src/PrestaShopBundle/Resources/views/Admin/Product/CatalogPage/Blocks/tools.html.twig +types: + - backoffice +hookTypes: + - twig +--- + +# Hook : displayDashboardToolbarIcons + +Located in : + + - src/PrestaShopBundle/Resources/views/Admin/Product/CatalogPage/Blocks/tools.html.twig + +## Parameters + +```php +{{ renderhook('displayDashboardToolbarIcons', {}) }} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayDashboardToolbarTopMenu.md b/modules/concepts/hooks/list-hooks/displayDashboardToolbarTopMenu.md new file mode 100644 index 0000000000..0ef19591df --- /dev/null +++ b/modules/concepts/hooks/list-hooks/displayDashboardToolbarTopMenu.md @@ -0,0 +1,23 @@ +--- +menuTitle: displayDashboardToolbarTopMenu +title: displayDashboardToolbarTopMenu +hidden: true +files: + - admin784x07v4swfhm9fgvc0/themes/new-theme/template/page_header_toolbar.tpl +types: + - frontoffice +hookTypes: + - smarty +--- + +# Hook : displayDashboardToolbarTopMenu + +Located in : + + - admin784x07v4swfhm9fgvc0/themes/new-theme/template/page_header_toolbar.tpl + +## Parameters + +```php +{hook h='displayDashboardToolbarTopMenu'} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayDashboardTop.md b/modules/concepts/hooks/list-hooks/displayDashboardTop.md new file mode 100644 index 0000000000..68da7fc7d3 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/displayDashboardTop.md @@ -0,0 +1,23 @@ +--- +menuTitle: displayDashboardTop +title: displayDashboardTop +hidden: true +files: + - admin784x07v4swfhm9fgvc0/themes/new-theme/template/page_header_toolbar.tpl +types: + - frontoffice +hookTypes: + - smarty +--- + +# Hook : displayDashboardTop + +Located in : + + - admin784x07v4swfhm9fgvc0/themes/new-theme/template/page_header_toolbar.tpl + +## Parameters + +```php +{hook h='displayDashboardTop'} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayEmptyModuleCategoryExtraMessage.md b/modules/concepts/hooks/list-hooks/displayEmptyModuleCategoryExtraMessage.md new file mode 100644 index 0000000000..a78da26e63 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/displayEmptyModuleCategoryExtraMessage.md @@ -0,0 +1,23 @@ +--- +menuTitle: displayEmptyModuleCategoryExtraMessage +title: displayEmptyModuleCategoryExtraMessage +hidden: true +files: + - src/PrestaShopBundle/Resources/views/Admin/Module/Includes/grid_manage_empty.html.twig +types: + - backoffice +hookTypes: + - twig +--- + +# Hook : displayEmptyModuleCategoryExtraMessage + +Located in : + + - src/PrestaShopBundle/Resources/views/Admin/Module/Includes/grid_manage_empty.html.twig + +## Parameters + +```php +{{ renderhook('displayEmptyModuleCategoryExtraMessage', {'category_name': category.name}) }} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayExpressCheckout.md b/modules/concepts/hooks/list-hooks/displayExpressCheckout.md new file mode 100644 index 0000000000..5c760ee734 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/displayExpressCheckout.md @@ -0,0 +1,23 @@ +--- +menuTitle: displayExpressCheckout +title: displayExpressCheckout +hidden: true +files: + - themes/classic/templates/checkout/_partials/cart-detailed-actions.tpl +types: + - frontoffice +hookTypes: + - smarty +--- + +# Hook : displayExpressCheckout + +Located in : + + - themes/classic/templates/checkout/_partials/cart-detailed-actions.tpl + +## Parameters + +```php +{hook h='displayExpressCheckout'} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayFeatureForm.md b/modules/concepts/hooks/list-hooks/displayFeatureForm.md new file mode 100644 index 0000000000..ce80af5abc --- /dev/null +++ b/modules/concepts/hooks/list-hooks/displayFeatureForm.md @@ -0,0 +1,23 @@ +--- +menuTitle: displayFeatureForm +title: displayFeatureForm +hidden: true +files: + - src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Features/Blocks/form.html.twig +types: + - backoffice +hookTypes: + - twig +--- + +# Hook : displayFeatureForm + +Located in : + + - src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Features/Blocks/form.html.twig + +## Parameters + +```php +{{ renderhook('displayFeatureForm', {'id_feature': featureId}) }} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayFooter.md b/modules/concepts/hooks/list-hooks/displayFooter.md new file mode 100644 index 0000000000..b7a68042b8 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/displayFooter.md @@ -0,0 +1,23 @@ +--- +menuTitle: displayFooter +title: displayFooter +hidden: true +files: + - themes/classic/templates/_partials/footer.tpl +types: + - frontoffice +hookTypes: + - smarty +--- + +# Hook : displayFooter + +Located in : + + - themes/classic/templates/_partials/footer.tpl + +## Parameters + +```php +{hook h='displayFooter'} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayFooterAfter.md b/modules/concepts/hooks/list-hooks/displayFooterAfter.md new file mode 100644 index 0000000000..aace9834f8 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/displayFooterAfter.md @@ -0,0 +1,23 @@ +--- +menuTitle: displayFooterAfter +title: displayFooterAfter +hidden: true +files: + - themes/classic/templates/_partials/footer.tpl +types: + - frontoffice +hookTypes: + - smarty +--- + +# Hook : displayFooterAfter + +Located in : + + - themes/classic/templates/_partials/footer.tpl + +## Parameters + +```php +{hook h='displayFooterAfter'} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayFooterBefore.md b/modules/concepts/hooks/list-hooks/displayFooterBefore.md new file mode 100644 index 0000000000..908d4cc8cd --- /dev/null +++ b/modules/concepts/hooks/list-hooks/displayFooterBefore.md @@ -0,0 +1,23 @@ +--- +menuTitle: displayFooterBefore +title: displayFooterBefore +hidden: true +files: + - themes/classic/templates/_partials/footer.tpl +types: + - frontoffice +hookTypes: + - smarty +--- + +# Hook : displayFooterBefore + +Located in : + + - themes/classic/templates/_partials/footer.tpl + +## Parameters + +```php +{hook h='displayFooterBefore'} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayFooterProduct.md b/modules/concepts/hooks/list-hooks/displayFooterProduct.md new file mode 100644 index 0000000000..42beb20d96 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/displayFooterProduct.md @@ -0,0 +1,23 @@ +--- +menuTitle: displayFooterProduct +title: displayFooterProduct +hidden: true +files: + - themes/classic/templates/catalog/product.tpl +types: + - frontoffice +hookTypes: + - smarty +--- + +# Hook : displayFooterProduct + +Located in : + + - themes/classic/templates/catalog/product.tpl + +## Parameters + +```php +{hook h='displayFooterProduct' product=$product category=$category} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayGDPRConsent.md b/modules/concepts/hooks/list-hooks/displayGDPRConsent.md new file mode 100644 index 0000000000..3169ffe066 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/displayGDPRConsent.md @@ -0,0 +1,23 @@ +--- +menuTitle: displayGDPRConsent +title: displayGDPRConsent +hidden: true +files: + - themes/classic/modules/ps_emailsubscription/views/templates/hook/ps_emailsubscription.tpl +types: + - frontoffice +hookTypes: + - smarty +--- + +# Hook : displayGDPRConsent + +Located in : + + - themes/classic/modules/ps_emailsubscription/views/templates/hook/ps_emailsubscription.tpl + +## Parameters + +```php +{hook h='displayGDPRConsent' id_module=$id_module} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayHeader.md b/modules/concepts/hooks/list-hooks/displayHeader.md new file mode 100644 index 0000000000..39cf0e5abd --- /dev/null +++ b/modules/concepts/hooks/list-hooks/displayHeader.md @@ -0,0 +1,23 @@ +--- +menuTitle: displayHeader +title: displayHeader +hidden: true +files: + - classes/controller/FrontController.php +types: + - frontoffice +hookTypes: + - legacy +--- + +# Hook : displayHeader + +Located in : + + - classes/controller/FrontController.php + +## Parameters + +```php +Hook::exec('displayHeader'), +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayHome.md b/modules/concepts/hooks/list-hooks/displayHome.md new file mode 100644 index 0000000000..52fda502a4 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/displayHome.md @@ -0,0 +1,23 @@ +--- +menuTitle: displayHome +title: displayHome +hidden: true +files: + - controllers/front/IndexController.php +types: + - frontoffice +hookTypes: + - legacy +--- + +# Hook : displayHome + +Located in : + + - controllers/front/IndexController.php + +## Parameters + +```php +Hook::exec('displayHome'), +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayInvoiceLegalFreeText.md b/modules/concepts/hooks/list-hooks/displayInvoiceLegalFreeText.md new file mode 100644 index 0000000000..c97396143d --- /dev/null +++ b/modules/concepts/hooks/list-hooks/displayInvoiceLegalFreeText.md @@ -0,0 +1,23 @@ +--- +menuTitle: displayInvoiceLegalFreeText +title: displayInvoiceLegalFreeText +hidden: true +files: + - classes/pdf/HTMLTemplateInvoice.php +types: + - frontoffice +hookTypes: + - legacy +--- + +# Hook : displayInvoiceLegalFreeText + +Located in : + + - classes/pdf/HTMLTemplateInvoice.php + +## Parameters + +```php +Hook::exec('displayInvoiceLegalFreeText', ['order' => $this->order]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayLeftColumnProduct.md b/modules/concepts/hooks/list-hooks/displayLeftColumnProduct.md new file mode 100644 index 0000000000..c8d760615e --- /dev/null +++ b/modules/concepts/hooks/list-hooks/displayLeftColumnProduct.md @@ -0,0 +1,23 @@ +--- +menuTitle: displayLeftColumnProduct +title: displayLeftColumnProduct +hidden: true +files: + - themes/classic/templates/layouts/layout-both-columns.tpl +types: + - frontoffice +hookTypes: + - smarty +--- + +# Hook : displayLeftColumnProduct + +Located in : + + - themes/classic/templates/layouts/layout-both-columns.tpl + +## Parameters + +```php +{hook h='displayLeftColumnProduct' product=$product category=$category} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayMaintenance.md b/modules/concepts/hooks/list-hooks/displayMaintenance.md new file mode 100644 index 0000000000..5ee0c10330 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/displayMaintenance.md @@ -0,0 +1,23 @@ +--- +menuTitle: displayMaintenance +title: displayMaintenance +hidden: true +files: + - classes/controller/FrontController.php +types: + - frontoffice +hookTypes: + - legacy +--- + +# Hook : displayMaintenance + +Located in : + + - classes/controller/FrontController.php + +## Parameters + +```php +Hook::exec('displayMaintenance', []), +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayMyAccountBlock.md b/modules/concepts/hooks/list-hooks/displayMyAccountBlock.md new file mode 100644 index 0000000000..0494fdd636 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/displayMyAccountBlock.md @@ -0,0 +1,23 @@ +--- +menuTitle: displayMyAccountBlock +title: displayMyAccountBlock +hidden: true +files: + - themes/classic/modules/ps_customeraccountlinks/ps_customeraccountlinks.tpl +types: + - frontoffice +hookTypes: + - smarty +--- + +# Hook : displayMyAccountBlock + +Located in : + + - themes/classic/modules/ps_customeraccountlinks/ps_customeraccountlinks.tpl + +## Parameters + +```php +{hook h='displayMyAccountBlock'} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayNav1.md b/modules/concepts/hooks/list-hooks/displayNav1.md new file mode 100644 index 0000000000..f4eae36650 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/displayNav1.md @@ -0,0 +1,23 @@ +--- +menuTitle: displayNav1 +title: displayNav1 +hidden: true +files: + - themes/classic/templates/checkout/_partials/header.tpl +types: + - frontoffice +hookTypes: + - smarty +--- + +# Hook : displayNav1 + +Located in : + + - themes/classic/templates/checkout/_partials/header.tpl + +## Parameters + +```php +{hook h='displayNav1'} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayNav2.md b/modules/concepts/hooks/list-hooks/displayNav2.md new file mode 100644 index 0000000000..7a25c4bbcc --- /dev/null +++ b/modules/concepts/hooks/list-hooks/displayNav2.md @@ -0,0 +1,23 @@ +--- +menuTitle: displayNav2 +title: displayNav2 +hidden: true +files: + - themes/classic/templates/checkout/_partials/header.tpl +types: + - frontoffice +hookTypes: + - smarty +--- + +# Hook : displayNav2 + +Located in : + + - themes/classic/templates/checkout/_partials/header.tpl + +## Parameters + +```php +{hook h='displayNav2'} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayNavFullWidth.md b/modules/concepts/hooks/list-hooks/displayNavFullWidth.md new file mode 100644 index 0000000000..6aba15f3b8 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/displayNavFullWidth.md @@ -0,0 +1,23 @@ +--- +menuTitle: displayNavFullWidth +title: displayNavFullWidth +hidden: true +files: + - themes/classic/templates/checkout/_partials/header.tpl +types: + - frontoffice +hookTypes: + - smarty +--- + +# Hook : displayNavFullWidth + +Located in : + + - themes/classic/templates/checkout/_partials/header.tpl + +## Parameters + +```php +{hook h='displayNavFullWidth'} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayNewsletterRegistration.md b/modules/concepts/hooks/list-hooks/displayNewsletterRegistration.md new file mode 100644 index 0000000000..d9d880d901 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/displayNewsletterRegistration.md @@ -0,0 +1,23 @@ +--- +menuTitle: displayNewsletterRegistration +title: displayNewsletterRegistration +hidden: true +files: + - themes/classic/modules/ps_emailsubscription/views/templates/hook/ps_emailsubscription.tpl +types: + - frontoffice +hookTypes: + - smarty +--- + +# Hook : displayNewsletterRegistration + +Located in : + + - themes/classic/modules/ps_emailsubscription/views/templates/hook/ps_emailsubscription.tpl + +## Parameters + +```php +{hook h='displayNewsletterRegistration'} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayNotFound.md b/modules/concepts/hooks/list-hooks/displayNotFound.md new file mode 100644 index 0000000000..034bb78d76 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/displayNotFound.md @@ -0,0 +1,23 @@ +--- +menuTitle: displayNotFound +title: displayNotFound +hidden: true +files: + - themes/classic/templates/errors/not-found.tpl +types: + - frontoffice +hookTypes: + - smarty +--- + +# Hook : displayNotFound + +Located in : + + - themes/classic/templates/errors/not-found.tpl + +## Parameters + +```php +{hook h='displayNotFound'} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayOrderConfirmation1.md b/modules/concepts/hooks/list-hooks/displayOrderConfirmation1.md new file mode 100644 index 0000000000..0037459364 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/displayOrderConfirmation1.md @@ -0,0 +1,23 @@ +--- +menuTitle: displayOrderConfirmation1 +title: displayOrderConfirmation1 +hidden: true +files: + - themes/classic/templates/checkout/order-confirmation.tpl +types: + - frontoffice +hookTypes: + - smarty +--- + +# Hook : displayOrderConfirmation1 + +Located in : + + - themes/classic/templates/checkout/order-confirmation.tpl + +## Parameters + +```php +{hook h='displayOrderConfirmation1'} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayOrderConfirmation2.md b/modules/concepts/hooks/list-hooks/displayOrderConfirmation2.md new file mode 100644 index 0000000000..2c220f4bf7 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/displayOrderConfirmation2.md @@ -0,0 +1,23 @@ +--- +menuTitle: displayOrderConfirmation2 +title: displayOrderConfirmation2 +hidden: true +files: + - themes/classic/templates/checkout/order-confirmation.tpl +types: + - frontoffice +hookTypes: + - smarty +--- + +# Hook : displayOrderConfirmation2 + +Located in : + + - themes/classic/templates/checkout/order-confirmation.tpl + +## Parameters + +```php +{hook h='displayOrderConfirmation2'} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayOrderDetail.md b/modules/concepts/hooks/list-hooks/displayOrderDetail.md new file mode 100644 index 0000000000..b5adae179e --- /dev/null +++ b/modules/concepts/hooks/list-hooks/displayOrderDetail.md @@ -0,0 +1,23 @@ +--- +menuTitle: displayOrderDetail +title: displayOrderDetail +hidden: true +files: + - controllers/front/OrderDetailController.php +types: + - frontoffice +hookTypes: + - legacy +--- + +# Hook : displayOrderDetail + +Located in : + + - controllers/front/OrderDetailController.php + +## Parameters + +```php +Hook::exec('displayOrderDetail', ['order' => $order]), +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayOrderPreview.md b/modules/concepts/hooks/list-hooks/displayOrderPreview.md new file mode 100644 index 0000000000..671696452e --- /dev/null +++ b/modules/concepts/hooks/list-hooks/displayOrderPreview.md @@ -0,0 +1,23 @@ +--- +menuTitle: displayOrderPreview +title: displayOrderPreview +hidden: true +files: + - src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/preview.html.twig +types: + - backoffice +hookTypes: + - twig +--- + +# Hook : displayOrderPreview + +Located in : + + - src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/preview.html.twig + +## Parameters + +```php +{{ renderhook('displayOrderPreview', {'order_id': orderId}) }} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayPaymentByBinaries.md b/modules/concepts/hooks/list-hooks/displayPaymentByBinaries.md new file mode 100644 index 0000000000..b304684888 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/displayPaymentByBinaries.md @@ -0,0 +1,23 @@ +--- +menuTitle: displayPaymentByBinaries +title: displayPaymentByBinaries +hidden: true +files: + - themes/classic/templates/checkout/_partials/steps/payment.tpl +types: + - frontoffice +hookTypes: + - smarty +--- + +# Hook : displayPaymentByBinaries + +Located in : + + - themes/classic/templates/checkout/_partials/steps/payment.tpl + +## Parameters + +```php +{hook h='displayPaymentByBinaries'} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayPaymentReturn.md b/modules/concepts/hooks/list-hooks/displayPaymentReturn.md new file mode 100644 index 0000000000..cf16c77965 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/displayPaymentReturn.md @@ -0,0 +1,80 @@ +--- +menuTitle: displayPaymentReturn +title: displayPaymentReturn +hidden: true +files: + - controllers/front/OrderConfirmationController.php +types: + - frontoffice +hookTypes: + - legacy +--- + +# Hook : displayPaymentReturn + +Located in : + + - controllers/front/OrderConfirmationController.php + +## Parameters + +```php +Hook::exec('displayPaymentReturn', ['order' => $order], $this->id_module); + } + + /** + * Execute the hook displayOrderConfirmation. + */ + public function displayOrderConfirmation($order) + { + return Hook::exec('displayOrderConfirmation', ['order' => $order]); + } + + /** + * Check if an order is free and create it. + */ + protected function checkFreeOrder() + { + $cart = $this->context->cart; + if ($cart->id_customer == 0 || $cart->id_address_delivery == 0 || $cart->id_address_invoice == 0) { + Tools::redirect($this->context->link->getPageLink('order')); + } + + $customer = new Customer($cart->id_customer); + if (!Validate::isLoadedObject($customer)) { + Tools::redirect($this->context->link->getPageLink('order')); + } + + $total = (float) $cart->getOrderTotal(true, Cart::BOTH); + if ($total > 0) { + Tools::redirect($this->context->link->getPageLink('order')); + } + + $order = new PaymentFree(); + $order->validateOrder( + $cart->id, + (int) Configuration::get('PS_OS_PAYMENT'), + 0, + $this->trans('Free order', [], 'Admin.Orderscustomers.Feature'), + null, + [], + null, + false, + $cart->secure_key + ); + + // redirect back to us with rest of the data + // note the id_module parameter with value -1 + // it acts as a marker for the module check to use "free_payment" + // for the check + Tools::redirect('index.php?controller=order-confirmation&id_cart=' . (int) $cart->id . '&id_module=-1&id_order=' . (int) $order->currentOrder . '&key=' . $cart->secure_key); + } + + public function getBreadcrumbLinks() + { + $breadcrumb = parent::getBreadcrumbLinks(); + + $breadcrumb['links'][] = [ + 'title' => $this->trans('Order confirmation', [], 'Shop.Theme.Checkout'), + 'url' => $this->context->link->getPageLink('order-confirmation'), +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayPaymentTop.md b/modules/concepts/hooks/list-hooks/displayPaymentTop.md new file mode 100644 index 0000000000..a1c88491f3 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/displayPaymentTop.md @@ -0,0 +1,23 @@ +--- +menuTitle: displayPaymentTop +title: displayPaymentTop +hidden: true +files: + - themes/classic/templates/checkout/_partials/steps/payment.tpl +types: + - frontoffice +hookTypes: + - smarty +--- + +# Hook : displayPaymentTop + +Located in : + + - themes/classic/templates/checkout/_partials/steps/payment.tpl + +## Parameters + +```php +{hook h='displayPaymentTop'} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayPersonalInformationTop.md b/modules/concepts/hooks/list-hooks/displayPersonalInformationTop.md new file mode 100644 index 0000000000..df73e51567 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/displayPersonalInformationTop.md @@ -0,0 +1,23 @@ +--- +menuTitle: displayPersonalInformationTop +title: displayPersonalInformationTop +hidden: true +files: + - themes/classic/templates/checkout/_partials/steps/personal-information.tpl +types: + - frontoffice +hookTypes: + - smarty +--- + +# Hook : displayPersonalInformationTop + +Located in : + + - themes/classic/templates/checkout/_partials/steps/personal-information.tpl + +## Parameters + +```php +{hook h='displayPersonalInformationTop' customer=$customer} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayProductActions.md b/modules/concepts/hooks/list-hooks/displayProductActions.md new file mode 100644 index 0000000000..ac9ee3fa24 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/displayProductActions.md @@ -0,0 +1,23 @@ +--- +menuTitle: displayProductActions +title: displayProductActions +hidden: true +files: + - themes/classic/templates/catalog/_partials/product-add-to-cart.tpl +types: + - frontoffice +hookTypes: + - smarty +--- + +# Hook : displayProductActions + +Located in : + + - themes/classic/templates/catalog/_partials/product-add-to-cart.tpl + +## Parameters + +```php +{hook h='displayProductActions' product=$product} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayProductAdditionalInfo.md b/modules/concepts/hooks/list-hooks/displayProductAdditionalInfo.md new file mode 100644 index 0000000000..12ee0e4ff1 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/displayProductAdditionalInfo.md @@ -0,0 +1,23 @@ +--- +menuTitle: displayProductAdditionalInfo +title: displayProductAdditionalInfo +hidden: true +files: + - themes/classic/templates/catalog/_partials/quickview.tpl +types: + - frontoffice +hookTypes: + - smarty +--- + +# Hook : displayProductAdditionalInfo + +Located in : + + - themes/classic/templates/catalog/_partials/quickview.tpl + +## Parameters + +```php +{hook h='displayProductAdditionalInfo' product=$product} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayProductListReviews.md b/modules/concepts/hooks/list-hooks/displayProductListReviews.md new file mode 100644 index 0000000000..4f49173e04 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/displayProductListReviews.md @@ -0,0 +1,23 @@ +--- +menuTitle: displayProductListReviews +title: displayProductListReviews +hidden: true +files: + - themes/classic/templates/catalog/_partials/miniatures/product.tpl +types: + - frontoffice +hookTypes: + - smarty +--- + +# Hook : displayProductListReviews + +Located in : + + - themes/classic/templates/catalog/_partials/miniatures/product.tpl + +## Parameters + +```php +{hook h='displayProductListReviews' product=$product} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayProductPriceBlock.md b/modules/concepts/hooks/list-hooks/displayProductPriceBlock.md new file mode 100644 index 0000000000..e7beb5e34b --- /dev/null +++ b/modules/concepts/hooks/list-hooks/displayProductPriceBlock.md @@ -0,0 +1,23 @@ +--- +menuTitle: displayProductPriceBlock +title: displayProductPriceBlock +hidden: true +files: + - themes/classic/templates/checkout/_partials/order-confirmation-table.tpl +types: + - frontoffice +hookTypes: + - smarty +--- + +# Hook : displayProductPriceBlock + +Located in : + + - themes/classic/templates/checkout/_partials/order-confirmation-table.tpl + +## Parameters + +```php +{hook h='displayProductPriceBlock' product=$product type="unit_price"} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayReassurance.md b/modules/concepts/hooks/list-hooks/displayReassurance.md new file mode 100644 index 0000000000..86b2128a87 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/displayReassurance.md @@ -0,0 +1,23 @@ +--- +menuTitle: displayReassurance +title: displayReassurance +hidden: true +files: + - themes/classic/templates/checkout/checkout.tpl +types: + - frontoffice +hookTypes: + - smarty +--- + +# Hook : displayReassurance + +Located in : + + - themes/classic/templates/checkout/checkout.tpl + +## Parameters + +```php +{hook h='displayReassurance'} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayRightColumnProduct.md b/modules/concepts/hooks/list-hooks/displayRightColumnProduct.md new file mode 100644 index 0000000000..fb269b03e6 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/displayRightColumnProduct.md @@ -0,0 +1,23 @@ +--- +menuTitle: displayRightColumnProduct +title: displayRightColumnProduct +hidden: true +files: + - themes/classic/templates/layouts/layout-both-columns.tpl +types: + - frontoffice +hookTypes: + - smarty +--- + +# Hook : displayRightColumnProduct + +Located in : + + - themes/classic/templates/layouts/layout-both-columns.tpl + +## Parameters + +```php +{hook h='displayRightColumnProduct'} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displaySearch.md b/modules/concepts/hooks/list-hooks/displaySearch.md new file mode 100644 index 0000000000..26c62254db --- /dev/null +++ b/modules/concepts/hooks/list-hooks/displaySearch.md @@ -0,0 +1,23 @@ +--- +menuTitle: displaySearch +title: displaySearch +hidden: true +files: + - themes/classic/templates/errors/not-found.tpl +types: + - frontoffice +hookTypes: + - smarty +--- + +# Hook : displaySearch + +Located in : + + - themes/classic/templates/errors/not-found.tpl + +## Parameters + +```php +{hook h='displaySearch'} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayShoppingCart.md b/modules/concepts/hooks/list-hooks/displayShoppingCart.md new file mode 100644 index 0000000000..61540a13c6 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/displayShoppingCart.md @@ -0,0 +1,23 @@ +--- +menuTitle: displayShoppingCart +title: displayShoppingCart +hidden: true +files: + - themes/classic/templates/checkout/cart.tpl +types: + - frontoffice +hookTypes: + - smarty +--- + +# Hook : displayShoppingCart + +Located in : + + - themes/classic/templates/checkout/cart.tpl + +## Parameters + +```php +{hook h='displayShoppingCart'} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayShoppingCartFooter.md b/modules/concepts/hooks/list-hooks/displayShoppingCartFooter.md new file mode 100644 index 0000000000..029bf9c3ac --- /dev/null +++ b/modules/concepts/hooks/list-hooks/displayShoppingCartFooter.md @@ -0,0 +1,23 @@ +--- +menuTitle: displayShoppingCartFooter +title: displayShoppingCartFooter +hidden: true +files: + - themes/classic/templates/checkout/cart.tpl +types: + - frontoffice +hookTypes: + - smarty +--- + +# Hook : displayShoppingCartFooter + +Located in : + + - themes/classic/templates/checkout/cart.tpl + +## Parameters + +```php +{hook h='displayShoppingCartFooter'} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayTop.md b/modules/concepts/hooks/list-hooks/displayTop.md new file mode 100644 index 0000000000..3f7b3fe4dc --- /dev/null +++ b/modules/concepts/hooks/list-hooks/displayTop.md @@ -0,0 +1,23 @@ +--- +menuTitle: displayTop +title: displayTop +hidden: true +files: + - themes/classic/templates/checkout/_partials/header.tpl +types: + - frontoffice +hookTypes: + - smarty +--- + +# Hook : displayTop + +Located in : + + - themes/classic/templates/checkout/_partials/header.tpl + +## Parameters + +```php +{hook h='displayTop'} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/filterProductSearch.md b/modules/concepts/hooks/list-hooks/filterProductSearch.md new file mode 100644 index 0000000000..a1f97268c2 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/filterProductSearch.md @@ -0,0 +1,23 @@ +--- +menuTitle: filterProductSearch +title: filterProductSearch +hidden: true +files: + - modules/blockwishlist/controllers/front/view.php +types: + - frontoffice +hookTypes: + - legacy +--- + +# Hook : filterProductSearch + +Located in : + + - modules/blockwishlist/controllers/front/view.php + +## Parameters + +```php +Hook::exec('filterProductSearch', ['searchVariables' => &$searchVariables]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/legacyblockkpi.md b/modules/concepts/hooks/list-hooks/legacyblockkpi.md new file mode 100644 index 0000000000..b95f7a94ad --- /dev/null +++ b/modules/concepts/hooks/list-hooks/legacyblockkpi.md @@ -0,0 +1,23 @@ +--- +menuTitle: legacyblockkpi +title: legacyblockkpi +hidden: true +files: + - src/PrestaShopBundle/Resources/views/Admin/Product/CatalogPage/catalog.html.twig +types: + - backoffice +hookTypes: + - twig +--- + +# Hook : legacyblockkpi + +Located in : + + - src/PrestaShopBundle/Resources/views/Admin/Product/CatalogPage/catalog.html.twig + +## Parameters + +```php +{{ renderhook('legacy_block_kpi', {'kpi_controller': 'AdminProductsController'}) }} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/overrideMinimalPurchasePrice.md b/modules/concepts/hooks/list-hooks/overrideMinimalPurchasePrice.md new file mode 100644 index 0000000000..3cee9feeea --- /dev/null +++ b/modules/concepts/hooks/list-hooks/overrideMinimalPurchasePrice.md @@ -0,0 +1,25 @@ +--- +menuTitle: overrideMinimalPurchasePrice +title: overrideMinimalPurchasePrice +hidden: true +files: + - src/Adapter/Presenter/Cart/CartPresenter.php +types: + - frontoffice +hookTypes: + - legacy +--- + +# Hook : overrideMinimalPurchasePrice + +Located in : + + - src/Adapter/Presenter/Cart/CartPresenter.php + +## Parameters + +```php +Hook::exec('overrideMinimalPurchasePrice', [ + 'minimalPurchase' => &$minimalPurchase, + ]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/termsAndConditions.md b/modules/concepts/hooks/list-hooks/termsAndConditions.md new file mode 100644 index 0000000000..2a0a1c5962 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/termsAndConditions.md @@ -0,0 +1,63 @@ +--- +menuTitle: termsAndConditions +title: termsAndConditions +hidden: true +files: + - classes/checkout/ConditionsToApproveFinder.php +types: + - frontoffice +hookTypes: + - legacy +--- + +# Hook : termsAndConditions + +Located in : + + - classes/checkout/ConditionsToApproveFinder.php + +## Parameters + +```php +Hook::exec('termsAndConditions', [], null, true); + if (!is_array($hookedConditions)) { + $hookedConditions = []; + } + foreach ($hookedConditions as $hookedCondition) { + if ($hookedCondition instanceof TermsAndConditions) { + $allConditions[] = $hookedCondition; + } elseif (is_array($hookedCondition)) { + foreach ($hookedCondition as $hookedConditionObject) { + if ($hookedConditionObject instanceof TermsAndConditions) { + $allConditions[] = $hookedConditionObject; + } + } + } + } + + if (Configuration::get('PS_CONDITIONS')) { + array_unshift($allConditions, $this->getDefaultTermsAndConditions()); + } + + /* + * If two TermsAndConditions objects have the same identifier, + * the one at the end of the list overrides the first one. + * This allows a module to override the default checkbox + * in a consistent manner. + */ + $reducedConditions = []; + foreach ($allConditions as $condition) { + if ($condition instanceof TermsAndConditions) { + $reducedConditions[$condition->getIdentifier()] = $condition; + } + } + + return $reducedConditions; + } + + public function getConditionsToApproveForTemplate() + { + return array_map(function (TermsAndConditions $condition) { + return $condition->format(); + }, $this->getConditionsToApprove()); +``` \ No newline at end of file From 983616d4a3e8ab5a65d338c031f77fbe9904fbc4 Mon Sep 17 00:00:00 2001 From: Thomas Nares Date: Thu, 3 Nov 2022 09:42:24 +0100 Subject: [PATCH 151/310] Add other hooks --- .../hooks/list-hooks/actionAjaxDie.md | 23 + .../hooks/list-hooks/actionAuthentication.md | 23 + ...ctionBeforeAjaxDie.md} | 6 +- .../hooks/list-hooks/actionCartSummary.md | 23 + .../actionCartUpdateQuantityBefore.md | 23 + .../list-hooks/actionDeleteGDPRCustomer.md | 23 + .../hooks/list-hooks/actionDispatcher.md | 23 + .../hooks/list-hooks/actionDispatcherAfter.md | 23 + .../hooks/list-hooks/actionExportGDPRData.md | 23 + .../actionObjectProductInCartDeleteAfter.md | 24 + .../actionObjectProductInCartDeleteBefore.md | 24 + .../list-hooks/actionOrderHistoryAddAfter.md | 23 + .../list-hooks/actionPaymentConfirmation.md | 508 ---- .../hooks/list-hooks/actionProductCancel.md | 31 - .../list-hooks/actionProductSearchAfter.md | 23 + .../list-hooks/actionSubmitAccountBefore.md | 41 - .../actionSubmitCustomerAddressForm.md | 23 + .../list-hooks/addWebserviceResources.md | 1574 ------------ .../additionalCustomerAddressFields.md | 83 - .../additionalCustomerFormFields.md | 28 - .../hooks/list-hooks/dashboardData.md | 23 + .../hooks/list-hooks/dashboardZoneOne.md | 23 + .../hooks/list-hooks/dashboardZoneThree.md | 23 + .../hooks/list-hooks/dashboardZoneTwo.md | 23 + .../list-hooks/displayAdminStatsModules.md | 101 - .../hooks/list-hooks/displayCustomization.md | 2271 ----------------- .../list-hooks/displayOrderConfirmation.md | 23 + .../hooks/list-hooks/displayPaymentReturn.md | 57 - .../concepts/hooks/list-hooks/moduleRoutes.md | 23 + .../hooks/list-hooks/termsAndConditions.md | 40 - .../list-hooks/validateCustomerFormFields.md | 23 + 31 files changed, 465 insertions(+), 4737 deletions(-) create mode 100644 modules/concepts/hooks/list-hooks/actionAjaxDie.md create mode 100644 modules/concepts/hooks/list-hooks/actionAuthentication.md rename modules/concepts/hooks/list-hooks/{actionBeforeAjaxDie.md => actionBeforeAjaxDie.md} (64%) create mode 100644 modules/concepts/hooks/list-hooks/actionCartSummary.md create mode 100644 modules/concepts/hooks/list-hooks/actionCartUpdateQuantityBefore.md create mode 100644 modules/concepts/hooks/list-hooks/actionDeleteGDPRCustomer.md create mode 100644 modules/concepts/hooks/list-hooks/actionDispatcher.md create mode 100644 modules/concepts/hooks/list-hooks/actionDispatcherAfter.md create mode 100644 modules/concepts/hooks/list-hooks/actionExportGDPRData.md create mode 100644 modules/concepts/hooks/list-hooks/actionObjectProductInCartDeleteAfter.md create mode 100644 modules/concepts/hooks/list-hooks/actionObjectProductInCartDeleteBefore.md create mode 100644 modules/concepts/hooks/list-hooks/actionOrderHistoryAddAfter.md create mode 100644 modules/concepts/hooks/list-hooks/actionProductSearchAfter.md create mode 100644 modules/concepts/hooks/list-hooks/actionSubmitCustomerAddressForm.md create mode 100644 modules/concepts/hooks/list-hooks/dashboardData.md create mode 100644 modules/concepts/hooks/list-hooks/dashboardZoneOne.md create mode 100644 modules/concepts/hooks/list-hooks/dashboardZoneThree.md create mode 100644 modules/concepts/hooks/list-hooks/dashboardZoneTwo.md create mode 100644 modules/concepts/hooks/list-hooks/displayOrderConfirmation.md create mode 100644 modules/concepts/hooks/list-hooks/moduleRoutes.md create mode 100644 modules/concepts/hooks/list-hooks/validateCustomerFormFields.md diff --git a/modules/concepts/hooks/list-hooks/actionAjaxDie.md b/modules/concepts/hooks/list-hooks/actionAjaxDie.md new file mode 100644 index 0000000000..dad29cb8a1 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionAjaxDie.md @@ -0,0 +1,23 @@ +--- +menuTitle: actionAjaxDie +title: actionAjaxDie +hidden: true +files: + - classes/controller/Controller.php +types: + - frontoffice +hookTypes: + - legacy +--- + +# Hook : actionAjaxDie + +Located in : + + - classes/controller/Controller.php + +## Parameters + +```php +Hook::exec('actionAjaxDie' . $controller . $method . 'Before', ['value' => $value]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionAuthentication.md b/modules/concepts/hooks/list-hooks/actionAuthentication.md new file mode 100644 index 0000000000..ec5d84b2fa --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionAuthentication.md @@ -0,0 +1,23 @@ +--- +menuTitle: actionAuthentication +title: actionAuthentication +hidden: true +files: + - classes/form/CustomerLoginForm.php +types: + - frontoffice +hookTypes: + - legacy +--- + +# Hook : actionAuthentication + +Located in : + + - classes/form/CustomerLoginForm.php + +## Parameters + +```php +Hook::exec('actionAuthentication', ['customer' => $this->context->customer]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionBeforeAjaxDie.md b/modules/concepts/hooks/list-hooks/actionBeforeAjaxDie.md similarity index 64% rename from modules/concepts/hooks/list-hooks/actionBeforeAjaxDie.md rename to modules/concepts/hooks/list-hooks/actionBeforeAjaxDie.md index 311a95a4cd..e3c966d4cd 100644 --- a/modules/concepts/hooks/list-hooks/actionBeforeAjaxDie.md +++ b/modules/concepts/hooks/list-hooks/actionBeforeAjaxDie.md @@ -1,6 +1,6 @@ --- -menuTitle: actionBeforeAjaxDie -title: actionBeforeAjaxDie +menuTitle: actionBeforeAjaxDie +title: actionBeforeAjaxDie hidden: true files: - classes/controller/Controller.php @@ -10,7 +10,7 @@ hookTypes: - legacy --- -# Hook : actionBeforeAjaxDie +# Hook : actionBeforeAjaxDie Located in : diff --git a/modules/concepts/hooks/list-hooks/actionCartSummary.md b/modules/concepts/hooks/list-hooks/actionCartSummary.md new file mode 100644 index 0000000000..cba2867361 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionCartSummary.md @@ -0,0 +1,23 @@ +--- +menuTitle: actionCartSummary +title: actionCartSummary +hidden: true +files: + - classes/Cart.php +types: + - frontoffice +hookTypes: + - legacy +--- + +# Hook : actionCartSummary + +Located in : + + - classes/Cart.php + +## Parameters + +```php +Hook::exec('actionCartSummary', $summary, null, true); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionCartUpdateQuantityBefore.md b/modules/concepts/hooks/list-hooks/actionCartUpdateQuantityBefore.md new file mode 100644 index 0000000000..df673bcdc3 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionCartUpdateQuantityBefore.md @@ -0,0 +1,23 @@ +--- +menuTitle: actionCartUpdateQuantityBefore +title: actionCartUpdateQuantityBefore +hidden: true +files: + - classes/Cart.php +types: + - frontoffice +hookTypes: + - legacy +--- + +# Hook : actionCartUpdateQuantityBefore + +Located in : + + - classes/Cart.php + +## Parameters + +```php +Hook::exec('actionCartUpdateQuantityBefore', $data); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionDeleteGDPRCustomer.md b/modules/concepts/hooks/list-hooks/actionDeleteGDPRCustomer.md new file mode 100644 index 0000000000..c3664c8d6c --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionDeleteGDPRCustomer.md @@ -0,0 +1,23 @@ +--- +menuTitle: actionDeleteGDPRCustomer +title: actionDeleteGDPRCustomer +hidden: true +files: + - modules/psgdpr/psgdpr.php +types: + - frontoffice +hookTypes: + - legacy +--- + +# Hook : actionDeleteGDPRCustomer + +Located in : + + - modules/psgdpr/psgdpr.php + +## Parameters + +```php +Hook::exec('actionDeleteGDPRCustomer', $customer, $module['id_module']); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionDispatcher.md b/modules/concepts/hooks/list-hooks/actionDispatcher.md new file mode 100644 index 0000000000..7d5d8ec86f --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionDispatcher.md @@ -0,0 +1,23 @@ +--- +menuTitle: actionDispatcher +title: actionDispatcher +hidden: true +files: + - classes/Dispatcher.php +types: + - frontoffice +hookTypes: + - legacy +--- + +# Hook : actionDispatcher + +Located in : + + - classes/Dispatcher.php + +## Parameters + +```php +Hook::exec('actionDispatcher', $params_hook_action_dispatcher); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionDispatcherAfter.md b/modules/concepts/hooks/list-hooks/actionDispatcherAfter.md new file mode 100644 index 0000000000..765c4e8279 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionDispatcherAfter.md @@ -0,0 +1,23 @@ +--- +menuTitle: actionDispatcherAfter +title: actionDispatcherAfter +hidden: true +files: + - classes/Dispatcher.php +types: + - frontoffice +hookTypes: + - legacy +--- + +# Hook : actionDispatcherAfter + +Located in : + + - classes/Dispatcher.php + +## Parameters + +```php +Hook::exec('actionDispatcherAfter', $params_hook_action_dispatcher); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionExportGDPRData.md b/modules/concepts/hooks/list-hooks/actionExportGDPRData.md new file mode 100644 index 0000000000..db6b5b5bb1 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionExportGDPRData.md @@ -0,0 +1,23 @@ +--- +menuTitle: actionExportGDPRData +title: actionExportGDPRData +hidden: true +files: + - modules/psgdpr/psgdpr.php +types: + - frontoffice +hookTypes: + - legacy +--- + +# Hook : actionExportGDPRData + +Located in : + + - modules/psgdpr/psgdpr.php + +## Parameters + +```php +Hook::exec('actionExportGDPRData', $customer, $module['id_module']); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionObjectProductInCartDeleteAfter.md b/modules/concepts/hooks/list-hooks/actionObjectProductInCartDeleteAfter.md new file mode 100644 index 0000000000..0e20241ca6 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionObjectProductInCartDeleteAfter.md @@ -0,0 +1,24 @@ +--- +menuTitle: actionObjectProductInCartDeleteAfter +title: actionObjectProductInCartDeleteAfter +hidden: true +files: + - controllers/front/CartController.php +types: + - backoffice + - frontoffice +hookTypes: + - legacy +--- + +# Hook : actionObjectProductInCartDeleteAfter + +Located in : + + - controllers/front/CartController.php + +## Parameters + +```php +Hook::exec('actionObjectProductInCartDeleteAfter', $data); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionObjectProductInCartDeleteBefore.md b/modules/concepts/hooks/list-hooks/actionObjectProductInCartDeleteBefore.md new file mode 100644 index 0000000000..9c15df9e74 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionObjectProductInCartDeleteBefore.md @@ -0,0 +1,24 @@ +--- +menuTitle: actionObjectProductInCartDeleteBefore +title: actionObjectProductInCartDeleteBefore +hidden: true +files: + - controllers/front/CartController.php +types: + - backoffice + - frontoffice +hookTypes: + - legacy +--- + +# Hook : actionObjectProductInCartDeleteBefore + +Located in : + + - controllers/front/CartController.php + +## Parameters + +```php +Hook::exec('actionObjectProductInCartDeleteBefore', $data, null, true); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionOrderHistoryAddAfter.md b/modules/concepts/hooks/list-hooks/actionOrderHistoryAddAfter.md new file mode 100644 index 0000000000..91edcbcc81 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionOrderHistoryAddAfter.md @@ -0,0 +1,23 @@ +--- +menuTitle: actionOrderHistoryAddAfter +title: actionOrderHistoryAddAfter +hidden: true +files: + - classes/order/OrderHistory.php +types: + - frontoffice +hookTypes: + - legacy +--- + +# Hook : actionOrderHistoryAddAfter + +Located in : + + - classes/order/OrderHistory.php + +## Parameters + +```php +Hook::exec('actionOrderHistoryAddAfter', ['order_history' => $this], null, false, true, false, $order->id_shop); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionPaymentConfirmation.md b/modules/concepts/hooks/list-hooks/actionPaymentConfirmation.md index 3a44c7244c..2f4da97d69 100644 --- a/modules/concepts/hooks/list-hooks/actionPaymentConfirmation.md +++ b/modules/concepts/hooks/list-hooks/actionPaymentConfirmation.md @@ -20,512 +20,4 @@ Located in : ```php Hook::exec('actionPaymentConfirmation', ['id_order' => (int) $order->id], null, false, true, false, $order->id_shop); - } - - // executes hook - Hook::exec('actionOrderStatusUpdate', [ - 'newOrderStatus' => $new_os, - 'oldOrderStatus' => $old_os, - 'id_order' => (int) $order->id, - ], null, false, true, false, $order->id_shop); - - if (Validate::isLoadedObject($order) && $new_os instanceof OrderState) { - $context = Context::getContext(); - - // An email is sent the first time a virtual item is validated - $virtual_products = $order->getVirtualProducts(); - if ($virtual_products && !$old_os->logable && $new_os->logable) { - $assign = []; - foreach ($virtual_products as $key => $virtual_product) { - $id_product_download = ProductDownload::getIdFromIdProduct($virtual_product['product_id']); - $product_download = new ProductDownload($id_product_download); - // If this virtual item has an associated file, we'll provide the link to download the file in the email - if ($product_download->display_filename != '') { - $assign[$key]['name'] = $product_download->display_filename; - $dl_link = $product_download->getTextLink(false, $virtual_product['download_hash']) - . '&id_order=' . (int) $order->id - . '&secure_key=' . $order->secure_key; - $assign[$key]['link'] = $dl_link; - if (isset($virtual_product['download_deadline']) && $virtual_product['download_deadline'] != '0000-00-00 00:00:00') { - $assign[$key]['deadline'] = Tools::displayDate($virtual_product['download_deadline']); - } - if ($product_download->nb_downloadable != 0) { - $assign[$key]['downloadable'] = (int) $product_download->nb_downloadable; - } - } - } - - $customer = new Customer((int) $order->id_customer); - $links = []; - foreach ($assign as $product) { - $complementaryText = []; - if (isset($product['deadline'])) { - $complementaryText[] = $this->trans('expires on %s.', [$product['deadline']], 'Admin.Orderscustomers.Notification'); - } - if (isset($product['downloadable'])) { - $complementaryText[] = $this->trans('downloadable %d time(s)', [(int) $product['downloadable']], 'Admin.Orderscustomers.Notification'); - } - $links[] = [ - 'text' => Tools::htmlentitiesUTF8($product['name']), - 'url' => $product['link'], - 'complementary_text' => implode(' ', $complementaryText), - ]; - } - - $context = Context::getContext(); - $partialRenderer = new MailPartialTemplateRenderer($context->smarty); - - $links_txt = $partialRenderer->render('download_product_virtual_products.txt', $context->language, $links, true); - $links_html = $partialRenderer->render('download_product_virtual_products.tpl', $context->language, $links); - - $data = [ - '{lastname}' => $customer->lastname, - '{firstname}' => $customer->firstname, - '{id_order}' => (int) $order->id, - '{order_name}' => $order->getUniqReference(), - '{nbProducts}' => count($virtual_products), - '{virtualProducts}' => $links_html, - '{virtualProductsTxt}' => $links_txt, - ]; - // If there is at least one downloadable file - if (!empty($assign)) { - $orderLanguage = new Language((int) $order->id_lang); - Mail::Send( - (int) $order->id_lang, - 'download_product', - Context::getContext()->getTranslator()->trans( - 'The virtual product that you bought is available for download', - [], - 'Emails.Subject', - $orderLanguage->locale - ), - $data, - $customer->email, - $customer->firstname . ' ' . $customer->lastname, - null, - null, - null, - null, - _PS_MAIL_DIR_, - false, - (int) $order->id_shop - ); - } - } - - /** @since 1.5.0 : gets the stock manager */ - $manager = null; - if (Configuration::get('PS_ADVANCED_STOCK_MANAGEMENT')) { - $manager = StockManagerFactory::getManager(); - } - - $error_or_canceled_statuses = [Configuration::get('PS_OS_ERROR'), Configuration::get('PS_OS_CANCELED')]; - - $employee = null; - if (!(int) $this->id_employee || !Validate::isLoadedObject(($employee = new Employee((int) $this->id_employee)))) { - if (!Validate::isLoadedObject($old_os) && $context != null) { - // First OrderHistory, there is no $old_os, so $employee is null before here - $employee = $context->employee; // filled if from BO and order created (because no old_os) - if ($employee) { - $this->id_employee = $employee->id; - } - } else { - $employee = null; - } - } - - // foreach products of the order - foreach ($order->getProductsDetail() as $product) { - if (Validate::isLoadedObject($old_os)) { - // if becoming logable => adds sale - if ($new_os->logable && !$old_os->logable) { - ProductSale::addProductSale($product['product_id'], $product['product_quantity']); - // @since 1.5.0 - Stock Management - if (!Pack::isPack($product['product_id']) && - in_array($old_os->id, $error_or_canceled_statuses) && - !StockAvailable::dependsOnStock($product['id_product'], (int) $order->id_shop)) { - StockAvailable::updateQuantity($product['product_id'], $product['product_attribute_id'], -(int) $product['product_quantity'], $order->id_shop); - } - } elseif (!$new_os->logable && $old_os->logable) { - // if becoming unlogable => removes sale - ProductSale::removeProductSale($product['product_id'], $product['product_quantity']); - - // @since 1.5.0 - Stock Management - if (!Pack::isPack($product['product_id']) && - in_array($new_os->id, $error_or_canceled_statuses) && - !StockAvailable::dependsOnStock($product['id_product'])) { - StockAvailable::updateQuantity($product['product_id'], $product['product_attribute_id'], (int) $product['product_quantity'], $order->id_shop); - } - } elseif (!$new_os->logable && !$old_os->logable && - in_array($new_os->id, $error_or_canceled_statuses) && - !in_array($old_os->id, $error_or_canceled_statuses) && - !StockAvailable::dependsOnStock($product['id_product']) - ) { - // if waiting for payment => payment error/canceled - StockAvailable::updateQuantity($product['product_id'], $product['product_attribute_id'], (int) $product['product_quantity'], $order->id_shop); - } - } - // From here, there is 2 cases : $old_os exists, and we can test shipped state evolution, - // Or old_os does not exists, and we should consider that initial shipped state is 0 (to allow decrease of stocks) - - // @since 1.5.0 : if the order is being shipped and this products uses the advanced stock management : - // decrements the physical stock using $id_warehouse - if ($new_os->shipped == 1 && (!Validate::isLoadedObject($old_os) || $old_os->shipped == 0) && - Configuration::get('PS_ADVANCED_STOCK_MANAGEMENT') && - Warehouse::exists($product['id_warehouse']) && - $manager != null && - (int) $product['advanced_stock_management'] == 1) { - // gets the warehouse - $warehouse = new Warehouse($product['id_warehouse']); - - // decrements the stock (if it's a pack, the StockManager does what is needed) - $manager->removeProduct( - $product['product_id'], - $product['product_attribute_id'], - $warehouse, - ($product['product_quantity'] - $product['product_quantity_refunded'] - $product['product_quantity_return']), - (int) Configuration::get('PS_STOCK_CUSTOMER_ORDER_REASON'), - true, - (int) $order->id - ); - } elseif ($new_os->shipped == 0 && Validate::isLoadedObject($old_os) && $old_os->shipped == 1 && - Configuration::get('PS_ADVANCED_STOCK_MANAGEMENT') && - Warehouse::exists($product['id_warehouse']) && - $manager != null && - (int) $product['advanced_stock_management'] == 1 - ) { - // @since.1.5.0 : if the order was shipped, and is not anymore, we need to restock products - - // if the product is a pack, we restock every products in the pack using the last negative stock mvts - if (Pack::isPack($product['product_id'])) { - $pack_products = Pack::getItems($product['product_id'], Configuration::get('PS_LANG_DEFAULT', null, null, $order->id_shop)); - foreach ($pack_products as $pack_product) { - if ($pack_product->advanced_stock_management == 1) { - $mvts = StockMvt::getNegativeStockMvts($order->id, $pack_product->id, 0, $pack_product->pack_quantity * $product['product_quantity']); - foreach ($mvts as $mvt) { - $manager->addProduct( - $pack_product->id, - 0, - new Warehouse($mvt['id_warehouse']), - $mvt['physical_quantity'], - null, - $mvt['price_te'], - true, - null - ); - } - if (!StockAvailable::dependsOnStock($product['id_product'])) { - StockAvailable::updateQuantity($pack_product->id, 0, (int) $pack_product->pack_quantity * $product['product_quantity'], $order->id_shop); - } - } - } - } else { - // else, it's not a pack, re-stock using the last negative stock mvts - - $mvts = StockMvt::getNegativeStockMvts( - $order->id, - $product['product_id'], - $product['product_attribute_id'], - ($product['product_quantity'] - $product['product_quantity_refunded'] - $product['product_quantity_return']) - ); - - foreach ($mvts as $mvt) { - $manager->addProduct( - $product['product_id'], - $product['product_attribute_id'], - new Warehouse($mvt['id_warehouse']), - $mvt['physical_quantity'], - null, - $mvt['price_te'], - true - ); - } - } - } - - // Save movement if : - // not Configuration::get('PS_ADVANCED_STOCK_MANAGEMENT') - // new_os->shipped != old_os->shipped - if (Validate::isLoadedObject($old_os) && Validate::isLoadedObject($new_os) && $new_os->shipped != $old_os->shipped && !Configuration::get('PS_ADVANCED_STOCK_MANAGEMENT')) { - $product_quantity = (int) ($product['product_quantity'] - $product['product_quantity_refunded'] - $product['product_quantity_return']); - - if ($product_quantity > 0) { - $current_shop_context_type = Context::getContext()->shop->getContextType(); - if ($current_shop_context_type !== Shop::CONTEXT_SHOP) { - //change to order shop context - $current_shop_group_id = Context::getContext()->shop->getContextShopGroupID(); - Context::getContext()->shop->setContext(Shop::CONTEXT_SHOP, $order->id_shop); - } - (new StockManager())->saveMovement( - (int) $product['product_id'], - (int) $product['product_attribute_id'], - (int) $product_quantity * ($new_os->shipped == 1 ? -1 : 1), - [ - 'id_order' => $order->id, - 'id_stock_mvt_reason' => ($new_os->shipped == 1 ? Configuration::get('PS_STOCK_CUSTOMER_ORDER_REASON') : Configuration::get('PS_STOCK_CUSTOMER_ORDER_CANCEL_REASON')), - ] - ); - //back to current shop context - if ($current_shop_context_type !== Shop::CONTEXT_SHOP && isset($current_shop_group_id)) { - Context::getContext()->shop->setContext($current_shop_context_type, $current_shop_group_id); - } - } - } - } - } - - $this->id_order_state = (int) $new_order_state; - - // changes invoice number of order ? - if (!Validate::isLoadedObject($new_os) || !Validate::isLoadedObject($order)) { - throw new PrestaShopException($this->trans('Invalid new order status', [], 'Admin.Orderscustomers.Notification')); - } - - // the order is valid if and only if the invoice is available and the order is not cancelled - $order->current_state = $this->id_order_state; - $order->valid = $new_os->logable; - $order->update(); - - if ($new_os->invoice && !$order->invoice_number) { - $order->setInvoice($use_existing_payment); - } elseif ($new_os->delivery && !$order->delivery_number) { - $order->setDeliverySlip(); - } - - // set orders as paid - if ($new_os->paid == 1) { - if ($order->total_paid != 0) { - $payment_method = Module::getInstanceByName($order->module); - } - - $invoices = $order->getInvoicesCollection(); - foreach ($invoices as $invoice) { - /** @var OrderInvoice $invoice */ - $rest_paid = $invoice->getRestPaid(); - if ($rest_paid > 0) { - $payment = new OrderPayment(); - $payment->order_reference = Tools::substr($order->reference, 0, 9); - $payment->id_currency = $order->id_currency; - $payment->amount = $rest_paid; - $payment->payment_method = isset($payment_method) && $payment_method instanceof Module ? $payment_method->displayName : null; - $payment->conversion_rate = $order->conversion_rate; - $payment->save(); - - // Update total_paid_real value for backward compatibility reasons - $order->total_paid_real += $rest_paid; - $order->save(); - - Db::getInstance()->insert( - 'order_invoice_payment', - [ - 'id_order_invoice' => (int) $invoice->id, - 'id_order_payment' => (int) $payment->id, - 'id_order' => (int) $order->id, - ] - ); - } - } - } - - // updates delivery date even if it was already set by another state change - if ($new_os->delivery) { - $order->setDelivery(); - } - - // executes hook - Hook::exec('actionOrderStatusPostUpdate', [ - 'newOrderStatus' => $new_os, - 'oldOrderStatus' => $old_os, - 'id_order' => (int) $order->id, - ], null, false, true, false, $order->id_shop); - - // sync all stock - (new StockManagerAdapter())->updatePhysicalProductQuantity( - (int) $order->id_shop, - (int) Configuration::get('PS_OS_ERROR'), - (int) Configuration::get('PS_OS_CANCELED'), - null, - (int) $order->id - ); - - ShopUrl::resetMainDomainCache(); - } - - /** - * @param bool $autodate Optional - * @param array|bool $template_vars Optional - * @param Context|null $context Deprecated - * - * @return bool - */ - public function addWithemail($autodate = true, $template_vars = false, Context $context = null) - { - $order = new Order($this->id_order); - - if (!$this->add($autodate)) { - return false; - } - Order::cleanHistoryCache(); - - if (!$this->sendEmail($order, $template_vars)) { - return false; - } - - return true; - } - - /** - * @param Order $order - * @param array|false $template_vars - * - * @return bool - */ - public function sendEmail($order, $template_vars = false) - { - $result = Db::getInstance()->getRow(' - SELECT osl.`template`, c.`lastname`, c.`firstname`, osl.`name` AS osname, c.`email`, os.`module_name`, os.`id_order_state`, os.`pdf_invoice`, os.`pdf_delivery` - FROM `' . _DB_PREFIX_ . 'order_history` oh - LEFT JOIN `' . _DB_PREFIX_ . 'orders` o ON oh.`id_order` = o.`id_order` - LEFT JOIN `' . _DB_PREFIX_ . 'customer` c ON o.`id_customer` = c.`id_customer` - LEFT JOIN `' . _DB_PREFIX_ . 'order_state` os ON oh.`id_order_state` = os.`id_order_state` - LEFT JOIN `' . _DB_PREFIX_ . 'order_state_lang` osl ON (os.`id_order_state` = osl.`id_order_state` AND osl.`id_lang` = o.`id_lang`) - WHERE oh.`id_order_history` = ' . (int) $this->id . ' AND os.`send_email` = 1'); - if (isset($result['template']) && Validate::isEmail($result['email'])) { - ShopUrl::cacheMainDomainForShop($order->id_shop); - - $topic = $result['osname']; - $carrierUrl = ''; - if (Validate::isLoadedObject($carrier = new Carrier((int) $order->id_carrier, $order->id_lang))) { - $carrierUrl = $carrier->url; - } - $data = [ - '{lastname}' => $result['lastname'], - '{firstname}' => $result['firstname'], - '{id_order}' => (int) $this->id_order, - '{order_name}' => $order->getUniqReference(), - '{followup}' => str_replace('@', $order->getShippingNumber() ?? '', $carrierUrl), - '{shipping_number}' => $order->getShippingNumber(), - ]; - - if ($result['module_name']) { - $module = Module::getInstanceByName($result['module_name']); - if (Validate::isLoadedObject($module) && isset($module->extra_mail_vars) && is_array($module->extra_mail_vars)) { - $data = array_merge($data, $module->extra_mail_vars); - } - } - - if (is_array($template_vars)) { - $data = array_merge($data, $template_vars); - } - - $context = Context::getContext(); - $data['{total_paid}'] = Tools::getContextLocale($context)->formatPrice((float) $order->total_paid, Currency::getIsoCodeById((int) $order->id_currency)); - - if (Validate::isLoadedObject($order)) { - // Attach invoice and / or delivery-slip if they exists and status is set to attach them - if (($result['pdf_invoice'] || $result['pdf_delivery'])) { - $currentLanguage = $context->language; - $orderLanguage = new Language((int) $order->id_lang); - $context->language = $orderLanguage; - $context->getTranslator()->setLocale($orderLanguage->locale); - $invoice = $order->getInvoicesCollection(); - $file_attachement = []; - - if ($result['pdf_invoice'] && (int) Configuration::get('PS_INVOICE') && $order->invoice_number) { - Hook::exec('actionPDFInvoiceRender', ['order_invoice_list' => $invoice]); - $pdf = new PDF($invoice, PDF::TEMPLATE_INVOICE, $context->smarty); - $file_attachement['invoice']['content'] = $pdf->render(false); - $file_attachement['invoice']['name'] = $pdf->getFilename(); - $file_attachement['invoice']['mime'] = 'application/pdf'; - } - if ($result['pdf_delivery'] && $order->delivery_number) { - $pdf = new PDF($invoice, PDF::TEMPLATE_DELIVERY_SLIP, $context->smarty); - $file_attachement['delivery']['content'] = $pdf->render(false); - $file_attachement['delivery']['name'] = $pdf->getFilename(); - $file_attachement['delivery']['mime'] = 'application/pdf'; - } - - $context->language = $currentLanguage; - $context->getTranslator()->setLocale($currentLanguage->locale); - } else { - $file_attachement = null; - } - - if (!Mail::Send( - (int) $order->id_lang, - $result['template'], - $topic, - $data, - $result['email'], - $result['firstname'] . ' ' . $result['lastname'], - null, - null, - $file_attachement, - null, - _PS_MAIL_DIR_, - false, - (int) $order->id_shop - )) { - return false; - } - } - - ShopUrl::resetMainDomainCache(); - } - - return true; - } - - public function add($autodate = true, $null_values = false) - { - if (!parent::add($autodate)) { - return false; - } - - $order = new Order((int) $this->id_order); - // Update id_order_state attribute in Order - $order->current_state = $this->id_order_state; - $order->update(); - - Hook::exec('actionOrderHistoryAddAfter', ['order_history' => $this], null, false, true, false, $order->id_shop); - - return true; - } - - /** - * @return int - */ - public function isValidated() - { - return (int) Db::getInstance()->getValue(' - SELECT COUNT(oh.`id_order_history`) AS nb - FROM `' . _DB_PREFIX_ . 'order_state` os - LEFT JOIN `' . _DB_PREFIX_ . 'order_history` oh ON (os.`id_order_state` = oh.`id_order_state`) - WHERE oh.`id_order` = ' . (int) $this->id_order . ' - AND os.`logable` = 1'); - } - - /** - * Add method for webservice create resource Order History - * If sendemail=1 GET parameter is present sends email to customer otherwise does not. - * - * @return bool - */ - public function addWs() - { - $sendemail = (bool) Tools::getValue('sendemail', false); - $this->changeIdOrderState($this->id_order_state, $this->id_order); - - if ($sendemail) { - //Mail::Send requires link object on context and is not set when getting here - $context = Context::getContext(); - if ($context->link == null) { - $protocol_link = (Tools::usingSecureMode() && Configuration::get('PS_SSL_ENABLED')) ? 'https://' : 'http://'; - $protocol_content = (Tools::usingSecureMode() && Configuration::get('PS_SSL_ENABLED')) ? 'https://' : 'http://'; - $context->link = new Link($protocol_link, $protocol_content); - } - - return $this->addWithemail(); - } else { - return $this->add(); ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionProductCancel.md b/modules/concepts/hooks/list-hooks/actionProductCancel.md index 827517f6d8..f2fb50f308 100644 --- a/modules/concepts/hooks/list-hooks/actionProductCancel.md +++ b/modules/concepts/hooks/list-hooks/actionProductCancel.md @@ -20,35 +20,4 @@ Located in : ```php Hook::exec('actionProductCancel', ['order' => $order, 'id_order_detail' => (int) $orderDetailId, 'cancel_quantity' => $productRefund['quantity'], 'action' => CancellationActionType::STANDARD_REFUND], null, false, true, false, $order->id_shop); - } - - // Update order carrier weight - $orderCarrier = new OrderCarrier((int) $order->getIdOrderCarrier()); - if (Validate::isLoadedObject($orderCarrier)) { - $orderCarrier->weight = (float) $order->getTotalWeight(); - if ($orderCarrier->update()) { - $order->weight = sprintf('%.3f %s', $orderCarrier->weight, $this->configuration->get('PS_WEIGHT_UNIT')); - } - } - - // Create order slip - if ($command->generateCreditSlip()) { - $this->orderSlipCreator->create($order, $orderRefundSummary); - } - - // Update refund details (standard refund only happen for an order not delivered, so it can't return products) - $this->refundUpdater->updateRefundData( - $orderRefundSummary, - false, - true - ); - - // Generate voucher if needed - if ($command->generateVoucher() && $orderRefundSummary->getRefundedAmount() > 0) { - $this->voucherGenerator->generateVoucher( - $order, - $orderRefundSummary->getRefundedAmount(), - Context::getContext()->currency->iso_code, - $orderRefundSummary->isTaxIncluded() - ); ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionProductSearchAfter.md b/modules/concepts/hooks/list-hooks/actionProductSearchAfter.md new file mode 100644 index 0000000000..18adbd779e --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionProductSearchAfter.md @@ -0,0 +1,23 @@ +--- +menuTitle: actionProductSearchAfter +title: actionProductSearchAfter +hidden: true +files: + - modules/blockwishlist/controllers/front/view.php +types: + - frontoffice +hookTypes: + - legacy +--- + +# Hook : actionProductSearchAfter + +Located in : + + - modules/blockwishlist/controllers/front/view.php + +## Parameters + +```php +Hook::exec('actionProductSearchAfter', $searchVariables); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionSubmitAccountBefore.md b/modules/concepts/hooks/list-hooks/actionSubmitAccountBefore.md index 5ff788e0a0..a13c8353b4 100644 --- a/modules/concepts/hooks/list-hooks/actionSubmitAccountBefore.md +++ b/modules/concepts/hooks/list-hooks/actionSubmitAccountBefore.md @@ -20,45 +20,4 @@ Located in : ```php Hook::exec('actionSubmitAccountBefore', [], null, true), - function ($carry, $item) { - return $carry && $item; - }, - true - ); - - // If no problem occured in the hook, let's get the user redirected - if ($hookResult && $register_form->submit() && !$this->ajax) { - // First option - redirect the customer to desired URL specified in 'back' parameter - // Before that, we need to check if 'back' is legit URL that is on OUR domain, with the right protocol - $back = rawurldecode(Tools::getValue('back')); - if (Tools::urlBelongsToShop($back)) { - return $this->redirectWithNotifications($back); - } - - // Second option - we will redirect him to authRedirection if set - if ($this->authRedirection) { - return $this->redirectWithNotifications($this->authRedirection); - } - - // Third option - we will redirect him to home URL - return $this->redirectWithNotifications(__PS_BASE_URI__); - } - } - - $this->context->smarty->assign([ - 'register_form' => $register_form->getProxy(), - 'hook_create_account_top' => Hook::exec('displayCustomerAccountFormTop'), - ]); - $this->setTemplate('customer/registration'); - - parent::initContent(); - } - - public function getBreadcrumbLinks() - { - $breadcrumb = parent::getBreadcrumbLinks(); - - $breadcrumb['links'][] = [ - 'title' => $this->trans('Create an account', [], 'Shop.Theme.Customeraccount'), - 'url' => $this->context->link->getPageLink('registration'), ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionSubmitCustomerAddressForm.md b/modules/concepts/hooks/list-hooks/actionSubmitCustomerAddressForm.md new file mode 100644 index 0000000000..a4f243ecab --- /dev/null +++ b/modules/concepts/hooks/list-hooks/actionSubmitCustomerAddressForm.md @@ -0,0 +1,23 @@ +--- +menuTitle: actionSubmitCustomerAddressForm +title: actionSubmitCustomerAddressForm +hidden: true +files: + - classes/form/CustomerAddressForm.php +types: + - frontoffice +hookTypes: + - legacy +--- + +# Hook : actionSubmitCustomerAddressForm + +Located in : + + - classes/form/CustomerAddressForm.php + +## Parameters + +```php +Hook::exec('actionSubmitCustomerAddressForm', ['address' => &$address]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/addWebserviceResources.md b/modules/concepts/hooks/list-hooks/addWebserviceResources.md index 13cd52cec2..ff1ec2c469 100644 --- a/modules/concepts/hooks/list-hooks/addWebserviceResources.md +++ b/modules/concepts/hooks/list-hooks/addWebserviceResources.md @@ -20,1578 +20,4 @@ Located in : ```php Hook::exec('addWebserviceResources', ['resources' => $resources], null, true, false); - if (is_countable($extra_resources) && count($extra_resources)) { - foreach ($extra_resources as $new_resources) { - if (is_countable($new_resources) && count($new_resources)) { - $resources = array_merge($resources, $new_resources); - } - } - } - ksort($resources); - - return $resources; - } - - /** - * This method is used for calculate the price for products on the output details. - * - * @param array $field - * @param ObjectModel $entity_object - * - * @return array field parameters - */ - public function getPriceForProduct($field, $entity_object) - { - if (is_int($entity_object->id)) { - $arr_return = $this->specificPriceForProduct($entity_object, ['default_price' => '']); - $field['value'] = $arr_return['default_price']['value']; - } - - return $field; - } - - /** - * This method is used for calculate the price for products on a virtual fields. - * - * @param ObjectModel $entity_object - * @param array $parameters - * - * @return array - */ - public function specificPriceForProduct($entity_object, $parameters) - { - foreach (array_keys($parameters) as $name) { - $parameters[$name]['object_id'] = $entity_object->id; - } - $arr_return = $this->specificPriceCalculation($parameters); - - return $arr_return; - } - - public function specificPriceCalculation($parameters) - { - $arr_return = []; - foreach ($parameters as $name => $value) { - $id_shop = (int) Context::getContext()->shop->id; - $id_country = (int) (isset($value['country']) ? $value['country'] : (Configuration::get('PS_COUNTRY_DEFAULT'))); - $id_state = (int) (isset($value['state']) ? $value['state'] : 0); - $id_currency = (int) (isset($value['currency']) ? $value['currency'] : Configuration::get('PS_CURRENCY_DEFAULT')); - $id_group = (int) (isset($value['group']) ? $value['group'] : (int) Configuration::get('PS_CUSTOMER_GROUP')); - $quantity = (int) (isset($value['quantity']) ? $value['quantity'] : 1); - $use_tax = (bool) (isset($value['use_tax']) ? $value['use_tax'] : Configuration::get('PS_TAX')); - $decimals = (int) (isset($value['decimals']) ? $value['decimals'] : Configuration::get('PS_PRICE_ROUND_MODE')); - $id_product_attribute = (int) (isset($value['product_attribute']) ? $value['product_attribute'] : null); - $only_reduc = (bool) (isset($value['only_reduction']) ? $value['only_reduction'] : false); - $use_reduc = (bool) (isset($value['use_reduction']) ? $value['use_reduction'] : true); - $use_ecotax = (bool) (isset($value['use_ecotax']) ? $value['use_ecotax'] : Configuration::get('PS_USE_ECOTAX')); - $specific_price_output = null; - $id_county = (string) (isset($value['county']) ? $value['county'] : 0); - $return_value = Product::priceCalculation( - $id_shop, - $value['object_id'], - $id_product_attribute, - $id_country, - $id_state, - $id_county, - $id_currency, - $id_group, - $quantity, - $use_tax, - $decimals, - $only_reduc, - $use_reduc, - $use_ecotax, - $specific_price_output, - false - ); - $arr_return[$name] = ['sqlId' => strtolower($name), 'value' => sprintf('%f', $return_value)]; - } - - return $arr_return; - } - - /** - * This method is used for calculate the price for products on a virtual fields. - * - * @param ObjectModel $entity_object - * @param array $parameters - * - * @return array - */ - public function specificPriceForCombination($entity_object, $parameters) - { - foreach (array_keys($parameters) as $name) { - $parameters[$name]['object_id'] = $entity_object->id_product; - $parameters[$name]['product_attribute'] = $entity_object->id; - } - $arr_return = $this->specificPriceCalculation($parameters); - - return $arr_return; - } - - /** - * Start Webservice request - * Check webservice activation - * Check authentication - * Check resource - * Check HTTP Method - * Execute the action - * Display the result. - * - * @param string $key - * @param string $method - * @param string $url - * @param array $params - * @param string $bad_class_name - * @param string $inputXml - * - * @return array Returns an array of results (headers, content, type of resource...) - */ - public function fetch($key, $method, $url, $params, $bad_class_name, $inputXml = null) - { - // Time logger - $this->_startTime = microtime(true); - $this->objects = []; - - // Error handler - set_error_handler([$this, 'webserviceErrorHandler']); - ini_set('html_errors', 'off'); - - // Two global vars, for compatibility with the PS core - global $webservice_call, $display_errors; - $webservice_call = true; - $display_errors = strtolower(ini_get('display_errors')) != 'off'; - // __PS_BASE_URI__ is from Shop::$current_base_uri - $this->wsUrl = Tools::getHttpHost(true) . __PS_BASE_URI__ . 'api/'; - // set the output object which manage the content and header structure and information - $this->objOutput = new WebserviceOutputBuilder($this->wsUrl); - - $this->_key = trim($key); - - if (isset($params['output_format'])) { - $this->outputFormat = $params['output_format']; - } - // Set the render object to build the output on the asked format (XML, JSON, CSV, ...) - $this->objOutput->setObjectRender($this->getOutputObject($this->outputFormat)); - $this->params = $params; - // Check webservice activation and request authentication - if ($this->webserviceChecks()) { - if ($bad_class_name) { - $this->setError(500, 'Class "' . htmlspecialchars($bad_class_name) . '" not found. Please update the class_name field in the webservice_account table.', 126); - } - // parse request url - $this->method = $method; - $this->urlSegment = explode('/', $url); - $this->urlFragments = $params; - $this->_inputXml = $inputXml; - $this->depth = isset($this->urlFragments['depth']) ? (int) $this->urlFragments['depth'] : $this->depth; - - try { - // Method below set a particular fonction to use on the price field for products entity - // @see WebserviceRequest::getPriceForProduct() method - // @see WebserviceOutputBuilder::setSpecificField() method - //$this->objOutput->setSpecificField($this, 'getPriceForProduct', 'price', 'products'); - if (isset($this->urlFragments['price'])) { - $this->objOutput->setVirtualField($this, 'specificPriceForCombination', 'combinations', $this->urlFragments['price']); - $this->objOutput->setVirtualField($this, 'specificPriceForProduct', 'products', $this->urlFragments['price']); - } - } catch (Exception $e) { - $this->setError(500, $e->getMessage(), $e->getCode()); - } - - if (isset($this->urlFragments['language'])) { - $this->_available_languages = $this->filterLanguage(); - } else { - $this->_available_languages = Language::getIDs(); - } - - if (empty($this->_available_languages)) { - $this->setError(400, 'language is not available', 81); - } - - // Need to set available languages for the render object. - // Thus we can filter i18n field for the output - // @see WebserviceOutputXML::renderField() method for example - $this->objOutput->objectRender->setLanguages($this->_available_languages); - - // check method and resource - if (empty($this->errors) && $this->checkResource() && $this->checkHTTPMethod()) { - // The resource list is necessary for build the output - $this->objOutput->setWsResources($this->resourceList); - - // if the resource is a core entity... - if (!isset($this->resourceList[$this->urlSegment[0]]['specific_management']) || !$this->resourceList[$this->urlSegment[0]]['specific_management']) { - // load resource configuration - if ($this->urlSegment[0] != '') { - /** @var ObjectModel $object */ - $object = new $this->resourceList[$this->urlSegment[0]]['class'](); - if (isset($this->resourceList[$this->urlSegment[0]]['parameters_attribute'])) { - $this->resourceConfiguration = $object->getWebserviceParameters($this->resourceList[$this->urlSegment[0]]['parameters_attribute']); - } else { - $this->resourceConfiguration = $object->getWebserviceParameters(); - } - } - $success = false; - // execute the action - switch ($this->method) { - case 'GET': - case 'HEAD': - if ($this->executeEntityGetAndHead()) { - $success = true; - } - - break; - case 'POST': - if ($this->executeEntityPost()) { - $success = true; - } - - break; - case 'PUT': - if ($this->executeEntityPut()) { - $success = true; - } - - break; - case 'PATCH': - if ($this->executeEntityPatch()) { - $success = true; - } - - break; - case 'DELETE': - $this->executeEntityDelete(); - - break; - } - // Need to set an object for the WebserviceOutputBuilder object in any case - // because schema need to get webserviceParameters of this object - if (isset($object)) { - $this->objects['empty'] = $object; - } - } else { - // if the management is specific - $specificObjectName = 'WebserviceSpecificManagement' . ucfirst(Tools::toCamelCase($this->urlSegment[0])); - if (!class_exists($specificObjectName)) { - $this->setError(501, sprintf('The specific management class is not implemented for the "%s" entity.', $this->urlSegment[0]), 124); - } else { - $this->setObjectSpecificManagement(new $specificObjectName()); - $this->objectSpecificManagement->setObjectOutput($this->objOutput); - if ($this instanceof WebserviceRequest) { - $this->objectSpecificManagement->setWsObject($this); - } - - try { - $this->objectSpecificManagement->manage(); - } catch (WebserviceException $e) { - if ($e->getType() == WebserviceException::DID_YOU_MEAN) { - $this->setErrorDidYouMean($e->getStatus(), $e->getMessage(), $e->getWrongValue(), $e->getAvailableValues(), $e->getCode()); - } elseif ($e->getType() == WebserviceException::SIMPLE) { - $this->setError($e->getStatus(), $e->getMessage(), $e->getCode()); - } - } - } - } - } - } - $return = $this->returnOutput(); - unset( - $webservice_call, - $display_errors - ); - - return $return; - } - - protected function webserviceChecks() - { - return $this->isActivated() && $this->authenticate() && $this->groupShopExists($this->params) && $this->shopExists($this->params) && $this->shopHasRight($this->_key); - } - - /** - * Set a webservice error. - * - * @param int $status - * @param string $label - * @param int $code - */ - public function setError($status, $label, $code) - { - global $display_errors; - if (!isset($display_errors)) { - $display_errors = strtolower(ini_get('display_errors')) != 'off'; - } - if (isset($this->objOutput)) { - $this->objOutput->setStatus($status); - } - $this->errors[] = [$code, $label]; - } - - /** - * Set a webservice error and propose a new value near from the available values. - * - * @param int $num - * @param string $label - * @param string $value - * @param array $available_values - * @param int $code - */ - public function setErrorDidYouMean($num, $label, $value, $available_values, $code) - { - $this->setError($num, $label . '. Did you mean: "' . $this->getClosest($value, $available_values) . '"?' . (count($available_values) > 1 ? ' The full list is: "' . implode('", "', $available_values) . '"' : ''), $code); - } - - /** - * Return the nearest value picked in the values list. - * - * @param string $input - * @param array $words - * - * @return string - */ - protected function getClosest($input, $words) - { - $shortest = -1; - $closest = ''; - foreach ($words as $word) { - $lev = levenshtein($input, $word); - if ($lev == 0) { - $closest = $word; - $shortest = 0; - - break; - } - if ($lev <= $shortest || $shortest < 0) { - $closest = $word; - $shortest = $lev; - } - } - - return $closest; - } - - /** - * Used to replace the default PHP error handler, in order to display PHP errors in a XML format. - * - * @param int $errno contains the level of the error raised, as an integer - * @param string $errstr contains the error message, as a string - * @param string $errfile errfile, which contains the filename that the error was raised in, as a string - * @param int $errline errline, which contains the line number the error was raised at, as an integer - * - * @return bool Always return true to avoid the default PHP error handler - */ - public function webserviceErrorHandler($errno, $errstr, $errfile, $errline) - { - $display_errors = strtolower(ini_get('display_errors')) != 'off'; - if (!(error_reporting() & $errno) || $display_errors) { - return true; - } - - $errortype = [ - E_ERROR => 'Error', - E_WARNING => 'Warning', - E_PARSE => 'Parse', - E_NOTICE => 'Notice', - E_CORE_ERROR => 'Core Error', - E_CORE_WARNING => 'Core Warning', - E_COMPILE_ERROR => 'Compile Error', - E_COMPILE_WARNING => 'Compile Warning', - E_USER_ERROR => 'Error', - E_USER_WARNING => 'User warning', - E_USER_NOTICE => 'User notice', - E_STRICT => 'Runtime Notice', - E_RECOVERABLE_ERROR => 'Recoverable error', - ]; - $type = $errortype[$errno] ?? 'Unknown error'; - Tools::error_log('[PHP ' . $type . ' #' . $errno . '] ' . $errstr . ' (' . $errfile . ', line ' . $errline . ')'); - - switch ($errno) { - case E_ERROR: - WebserviceRequest::getInstance()->setError(500, '[PHP Error #' . $errno . '] ' . $errstr . ' (' . $errfile . ', line ' . $errline . ')', 2); - - break; - case E_WARNING: - WebserviceRequest::getInstance()->setError(500, '[PHP Warning #' . $errno . '] ' . $errstr . ' (' . $errfile . ', line ' . $errline . ')', 3); - - break; - case E_PARSE: - WebserviceRequest::getInstance()->setError(500, '[PHP Parse #' . $errno . '] ' . $errstr . ' (' . $errfile . ', line ' . $errline . ')', 4); - - break; - case E_NOTICE: - WebserviceRequest::getInstance()->setError(500, '[PHP Notice #' . $errno . '] ' . $errstr . ' (' . $errfile . ', line ' . $errline . ')', 5); - - break; - case E_CORE_ERROR: - WebserviceRequest::getInstance()->setError(500, '[PHP Core #' . $errno . '] ' . $errstr . ' (' . $errfile . ', line ' . $errline . ')', 6); - - break; - case E_CORE_WARNING: - WebserviceRequest::getInstance()->setError(500, '[PHP Core warning #' . $errno . '] ' . $errstr . ' (' . $errfile . ', line ' . $errline . ')', 7); - - break; - case E_COMPILE_ERROR: - WebserviceRequest::getInstance()->setError(500, '[PHP Compile #' . $errno . '] ' . $errstr . ' (' . $errfile . ', line ' . $errline . ')', 8); - - break; - case E_COMPILE_WARNING: - WebserviceRequest::getInstance()->setError(500, '[PHP Compile warning #' . $errno . '] ' . $errstr . ' (' . $errfile . ', line ' . $errline . ')', 9); - - break; - case E_USER_ERROR: - WebserviceRequest::getInstance()->setError(500, '[PHP Error #' . $errno . '] ' . $errstr . ' (' . $errfile . ', line ' . $errline . ')', 10); - - break; - case E_USER_WARNING: - WebserviceRequest::getInstance()->setError(500, '[PHP User warning #' . $errno . '] ' . $errstr . ' (' . $errfile . ', line ' . $errline . ')', 11); - - break; - case E_USER_NOTICE: - WebserviceRequest::getInstance()->setError(500, '[PHP User notice #' . $errno . '] ' . $errstr . ' (' . $errfile . ', line ' . $errline . ')', 12); - - break; - case E_STRICT: - WebserviceRequest::getInstance()->setError(500, '[PHP Strict #' . $errno . '] ' . $errstr . ' (' . $errfile . ', line ' . $errline . ')', 13); - - break; - case E_RECOVERABLE_ERROR: - WebserviceRequest::getInstance()->setError(500, '[PHP Recoverable error #' . $errno . '] ' . $errstr . ' (' . $errfile . ', line ' . $errline . ')', 14); - - break; - default: - WebserviceRequest::getInstance()->setError(500, '[PHP Unknown error #' . $errno . '] ' . $errstr . ' (' . $errfile . ', line ' . $errline . ')', 15); - } - - return true; - } - - /** - * Check if there is one or more error. - * - * @return bool - */ - protected function hasErrors() - { - return (bool) $this->errors; - } - - /** - * Check request authentication. - * - * @return bool - */ - protected function authenticate() - { - if ($this->hasErrors()) { - return false; - } - - if (null === $this->_key) { - $this->setError(401, 'Please enter the authentication key as the login. No password required', 16); - } else { - if (empty($this->_key)) { - $this->setError(401, 'Authentication key is empty', 17); - } elseif (strlen($this->_key) != '32') { - $this->setError(401, 'Invalid authentication key format', 18); - } else { - if (WebserviceKey::isKeyActive($this->_key)) { - $this->keyPermissions = WebserviceKey::getPermissionForAccount($this->_key); - } else { - $this->setError(401, 'Authentification key is not active', 20); - } - - if (!$this->keyPermissions) { - $this->setError(401, 'No permission for this authentication key', 21); - } - } - } - if ($this->hasErrors()) { - header('WWW-Authenticate: Basic realm="Welcome to PrestaShop Webservice, please enter the authentication key as the login. No password required."'); - $this->objOutput->setStatus(401); - - return false; - } else { - // only now we can say the access is authenticated - $this->_authenticated = true; - - return true; - } - } - - /** - * Check webservice activation. - * - * @return bool - */ - protected function isActivated() - { - if (!Configuration::get('PS_WEBSERVICE')) { - $this->setError(503, 'The PrestaShop webservice is disabled. Please activate it in the PrestaShop Back Office', 22); - - return false; - } - - return true; - } - - /** - * @param string $key - * - * @return bool - */ - protected function shopHasRight($key) - { - $sql = 'SELECT 1 - FROM ' . _DB_PREFIX_ . 'webservice_account wsa LEFT JOIN ' . _DB_PREFIX_ . 'webservice_account_shop wsas ON (wsa.id_webservice_account = wsas.id_webservice_account) - WHERE wsa.key = \'' . pSQL($key) . '\''; - $OR = []; - foreach (self::$shopIDs as $id_shop) { - $OR[] = ' wsas.id_shop = ' . (int) $id_shop . ' '; - } - $sql .= ' AND (' . implode('OR', $OR) . ') '; - if (!Db::getInstance()->getValue($sql)) { - $this->setError(403, 'No permission for this key on this shop', 132); - - return false; - } - - return true; - } - - /** - * @param array $params - * - * @return bool - */ - protected function shopExists($params) - { - if (is_countable(self::$shopIDs) && count(self::$shopIDs)) { - return true; - } - - if (isset($params['id_shop'])) { - if ($params['id_shop'] != 'all' && is_numeric($params['id_shop'])) { - Shop::setContext(Shop::CONTEXT_SHOP, (int) $params['id_shop']); - self::$shopIDs[] = (int) $params['id_shop']; - - return true; - } elseif ($params['id_shop'] == 'all') { - Shop::setContext(Shop::CONTEXT_ALL); - self::$shopIDs = Shop::getShops(true, null, true); - - return true; - } - } else { - self::$shopIDs[] = Context::getContext()->shop->id; - - return true; - } - $this->setError(404, 'This shop id does not exist', 999); - - return false; - } - - /** - * @param array $params - * - * @return bool - */ - protected function groupShopExists($params) - { - $idShopGroup = null; - if (isset($params['id_shop_group']) && is_numeric($params['id_shop_group'])) { - $idShopGroup = (int) $params['id_shop_group']; - } elseif (isset($params['id_group_shop']) && is_numeric($params['id_group_shop'])) { - $idShopGroup = (int) $params['id_group_shop']; - } - - if (null !== $idShopGroup) { - Shop::setContext(Shop::CONTEXT_GROUP, $idShopGroup); - self::$shopIDs = Shop::getShops(true, $idShopGroup, true); - if (!is_countable(self::$shopIDs) || count(self::$shopIDs) == 0) { - // @FIXME Set ErrorCode ! - $this->setError(500, 'This shop group doesn\'t have shops', 999); - - return false; - } - } - // id_shop_group isn't mandatory - return true; - } - - /** - * Check HTTP method. - * - * @return bool - */ - protected function checkHTTPMethod() - { - if (!in_array($this->method, ['GET', 'PUT', 'POST', 'PATCH', 'DELETE', 'HEAD'])) { - $this->setError(405, 'Method ' . $this->method . ' is not valid', 23); - } elseif (isset($this->urlSegment[0], $this->resourceList[$this->urlSegment[0]]['forbidden_method']) && in_array($this->method, $this->resourceList[$this->urlSegment[0]]['forbidden_method'])) { - $this->setError(405, 'Method ' . $this->method . ' is not allowed for the resource ' . $this->urlSegment[0], 101); - } elseif ($this->urlSegment[0] && !in_array($this->method, $this->keyPermissions[$this->urlSegment[0]])) { - $this->setError(405, 'Method ' . $this->method . ' is not allowed for the resource ' . $this->urlSegment[0] . ' with this authentication key', 25); - } else { - return true; - } - - return false; - } - - /** - * Check resource validity. - * - * @return bool - */ - protected function checkResource() - { - $this->resourceList = $this->getResources(); - $resourceNames = array_keys($this->resourceList); - if ($this->urlSegment[0] == '') { - $this->resourceConfiguration['objectsNodeName'] = 'resources'; - } elseif (in_array($this->urlSegment[0], $resourceNames)) { - if (!in_array($this->urlSegment[0], array_keys($this->keyPermissions))) { - $this->setError(401, 'Resource of type "' . $this->urlSegment[0] . '" is not allowed with this authentication key', 26); - - return false; - } - } else { - $this->setErrorDidYouMean(400, 'Resource of type "' . $this->urlSegment[0] . '" does not exists', $this->urlSegment[0], $resourceNames, 27); - - return false; - } - - return true; - } - - protected function setObjects() - { - $objects = []; - $arr_avoid_id = []; - $ids = []; - if (isset($this->urlFragments['id'])) { - preg_match('#^\[(.*)\]$#Ui', $this->urlFragments['id'], $matches); - if (count($matches) > 1) { - $ids = explode(',', $matches[1]); - } - } else { - $ids[] = (int) $this->urlSegment[1]; - } - if (!empty($ids)) { - foreach ($ids as $id) { - $object = new $this->resourceConfiguration['retrieveData']['className']((int) $id); - if (!$object->id) { - $arr_avoid_id[] = $id; - } else { - $objects[] = $object; - } - } - } - - if (!empty($arr_avoid_id) || empty($ids)) { - $this->setError(404, 'Id(s) not exists: ' . implode(', ', $arr_avoid_id), 87); - $this->_outputEnabled = true; - } - } - - protected function parseDisplayFields($str) - { - $bracket_level = 0; - $part = []; - $tmp = ''; - $str_len = strlen($str); - for ($i = 0; $i < $str_len; ++$i) { - if ($str[$i] == ',' && $bracket_level == 0) { - $part[] = $tmp; - $tmp = ''; - } else { - $tmp .= $str[$i]; - } - if ($str[$i] == '[') { - ++$bracket_level; - } - if ($str[$i] == ']') { - --$bracket_level; - } - } - if ($tmp != '') { - $part[] = $tmp; - } - $fields = []; - foreach ($part as $str) { - $field_name = trim(substr($str, 0, (strpos($str, '[') === false ? strlen($str) : strpos($str, '[')))); - if (!isset($fields[$field_name])) { - $fields[$field_name] = null; - } - if (strpos($str, '[') !== false) { - $sub_fields = substr($str, strpos($str, '[') + 1, strlen($str) - strpos($str, '[') - 2); - $tmp_array = []; - if (strpos($sub_fields, ',') !== false) { - $tmp_array = explode(',', $sub_fields); - } else { - $tmp_array = [$sub_fields]; - } - $fields[$field_name] = (is_array($fields[$field_name])) ? array_merge($fields[$field_name], $tmp_array) : $tmp_array; - } - } - - return $fields; - } - - public function setFieldsToDisplay() - { - // set the fields to display in the list : "full", "minimum", "field_1", "field_1,field_2,field_3" - if (isset($this->urlFragments['display'])) { - $this->fieldsToDisplay = $this->urlFragments['display']; - if ($this->fieldsToDisplay != 'full' && $this->fieldsToDisplay != 'minimum') { - preg_match('#^\[(.*)\]$#Ui', $this->fieldsToDisplay, $matches); - if (count($matches)) { - $error = false; - $fieldsToTest = $this->parseDisplayFields($matches[1]); - foreach ($fieldsToTest as $field_name => $part) { - // in case it is not an association - if (!is_array($part)) { - // We have to allow new specific field for price calculation too - $error = (!isset($this->resourceConfiguration['fields'][$field_name]) && !isset($this->urlFragments['price'][$field_name])); - } else { - // if this association does not exists - if (!array_key_exists($field_name, $this->resourceConfiguration['associations'])) { - $error = true; - } - - foreach ($part as $field) { - if ($field != 'id' && !array_key_exists($field, $this->resourceConfiguration['associations'][$field_name]['fields'])) { - $error = true; - - break; - } - } - } - if ($error) { - $this->setError(400, 'Unable to display this field "' . $field_name . (is_array($part) ? ' (details : ' . var_export($part, true) . ')' : '') . '". However, these are available: ' . implode(', ', array_keys($this->resourceConfiguration['fields'])), 35); - - return false; - } - } - $this->fieldsToDisplay = $fieldsToTest; - } else { - $this->setError(400, 'The \'display\' syntax is wrong. You can set \'full\' or \'[field_1,field_2,field_3,...]\'. These are available: ' . implode(', ', array_keys($this->resourceConfiguration['fields'])), 36); - - return false; - } - } - } - - return true; - } - - protected function manageFilters() - { - // filtered fields which can not use filters : hidden_fields - $available_filters = []; - // filtered i18n fields which can use filters - $i18n_available_filters = []; - foreach ($this->resourceConfiguration['fields'] as $fieldName => $field) { - if ((!isset($this->resourceConfiguration['hidden_fields']) || - (isset($this->resourceConfiguration['hidden_fields']) && !in_array($fieldName, $this->resourceConfiguration['hidden_fields'])))) { - if ((!isset($field['i18n']) || - (isset($field['i18n']) && !$field['i18n']))) { - $available_filters[] = $fieldName; - } else { - $i18n_available_filters[] = $fieldName; - } - } - } - - // Date feature : date=1 - if (!empty($this->urlFragments['date'])) { - if (!in_array('date_add', $available_filters)) { - $available_filters[] = 'date_add'; - } - if (!in_array('date_upd', $available_filters)) { - $available_filters[] = 'date_upd'; - } - if (!array_key_exists('date_add', $this->resourceConfiguration['fields'])) { - $this->resourceConfiguration['fields']['date_add'] = ['sqlId' => 'date_add']; - } - if (!array_key_exists('date_upd', $this->resourceConfiguration['fields'])) { - $this->resourceConfiguration['fields']['date_upd'] = ['sqlId' => 'date_upd']; - } - } else { - foreach ($available_filters as $key => $value) { - if ($value == 'date_add' || $value == 'date_upd') { - unset($available_filters[$key]); - } - } - } - - //construct SQL filter - $sql_filter = ''; - $sql_join = ''; - if ($this->urlFragments) { - $schema = 'schema'; - // if we have to display the schema - if (isset($this->urlFragments[$schema])) { - if ($this->urlFragments[$schema] == 'blank' || $this->urlFragments[$schema] == 'synopsis') { - $this->schemaToDisplay = $this->urlFragments[$schema]; - - return true; - } else { - $this->setError(400, 'Please select a schema of type \'synopsis\' to get the whole schema informations (which fields are required, which kind of content...) or \'blank\' to get an empty schema to fill before using POST request', 28); - - return false; - } - } else { - // if there are filters - if (isset($this->urlFragments['filter'])) { - foreach ($this->urlFragments['filter'] as $field => $url_param) { - if ($field != 'sort' && $field != 'limit') { - if (!in_array($field, $available_filters)) { - // if there are linked tables - if (isset($this->resourceConfiguration['linked_tables'][$field])) { - // contruct SQL join for linked tables - $sql_join .= 'LEFT JOIN `' . bqSQL(_DB_PREFIX_ . $this->resourceConfiguration['linked_tables'][$field]['table']) . '` `' . bqSQL($field) . '` ON (main.`' . bqSQL($this->resourceConfiguration['fields']['id']['sqlId']) . '` = `' . bqSQL($field) . '`.`' . bqSQL($this->resourceConfiguration['fields']['id']['sqlId']) . '`)' . "\n"; - - // construct SQL filter for linked tables - foreach ($url_param as $field2 => $value) { - if (isset($this->resourceConfiguration['linked_tables'][$field]['fields'][$field2])) { - $linked_field = $this->resourceConfiguration['linked_tables'][$field]['fields'][$field2]; - $sql_filter .= $this->getSQLRetrieveFilter($linked_field['sqlId'], $value, $field . '.'); - } else { - $list = array_keys($this->resourceConfiguration['linked_tables'][$field]['fields']); - $this->setErrorDidYouMean(400, 'This filter does not exist for this linked table', $field2, $list, 29); - - return false; - } - } - } elseif ($url_param != '' && in_array($field, $i18n_available_filters)) { - if (!is_array($url_param)) { - $url_param = [$url_param]; - } - $sql_join .= 'LEFT JOIN `' . bqSQL(_DB_PREFIX_ . $this->resourceConfiguration['retrieveData']['table']) . '_lang` AS main_i18n ON (main.`' . bqSQL($this->resourceConfiguration['fields']['id']['sqlId']) . '` = main_i18n.`' . bqSQL($this->resourceConfiguration['fields']['id']['sqlId']) . '`)' . "\n"; - foreach ($url_param as $field2 => $value) { - $linked_field = $this->resourceConfiguration['fields'][$field]; - $sql_filter .= $this->getSQLRetrieveFilter($linked_field['sqlId'], $value, 'main_i18n.'); - $language_filter = '[' . implode('|', $this->_available_languages) . ']'; - $sql_filter .= $this->getSQLRetrieveFilter('id_lang', $language_filter, 'main_i18n.'); - } - } elseif (is_array($url_param)) { - // if there are filters on linked tables but there are no linked table - if (isset($this->resourceConfiguration['linked_tables'])) { - $this->setErrorDidYouMean(400, 'This linked table does not exist', $field, array_keys($this->resourceConfiguration['linked_tables']), 30); - } else { - $this->setError(400, 'There is no existing linked table for this resource', 31); - } - - return false; - } else { - $this->setErrorDidYouMean(400, 'This filter does not exist', $field, $available_filters, 32); - - return false; - } - } elseif ($url_param == '') { - $this->setError(400, 'The filter "' . $field . '" is malformed.', 33); - - return false; - } else { - if (isset($this->resourceConfiguration['fields'][$field]['getter'])) { - $this->setError(400, 'The field "' . $field . '" is dynamic. It is not possible to filter GET query with this field.', 34); - - return false; - } else { - if (isset($this->resourceConfiguration['retrieveData']['tableAlias'])) { - $sql_filter .= $this->getSQLRetrieveFilter($this->resourceConfiguration['fields'][$field]['sqlId'], $url_param, $this->resourceConfiguration['retrieveData']['tableAlias'] . '.'); - } else { - $sql_filter .= $this->getSQLRetrieveFilter($this->resourceConfiguration['fields'][$field]['sqlId'], $url_param); - } - } - } - } - } - } - } - } - - if (!$this->setFieldsToDisplay()) { - return false; - } - // construct SQL Sort - $sql_sort = ''; - if (isset($this->urlFragments['sort'])) { - preg_match('#^\[(.*)\]$#Ui', $this->urlFragments['sort'], $matches); - if (count($matches) > 1) { - $sorts = explode(',', $matches[1]); - } else { - $sorts = [$this->urlFragments['sort']]; - } - - $sql_sort .= ' ORDER BY '; - - foreach ($sorts as $sort) { - $delimiterPosition = strrpos($sort, '_'); - $fieldName = $direction = ''; - if ($delimiterPosition !== false) { - $fieldName = substr($sort, 0, $delimiterPosition); - $direction = strtoupper(substr($sort, $delimiterPosition + 1)); - } - if ($delimiterPosition === false || !in_array($direction, ['ASC', 'DESC'])) { - $this->setError(400, 'The "sort" value has to be formed as this example: "field_ASC" or \'[field_1_DESC,field_2_ASC,field_3_ASC,...]\' ("field" has to be an available field)', 37); - - return false; - } elseif (!in_array($fieldName, $available_filters) && !in_array($fieldName, $i18n_available_filters)) { - $this->setError(400, 'Unable to filter by this field. However, these are available: ' . implode(', ', $available_filters) . ', for i18n fields:' . implode(', ', $i18n_available_filters), 38); - - return false; - } elseif (in_array($fieldName, $i18n_available_filters)) { - // for sort on i18n field - if (!preg_match('#main_i18n#', $sql_join)) { - $sql_join .= 'LEFT JOIN `' . _DB_PREFIX_ . bqSQL($this->resourceConfiguration['retrieveData']['table']) . '_lang` AS main_i18n ON (main.`' . bqSQL($this->resourceConfiguration['fields']['id']['sqlId']) . '` = main_i18n.`' . bqSQL($this->resourceConfiguration['fields']['id']['sqlId']) . '`)' . "\n"; - } - $sql_sort .= 'main_i18n.`' . bqSQL($this->resourceConfiguration['fields'][$fieldName]['sqlId']) . '` ' . $direction . ', '; // ORDER BY main_i18n.`field` ASC|DESC - } else { - /** @var ObjectModel $object */ - $object = new $this->resourceConfiguration['retrieveData']['className'](); - $assoc = Shop::getAssoTable($this->resourceConfiguration['retrieveData']['table']); - if ($assoc !== false && $assoc['type'] == 'shop' && ($object->isMultiShopField($this->resourceConfiguration['fields'][$fieldName]['sqlId']) || $fieldName == 'id')) { - $table_alias = 'multi_shop_' . $this->resourceConfiguration['retrieveData']['table']; - } else { - $table_alias = ''; - } - $sql_sort .= (isset($this->resourceConfiguration['retrieveData']['tableAlias']) ? '`' . bqSQL($this->resourceConfiguration['retrieveData']['tableAlias']) . '`.' : '`' . bqSQL($table_alias) . '`.') . '`' . pSQL($this->resourceConfiguration['fields'][$fieldName]['sqlId']) . '` ' . $direction . ', '; // ORDER BY `field` ASC|DESC - } - } - $sql_sort = rtrim($sql_sort, ', ') . "\n"; - } - - //construct SQL Limit - $sql_limit = ''; - if (isset($this->urlFragments['limit'])) { - $limitArgs = explode(',', $this->urlFragments['limit']); - if (count($limitArgs) > 2) { - $this->setError(400, 'The "limit" value has to be formed as this example: "5,25" or "10"', 39); - - return false; - } else { - $sql_limit .= ' LIMIT ' . (int) ($limitArgs[0]) . (isset($limitArgs[1]) ? ', ' . (int) ($limitArgs[1]) : '') . "\n"; // LIMIT X|X, Y - } - } - $filters['sql_join'] = $sql_join; - $filters['sql_filter'] = $sql_filter; - $filters['sql_sort'] = $sql_sort; - $filters['sql_limit'] = $sql_limit; - - return $filters; - } - - public function getFilteredObjectList() - { - $objects = []; - $filters = $this->manageFilters(); - - /* If we only need to display the synopsis, analyzing the first row is sufficient */ - if (isset($this->urlFragments['schema']) && in_array($this->urlFragments['schema'], ['blank', 'synopsis'])) { - $filters = ['sql_join' => '', 'sql_filter' => '', 'sql_sort' => '', 'sql_limit' => ' LIMIT 1']; - } - - $this->resourceConfiguration['retrieveData']['params'][] = $filters['sql_join']; - $this->resourceConfiguration['retrieveData']['params'][] = $filters['sql_filter']; - $this->resourceConfiguration['retrieveData']['params'][] = $filters['sql_sort']; - $this->resourceConfiguration['retrieveData']['params'][] = $filters['sql_limit']; - //list entities - - $tmp = new $this->resourceConfiguration['retrieveData']['className'](); - $sqlObjects = call_user_func_array([$tmp, $this->resourceConfiguration['retrieveData']['retrieveMethod']], $this->resourceConfiguration['retrieveData']['params']); - if ($sqlObjects) { - foreach ($sqlObjects as $sqlObject) { - if ($this->fieldsToDisplay == 'minimum') { - $obj = new $this->resourceConfiguration['retrieveData']['className'](); - $obj->id = (int) $sqlObject[$this->resourceConfiguration['fields']['id']['sqlId']]; - $objects[] = $obj; - } else { - $objects[] = new $this->resourceConfiguration['retrieveData']['className']((int) $sqlObject[$this->resourceConfiguration['fields']['id']['sqlId']]); - } - } - - return $objects; - } - } - - public function getFilteredObjectDetails() - { - if (!$this->setFieldsToDisplay()) { - return false; - } - - $objects = []; - if (!isset($this->urlFragments['display'])) { - $this->fieldsToDisplay = 'full'; - } - - //get entity details - $object = new $this->resourceConfiguration['retrieveData']['className']((int) $this->urlSegment[1]); - if ($object->id) { - $objects[] = $object; - // Check if Object is accessible for this/those id_shop - $assoc = Shop::getAssoTable($this->resourceConfiguration['retrieveData']['table']); - if ($assoc !== false) { - $check_shop_group = false; - - $sql = 'SELECT 1 - FROM `' . bqSQL(_DB_PREFIX_ . $this->resourceConfiguration['retrieveData']['table']); - if ($assoc['type'] != 'fk_shop') { - $sql .= '_' . $assoc['type']; - } else { - $def = ObjectModel::getDefinition($this->resourceConfiguration['retrieveData']['className']); - if (isset($def['fields']['id_shop_group'])) { - $check_shop_group = true; - } - } - $sql .= '`'; - - $OR = []; - foreach (self::$shopIDs as $id_shop) { - $OR[] = ' (id_shop = ' . (int) $id_shop . ($check_shop_group ? ' OR (id_shop = 0 AND id_shop_group=' . (int) Shop::getGroupFromShop((int) $id_shop) . ')' : '') . ') '; - } - - $check = ' WHERE (' . implode('OR', $OR) . ') AND `' . bqSQL($this->resourceConfiguration['fields']['id']['sqlId']) . '` = ' . (int) $this->urlSegment[1]; - if (!Db::getInstance()->getValue($sql . $check)) { - $this->setError(404, 'This ' . $this->resourceConfiguration['retrieveData']['className'] . ' (' . (int) $this->urlSegment[1] . ') does not exists on this shop', 131); - } - } - - return $objects; - } - if (!count($this->errors)) { - $this->objOutput->setStatus(404); - $this->_outputEnabled = false; - - return false; - } - } - - /** - * Execute GET and HEAD requests. - * - * Build filter - * Build fields display - * Build sort - * Build limit - * - * @return bool - */ - public function executeEntityGetAndHead() - { - if ($this->resourceConfiguration['objectsNodeName'] != 'resources') { - if (!isset($this->urlSegment[1]) || !strlen($this->urlSegment[1])) { - $return = $this->getFilteredObjectList(); - } else { - $return = $this->getFilteredObjectDetails(); - } - - if (!$return) { - return false; - } else { - $this->_outputEnabled = true; - $this->objects = $return; - } - } - - return true; - } - - /** - * Execute POST method on a PrestaShop entity. - * - * @return bool - */ - public function executeEntityPost() - { - return $this->saveEntityFromXml(201); - } - - /** - * Execute PUT method on a PrestaShop entity. - * - * @return bool - */ - public function executeEntityPut() - { - return $this->saveEntityFromXml(200); - } - - /** - * Execute PATCH method on a PrestaShop entity. - * - * @return bool - */ - public function executeEntityPatch(): bool - { - return $this->saveEntityFromXml(200); - } - - /** - * Execute DELETE method on a PrestaShop entity. - * - * @return void - */ - public function executeEntityDelete() - { - $objects = []; - $arr_avoid_id = []; - $ids = []; - if (isset($this->urlFragments['id'])) { - preg_match('#^\[(.*)\]$#Ui', $this->urlFragments['id'], $matches); - if (count($matches) > 1) { - $ids = explode(',', $matches[1]); - } - } else { - $ids[] = (int) $this->urlSegment[1]; - } - if (!empty($ids)) { - foreach ($ids as $id) { - $object = new $this->resourceConfiguration['retrieveData']['className']((int) $id); - if (!$object->id) { - $arr_avoid_id[] = $id; - } else { - $objects[] = $object; - } - } - } - - $postponeNTreeRegeneration = false; - - if (!empty($arr_avoid_id) || empty($ids)) { - $this->setError(404, 'Id(s) not exists: ' . implode(', ', $arr_avoid_id), 87); - $this->_outputEnabled = true; - } else { - foreach ($objects as $object) { - if ($object instanceof Category) { - $object->doNotRegenerateNTree = true; - $postponeNTreeRegeneration = true; - } - - /* @var ObjectModel $object */ - if (isset($this->resourceConfiguration['objectMethods']['delete'])) { - $result = $object->{$this->resourceConfiguration['objectMethods']['delete']}(); - } else { - $result = $object->delete(); - } - - if (!$result) { - $arr_avoid_id[] = $object->id; - } - } - if (!empty($arr_avoid_id)) { - $this->setError(500, 'Id(s) wasn\'t deleted: ' . implode(', ', $arr_avoid_id), 88); - $this->_outputEnabled = true; - } else { - $this->_outputEnabled = false; - } - } - - if ($postponeNTreeRegeneration) { - Category::regenerateEntireNtree(); - } - } - - /** - * save Entity Object from XML. - * - * @param int $successReturnCode - * - * @return bool - */ - protected function saveEntityFromXml($successReturnCode) - { - try { - $xml = new SimpleXMLElement($this->_inputXml); - } catch (Exception $error) { - $this->setError(500, 'XML error : ' . $error->getMessage() . "\n" . 'XML length : ' . strlen($this->_inputXml) . "\n" . 'Original XML : ' . $this->_inputXml, 127); - - return false; - } - - $xmlEntities = $xml->children(); - $object = null; - - $ids = []; - foreach ($xmlEntities as $entity) { - // To cast in string allow to check null values - if ((string) $entity->id != '') { - $ids[] = (int) $entity->id; - } - } - if ($this->method == 'PUT' || $this->method == 'PATCH') { - $ids2 = array_unique($ids); - if (count($ids2) != count($ids)) { - $this->setError(400, 'id is duplicate in request', 89); - - return false; - } - if (count($xmlEntities) != count($ids)) { - $this->setError(400, 'id is required when modifying a resource', 90); - - return false; - } - } elseif ($this->method == 'POST' && count($ids) > 0) { - $this->setError(400, 'id is forbidden when adding a new resource', 91); - - return false; - } - - $postponeNTreeRegeneration = false; - foreach ($xmlEntities as $xmlEntity) { - /** @var SimpleXMLElement $xmlEntity */ - $attributes = $xmlEntity->children(); - - /* @var ObjectModel $object */ - if ($this->method == 'POST') { - $object = new $this->resourceConfiguration['retrieveData']['className'](); - } elseif ($this->method == 'PUT' || $this->method == 'PATCH') { - $object = new $this->resourceConfiguration['retrieveData']['className']((int) $attributes->id); - if (!$object->id) { - $this->setError(404, 'Invalid ID', 92); - - return false; - } - } - - if ($object instanceof Category) { - $object->doNotRegenerateNTree = true; - $postponeNTreeRegeneration = true; - } - - $this->objects[] = $object; - $i18n = false; - // attributes - foreach ($this->resourceConfiguration['fields'] as $fieldName => $fieldProperties) { - // only process fields actually in the input XML - if ($this->method == 'PATCH' && !isset($attributes->$fieldName)) { - continue; - } - $sqlId = $fieldProperties['sqlId']; - if ($fieldName == 'id') { - $sqlId = $fieldName; - } - if (isset($attributes->$fieldName, $fieldProperties['sqlId']) && (!isset($fieldProperties['i18n']) || !$fieldProperties['i18n'])) { - if (isset($fieldProperties['setter'])) { - // if we have to use a specific setter - if (!$fieldProperties['setter']) { - // if it's forbidden to set this field - $this->setError(400, 'parameter "' . $fieldName . '" not writable. Please remove this attribute of this XML', 93); - - return false; - } else { - $object->{$fieldProperties['setter']}((string) $attributes->$fieldName); - } - } elseif (property_exists($object, $sqlId)) { - $object->$sqlId = (string) $attributes->$fieldName; - } else { - $this->setError(400, 'Parameter "' . $fieldName . '" can\'t be set to the object "' . $this->resourceConfiguration['retrieveData']['className'] . '"', 123); - } - } elseif (isset($fieldProperties['required']) && $fieldProperties['required'] && !$fieldProperties['i18n']) { - $this->setError(400, 'parameter "' . $fieldName . '" required', 41); - - return false; - } elseif ((!isset($fieldProperties['required']) || !$fieldProperties['required']) && property_exists($object, $sqlId)) { - $object->$sqlId = null; - } - if (isset($fieldProperties['i18n']) && $fieldProperties['i18n']) { - $i18n = true; - if (isset($attributes->$fieldName, $attributes->$fieldName->language)) { - foreach ($attributes->$fieldName->language as $lang) { - /* @var SimpleXMLElement $lang */ - $object->{$fieldName}[(int) $lang->attributes()->id] = (string) $lang; - } - } else { - $object->{$fieldName} = (string) $attributes->$fieldName; - } - } - } - - // Apply the modifiers if they exist - foreach ($this->resourceConfiguration['fields'] as $fieldName => $fieldProperties) { - if (isset($fieldProperties['modifier']['modifier']) && $fieldProperties['modifier']['http_method'] & constant('WebserviceRequest::HTTP_' . $this->method)) { - $object->{$fieldProperties['modifier']['modifier']}(); - } - } - - if (!$this->hasErrors()) { - if ($i18n && ($retValidateFieldsLang = $object->validateFieldsLang(false, true)) !== true) { - $this->setError(400, 'Validation error: "' . $retValidateFieldsLang . '"', 84); - - return false; - } elseif (($retValidateFields = $object->validateFields(false, true)) !== true) { - $this->setError(400, 'Validation error: "' . $retValidateFields . '"', 85); - - return false; - } else { - // Call alternative method for add/update - $objectMethod = ($this->method == 'POST' ? 'add' : 'update'); - if (isset($this->resourceConfiguration['objectMethods']) && array_key_exists($objectMethod, $this->resourceConfiguration['objectMethods'])) { - $objectMethod = $this->resourceConfiguration['objectMethods'][$objectMethod]; - } - $result = $object->{$objectMethod}(); - if ($result) { - if (isset($attributes->associations)) { - foreach ($attributes->associations->children() as $association) { - /** @var SimpleXMLElement $association */ - // associations - if (isset($this->resourceConfiguration['associations'][$association->getName()])) { - $assocItems = $association->children(); - $values = []; - foreach ($assocItems as $assocItem) { - /** @var SimpleXMLElement $assocItem */ - $fields = $assocItem->children(); - $entry = []; - foreach ($fields as $fieldName => $fieldValue) { - $entry[$fieldName] = (string) $fieldValue; - } - $values[] = $entry; - } - $setter = $this->resourceConfiguration['associations'][$association->getName()]['setter']; - if (null !== $setter && $setter && method_exists($object, $setter) && !$object->$setter($values)) { - $this->setError(500, 'Error occurred while setting the ' . $association->getName() . ' value', 85); - - return false; - } - } elseif ($association->getName() != 'i18n') { - $this->setError(400, 'The association "' . $association->getName() . '" does not exists', 86); - - return false; - } - } - } - $assoc = Shop::getAssoTable($this->resourceConfiguration['retrieveData']['table']); - if ($assoc !== false && $assoc['type'] != 'fk_shop') { - // PUT nor POST is destructive, no deletion - $sql = 'INSERT IGNORE INTO `' . bqSQL(_DB_PREFIX_ . $this->resourceConfiguration['retrieveData']['table'] . '_' . $assoc['type']) . '` (id_shop, `' . bqSQL($this->resourceConfiguration['fields']['id']['sqlId']) . '`) VALUES '; - foreach (self::$shopIDs as $id) { - $sql .= '(' . (int) $id . ',' . (int) $object->id . ')'; - if ($id != end(self::$shopIDs)) { - $sql .= ', '; - } - } - Db::getInstance()->execute($sql); - } - } else { - $this->setError(500, 'Unable to save resource', 46); - } - } - } - } - - if ($postponeNTreeRegeneration) { - Category::regenerateEntireNtree(); - } - - if (!$this->hasErrors()) { - $this->objOutput->setStatus($successReturnCode); - - return true; - } - - return false; - } - - /** - * @param string $sqlId - * @param string $filterValue - * @param string $tableAlias default value is 'main.' - * - * @return string - */ - protected function getSQLRetrieveFilter($sqlId, $filterValue, $tableAlias = 'main.') - { - return SQLUtils::getSQLRetrieveFilter($sqlId, $filterValue, $tableAlias); - } - - public function filterLanguage() - { - $arr_languages = []; - $length_values = strlen($this->urlFragments['language']); - // if just one language is asked - if (is_numeric($this->urlFragments['language'])) { - $arr_languages[] = (int) $this->urlFragments['language']; - } elseif (strpos($this->urlFragments['language'], '[') === 0 - // if a range or a list is asked - && strpos($this->urlFragments['language'], ']') === $length_values - 1) { - if (strpos($this->urlFragments['language'], '|') !== false - xor strpos($this->urlFragments['language'], ',') !== false) { - $params_values = str_replace([']', '['], '', $this->urlFragments['language']); - // it's a list - if (strpos($params_values, '|') !== false) { - $list_enabled_lang = explode('|', $params_values); - $arr_languages = $list_enabled_lang; - } elseif (strpos($params_values, ',') !== false) { - // it's a range - $range_enabled_lang = explode(',', $params_values); - if (count($range_enabled_lang) != 2) { - $this->setError(400, 'A range value for a language must contains only 2 values', 78); - - return false; - } - for ($i = $range_enabled_lang[0]; $i <= $range_enabled_lang[1]; ++$i) { - $arr_languages[] = $i; - } - } - } elseif (preg_match('#\[(\d)+\]#Ui', $this->urlFragments['language'], $match_lang)) { - $arr_languages[] = $match_lang[1]; - } - } else { - $this->setError(400, 'language value is wrong', 79); - - return false; - } - - $result = array_map('is_numeric', $arr_languages); - if (array_search(false, $result, true)) { - $this->setError(400, 'Language ID must be numeric', 80); - - return false; - } - - foreach ($arr_languages as $key => $id_lang) { - if (!Language::getLanguage($id_lang)) { - unset($arr_languages[$key]); - } - } - - return $arr_languages; - } - - /** - * Thanks to the (WebserviceOutputBuilder) WebserviceKey::objOutput - * Method build the output depend on the WebserviceRequest::outputFormat - * and set HTTP header parameters. - * - * @return array with displaying informations (used in the dispatcher) - */ - protected function returnOutput() - { - $return = []; - - // Write headers - $this->objOutput - ->setHeaderParams('Access-Time', (string) time()) - ->setHeaderParams('X-Powered-By', 'PrestaShop Webservice') - ->setHeaderParams('Execution-Time', (string) round(microtime(true) - $this->_startTime, 3)) - ; - - $return['type'] = strtolower($this->outputFormat); - - // write this header only now (avoid hackers happiness...) - if ($this->_authenticated) { - $this->objOutput->setHeaderParams('PSWS-Version', _PS_VERSION_); - } - - // If Specific Management is asked - if ($this->objectSpecificManagement instanceof WebserviceSpecificManagementInterface) { - try { - $return['content'] = $this->objectSpecificManagement->getContent(); - } catch (WebserviceException $e) { - if ($e->getType() == WebserviceException::DID_YOU_MEAN) { - $this->setErrorDidYouMean($e->getStatus(), $e->getMessage(), $e->getWrongValue(), $e->getAvailableValues(), $e->getCode()); - } elseif ($e->getType() == WebserviceException::SIMPLE) { - $this->setError($e->getStatus(), $e->getMessage(), $e->getCode()); - } - } - } - - // for use a general output - if (!$this->hasErrors() && $this->objectSpecificManagement == null) { - if (empty($this->objects)) { - try { - $return['content'] = $this->objOutput->getResourcesList($this->keyPermissions); - } catch (WebserviceException $e) { - if ($e->getType() == WebserviceException::DID_YOU_MEAN) { - $this->setErrorDidYouMean($e->getStatus(), $e->getMessage(), $e->getWrongValue(), $e->getAvailableValues(), $e->getCode()); - } elseif ($e->getType() == WebserviceException::SIMPLE) { - $this->setError($e->getStatus(), $e->getMessage(), $e->getCode()); - } - } - } else { - try { - if (isset($this->urlSegment[1]) && !empty($this->urlSegment[1])) { - $type_of_view = WebserviceOutputBuilder::VIEW_DETAILS; - } else { - $type_of_view = WebserviceOutputBuilder::VIEW_LIST; - } - - if (in_array($this->method, ['PUT', 'POST', 'PATCH'])) { - $type_of_view = WebserviceOutputBuilder::VIEW_DETAILS; - $this->fieldsToDisplay = 'full'; - } - - $return['content'] = $this->objOutput->getContent($this->objects, $this->schemaToDisplay, $this->fieldsToDisplay, $this->depth, $type_of_view); - } catch (WebserviceException $e) { - if ($e->getType() == WebserviceException::DID_YOU_MEAN) { - $this->setErrorDidYouMean($e->getStatus(), $e->getMessage(), $e->getWrongValue(), $e->getAvailableValues(), $e->getCode()); - } elseif ($e->getType() == WebserviceException::SIMPLE) { - $this->setError($e->getStatus(), $e->getMessage(), $e->getCode()); - } - } catch (Exception $e) { - $this->setError(500, $e->getMessage(), $e->getCode()); - } - } - } - - // if the output is not enable, delete the content - // the type content too - if (!$this->_outputEnabled) { - unset($return['type']); - if (isset($return['content'])) { - unset($return['content']); - } - } elseif (isset($return['content'])) { - $return['content_sha1'] = sha1($return['content']); - $this->objOutput->setHeaderParams('Content-Sha1', $return['content_sha1']); - } - - // if errors happens when creating returned xml, - // the usual xml content is replaced by the nice error handler content - if ($this->hasErrors()) { - $this->_outputEnabled = true; - $return['content'] = $this->objOutput->getErrors($this->errors); - } - - if (!isset($return['content']) || strlen($return['content']) <= 0) { - $this->objOutput->setHeaderParams('Content-Type', ''); - } - - $return['headers'] = $this->objOutput->buildHeader(); - restore_error_handler(); - - return $return; - } - - /** - * @return array - */ - public static function getallheaders() - { - $retarr = []; - - if (function_exists('apache_request_headers')) { - $headers = apache_request_headers(); - } else { - $headers = array_merge($_ENV, $_SERVER); - foreach ($headers as $key => $val) { - //we need this header - if (strpos(strtolower($key), 'content-type') !== false) { - continue; - } - if (strtoupper(substr($key, 0, 5)) != 'HTTP_') { - unset($headers[$key]); - } - } - } - //Normalize this array to Cased-Like-This structure. - foreach ($headers as $key => $value) { - $key = preg_replace('/^HTTP_/i', '', $key); - $key = str_replace(' ', '-', ucwords(strtolower(str_replace(['-', '_'], ' ', $key)))); - $retarr[$key] = $value; - } - ksort($retarr); ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/additionalCustomerAddressFields.md b/modules/concepts/hooks/list-hooks/additionalCustomerAddressFields.md index bfa2d950f8..428f457f40 100644 --- a/modules/concepts/hooks/list-hooks/additionalCustomerAddressFields.md +++ b/modules/concepts/hooks/list-hooks/additionalCustomerAddressFields.md @@ -20,87 +20,4 @@ Located in : ```php Hook::exec('additionalCustomerAddressFields', ['fields' => &$format], null, true); - if (is_array($additionalAddressFormFields)) { - foreach ($additionalAddressFormFields as $moduleName => $additionnalFormFields) { - if (!is_array($additionnalFormFields)) { - continue; - } - - foreach ($additionnalFormFields as $formField) { - $formField->moduleName = $moduleName; - $format[$moduleName . '_' . $formField->getName()] = $formField; - } - } - } - - return $this->addConstraints( - $this->addMaxLength( - $format - ) - ); - } - - private function addConstraints(array $format) - { - foreach ($format as $field) { - if (!empty($this->definition[$field->getName()]['validate'])) { - $field->addConstraint( - $this->definition[$field->getName()]['validate'] - ); - } - } - - return $format; - } - - private function addMaxLength(array $format) - { - foreach ($format as $field) { - if (!empty($this->definition[$field->getName()]['size'])) { - $field->setMaxLength( - $this->definition[$field->getName()]['size'] - ); - } - } - - return $format; - } - - private function getFieldLabel($field) - { - // Country:name => Country, Country:iso_code => Country, - // same label regardless of which field is used for mapping. - $field = explode(':', $field)[0]; - - switch ($field) { - case 'alias': - return $this->translator->trans('Alias', [], 'Shop.Forms.Labels'); - case 'firstname': - return $this->translator->trans('First name', [], 'Shop.Forms.Labels'); - case 'lastname': - return $this->translator->trans('Last name', [], 'Shop.Forms.Labels'); - case 'address1': - return $this->translator->trans('Address', [], 'Shop.Forms.Labels'); - case 'address2': - return $this->translator->trans('Address Complement', [], 'Shop.Forms.Labels'); - case 'postcode': - return $this->translator->trans('Zip/Postal Code', [], 'Shop.Forms.Labels'); - case 'city': - return $this->translator->trans('City', [], 'Shop.Forms.Labels'); - case 'Country': - return $this->translator->trans('Country', [], 'Shop.Forms.Labels'); - case 'State': - return $this->translator->trans('State', [], 'Shop.Forms.Labels'); - case 'phone': - return $this->translator->trans('Phone', [], 'Shop.Forms.Labels'); - case 'phone_mobile': - return $this->translator->trans('Mobile phone', [], 'Shop.Forms.Labels'); - case 'company': - return $this->translator->trans('Company', [], 'Shop.Forms.Labels'); - case 'vat_number': - return $this->translator->trans('VAT number', [], 'Shop.Forms.Labels'); - case 'dni': - return $this->translator->trans('Identification number', [], 'Shop.Forms.Labels'); - case 'other': - return $this->translator->trans('Other', [], 'Shop.Forms.Labels'); ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/additionalCustomerFormFields.md b/modules/concepts/hooks/list-hooks/additionalCustomerFormFields.md index e45f3f1b8c..ba773a90e4 100644 --- a/modules/concepts/hooks/list-hooks/additionalCustomerFormFields.md +++ b/modules/concepts/hooks/list-hooks/additionalCustomerFormFields.md @@ -20,32 +20,4 @@ Located in : ```php Hook::exec('additionalCustomerFormFields', ['fields' => &$format], null, true); - - if (is_array($additionalCustomerFormFields)) { - foreach ($additionalCustomerFormFields as $moduleName => $additionnalFormFields) { - if (!is_array($additionnalFormFields)) { - continue; - } - - foreach ($additionnalFormFields as $formField) { - $formField->moduleName = $moduleName; - $format[$moduleName . '_' . $formField->getName()] = $formField; - } - } - } - - // TODO: TVA etc.? - - return $this->addConstraints($format); - } - - private function addConstraints(array $format) - { - $constraints = Customer::$definition['fields']; - - foreach ($format as $field) { - if (!empty($constraints[$field->getName()]['validate'])) { - $field->addConstraint( - $constraints[$field->getName()]['validate'] - ); ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/dashboardData.md b/modules/concepts/hooks/list-hooks/dashboardData.md new file mode 100644 index 0000000000..298878616e --- /dev/null +++ b/modules/concepts/hooks/list-hooks/dashboardData.md @@ -0,0 +1,23 @@ +--- +menuTitle: dashboardData +title: dashboardData +hidden: true +files: + - controllers/admin/AdminDashboardController.php +types: + - backoffice +hookTypes: + - legacy +--- + +# Hook : dashboardData + +Located in : + + - controllers/admin/AdminDashboardController.php + +## Parameters + +```php +Hook::exec('dashboardData', $params, $id_module, true))); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/dashboardZoneOne.md b/modules/concepts/hooks/list-hooks/dashboardZoneOne.md new file mode 100644 index 0000000000..0a0d4131f6 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/dashboardZoneOne.md @@ -0,0 +1,23 @@ +--- +menuTitle: dashboardZoneOne +title: dashboardZoneOne +hidden: true +files: + - controllers/admin/AdminDashboardController.php +types: + - backoffice +hookTypes: + - legacy +--- + +# Hook : dashboardZoneOne + +Located in : + + - controllers/admin/AdminDashboardController.php + +## Parameters + +```php +Hook::exec('dashboardZoneOne', $params), +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/dashboardZoneThree.md b/modules/concepts/hooks/list-hooks/dashboardZoneThree.md new file mode 100644 index 0000000000..56db879a5b --- /dev/null +++ b/modules/concepts/hooks/list-hooks/dashboardZoneThree.md @@ -0,0 +1,23 @@ +--- +menuTitle: dashboardZoneThree +title: dashboardZoneThree +hidden: true +files: + - controllers/admin/AdminDashboardController.php +types: + - backoffice +hookTypes: + - legacy +--- + +# Hook : dashboardZoneThree + +Located in : + + - controllers/admin/AdminDashboardController.php + +## Parameters + +```php +Hook::exec('dashboardZoneThree', $params), +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/dashboardZoneTwo.md b/modules/concepts/hooks/list-hooks/dashboardZoneTwo.md new file mode 100644 index 0000000000..05c3a72b5d --- /dev/null +++ b/modules/concepts/hooks/list-hooks/dashboardZoneTwo.md @@ -0,0 +1,23 @@ +--- +menuTitle: dashboardZoneTwo +title: dashboardZoneTwo +hidden: true +files: + - controllers/admin/AdminDashboardController.php +types: + - backoffice +hookTypes: + - legacy +--- + +# Hook : dashboardZoneTwo + +Located in : + + - controllers/admin/AdminDashboardController.php + +## Parameters + +```php +Hook::exec('dashboardZoneTwo', $params), +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayAdminStatsModules.md b/modules/concepts/hooks/list-hooks/displayAdminStatsModules.md index ee1f9f44ac..ec122ef6bd 100644 --- a/modules/concepts/hooks/list-hooks/displayAdminStatsModules.md +++ b/modules/concepts/hooks/list-hooks/displayAdminStatsModules.md @@ -20,105 +20,4 @@ Located in : ```php Hook::exec('displayAdminStatsModules', [], $module_instance->id); - } - } - - $tpl->assign([ - 'module_name' => $module_name, - 'module_instance' => isset($module_instance) ? $module_instance : null, - 'hook' => isset($hook) ? $hook : null, - ]); - - return $tpl->fetch(); - } - - public function postProcess() - { - $this->context = Context::getContext(); - - $this->processDateRange(); - - if (Tools::getValue('submitSettings')) { - if ($this->access('edit')) { - self::$currentIndex .= '&module=' . Tools::getValue('module'); - Configuration::updateValue('PS_STATS_RENDER', Tools::getValue('PS_STATS_RENDER', Configuration::get('PS_STATS_RENDER'))); - Configuration::updateValue('PS_STATS_GRID_RENDER', Tools::getValue('PS_STATS_GRID_RENDER', Configuration::get('PS_STATS_GRID_RENDER'))); - Configuration::updateValue('PS_STATS_OLD_CONNECT_AUTO_CLEAN', Tools::getValue('PS_STATS_OLD_CONNECT_AUTO_CLEAN', Configuration::get('PS_STATS_OLD_CONNECT_AUTO_CLEAN'))); - } else { - $this->errors[] = $this->trans('You do not have permission to edit this.', [], 'Admin.Notifications.Error'); - } - } - } - - public function processDateRange() - { - if (Tools::isSubmit('submitDatePicker')) { - if ((!Validate::isDate($from = Tools::getValue('datepickerFrom')) || !Validate::isDate($to = Tools::getValue('datepickerTo'))) || (strtotime($from) > strtotime($to))) { - $this->errors[] = $this->trans('The specified date is invalid.', [], 'Admin.Stats.Notification'); - } - } - if (Tools::isSubmit('submitDateDay')) { - $from = date('Y-m-d'); - $to = date('Y-m-d'); - } - if (Tools::isSubmit('submitDateDayPrev')) { - $yesterday = time() - 60 * 60 * 24; - $from = date('Y-m-d', $yesterday); - $to = date('Y-m-d', $yesterday); - } - if (Tools::isSubmit('submitDateMonth')) { - $from = date('Y-m-01'); - $to = date('Y-m-t'); - } - if (Tools::isSubmit('submitDateMonthPrev')) { - $m = (date('m') == 1 ? 12 : date('m') - 1); - $y = ($m == 12 ? date('Y') - 1 : date('Y')); - $from = $y . '-' . $m . '-01'; - $to = $y . '-' . $m . date('-t', mktime(12, 0, 0, $m, 15, $y)); - } - if (Tools::isSubmit('submitDateYear')) { - $from = date('Y-01-01'); - $to = date('Y-12-31'); - } - if (Tools::isSubmit('submitDateYearPrev')) { - $from = (date('Y') - 1) . date('-01-01'); - $to = (date('Y') - 1) . date('-12-31'); - } - if (isset($from, $to) && !count($this->errors)) { - $this->context->employee->stats_date_from = $from; - $this->context->employee->stats_date_to = $to; - $this->context->employee->update(); - if (!$this->isXmlHttpRequest()) { - Tools::redirectAdmin($_SERVER['REQUEST_URI']); - } - } - } - - public function ajaxProcessSetDashboardDateRange() - { - $this->processDateRange(); - - if ($this->isXmlHttpRequest()) { - if (is_array($this->errors) && count($this->errors)) { - die(json_encode( - [ - 'has_errors' => true, - 'errors' => [$this->errors], - 'date_from' => $this->context->employee->stats_date_from, - 'date_to' => $this->context->employee->stats_date_to, ] - )); - } else { - die(json_encode( - [ - 'has_errors' => false, - 'date_from' => $this->context->employee->stats_date_from, - 'date_to' => $this->context->employee->stats_date_to, ] - )); - } - } - } - - protected function getDate() - { - $year = isset($this->context->cookie->stats_year) ? $this->context->cookie->stats_year : date('Y'); ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayCustomization.md b/modules/concepts/hooks/list-hooks/displayCustomization.md index 1b56c7f62b..2138318ee9 100644 --- a/modules/concepts/hooks/list-hooks/displayCustomization.md +++ b/modules/concepts/hooks/list-hooks/displayCustomization.md @@ -20,2275 +20,4 @@ Located in : ```php Hook::exec('displayCustomization', ['customization' => $row], (int) $row['id_module']); - } - $customized_datas[(int) $row['id_product']][(int) $row['id_product_attribute']][(int) $row['id_address_delivery']][(int) $row['id_customization']]['datas'][(int) $row['type']][] = $row; - } - - if (!$result = Db::getInstance()->executeS( - 'SELECT `id_product`, `id_product_attribute`, `id_customization`, `id_address_delivery`, `quantity`, `quantity_refunded`, `quantity_returned` - FROM `' . _DB_PREFIX_ . 'customization` - WHERE `id_cart` = ' . (int) $id_cart . - ((int) $id_customization ? ' AND `id_customization` = ' . (int) $id_customization : '') . - ($only_in_cart ? ' AND `in_cart` = 1' : '') - )) { - return false; - } - - foreach ($result as $row) { - $customized_datas[(int) $row['id_product']][(int) $row['id_product_attribute']][(int) $row['id_address_delivery']][(int) $row['id_customization']]['quantity'] = (int) $row['quantity']; - $customized_datas[(int) $row['id_product']][(int) $row['id_product_attribute']][(int) $row['id_address_delivery']][(int) $row['id_customization']]['quantity_refunded'] = (int) $row['quantity_refunded']; - $customized_datas[(int) $row['id_product']][(int) $row['id_product_attribute']][(int) $row['id_address_delivery']][(int) $row['id_customization']]['quantity_returned'] = (int) $row['quantity_returned']; - $customized_datas[(int) $row['id_product']][(int) $row['id_product_attribute']][(int) $row['id_address_delivery']][(int) $row['id_customization']]['id_customization'] = (int) $row['id_customization']; - } - - return $customized_datas; - } - - /** - * @param array $products - * @param array $customized_datas - */ - public static function addCustomizationPrice(&$products, &$customized_datas) - { - if (!$customized_datas) { - return; - } - - foreach ($products as &$product_update) { - if (!Customization::isFeatureActive()) { - $product_update['customizationQuantityTotal'] = 0; - $product_update['customizationQuantityRefunded'] = 0; - $product_update['customizationQuantityReturned'] = 0; - } else { - $customization_quantity = 0; - $customization_quantity_refunded = 0; - $customization_quantity_returned = 0; - - /* Compatibility */ - $product_id = isset($product_update['id_product']) ? (int) $product_update['id_product'] : (int) $product_update['product_id']; - $product_attribute_id = isset($product_update['id_product_attribute']) ? (int) $product_update['id_product_attribute'] : (int) $product_update['product_attribute_id']; - $id_address_delivery = (int) $product_update['id_address_delivery']; - $product_quantity = isset($product_update['cart_quantity']) ? (int) $product_update['cart_quantity'] : (int) $product_update['product_quantity']; - $price = isset($product_update['price']) ? $product_update['price'] : $product_update['product_price']; - if (isset($product_update['price_wt']) && $product_update['price_wt']) { - $price_wt = $product_update['price_wt']; - } else { - $price_wt = $price * (1 + ((isset($product_update['tax_rate']) ? $product_update['tax_rate'] : $product_update['rate']) * 0.01)); - } - - if (!isset($customized_datas[$product_id][$product_attribute_id][$id_address_delivery])) { - $id_address_delivery = 0; - } - if (isset($customized_datas[$product_id][$product_attribute_id][$id_address_delivery])) { - foreach ($customized_datas[$product_id][$product_attribute_id][$id_address_delivery] as $customization) { - if ((int) $product_update['id_customization'] && $customization['id_customization'] != $product_update['id_customization']) { - continue; - } - $customization_quantity += (int) $customization['quantity']; - $customization_quantity_refunded += (int) $customization['quantity_refunded']; - $customization_quantity_returned += (int) $customization['quantity_returned']; - } - } - - $product_update['customizationQuantityTotal'] = $customization_quantity; - $product_update['customizationQuantityRefunded'] = $customization_quantity_refunded; - $product_update['customizationQuantityReturned'] = $customization_quantity_returned; - - if ($customization_quantity) { - $product_update['total_wt'] = $price_wt * ($product_quantity - $customization_quantity); - $product_update['total_customization_wt'] = $price_wt * $customization_quantity; - $product_update['total'] = $price * ($product_quantity - $customization_quantity); - $product_update['total_customization'] = $price * $customization_quantity; - } - } - } - } - - /** - * Add customization price for a single product - * - * @param array $product Product data - * @param array $customized_datas Customized data - */ - public static function addProductCustomizationPrice(&$product, &$customized_datas) - { - if (!$customized_datas) { - return; - } - - $products = [$product]; - self::addCustomizationPrice($products, $customized_datas); - $product = $products[0]; - } - - /** - * Customization fields label management - * - * @param string $field - * @param string $value - * - * @return array|false - */ - protected function _checkLabelField($field, $value) - { - if (!Validate::isLabel($value)) { - return false; - } - $tmp = explode('_', $field); - if (count($tmp) < 4) { - return false; - } - - return $tmp; - } - - /** - * @return bool - */ - protected function _deleteOldLabels() - { - $max = [ - Product::CUSTOMIZE_FILE => (int) $this->uploadable_files, - Product::CUSTOMIZE_TEXTFIELD => (int) $this->text_fields, - ]; - - /* Get customization field ids */ - if (( - $result = Db::getInstance()->executeS( - 'SELECT `id_customization_field`, `type` - FROM `' . _DB_PREFIX_ . 'customization_field` - WHERE `id_product` = ' . (int) $this->id . ' - ORDER BY `id_customization_field`' - ) - ) === false) { - return false; - } - - if (empty($result)) { - return true; - } - - $customization_fields = [ - Product::CUSTOMIZE_FILE => [], - Product::CUSTOMIZE_TEXTFIELD => [], - ]; - - foreach ($result as $row) { - $customization_fields[(int) $row['type']][] = (int) $row['id_customization_field']; - } - - $extra_file = count($customization_fields[Product::CUSTOMIZE_FILE]) - $max[Product::CUSTOMIZE_FILE]; - $extra_text = count($customization_fields[Product::CUSTOMIZE_TEXTFIELD]) - $max[Product::CUSTOMIZE_TEXTFIELD]; - - /* If too much inside the database, deletion */ - if ($extra_file > 0 && count($customization_fields[Product::CUSTOMIZE_FILE]) - $extra_file >= 0 && - (!Db::getInstance()->execute( - 'DELETE `' . _DB_PREFIX_ . 'customization_field`,`' . _DB_PREFIX_ . 'customization_field_lang` - FROM `' . _DB_PREFIX_ . 'customization_field` JOIN `' . _DB_PREFIX_ . 'customization_field_lang` - WHERE `' . _DB_PREFIX_ . 'customization_field`.`id_product` = ' . (int) $this->id . ' - AND `' . _DB_PREFIX_ . 'customization_field`.`type` = ' . Product::CUSTOMIZE_FILE . ' - AND `' . _DB_PREFIX_ . 'customization_field_lang`.`id_customization_field` = `' . _DB_PREFIX_ . 'customization_field`.`id_customization_field` - AND `' . _DB_PREFIX_ . 'customization_field`.`id_customization_field` >= ' . (int) $customization_fields[Product::CUSTOMIZE_FILE][count($customization_fields[Product::CUSTOMIZE_FILE]) - $extra_file] - ))) { - return false; - } - - if ($extra_text > 0 && count($customization_fields[Product::CUSTOMIZE_TEXTFIELD]) - $extra_text >= 0 && - (!Db::getInstance()->execute( - 'DELETE `' . _DB_PREFIX_ . 'customization_field`,`' . _DB_PREFIX_ . 'customization_field_lang` - FROM `' . _DB_PREFIX_ . 'customization_field` JOIN `' . _DB_PREFIX_ . 'customization_field_lang` - WHERE `' . _DB_PREFIX_ . 'customization_field`.`id_product` = ' . (int) $this->id . ' - AND `' . _DB_PREFIX_ . 'customization_field`.`type` = ' . Product::CUSTOMIZE_TEXTFIELD . ' - AND `' . _DB_PREFIX_ . 'customization_field_lang`.`id_customization_field` = `' . _DB_PREFIX_ . 'customization_field`.`id_customization_field` - AND `' . _DB_PREFIX_ . 'customization_field`.`id_customization_field` >= ' . (int) $customization_fields[Product::CUSTOMIZE_TEXTFIELD][count($customization_fields[Product::CUSTOMIZE_TEXTFIELD]) - $extra_text] - ))) { - return false; - } - - // Refresh cache of feature detachable - Configuration::updateGlobalValue('PS_CUSTOMIZATION_FEATURE_ACTIVE', Customization::isCurrentlyUsed()); - - return true; - } - - /** - * @param array $languages An array of language data - * @param int $type Product::CUSTOMIZE_FILE or Product::CUSTOMIZE_TEXTFIELD - * - * @return bool - */ - protected function _createLabel($languages, $type) - { - // Label insertion - if (!Db::getInstance()->execute(' - INSERT INTO `' . _DB_PREFIX_ . 'customization_field` (`id_product`, `type`, `required`) - VALUES (' . (int) $this->id . ', ' . (int) $type . ', 0)') || - !$id_customization_field = (int) Db::getInstance()->Insert_ID()) { - return false; - } - - // Multilingual label name creation - $values = ''; - - foreach ($languages as $language) { - foreach (Shop::getContextListShopID() as $id_shop) { - $values .= '(' . (int) $id_customization_field . ', ' . (int) $language['id_lang'] . ', ' . (int) $id_shop . ',\'\'), '; - } - } - - $values = rtrim($values, ', '); - if (!Db::getInstance()->execute(' - INSERT INTO `' . _DB_PREFIX_ . 'customization_field_lang` (`id_customization_field`, `id_lang`, `id_shop`, `name`) - VALUES ' . $values)) { - return false; - } - - // Set cache of feature detachable to true - Configuration::updateGlobalValue('PS_CUSTOMIZATION_FEATURE_ACTIVE', '1'); - - return true; - } - - /** - * @param int $uploadable_files - * @param int $text_fields - * - * @return bool - */ - public function createLabels($uploadable_files, $text_fields) - { - $languages = Language::getLanguages(); - if ((int) $uploadable_files > 0) { - for ($i = 0; $i < (int) $uploadable_files; ++$i) { - if (!$this->_createLabel($languages, Product::CUSTOMIZE_FILE)) { - return false; - } - } - } - - if ((int) $text_fields > 0) { - for ($i = 0; $i < (int) $text_fields; ++$i) { - if (!$this->_createLabel($languages, Product::CUSTOMIZE_TEXTFIELD)) { - return false; - } - } - } - - return true; - } - - /** - * @return bool - */ - public function updateLabels() - { - $has_required_fields = 0; - foreach ($_POST as $field => $value) { - /* Label update */ - if (strncmp($field, 'label_', 6) == 0) { - if (!$tmp = $this->_checkLabelField($field, $value)) { - return false; - } - /* Multilingual label name update */ - if (Shop::isFeatureActive()) { - foreach (Shop::getContextListShopID() as $id_shop) { - if (!Db::getInstance()->execute('INSERT INTO `' . _DB_PREFIX_ . 'customization_field_lang` - (`id_customization_field`, `id_lang`, `id_shop`, `name`) VALUES (' . (int) $tmp[2] . ', ' . (int) $tmp[3] . ', ' . (int) $id_shop . ', \'' . pSQL($value) . '\') - ON DUPLICATE KEY UPDATE `name` = \'' . pSQL($value) . '\'')) { - return false; - } - } - } elseif (!Db::getInstance()->execute(' - INSERT INTO `' . _DB_PREFIX_ . 'customization_field_lang` - (`id_customization_field`, `id_lang`, `name`) VALUES (' . (int) $tmp[2] . ', ' . (int) $tmp[3] . ', \'' . pSQL($value) . '\') - ON DUPLICATE KEY UPDATE `name` = \'' . pSQL($value) . '\'')) { - return false; - } - - $is_required = isset($_POST['require_' . (int) $tmp[1] . '_' . (int) $tmp[2]]) ? 1 : 0; - $has_required_fields |= $is_required; - /* Require option update */ - if (!Db::getInstance()->execute( - 'UPDATE `' . _DB_PREFIX_ . 'customization_field` - SET `required` = ' . (int) $is_required . ' - WHERE `id_customization_field` = ' . (int) $tmp[2] - )) { - return false; - } - } - } - - if ($has_required_fields && !ObjectModel::updateMultishopTable('product', ['customizable' => 2], 'a.id_product = ' . (int) $this->id)) { - return false; - } - - if (!$this->_deleteOldLabels()) { - return false; - } - - return true; - } - - /** - * @param int|false $id_lang Language identifier - * @param int|null $id_shop Shop identifier - * - * @return array|bool - */ - public function getCustomizationFields($id_lang = false, $id_shop = null) - { - if (!Customization::isFeatureActive()) { - return false; - } - - if (Shop::isFeatureActive() && !$id_shop) { - $id_shop = (int) Context::getContext()->shop->id; - } - - // Hide the modules fields in the front-office - // When a module adds a customization programmatically, it should set the `is_module` to 1 - $context = Context::getContext(); - $front = isset($context->controller->controller_type) && in_array($context->controller->controller_type, ['front']); - - if (!$result = Db::getInstance()->executeS( - 'SELECT cf.`id_customization_field`, cf.`type`, cf.`required`, cfl.`name`, cfl.`id_lang` - FROM `' . _DB_PREFIX_ . 'customization_field` cf - NATURAL JOIN `' . _DB_PREFIX_ . 'customization_field_lang` cfl - WHERE cf.`id_product` = ' . (int) $this->id . ($id_lang ? ' AND cfl.`id_lang` = ' . (int) $id_lang : '') . - ($id_shop ? ' AND cfl.`id_shop` = ' . (int) $id_shop : '') . - ($front ? ' AND !cf.`is_module`' : '') . ' - AND cf.`is_deleted` = 0 - ORDER BY cf.`id_customization_field`') - ) { - return false; - } - - if ($id_lang) { - return $result; - } - - $customization_fields = []; - foreach ($result as $row) { - $customization_fields[(int) $row['type']][(int) $row['id_customization_field']][(int) $row['id_lang']] = $row; - } - - return $customization_fields; - } - - /** - * check if product has an activated and required customizationFields. - * - * @return bool - * - * @throws PrestaShopDatabaseException - */ - public function hasActivatedRequiredCustomizableFields() - { - if (!Customization::isFeatureActive()) { - return false; - } - - return (bool) Db::getInstance()->executeS( - ' - SELECT 1 - FROM `' . _DB_PREFIX_ . 'customization_field` - WHERE `id_product` = ' . (int) $this->id . ' - AND `required` = 1 - AND `is_deleted` = 0' - ); - } - - /** - * @return array - */ - public function getCustomizationFieldIds() - { - if (!Customization::isFeatureActive()) { - return []; - } - - return Db::getInstance()->executeS(' - SELECT `id_customization_field`, `type`, `required` - FROM `' . _DB_PREFIX_ . 'customization_field` - WHERE `id_product` = ' . (int) $this->id); - } - - /** - * @return array - */ - public function getNonDeletedCustomizationFieldIds() - { - if (!Customization::isFeatureActive()) { - return []; - } - - $results = Db::getInstance()->executeS(' - SELECT `id_customization_field` - FROM `' . _DB_PREFIX_ . 'customization_field` - WHERE `is_deleted` = 0 - AND `id_product` = ' . (int) $this->id - ); - - return array_map(function ($result) { - return (int) $result['id_customization_field']; - }, $results); - } - - /** - * @param int $fieldType |null - * - * @return int - * - * @throws PrestaShopDatabaseException - */ - public function countCustomizationFields(?int $fieldType = null): int - { - $query = ' - SELECT COUNT(`id_customization_field`) as customizations_count - FROM `' . _DB_PREFIX_ . 'customization_field` - WHERE `is_deleted` = 0 - AND `id_product` = ' . (int) $this->id - ; - - if (null !== $fieldType) { - $query .= sprintf(' AND type = %d', $fieldType); - } - - $results = Db::getInstance()->executeS($query); - - if (empty($results)) { - return 0; - } - - return (int) reset($results)['customizations_count']; - } - - /** - * @return array - */ - public function getRequiredCustomizableFields() - { - if (!Customization::isFeatureActive()) { - return []; - } - - return Product::getRequiredCustomizableFieldsStatic($this->id); - } - - /** - * @param int $id Product identifier - * - * @return array - */ - public static function getRequiredCustomizableFieldsStatic($id) - { - if (!$id || !Customization::isFeatureActive()) { - return []; - } - - return Db::getInstance()->executeS( - ' - SELECT `id_customization_field`, `type` - FROM `' . _DB_PREFIX_ . 'customization_field` - WHERE `id_product` = ' . (int) $id . ' - AND `required` = 1 AND `is_deleted` = 0' - ); - } - - /** - * @param Context|null $context - * - * @return bool - */ - public function hasAllRequiredCustomizableFields(Context $context = null) - { - if (!Customization::isFeatureActive()) { - return true; - } - if (!$context) { - $context = Context::getContext(); - } - - $fields = $context->cart->getProductCustomization($this->id, null, true); - $required_fields = $this->getRequiredCustomizableFields(); - - $fields_present = []; - foreach ($fields as $field) { - $fields_present[] = ['id_customization_field' => $field['index'], 'type' => $field['type']]; - } - - foreach ($required_fields as $required_field) { - if (!in_array($required_field, $fields_present)) { - return false; - } - } - - return true; - } - - /** - * Return the list of old temp products. - * - * @return array - */ - public static function getOldTempProducts() - { - $sql = 'SELECT id_product FROM `' . _DB_PREFIX_ . 'product` WHERE state=' . Product::STATE_TEMP . ' AND date_upd < NOW() - INTERVAL 1 DAY'; - - return Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS($sql, true, false); - } - - /** - * Checks if the product is in at least one of the submited categories. - * - * @param int $id_product Product identifier - * @param array $categories array of category arrays - * - * @return bool is the product in at least one category - */ - public static function idIsOnCategoryId($id_product, $categories) - { - if (!((int) $id_product > 0) || !is_array($categories) || empty($categories)) { - return false; - } - $sql = 'SELECT id_product FROM `' . _DB_PREFIX_ . 'category_product` WHERE `id_product` = ' . (int) $id_product . ' AND `id_category` IN ('; - foreach ($categories as $category) { - $sql .= (int) $category['id_category'] . ','; - } - $sql = rtrim($sql, ',') . ')'; - - $hash = md5($sql); - if (!isset(self::$_incat[$hash])) { - if (!Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue($sql)) { - return false; - } - self::$_incat[$hash] = (Db::getInstance(_PS_USE_SQL_SLAVE_)->numRows() > 0 ? true : false); - } - - return self::$_incat[$hash]; - } - - /** - * @return string - */ - public function getNoPackPrice() - { - $context = Context::getContext(); - - return Tools::getContextLocale($context)->formatPrice(Pack::noPackPrice((int) $this->id), $context->currency->iso_code); - } - - /** - * @param int $id_customer Customer identifier - * - * @return bool - */ - public function checkAccess($id_customer) - { - return Product::checkAccessStatic((int) $this->id, (int) $id_customer); - } - - /** - * @param int $id_product Product identifier - * @param int|bool $id_customer Customer identifier - * - * @return bool - */ - public static function checkAccessStatic($id_product, $id_customer) - { - if (!Group::isFeatureActive()) { - return true; - } - - $cache_id = 'Product::checkAccess_' . (int) $id_product . '-' . (int) $id_customer . (!$id_customer ? '-' . (int) Group::getCurrent()->id : ''); - if (!Cache::isStored($cache_id)) { - if (!$id_customer) { - $result = (bool) Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue(' - SELECT ctg.`id_group` - FROM `' . _DB_PREFIX_ . 'category_product` cp - INNER JOIN `' . _DB_PREFIX_ . 'category_group` ctg ON (ctg.`id_category` = cp.`id_category`) - WHERE cp.`id_product` = ' . (int) $id_product . ' AND ctg.`id_group` = ' . (int) Group::getCurrent()->id); - } else { - $result = (bool) Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue(' - SELECT cg.`id_group` - FROM `' . _DB_PREFIX_ . 'category_product` cp - INNER JOIN `' . _DB_PREFIX_ . 'category_group` ctg ON (ctg.`id_category` = cp.`id_category`) - INNER JOIN `' . _DB_PREFIX_ . 'customer_group` cg ON (cg.`id_group` = ctg.`id_group`) - WHERE cp.`id_product` = ' . (int) $id_product . ' AND cg.`id_customer` = ' . (int) $id_customer); - } - - Cache::store($cache_id, $result); - - return $result; - } - - return Cache::retrieve($cache_id); - } - - /** - * Add a stock movement for current product. - * - * Since 1.5, this method only permit to add/remove available quantities of the current product in the current shop - * - * @see StockManager if you want to manage real stock - * @see StockAvailable if you want to manage available quantities for sale on your shop(s) - * @deprecated since 1.5.0 - * - * @param int $quantity - * @param int $id_reason StockMvtReason identifier - useless - * @param int|null $id_product_attribute Attribute identifier - * @param int|null $id_order Order identifier - DEPRECATED - * @param int|null $id_employee Employee identifier - DEPRECATED - * - * @return bool - */ - public function addStockMvt($quantity, $id_reason, $id_product_attribute = null, $id_order = null, $id_employee = null) - { - if (!$this->id || !$id_reason) { - return false; - } - - if ($id_product_attribute == null) { - $id_product_attribute = 0; - } - - $reason = new StockMvtReason((int) $id_reason); - if (!Validate::isLoadedObject($reason)) { - return false; - } - - $quantity = abs((int) $quantity) * $reason->sign; - - return StockAvailable::updateQuantity($this->id, $id_product_attribute, $quantity); - } - - /** - * @deprecated since 1.5.0 - * - * @param int $id_lang Language identifier - * - * @return array - */ - public function getStockMvts($id_lang) - { - Tools::displayAsDeprecated(); - - return Db::getInstance()->executeS(' - SELECT sm.id_stock_mvt, sm.date_add, sm.quantity, sm.id_order, - CONCAT(pl.name, \' \', GROUP_CONCAT(IFNULL(al.name, \'\'), \'\')) product_name, CONCAT(e.lastname, \' \', e.firstname) employee, mrl.name reason - FROM `' . _DB_PREFIX_ . 'stock_mvt` sm - LEFT JOIN `' . _DB_PREFIX_ . 'product_lang` pl ON ( - sm.id_product = pl.id_product - AND pl.id_lang = ' . (int) $id_lang . Shop::addSqlRestrictionOnLang('pl') . ' - ) - LEFT JOIN `' . _DB_PREFIX_ . 'stock_mvt_reason_lang` mrl ON ( - sm.id_stock_mvt_reason = mrl.id_stock_mvt_reason - AND mrl.id_lang = ' . (int) $id_lang . ' - ) - LEFT JOIN `' . _DB_PREFIX_ . 'employee` e ON ( - e.id_employee = sm.id_employee - ) - LEFT JOIN `' . _DB_PREFIX_ . 'product_attribute_combination` pac ON ( - pac.id_product_attribute = sm.id_product_attribute - ) - LEFT JOIN `' . _DB_PREFIX_ . 'attribute_lang` al ON ( - al.id_attribute = pac.id_attribute - AND al.id_lang = ' . (int) $id_lang . ' - ) - WHERE sm.id_product=' . (int) $this->id . ' - GROUP BY sm.id_stock_mvt - '); - } - - /** - * @param int $id_product Product identifier - * - * @return array - */ - public static function getUrlRewriteInformations($id_product) - { - return Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS(' - SELECT pl.`id_lang`, pl.`link_rewrite`, p.`ean13`, cl.`link_rewrite` AS category_rewrite - FROM `' . _DB_PREFIX_ . 'product` p - LEFT JOIN `' . _DB_PREFIX_ . 'product_lang` pl ON (p.`id_product` = pl.`id_product`' . Shop::addSqlRestrictionOnLang('pl') . ') - ' . Shop::addSqlAssociation('product', 'p') . ' - LEFT JOIN `' . _DB_PREFIX_ . 'lang` l ON (pl.`id_lang` = l.`id_lang`) - LEFT JOIN `' . _DB_PREFIX_ . 'category_lang` cl ON (cl.`id_category` = product_shop.`id_category_default` AND cl.`id_lang` = pl.`id_lang`' . Shop::addSqlRestrictionOnLang('cl') . ') - WHERE p.`id_product` = ' . (int) $id_product . ' - AND l.`active` = 1 - '); - } - - /** - * @return int TaxRulesGroup identifier - */ - public function getIdTaxRulesGroup() - { - return $this->id_tax_rules_group; - } - - /** - * @param int $id_product Product identifier - * @param Context|null $context - * - * @return int TaxRulesGroup identifier - */ - public static function getIdTaxRulesGroupByIdProduct($id_product, Context $context = null) - { - if (!$context) { - $context = Context::getContext(); - } - $key = 'product_id_tax_rules_group_' . (int) $id_product . '_' . (int) $context->shop->id; - if (!Cache::isStored($key)) { - $result = Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue(' - SELECT `id_tax_rules_group` - FROM `' . _DB_PREFIX_ . 'product_shop` - WHERE `id_product` = ' . (int) $id_product . ' AND id_shop=' . (int) $context->shop->id); - Cache::store($key, (int) $result); - - return (int) $result; - } - - return Cache::retrieve($key); - } - - /** - * Returns tax rate. - * - * @param Address|null $address - * - * @return float The total taxes rate applied to the product - */ - public function getTaxesRate(Address $address = null) - { - if (!$address || !$address->id_country) { - $address = Address::initialize(); - } - - $tax_manager = TaxManagerFactory::getManager($address, $this->id_tax_rules_group); - $tax_calculator = $tax_manager->getTaxCalculator(); - - return $tax_calculator->getTotalRate(); - } - - /** - * Webservice getter : get product features association. - * - * @return array - */ - public function getWsProductFeatures() - { - $rows = $this->getFeatures(); - foreach ($rows as $keyrow => $row) { - foreach ($row as $keyfeature => $feature) { - if ($keyfeature == 'id_feature') { - $rows[$keyrow]['id'] = $feature; - unset($rows[$keyrow]['id_feature']); - } - unset( - $rows[$keyrow]['id_product'], - $rows[$keyrow]['custom'] - ); - } - asort($rows[$keyrow]); - } - - return $rows; - } - - /** - * Webservice setter : set product features association. - * - * @param array $product_features Feature data - * - * @return bool - */ - public function setWsProductFeatures($product_features) - { - Db::getInstance()->execute( - ' - DELETE FROM `' . _DB_PREFIX_ . 'feature_product` - WHERE `id_product` = ' . (int) $this->id - ); - foreach ($product_features as $product_feature) { - $this->addFeaturesToDB($product_feature['id'], $product_feature['id_feature_value']); - } - - return true; - } - - /** - * Webservice getter : get virtual field default combination. - * - * @return int Default Attribute identifier - */ - public function getWsDefaultCombination() - { - return Product::getDefaultAttribute($this->id); - } - - /** - * Webservice setter : set virtual field default combination. - * - * @param int $id_combination Default Attribute identifier - * - * @return bool - */ - public function setWsDefaultCombination($id_combination) - { - $this->deleteDefaultAttributes(); - - return $this->setDefaultAttribute((int) $id_combination); - } - - /** - * Webservice getter : get category ids of current product for association. - * - * @return array - */ - public function getWsCategories() - { - $result = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS( - 'SELECT cp.`id_category` AS id - FROM `' . _DB_PREFIX_ . 'category_product` cp - LEFT JOIN `' . _DB_PREFIX_ . 'category` c ON (c.id_category = cp.id_category) - ' . Shop::addSqlAssociation('category', 'c') . ' - WHERE cp.`id_product` = ' . (int) $this->id - ); - - return $result; - } - - /** - * Webservice setter : set category ids of current product for association. - * - * @param array $category_ids category ids - * - * @return bool - */ - public function setWsCategories($category_ids) - { - $ids = []; - foreach ($category_ids as $value) { - if ($value instanceof Category) { - $ids[] = (int) $value->id; - } elseif (is_array($value) && array_key_exists('id', $value)) { - $ids[] = (int) $value['id']; - } else { - $ids[] = (int) $value; - } - } - $ids = array_unique($ids); - - $positions = Db::getInstance()->executeS( - 'SELECT `id_category`, `position` - FROM `' . _DB_PREFIX_ . 'category_product` - WHERE `id_product` = ' . (int) $this->id - ); - - $max_positions = Db::getInstance()->executeS( - 'SELECT `id_category`, max(`position`) as maximum - FROM `' . _DB_PREFIX_ . 'category_product` - GROUP BY id_category' - ); - - $positions_lookup = []; - $max_position_lookup = []; - - foreach ($positions as $row) { - $positions_lookup[(int) $row['id_category']] = (int) $row['position']; - } - foreach ($max_positions as $row) { - $max_position_lookup[(int) $row['id_category']] = (int) $row['maximum']; - } - - $return = true; - if ($this->deleteCategories() && !empty($ids)) { - $sql_values = []; - foreach ($ids as $id) { - $pos = 1; - if (array_key_exists((int) $id, $positions_lookup)) { - $pos = (int) $positions_lookup[(int) $id]; - } elseif (array_key_exists((int) $id, $max_position_lookup)) { - $pos = (int) $max_position_lookup[(int) $id] + 1; - } - - $sql_values[] = '(' . (int) $id . ', ' . (int) $this->id . ', ' . $pos . ')'; - } - - $return = Db::getInstance()->execute( - ' - INSERT INTO `' . _DB_PREFIX_ . 'category_product` (`id_category`, `id_product`, `position`) - VALUES ' . implode(',', $sql_values) - ); - } - - Hook::exec('actionProductUpdate', ['id_product' => (int) $this->id]); - - return $return; - } - - /** - * Webservice getter : get product accessories ids of current product for association. - * - * @return array - */ - public function getWsAccessories() - { - $result = Db::getInstance()->executeS( - 'SELECT p.`id_product` AS id - FROM `' . _DB_PREFIX_ . 'accessory` a - LEFT JOIN `' . _DB_PREFIX_ . 'product` p ON (p.id_product = a.id_product_2) - ' . Shop::addSqlAssociation('product', 'p') . ' - WHERE a.`id_product_1` = ' . (int) $this->id - ); - - return $result; - } - - /** - * Webservice setter : set product accessories ids of current product for association. - * - * @param array $accessories product ids - * - * @return bool - */ - public function setWsAccessories($accessories) - { - $this->deleteAccessories(); - foreach ($accessories as $accessory) { - Db::getInstance()->execute('INSERT INTO `' . _DB_PREFIX_ . 'accessory` (`id_product_1`, `id_product_2`) VALUES (' . (int) $this->id . ', ' . (int) $accessory['id'] . ')'); - } - - return true; - } - - /** - * Webservice getter : get combination ids of current product for association. - * - * @return array - */ - public function getWsCombinations() - { - $result = Db::getInstance()->executeS( - 'SELECT pa.`id_product_attribute` as id - FROM `' . _DB_PREFIX_ . 'product_attribute` pa - ' . Shop::addSqlAssociation('product_attribute', 'pa') . ' - WHERE pa.`id_product` = ' . (int) $this->id - ); - - return $result; - } - - /** - * Webservice setter : set combination ids of current product for association. - * - * @param array $combinations combination ids - * - * @return bool - */ - public function setWsCombinations($combinations) - { - // No hook exec - $ids_new = []; - foreach ($combinations as $combination) { - $ids_new[] = (int) $combination['id']; - } - - $ids_orig = []; - $original = Db::getInstance()->executeS( - 'SELECT pa.`id_product_attribute` as id - FROM `' . _DB_PREFIX_ . 'product_attribute` pa - ' . Shop::addSqlAssociation('product_attribute', 'pa') . ' - WHERE pa.`id_product` = ' . (int) $this->id - ); - - if (is_array($original)) { - foreach ($original as $id) { - $ids_orig[] = $id['id']; - } - } - - $all_ids = []; - $all = Db::getInstance()->executeS('SELECT pa.`id_product_attribute` as id FROM `' . _DB_PREFIX_ . 'product_attribute` pa ' . Shop::addSqlAssociation('product_attribute', 'pa')); - if (is_array($all)) { - foreach ($all as $id) { - $all_ids[] = $id['id']; - } - } - - $to_add = []; - foreach ($ids_new as $id) { - if (!in_array($id, $ids_orig)) { - $to_add[] = $id; - } - } - - $to_delete = []; - foreach ($ids_orig as $id) { - if (!in_array($id, $ids_new)) { - $to_delete[] = $id; - } - } - - // Delete rows - if (count($to_delete) > 0) { - foreach ($to_delete as $id) { - $combination = new Combination($id); - $combination->delete(); - } - } - - foreach ($to_add as $id) { - // Update id_product if exists else create - if (in_array($id, $all_ids)) { - Db::getInstance()->execute('UPDATE `' . _DB_PREFIX_ . 'product_attribute` SET id_product = ' . (int) $this->id . ' WHERE id_product_attribute=' . $id); - } else { - Db::getInstance()->execute('INSERT INTO `' . _DB_PREFIX_ . 'product_attribute` (`id_product`) VALUES (' . (int) $this->id . ')'); - } - } - - return true; - } - - /** - * Webservice getter : get product option ids of current product for association. - * - * @return array - */ - public function getWsProductOptionValues() - { - $result = Db::getInstance()->executeS('SELECT DISTINCT pac.id_attribute as id - FROM `' . _DB_PREFIX_ . 'product_attribute` pa - ' . Shop::addSqlAssociation('product_attribute', 'pa') . ' - LEFT JOIN `' . _DB_PREFIX_ . 'product_attribute_combination` pac ON (pac.id_product_attribute = pa.id_product_attribute) - WHERE pa.id_product = ' . (int) $this->id); - - return $result; - } - - /** - * Webservice getter : get virtual field position in category. - * - * @return int|string - */ - public function getWsPositionInCategory() - { - $result = Db::getInstance()->executeS( - 'SELECT `position` - FROM `' . _DB_PREFIX_ . 'category_product` - WHERE `id_category` = ' . (int) $this->id_category_default . ' - AND `id_product` = ' . (int) $this->id); - if (count($result) > 0) { - return $result[0]['position']; - } - - return ''; - } - - /** - * Webservice setter : set virtual field position in category. - * - * @param int $position - * - * @return bool - */ - public function setWsPositionInCategory($position) - { - if ($position <= 0) { - WebserviceRequest::getInstance()->setError( - 500, - $this->trans( - 'You cannot set 0 or a negative position, the minimum is 1.', - [], - 'Admin.Catalog.Notification' - ), - 134 - ); - - return false; - } - - $result = Db::getInstance()->executeS( - 'SELECT `id_product` ' . - 'FROM `' . _DB_PREFIX_ . 'category_product` ' . - 'WHERE `id_category` = ' . (int) $this->id_category_default . ' ' . - 'ORDER BY `position`' - ); - - if ($position > count($result)) { - WebserviceRequest::getInstance()->setError( - 500, - $this->trans( - 'You cannot set a position greater than the total number of products in the category, starting at 1.', - [], - 'Admin.Catalog.Notification' - ), - 135 - ); - - return false; - } - - // result is indexed by recordset order and not position. positions start at index 1 so we need an empty element - array_unshift($result, null); - foreach ($result as &$value) { - $value = $value['id_product']; - } - - $current_position = $this->getWsPositionInCategory(); - - if ($current_position && isset($result[$current_position])) { - $save = $result[$current_position]; - unset($result[$current_position]); - array_splice($result, (int) $position, 0, $save); - } - - foreach ($result as $position => $id_product) { - Db::getInstance()->update('category_product', [ - 'position' => $position, - ], '`id_category` = ' . (int) $this->id_category_default . ' AND `id_product` = ' . (int) $id_product); - } - - return true; - } - - /** - * Webservice getter : get virtual field id_default_image in category. - * - * @return int|string|null - */ - public function getCoverWs() - { - $result = $this->getCover($this->id); - - return $result ? $result['id_image'] : null; - } - - /** - * Webservice setter : set virtual field id_default_image in category. - * - * @param int $id_image - * - * @return bool - */ - public function setCoverWs($id_image) - { - Db::getInstance()->execute('UPDATE `' . _DB_PREFIX_ . 'image_shop` image_shop, `' . _DB_PREFIX_ . 'image` i - SET image_shop.`cover` = NULL - WHERE i.`id_product` = ' . (int) $this->id . ' AND i.id_image = image_shop.id_image - AND image_shop.id_shop=' . (int) Context::getContext()->shop->id); - - Db::getInstance()->execute('UPDATE `' . _DB_PREFIX_ . 'image_shop` - SET `cover` = 1 WHERE `id_image` = ' . (int) $id_image); - - return true; - } - - /** - * Webservice getter : get image ids of current product for association. - * - * @return array - */ - public function getWsImages() - { - return Db::getInstance()->executeS(' - SELECT i.`id_image` as id - FROM `' . _DB_PREFIX_ . 'image` i - ' . Shop::addSqlAssociation('image', 'i') . ' - WHERE i.`id_product` = ' . (int) $this->id . ' - ORDER BY i.`position`'); - } - - /** - * Webservice getter : Get StockAvailable identifier and Attribute identifier - * - * @return array - */ - public function getWsStockAvailables() - { - return Db::getInstance()->executeS('SELECT `id_stock_available` id, `id_product_attribute` - FROM `' . _DB_PREFIX_ . 'stock_available` - WHERE `id_product`=' . (int) $this->id . StockAvailable::addSqlShopRestriction()); - } - - /** - * Webservice getter: Get product attachments ids of current product for association - * - * @return array - */ - public function getWsAttachments(): array - { - return Db::getInstance()->executeS( - 'SELECT a.`id_attachment` AS id ' . - 'FROM `' . _DB_PREFIX_ . 'product_attachment` pa ' . - 'INNER JOIN `' . _DB_PREFIX_ . 'attachment` a ON (pa.id_attachment = a.id_attachment) ' . - Shop::addSqlAssociation('attachment', 'a') . ' ' . - 'WHERE pa.`id_product` = ' . (int) $this->id - ); - } - - /** - * Webservice setter: set product attachments ids of current product for association - * - * @param array $attachments ids - */ - public function setWsAttachments(array $attachments): bool - { - $this->deleteAttachments(true); - foreach ($attachments as $attachment) { - Db::getInstance()->execute('INSERT INTO `' . _DB_PREFIX_ . 'product_attachment` - (`id_product`, `id_attachment`) VALUES (' . (int) $this->id . ', ' . (int) $attachment['id'] . ')'); - } - Product::updateCacheAttachment((int) $this->id); - - return true; - } - - public function getWsTags() - { - return Db::getInstance()->executeS(' - SELECT `id_tag` as id - FROM `' . _DB_PREFIX_ . 'product_tag` - WHERE `id_product` = ' . (int) $this->id); - } - - /** - * Webservice setter : set tag ids of current product for association. - * - * @param array $tag_ids Tag identifiers - * - * @return bool - */ - public function setWsTags($tag_ids) - { - $ids = []; - foreach ($tag_ids as $value) { - $ids[] = $value['id']; - } - if ($this->deleteWsTags()) { - if ($ids) { - $sql_values = []; - $ids = array_map('intval', $ids); - foreach ($ids as $position => $id) { - $id_lang = Db::getInstance()->getValue('SELECT `id_lang` FROM `' . _DB_PREFIX_ . 'tag` WHERE `id_tag`=' . (int) $id); - $sql_values[] = '(' . (int) $this->id . ', ' . (int) $id . ', ' . (int) $id_lang . ')'; - } - $result = Db::getInstance()->execute( - ' - INSERT INTO `' . _DB_PREFIX_ . 'product_tag` (`id_product`, `id_tag`, `id_lang`) - VALUES ' . implode(',', $sql_values) - ); - - return $result; - } - } - - return true; - } - - /** - * Delete products tags entries without delete tags for webservice usage. - * - * @return bool Deletion result - */ - public function deleteWsTags() - { - return Db::getInstance()->delete('product_tag', 'id_product = ' . (int) $this->id); - } - - /** - * @return string - */ - public function getWsManufacturerName() - { - return Manufacturer::getNameById((int) $this->id_manufacturer); - } - - /** - * @return bool - */ - public static function resetEcoTax() - { - return ObjectModel::updateMultishopTable('product', [ - 'ecotax' => 0, - ]); - } - - /** - * Set Group reduction if needed. - */ - public function setGroupReduction() - { - return GroupReduction::setProductReduction($this->id); - } - - /** - * Checks if reference exists. - * - * @param string $reference Product reference - * - * @return bool - */ - public function existsRefInDatabase($reference) - { - $row = Db::getInstance()->getRow(' - SELECT `reference` - FROM `' . _DB_PREFIX_ . 'product` p - WHERE p.reference = "' . pSQL($reference) . '"', false); - - return isset($row['reference']); - } - - /** - * Get all product attributes ids. - * - * @since 1.5.0 - * - * @param int $id_product Product identifier - * @param bool $shop_only - * - * @return array Attribute identifiers list - */ - public static function getProductAttributesIds($id_product, $shop_only = false) - { - return Db::getInstance()->executeS(' - SELECT pa.id_product_attribute - FROM `' . _DB_PREFIX_ . 'product_attribute` pa' . - ($shop_only ? Shop::addSqlAssociation('product_attribute', 'pa') : '') . ' - WHERE pa.`id_product` = ' . (int) $id_product); - } - - /** - * Get label by lang and value by lang too. - * - * @param int $id_product Product identifier - * @param int $id_product_attribute Attribute identifier - * - * @return array - */ - public static function getAttributesParams($id_product, $id_product_attribute) - { - if ($id_product_attribute == 0) { - return []; - } - $id_lang = (int) Context::getContext()->language->id; - $cache_id = 'Product::getAttributesParams_' . (int) $id_product . '-' . (int) $id_product_attribute . '-' . (int) $id_lang; - - if (!Cache::isStored($cache_id)) { - $result = Db::getInstance()->executeS(' - SELECT a.`id_attribute`, a.`id_attribute_group`, al.`name`, agl.`name` as `group`, pa.`reference`, pa.`ean13`, pa.`isbn`, pa.`upc`, pa.`mpn` - FROM `' . _DB_PREFIX_ . 'attribute` a - LEFT JOIN `' . _DB_PREFIX_ . 'attribute_lang` al - ON (al.`id_attribute` = a.`id_attribute` AND al.`id_lang` = ' . (int) $id_lang . ') - LEFT JOIN `' . _DB_PREFIX_ . 'product_attribute_combination` pac - ON (pac.`id_attribute` = a.`id_attribute`) - LEFT JOIN `' . _DB_PREFIX_ . 'product_attribute` pa - ON (pa.`id_product_attribute` = pac.`id_product_attribute`) - ' . Shop::addSqlAssociation('product_attribute', 'pa') . ' - LEFT JOIN `' . _DB_PREFIX_ . 'attribute_group_lang` agl - ON (a.`id_attribute_group` = agl.`id_attribute_group` AND agl.`id_lang` = ' . (int) $id_lang . ') - WHERE pa.`id_product` = ' . (int) $id_product . ' - AND pac.`id_product_attribute` = ' . (int) $id_product_attribute . ' - AND agl.`id_lang` = ' . (int) $id_lang); - Cache::store($cache_id, $result); - } else { - $result = Cache::retrieve($cache_id); - } - - return $result; - } - - /** - * @param int $id_product Product identifier - * - * @return array - */ - public static function getAttributesInformationsByProduct($id_product) - { - $result = Db::getInstance()->executeS(' - SELECT DISTINCT a.`id_attribute`, a.`id_attribute_group`, al.`name` as `attribute`, agl.`name` as `group`,pa.`reference`, pa.`ean13`, pa.`isbn`, pa.`upc`, pa.`mpn` - FROM `' . _DB_PREFIX_ . 'attribute` a - LEFT JOIN `' . _DB_PREFIX_ . 'attribute_lang` al - ON (a.`id_attribute` = al.`id_attribute` AND al.`id_lang` = ' . (int) Context::getContext()->language->id . ') - LEFT JOIN `' . _DB_PREFIX_ . 'attribute_group_lang` agl - ON (a.`id_attribute_group` = agl.`id_attribute_group` AND agl.`id_lang` = ' . (int) Context::getContext()->language->id . ') - LEFT JOIN `' . _DB_PREFIX_ . 'product_attribute_combination` pac - ON (a.`id_attribute` = pac.`id_attribute`) - LEFT JOIN `' . _DB_PREFIX_ . 'product_attribute` pa - ON (pac.`id_product_attribute` = pa.`id_product_attribute`) - ' . Shop::addSqlAssociation('product_attribute', 'pa') . ' - ' . Shop::addSqlAssociation('attribute', 'pac') . ' - WHERE pa.`id_product` = ' . (int) $id_product); - - return $result; - } - - /** - * @return bool - */ - public function hasCombinations() - { - if (null === $this->id || 0 >= $this->id) { - return false; - } - $attributes = self::getAttributesInformationsByProduct($this->id); - - return !empty($attributes); - } - - /** - * Get an id_product_attribute by an id_product and one or more - * id_attribute. - * - * e.g: id_product 8 with id_attribute 4 (size medium) and - * id_attribute 5 (color blue) returns id_product_attribute 9 which - * is the dress size medium and color blue. - * - * @param int $idProduct Product identifier - * @param int|int[] $idAttributes Attribute identifier(s) - * @param bool $findBest - * - * @return int - * - * @throws PrestaShopException - */ - public static function getIdProductAttributeByIdAttributes($idProduct, $idAttributes, $findBest = false) - { - $idProduct = (int) $idProduct; - - if (!is_array($idAttributes) && is_numeric($idAttributes)) { - $idAttributes = [(int) $idAttributes]; - } - - if (!is_array($idAttributes) || empty($idAttributes)) { - throw new PrestaShopException(sprintf('Invalid parameter $idAttributes with value: "%s"', print_r($idAttributes, true))); - } - - $idAttributesImploded = implode(',', array_map('intval', $idAttributes)); - $idProductAttribute = Db::getInstance()->getValue( - 'SELECT pac.`id_product_attribute` - FROM `' . _DB_PREFIX_ . 'product_attribute_combination` pac - INNER JOIN `' . _DB_PREFIX_ . 'product_attribute` pa ON pa.id_product_attribute = pac.id_product_attribute - WHERE pa.id_product = ' . $idProduct . ' - AND pac.id_attribute IN (' . $idAttributesImploded . ') - GROUP BY pac.`id_product_attribute` - HAVING COUNT(pa.id_product) = ' . count($idAttributes) - ); - - if ($idProductAttribute === false && $findBest) { - //find the best possible combination - //first we order $idAttributes by the group position - $orderred = []; - $result = Db::getInstance()->executeS( - 'SELECT a.`id_attribute` - FROM `' . _DB_PREFIX_ . 'attribute` a - INNER JOIN `' . _DB_PREFIX_ . 'attribute_group` g ON a.`id_attribute_group` = g.`id_attribute_group` - WHERE a.`id_attribute` IN (' . $idAttributesImploded . ') - ORDER BY g.`position` ASC' - ); - - foreach ($result as $row) { - $orderred[] = $row['id_attribute']; - } - - while ($idProductAttribute === false && count($orderred) > 1) { - array_pop($orderred); - $idProductAttribute = Db::getInstance()->getValue( - 'SELECT pac.`id_product_attribute` - FROM `' . _DB_PREFIX_ . 'product_attribute_combination` pac - INNER JOIN `' . _DB_PREFIX_ . 'product_attribute` pa ON pa.id_product_attribute = pac.id_product_attribute - WHERE pa.id_product = ' . (int) $idProduct . ' - AND pac.id_attribute IN (' . implode(',', array_map('intval', $orderred)) . ') - GROUP BY pac.id_product_attribute - HAVING COUNT(pa.id_product) = ' . count($orderred) - ); - } - } - - if (empty($idProductAttribute)) { - throw new PrestaShopObjectNotFoundException('Cannot retrieve the id_product_attribute'); - } - - return (int) $idProductAttribute; - } - - /** - * Get the combination url anchor of the product. - * - * @param int $id_product_attribute Attribute identifier - * @param bool $with_id - * - * @return string - */ - public function getAnchor($id_product_attribute, $with_id = false) - { - $attributes = Product::getAttributesParams($this->id, $id_product_attribute); - $anchor = '#'; - $sep = Configuration::get('PS_ATTRIBUTE_ANCHOR_SEPARATOR'); - foreach ($attributes as &$a) { - foreach ($a as &$b) { - $b = str_replace($sep, '_', Tools::link_rewrite((string) $b)); - } - $anchor .= '/' . ($with_id && isset($a['id_attribute']) && $a['id_attribute'] ? (int) $a['id_attribute'] . $sep : '') . $a['group'] . $sep . $a['name']; - } - - return $anchor; - } - - /** - * Gets the name of a given product, in the given lang. - * - * @since 1.5.0 - * - * @param int $id_product Product identifier - * @param int|null $id_product_attribute Attribute identifier - * @param int|null $id_lang Language identifier - * - * @return string - */ - public static function getProductName($id_product, $id_product_attribute = null, $id_lang = null) - { - // use the lang in the context if $id_lang is not defined - if (!$id_lang) { - $id_lang = (int) Context::getContext()->language->id; - } - - // creates the query object - $query = new DbQuery(); - - // selects different names, if it is a combination - if ($id_product_attribute) { - $query->select('IFNULL(CONCAT(pl.name, \' : \', GROUP_CONCAT(DISTINCT agl.`name`, \' - \', al.name SEPARATOR \', \')),pl.name) as name'); - } else { - $query->select('DISTINCT pl.name as name'); - } - - // adds joins & where clauses for combinations - if ($id_product_attribute) { - $query->from('product_attribute', 'pa'); - $query->join(Shop::addSqlAssociation('product_attribute', 'pa')); - $query->innerJoin('product_lang', 'pl', 'pl.id_product = pa.id_product AND pl.id_lang = ' . (int) $id_lang . Shop::addSqlRestrictionOnLang('pl')); - $query->leftJoin('product_attribute_combination', 'pac', 'pac.id_product_attribute = pa.id_product_attribute'); - $query->leftJoin('attribute', 'atr', 'atr.id_attribute = pac.id_attribute'); - $query->leftJoin('attribute_lang', 'al', 'al.id_attribute = atr.id_attribute AND al.id_lang = ' . (int) $id_lang); - $query->leftJoin('attribute_group_lang', 'agl', 'agl.id_attribute_group = atr.id_attribute_group AND agl.id_lang = ' . (int) $id_lang); - $query->where('pa.id_product = ' . (int) $id_product . ' AND pa.id_product_attribute = ' . (int) $id_product_attribute); - } else { - // or just adds a 'where' clause for a simple product - - $query->from('product_lang', 'pl'); - $query->where('pl.id_product = ' . (int) $id_product); - $query->where('pl.id_lang = ' . (int) $id_lang . Shop::addSqlRestrictionOnLang('pl')); - } - - return Db::getInstance()->getValue($query); - } - - /** - * @param bool $autodate - * @param bool $null_values - * - * @return bool - */ - public function addWs($autodate = true, $null_values = false) - { - $success = $this->add($autodate, $null_values); - if ($success && Configuration::get('PS_SEARCH_INDEXATION')) { - Search::indexation(false, $this->id); - } - - return $success; - } - - /** - * @param bool $null_values - * - * @return bool - */ - public function updateWs($null_values = false) - { - if (null === $this->price) { - $this->price = Product::getPriceStatic((int) $this->id, false, null, 6, null, false, true, 1, false, null, null, null, $this->specificPrice); - } - - if (null === $this->unit_price_ratio) { - $this->unit_price_ratio = ($this->unit_price != 0 ? $this->price / $this->unit_price : 0); - } - - $success = parent::update($null_values); - if ($success && Configuration::get('PS_SEARCH_INDEXATION')) { - Search::indexation(false, $this->id); - } - Hook::exec('actionProductUpdate', ['id_product' => (int) $this->id]); - - return $success; - } - - /** - * For a given product, returns its real quantity. - * - * @since 1.5.0 - * - * @param int $id_product Product identifier - * @param int $id_product_attribute Attribute identifier - * @param int $id_warehouse Warehouse identifier - * @param int|null $id_shop Shop identifier - * - * @return int real_quantity - */ - public static function getRealQuantity($id_product, $id_product_attribute = 0, $id_warehouse = 0, $id_shop = null) - { - static $manager = null; - - if (Configuration::get('PS_ADVANCED_STOCK_MANAGEMENT') && null === $manager) { - $manager = StockManagerFactory::getManager(); - } - - if (Configuration::get('PS_ADVANCED_STOCK_MANAGEMENT') && Product::usesAdvancedStockManagement($id_product) && - StockAvailable::dependsOnStock($id_product, $id_shop)) { - return $manager->getProductRealQuantities($id_product, $id_product_attribute, $id_warehouse, true); - } else { - return StockAvailable::getQuantityAvailableByProduct($id_product, $id_product_attribute, $id_shop); - } - } - - /** - * For a given product, tells if it uses the advanced stock management. - * - * @since 1.5.0 - * - * @param int $id_product Product identifier - * - * @return bool - */ - public static function usesAdvancedStockManagement($id_product) - { - $query = new DbQuery(); - $query->select('product_shop.advanced_stock_management'); - $query->from('product', 'p'); - $query->join(Shop::addSqlAssociation('product', 'p')); - $query->where('p.id_product = ' . (int) $id_product); - - return (bool) Db::getInstance()->getValue($query); - } - - /** - * This method allows to flush price cache. - * - * @since 1.5.0 - */ - public static function flushPriceCache() - { - self::$_prices = []; - self::$_pricesLevel2 = []; - } - - /** - * Get list of parent categories. - * - * @since 1.5.0 - * - * @param int|null $id_lang Language identifier - * - * @return array - */ - public function getParentCategories($id_lang = null) - { - if (!$id_lang) { - $id_lang = Context::getContext()->language->id; - } - - $interval = Category::getInterval($this->id_category_default); - $sql = new DbQuery(); - $sql->from('category', 'c'); - $sql->leftJoin('category_lang', 'cl', 'c.id_category = cl.id_category AND id_lang = ' . (int) $id_lang . Shop::addSqlRestrictionOnLang('cl')); - $sql->where('c.nleft <= ' . (int) $interval['nleft'] . ' AND c.nright >= ' . (int) $interval['nright']); - $sql->orderBy('c.nleft'); - - return Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS($sql); - } - - /** - * Fill the variables used for stock management. - */ - public function loadStockData() - { - if (false === Validate::isLoadedObject($this)) { - return; - } - - // Default product quantity is available quantity to sell in current shop - $this->quantity = StockAvailable::getQuantityAvailableByProduct($this->id, 0); - $this->out_of_stock = StockAvailable::outOfStock($this->id); - $this->depends_on_stock = StockAvailable::dependsOnStock($this->id); - $this->location = StockAvailable::getLocation($this->id) ?: ''; - - if (Context::getContext()->shop->getContext() == Shop::CONTEXT_GROUP && Context::getContext()->shop->getContextShopGroup()->share_stock == 1) { - $this->advanced_stock_management = $this->useAdvancedStockManagement(); - } - } - - /** - * Get Advanced Stock Management status for this product - * - * @return bool 0 for disabled, 1 for enabled - */ - public function useAdvancedStockManagement() - { - return (bool) Db::getInstance()->getValue( - 'SELECT `advanced_stock_management` - FROM ' . _DB_PREFIX_ . 'product_shop - WHERE id_product=' . (int) $this->id . Shop::addSqlRestriction() - ); - } - - /** - * Set Advanced Stock Management status for this product - * - * @param bool $value false for disabled, true for enabled - */ - public function setAdvancedStockManagement($value) - { - $this->advanced_stock_management = (bool) $value; - if (Context::getContext()->shop->getContext() == Shop::CONTEXT_GROUP - && Context::getContext()->shop->getContextShopGroup()->share_stock == 1) { - Db::getInstance()->execute( - ' - UPDATE `' . _DB_PREFIX_ . 'product_shop` - SET `advanced_stock_management`=' . (int) $value . ' - WHERE id_product=' . (int) $this->id . Shop::addSqlRestriction() - ); - } else { - $this->setFieldsToUpdate(['advanced_stock_management' => true]); - $this->save(); - } - } - - /** - * Get the default category according to the shop. - * - * @return array{id_category_default: int}|int - */ - public function getDefaultCategory() - { - $default_category = Db::getInstance()->getValue( - 'SELECT product_shop.`id_category_default` - FROM `' . _DB_PREFIX_ . 'product` p - ' . Shop::addSqlAssociation('product', 'p') . ' - WHERE p.`id_product` = ' . (int) $this->id - ); - - if (!$default_category) { - return ['id_category_default' => Context::getContext()->shop->id_category]; - } else { - return (int) $default_category; - } - } - - /** - * Get Shop identifiers - * - * @param int $id_product Product identifier - * - * @return array - */ - public static function getShopsByProduct($id_product) - { - return Db::getInstance()->executeS(' - SELECT `id_shop` - FROM `' . _DB_PREFIX_ . 'product_shop` - WHERE `id_product` = ' . (int) $id_product); - } - - /** - * Remove all downloadable files for product and its attributes. - * - * @return bool - */ - public function deleteDownload() - { - $result = true; - $collection_download = new PrestaShopCollection('ProductDownload'); - $collection_download->where('id_product', '=', $this->id); - /** @var ProductDownload $product_download */ - foreach ($collection_download as $product_download) { - $result &= $product_download->delete($product_download->checkFile()); - } - - return $result; - } - - /** - * Get the product type (simple, virtual, pack). - * - * @since in 1.5.0 - * - * @return int - */ - public function getType() - { - if (!$this->id) { - return Product::PTYPE_SIMPLE; - } - if (Pack::isPack($this->id)) { - return Product::PTYPE_PACK; - } - if ($this->is_virtual) { - return Product::PTYPE_VIRTUAL; - } - - return Product::PTYPE_SIMPLE; - } - - /** - * @return bool - */ - public function hasAttributesInOtherShops() - { - return (bool) Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue( - ' - SELECT pa.id_product_attribute - FROM `' . _DB_PREFIX_ . 'product_attribute` pa - LEFT JOIN `' . _DB_PREFIX_ . 'product_attribute_shop` pas ON (pa.`id_product_attribute` = pas.`id_product_attribute`) - WHERE pa.`id_product` = ' . (int) $this->id - ); - } - - /** - * @return string TaxRulesGroup identifier most used - */ - public static function getIdTaxRulesGroupMostUsed() - { - return Db::getInstance()->getValue( - ' - SELECT id_tax_rules_group - FROM ( - SELECT COUNT(*) n, product_shop.id_tax_rules_group - FROM ' . _DB_PREFIX_ . 'product p - ' . Shop::addSqlAssociation('product', 'p') . ' - JOIN ' . _DB_PREFIX_ . 'tax_rules_group trg ON (product_shop.id_tax_rules_group = trg.id_tax_rules_group) - WHERE trg.active = 1 AND trg.deleted = 0 - GROUP BY product_shop.id_tax_rules_group - ORDER BY n DESC - LIMIT 1 - ) most_used' - ); - } - - /** - * For a given ean13 reference, returns the corresponding id. - * - * @param string $ean13 - * - * @return int|string Product identifier - */ - public static function getIdByEan13($ean13) - { - if (empty($ean13)) { - return 0; - } - - if (!Validate::isEan13($ean13)) { - return 0; - } - - $query = new DbQuery(); - $query->select('p.id_product'); - $query->from('product', 'p'); - $query->where('p.ean13 = \'' . pSQL($ean13) . '\''); - - return Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue($query); - } - - /** - * For a given reference, returns the corresponding id. - * - * @param string $reference - * - * @return int|string Product identifier - */ - public static function getIdByReference($reference) - { - if (empty($reference)) { - return 0; - } - - if (!Validate::isReference($reference)) { - return 0; - } - - $query = new DbQuery(); - $query->select('p.id_product'); - $query->from('product', 'p'); - $query->where('p.reference = \'' . pSQL($reference) . '\''); - - return Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue($query); - } - - /** - * @return string simple, pack, virtual - */ - public function getWsType() - { - $type_information = [ - Product::PTYPE_SIMPLE => 'simple', - Product::PTYPE_PACK => 'pack', - Product::PTYPE_VIRTUAL => 'virtual', - ]; - - return $type_information[$this->getType()]; - } - - /** - * Create the link rewrite if not exists or invalid on product creation - * - * @return bool - */ - public function modifierWsLinkRewrite() - { - if (empty($this->link_rewrite)) { - $this->link_rewrite = []; - } - - foreach ($this->name as $id_lang => $name) { - if (empty($this->link_rewrite[$id_lang])) { - $this->link_rewrite[$id_lang] = Tools::link_rewrite($name); - } elseif (!Validate::isLinkRewrite($this->link_rewrite[$id_lang])) { - $this->link_rewrite[$id_lang] = Tools::link_rewrite($this->link_rewrite[$id_lang]); - } - } - - return true; - } - - /** - * @return array - */ - public function getWsProductBundle() - { - return Db::getInstance()->executeS('SELECT id_product_item as id, id_product_attribute_item as id_product_attribute, quantity FROM ' . _DB_PREFIX_ . 'pack WHERE id_product_pack = ' . (int) $this->id); - } - - /** - * @param string $type_str simple, pack, virtual - * - * @return bool - */ - public function setWsType($type_str) - { - $reverse_type_information = [ - 'simple' => Product::PTYPE_SIMPLE, - 'pack' => Product::PTYPE_PACK, - 'virtual' => Product::PTYPE_VIRTUAL, - ]; - - if (!isset($reverse_type_information[$type_str])) { - return false; - } - - $type = $reverse_type_information[$type_str]; - - if (Pack::isPack((int) $this->id) && $type != Product::PTYPE_PACK) { - Pack::deleteItems($this->id); - } - - $this->cache_is_pack = ($type == Product::PTYPE_PACK); - $this->is_virtual = ($type == Product::PTYPE_VIRTUAL); - $this->product_type = $this->getDynamicProductType(); - - return true; - } - - /** - * @param array $items - * - * @return bool - */ - public function setWsProductBundle($items) - { - if ($this->is_virtual) { - return false; - } - - Pack::deleteItems($this->id); - - foreach ($items as $item) { - // Combination of a product is optional, and can be omitted. - if (!isset($item['product_attribute_id'])) { - $item['product_attribute_id'] = 0; - } - if ((int) $item['id'] > 0) { - Pack::addItem($this->id, (int) $item['id'], (int) $item['quantity'], (int) $item['product_attribute_id']); - } - } - - return true; - } - - /** - * @param int $id_attribute Attribute identifier - * @param int $id_shop Shop identifier - * - * @return string Attribute identifier - */ - public function isColorUnavailable($id_attribute, $id_shop) - { - return Db::getInstance()->getValue( - ' - SELECT sa.id_product_attribute - FROM ' . _DB_PREFIX_ . 'stock_available sa - WHERE id_product=' . (int) $this->id . ' AND quantity <= 0 - ' . StockAvailable::addSqlShopRestriction(null, $id_shop, 'sa') . ' - AND EXISTS ( - SELECT 1 - FROM ' . _DB_PREFIX_ . 'product_attribute pa - JOIN ' . _DB_PREFIX_ . 'product_attribute_shop product_attribute_shop - ON (product_attribute_shop.id_product_attribute = pa.id_product_attribute AND product_attribute_shop.id_shop=' . (int) $id_shop . ') - JOIN ' . _DB_PREFIX_ . 'product_attribute_combination pac - ON (pac.id_product_attribute AND product_attribute_shop.id_product_attribute) - WHERE sa.id_product_attribute = pa.id_product_attribute AND pa.id_product=' . (int) $this->id . ' AND pac.id_attribute=' . (int) $id_attribute . ' - )' - ); - } - - /** - * @param int $id_product Product identifier - * @param bool $full - * - * @return string - */ - public static function getColorsListCacheId($id_product, $full = true) - { - $cache_id = 'productlist_colors'; - if ($id_product) { - $cache_id .= '|' . (int) $id_product; - } - - if ($full) { - $cache_id .= '|' . (int) Context::getContext()->shop->id . '|' . (int) Context::getContext()->cookie->id_lang; - } - - return $cache_id; - } - - /** - * @param int $id_product Product identifier - * @param int $pack_stock_type value of Pack stock type, see constants defined in Pack class - * - * @return bool - */ - public static function setPackStockType($id_product, $pack_stock_type) - { - return Db::getInstance()->execute('UPDATE ' . _DB_PREFIX_ . 'product p - ' . Shop::addSqlAssociation('product', 'p') . ' SET product_shop.pack_stock_type = ' . (int) $pack_stock_type . ' WHERE p.`id_product` = ' . (int) $id_product); - } - - /** - * Gets a list of IDs from a list of IDs/Refs. The result will avoid duplicates, and checks if given IDs/Refs exists in DB. - * Useful when a product list should be checked before a bulk operation on them (Only 1 query => performances). - * - * @param int|string|int[]|string[] $ids_or_refs Product identifier(s) or reference(s) - * - * @return array|false Product identifiers, without duplicate and only existing ones - */ - public static function getExistingIdsFromIdsOrRefs($ids_or_refs) - { - // separate IDs and Refs - $ids = []; - $refs = []; - $whereStatements = []; - foreach ((is_array($ids_or_refs) ? $ids_or_refs : [$ids_or_refs]) as $id_or_ref) { - if (is_numeric($id_or_ref)) { - $ids[] = (int) $id_or_ref; - } elseif (is_string($id_or_ref)) { - $refs[] = '\'' . pSQL($id_or_ref) . '\''; - } - } - - // construct WHERE statement with OR combination - if (count($ids) > 0) { - $whereStatements[] = ' p.id_product IN (' . implode(',', $ids) . ') '; - } - if (count($refs) > 0) { - $whereStatements[] = ' p.reference IN (' . implode(',', $refs) . ') '; - } - if (!count($whereStatements)) { - return false; - } - - $results = Db::getInstance()->executeS(' - SELECT DISTINCT `id_product` - FROM `' . _DB_PREFIX_ . 'product` p - WHERE ' . implode(' OR ', $whereStatements)); - - // simplify array since there is 1 useless dimension. - // FIXME : find a better way to avoid this, directly in SQL? - foreach ($results as $k => $v) { - $results[$k] = (int) $v['id_product']; - } - - return $results; - } - - /** - * Get object of redirect_type. - * - * @return string|false category, product, false if unknown redirect_type - */ - public function getRedirectType() - { - switch ($this->redirect_type) { - case RedirectType::TYPE_CATEGORY_PERMANENT: - case RedirectType::TYPE_CATEGORY_TEMPORARY: - return 'category'; - - case RedirectType::TYPE_PRODUCT_PERMANENT: - case RedirectType::TYPE_PRODUCT_TEMPORARY: - return 'product'; - } - - return false; - } - - /** - * Return an array of customization fields IDs. - * - * @return array|false - */ - public function getUsedCustomizationFieldsIds() - { - return Db::getInstance()->executeS( - 'SELECT cd.`index` FROM `' . _DB_PREFIX_ . 'customized_data` cd - LEFT JOIN `' . _DB_PREFIX_ . 'customization_field` cf ON cf.`id_customization_field` = cd.`index` - WHERE cf.`id_product` = ' . (int) $this->id - ); - } - - /** - * Remove unused customization for the product. - * - * @param array $customizationIds - Array of customization fields IDs - * - * @return bool - * - * @throws PrestaShopDatabaseException - */ - public function deleteUnusedCustomizationFields($customizationIds) - { - $return = true; - if (is_array($customizationIds) && !empty($customizationIds)) { - $toDeleteIds = implode(',', $customizationIds); - $return &= Db::getInstance()->execute('DELETE FROM `' . _DB_PREFIX_ . 'customization_field` WHERE - `id_product` = ' . (int) $this->id . ' AND `id_customization_field` IN (' . $toDeleteIds . ')'); - - $return &= Db::getInstance()->execute('DELETE FROM `' . _DB_PREFIX_ . 'customization_field_lang` WHERE - `id_customization_field` IN (' . $toDeleteIds . ')'); - } - - if (!$return) { - throw new PrestaShopDatabaseException('An error occurred while deletion the customization fields'); - } - - return $return; - } - - /** - * Update the customization fields to be deleted if not used. - * - * @param array $customizationIds - Array of excluded customization fields IDs - * - * @return bool - * - * @throws PrestaShopDatabaseException - */ - public function softDeleteCustomizationFields($customizationIds) - { - $updateQuery = 'UPDATE `' . _DB_PREFIX_ . 'customization_field` cf - SET cf.`is_deleted` = 1 - WHERE - cf.`id_product` = ' . (int) $this->id . ' - AND cf.`is_deleted` = 0 '; - - if (is_array($customizationIds) && !empty($customizationIds)) { - $updateQuery .= 'AND cf.`id_customization_field` NOT IN (' . implode(',', array_map('intval', $customizationIds)) . ')'; - } - - $return = Db::getInstance()->execute($updateQuery); - - if (!$return) { - throw new PrestaShopDatabaseException('An error occurred while soft deletion the customization fields'); - } - - return $return; - } - - /** - * Update default supplier data - * - * @param int $idSupplier - * @param float $wholesalePrice - * @param string $supplierReference - * - * @return bool - */ - public function updateDefaultSupplierData(int $idSupplier, string $supplierReference, float $wholesalePrice): bool - { - if (!$this->id) { - return false; - } - - $sql = 'UPDATE `' . _DB_PREFIX_ . 'product` ' . - 'SET ' . - 'id_supplier = %d, ' . - 'supplier_reference = "%s", ' . - 'wholesale_price = "%s" ' . - 'WHERE id_product = %d'; - - return Db::getInstance()->execute( - sprintf( - $sql, - $idSupplier, - pSQL($supplierReference), - $wholesalePrice, - $this->id - ) - ); - } - - /** - * Get Product ecotax - * - * @param int $precision - * @param bool $include_tax - * @param bool $formated - * - * @return string|float - */ - public function getEcotax($precision = null, $include_tax = true, $formated = false) - { - $context = Context::getContext(); - $currency = $context->currency; - $precision = $precision ?? $currency->precision; - $ecotax_rate = $include_tax ? (float) Tax::getProductEcotaxRate() : 0; - $ecotax = Tools::ps_round( - (float) $this->ecotax * (1 + $ecotax_rate / 100), - $precision, - null - ); - - return $formated ? $context->getCurrentLocale()->formatPrice($ecotax, $currency->iso_code) : $ecotax; - } - - /** - * @return string - */ - public function getProductType(): string - { - // Default value is the one saved, but in case it is not set we use dynamic definition - if (!empty($this->product_type) && in_array($this->product_type, ProductType::AVAILABLE_TYPES)) { - return $this->product_type; - } - - return $this->getDynamicProductType(); ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayOrderConfirmation.md b/modules/concepts/hooks/list-hooks/displayOrderConfirmation.md new file mode 100644 index 0000000000..7f7ee33e46 --- /dev/null +++ b/modules/concepts/hooks/list-hooks/displayOrderConfirmation.md @@ -0,0 +1,23 @@ +--- +menuTitle: displayOrderConfirmation +title: displayOrderConfirmation +hidden: true +files: + - controllers/front/OrderConfirmationController.php +types: + - frontoffice +hookTypes: + - legacy +--- + +# Hook : displayOrderConfirmation + +Located in : + + - controllers/front/OrderConfirmationController.php + +## Parameters + +```php +Hook::exec('displayOrderConfirmation', ['order' => $order]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayPaymentReturn.md b/modules/concepts/hooks/list-hooks/displayPaymentReturn.md index cf16c77965..bd87f39618 100644 --- a/modules/concepts/hooks/list-hooks/displayPaymentReturn.md +++ b/modules/concepts/hooks/list-hooks/displayPaymentReturn.md @@ -20,61 +20,4 @@ Located in : ```php Hook::exec('displayPaymentReturn', ['order' => $order], $this->id_module); - } - - /** - * Execute the hook displayOrderConfirmation. - */ - public function displayOrderConfirmation($order) - { - return Hook::exec('displayOrderConfirmation', ['order' => $order]); - } - - /** - * Check if an order is free and create it. - */ - protected function checkFreeOrder() - { - $cart = $this->context->cart; - if ($cart->id_customer == 0 || $cart->id_address_delivery == 0 || $cart->id_address_invoice == 0) { - Tools::redirect($this->context->link->getPageLink('order')); - } - - $customer = new Customer($cart->id_customer); - if (!Validate::isLoadedObject($customer)) { - Tools::redirect($this->context->link->getPageLink('order')); - } - - $total = (float) $cart->getOrderTotal(true, Cart::BOTH); - if ($total > 0) { - Tools::redirect($this->context->link->getPageLink('order')); - } - - $order = new PaymentFree(); - $order->validateOrder( - $cart->id, - (int) Configuration::get('PS_OS_PAYMENT'), - 0, - $this->trans('Free order', [], 'Admin.Orderscustomers.Feature'), - null, - [], - null, - false, - $cart->secure_key - ); - - // redirect back to us with rest of the data - // note the id_module parameter with value -1 - // it acts as a marker for the module check to use "free_payment" - // for the check - Tools::redirect('index.php?controller=order-confirmation&id_cart=' . (int) $cart->id . '&id_module=-1&id_order=' . (int) $order->currentOrder . '&key=' . $cart->secure_key); - } - - public function getBreadcrumbLinks() - { - $breadcrumb = parent::getBreadcrumbLinks(); - - $breadcrumb['links'][] = [ - 'title' => $this->trans('Order confirmation', [], 'Shop.Theme.Checkout'), - 'url' => $this->context->link->getPageLink('order-confirmation'), ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/moduleRoutes.md b/modules/concepts/hooks/list-hooks/moduleRoutes.md new file mode 100644 index 0000000000..1de89585ba --- /dev/null +++ b/modules/concepts/hooks/list-hooks/moduleRoutes.md @@ -0,0 +1,23 @@ +--- +menuTitle: moduleRoutes +title: moduleRoutes +hidden: true +files: + - classes/Dispatcher.php +types: + - frontoffice +hookTypes: + - legacy +--- + +# Hook : moduleRoutes + +Located in : + + - classes/Dispatcher.php + +## Parameters + +```php +Hook::exec('moduleRoutes', ['id_shop' => $id_shop], null, true, false); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/termsAndConditions.md b/modules/concepts/hooks/list-hooks/termsAndConditions.md index 2a0a1c5962..024d58ab53 100644 --- a/modules/concepts/hooks/list-hooks/termsAndConditions.md +++ b/modules/concepts/hooks/list-hooks/termsAndConditions.md @@ -20,44 +20,4 @@ Located in : ```php Hook::exec('termsAndConditions', [], null, true); - if (!is_array($hookedConditions)) { - $hookedConditions = []; - } - foreach ($hookedConditions as $hookedCondition) { - if ($hookedCondition instanceof TermsAndConditions) { - $allConditions[] = $hookedCondition; - } elseif (is_array($hookedCondition)) { - foreach ($hookedCondition as $hookedConditionObject) { - if ($hookedConditionObject instanceof TermsAndConditions) { - $allConditions[] = $hookedConditionObject; - } - } - } - } - - if (Configuration::get('PS_CONDITIONS')) { - array_unshift($allConditions, $this->getDefaultTermsAndConditions()); - } - - /* - * If two TermsAndConditions objects have the same identifier, - * the one at the end of the list overrides the first one. - * This allows a module to override the default checkbox - * in a consistent manner. - */ - $reducedConditions = []; - foreach ($allConditions as $condition) { - if ($condition instanceof TermsAndConditions) { - $reducedConditions[$condition->getIdentifier()] = $condition; - } - } - - return $reducedConditions; - } - - public function getConditionsToApproveForTemplate() - { - return array_map(function (TermsAndConditions $condition) { - return $condition->format(); - }, $this->getConditionsToApprove()); ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/validateCustomerFormFields.md b/modules/concepts/hooks/list-hooks/validateCustomerFormFields.md new file mode 100644 index 0000000000..0340f9833e --- /dev/null +++ b/modules/concepts/hooks/list-hooks/validateCustomerFormFields.md @@ -0,0 +1,23 @@ +--- +menuTitle: validateCustomerFormFields +title: validateCustomerFormFields +hidden: true +files: + - classes/form/CustomerForm.php +types: + - frontoffice +hookTypes: + - legacy +--- + +# Hook : validateCustomerFormFields + +Located in : + + - classes/form/CustomerForm.php + +## Parameters + +```php +Hook::exec('validateCustomerFormFields', ['fields' => $formFields], $moduleId, true); +``` \ No newline at end of file From 7f540f2150442ade7661759067343fe5c2d7ccbb Mon Sep 17 00:00:00 2001 From: Thomas Nares Date: Thu, 3 Nov 2022 09:47:49 +0100 Subject: [PATCH 152/310] Fix wrong extracts --- .../actionAdminOrdersTrackingNumberUpdate.md | 3 - .../hooks/list-hooks/actionOrderSlipAdd.md | 253 ------------------ .../list-hooks/actionShopDataDuplication.md | 78 ------ .../actionValidateCustomerAddressForm.md | 95 +------ 4 files changed, 1 insertion(+), 428 deletions(-) diff --git a/modules/concepts/hooks/list-hooks/actionAdminOrdersTrackingNumberUpdate.md b/modules/concepts/hooks/list-hooks/actionAdminOrdersTrackingNumberUpdate.md index fc26c8dca3..3e7d6f3b68 100644 --- a/modules/concepts/hooks/list-hooks/actionAdminOrdersTrackingNumberUpdate.md +++ b/modules/concepts/hooks/list-hooks/actionAdminOrdersTrackingNumberUpdate.md @@ -24,7 +24,4 @@ Hook::exec('actionAdminOrdersTrackingNumberUpdate', [ 'customer' => $customer, 'carrier' => $carrier, ], null, false, true, false, $order->id_shop); - } - } finally { - $this->contextStateManager->restorePreviousContext(); ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionOrderSlipAdd.md b/modules/concepts/hooks/list-hooks/actionOrderSlipAdd.md index fcafdbaae0..70aa20a093 100644 --- a/modules/concepts/hooks/list-hooks/actionOrderSlipAdd.md +++ b/modules/concepts/hooks/list-hooks/actionOrderSlipAdd.md @@ -24,257 +24,4 @@ Hook::exec('actionOrderSlipAdd', [ 'productList' => $orderRefundSummary->getProductRefunds(), 'qtyList' => $fullQuantityList, ], null, false, true, false, $order->id_shop); - - $customer = new Customer((int) $order->id_customer); - - // @todo: use private method to send mail - $params = [ - '{lastname}' => $customer->lastname, - '{firstname}' => $customer->firstname, - '{id_order}' => $order->id, - '{order_name}' => $order->getUniqReference(), - ]; - - $orderLanguage = $order->getAssociatedLanguage(); - - // @todo: use a dedicated Mail class (see #13945) - // @todo: remove this @and have a proper error handling - @Mail::Send( - (int) $orderLanguage->getId(), - 'credit_slip', - $this->translator->trans( - 'New credit slip regarding your order', - [], - 'Emails.Subject', - $orderLanguage->locale - ), - $params, - $customer->email, - $customer->firstname . ' ' . $customer->lastname, - null, - null, - null, - null, - _PS_MAIL_DIR_, - true, - (int) $order->id_shop - ); - - /** @var OrderDetail $orderDetail */ - foreach ($orderRefundSummary->getOrderDetails() as $orderDetail) { - if ($this->configuration->get('PS_ADVANCED_STOCK_MANAGEMENT')) { - StockAvailable::synchronize($orderDetail->product_id); - } - } - } else { - throw new InvalidCancelProductException(InvalidCancelProductException::INVALID_AMOUNT); - } - } - - /** - * This is a copy of OrderSlip::create except the OrderDetail modification has been removed - * since it's now managed in the handler, this allows to update order details even without - * generating a credit slip - * - * @todo this copy uses array data but could probably be refactored to use OrderDetailRefund objects - * - * @param Order $order - * @param array $product_list - * @param float $shipping_cost - * @param float $amount - * @param bool $amount_choosen - * @param bool $add_tax - * @param int $precision - * - * @return bool - * - * @throws PrestaShopDatabaseException - * @throws PrestaShopException - */ - private function createOrderSlip( - Order $order, - array $product_list, - float $shipping_cost = 0, - float $amount = 0, - bool $amount_choosen = false, - bool $add_tax = true, - int $precision = 6 - ) { - $currency = new Currency((int) $order->id_currency); - $orderSlip = new OrderSlip(); - $orderSlip->id_customer = (int) $order->id_customer; - $orderSlip->id_order = (int) $order->id; - $orderSlip->conversion_rate = $currency->conversion_rate; - - $orderSlip->total_shipping_tax_excl = 0; - $orderSlip->total_shipping_tax_incl = 0; - $orderSlip->partial = 0; - - if ($shipping_cost > 0) { - $orderSlip->shipping_cost = true; - $carrier = new Carrier((int) $order->id_carrier); - // @todo: define if we use invoice or delivery address, or we use configuration PS_TAX_ADDRESS_TYPE - $address = Address::initialize($order->id_address_delivery, false); - $tax_calculator = $carrier->getTaxCalculator($address); - - if ($add_tax) { - $orderSlip->total_shipping_tax_excl = $shipping_cost; - if ($tax_calculator instanceof TaxCalculator) { - $orderSlip->total_shipping_tax_incl = Tools::ps_round($tax_calculator->addTaxes($orderSlip->total_shipping_tax_excl), $precision); - } else { - $orderSlip->total_shipping_tax_incl = $orderSlip->total_shipping_tax_excl; - } - } else { - $orderSlip->total_shipping_tax_incl = $shipping_cost; - if ($tax_calculator instanceof TaxCalculator) { - $orderSlip->total_shipping_tax_excl = Tools::ps_round($tax_calculator->removeTaxes($orderSlip->total_shipping_tax_incl), $precision); - } else { - $orderSlip->total_shipping_tax_excl = $orderSlip->total_shipping_tax_incl; - } - } - } else { - $orderSlip->shipping_cost = false; - } - - $orderSlip->amount = 0; - $orderSlip->total_products_tax_excl = 0; - $orderSlip->total_products_tax_incl = 0; - $total_products = []; - foreach ($product_list as &$product) { - $order_detail = new OrderDetail((int) $product['id_order_detail']); - $price = (float) $product['unit_price']; - $quantity = (int) $product['quantity']; - - // @todo: define if we use invoice or delivery address, or we use configuration PS_TAX_ADDRESS_TYPE - $address = Address::initialize($order->id_address_invoice, false); - $id_address = (int) $address->id; - $id_tax_rules_group = (int) $order_detail->id_tax_rules_group; - $tax_calculator = $order_detail->getTaxCalculator(); - - if ($add_tax) { - $orderSlip->total_products_tax_excl += $price * $quantity; - } else { - $orderSlip->total_products_tax_incl += $price * $quantity; - } - - if (in_array($this->configuration->get('PS_ROUND_TYPE'), [Order::ROUND_ITEM, Order::ROUND_LINE])) { - if (!isset($total_products[$id_tax_rules_group])) { - $total_products[$id_tax_rules_group] = 0; - } - } else { - if (!isset($total_products[$id_tax_rules_group . '_' . $id_address])) { - $total_products[$id_tax_rules_group . '_' . $id_address] = 0; - } - } - - if ($add_tax) { - $product_tax_incl_line = Tools::ps_round($tax_calculator->addTaxes($price) * $quantity, $precision); - } else { - $product_tax_incl_line = Tools::ps_round($tax_calculator->removeTaxes($price) * $quantity, $precision); - } - switch ($this->configuration->get('PS_ROUND_TYPE')) { - case Order::ROUND_ITEM: - if ($add_tax) { - $product_tax_incl = Tools::ps_round($tax_calculator->addTaxes($price), $precision) * $quantity; - } else { - $product_tax_incl = Tools::ps_round($tax_calculator->removeTaxes($price), $precision) * $quantity; - } - $total_products[$id_tax_rules_group] += $product_tax_incl; - break; - case Order::ROUND_LINE: - $product_tax_incl = $product_tax_incl_line; - $total_products[$id_tax_rules_group] += $product_tax_incl; - break; - case Order::ROUND_TOTAL: - $product_tax_incl = $product_tax_incl_line; - $total_products[$id_tax_rules_group . '_' . $id_address] += $price * $quantity; - break; - default: - $product_tax_incl = 0; - } - - if ($add_tax) { - $product['unit_price_tax_excl'] = $price; - $product['unit_price_tax_incl'] = Tools::ps_round($tax_calculator->addTaxes($price), $precision); - $product['total_price_tax_excl'] = Tools::ps_round($price * $quantity, $precision); - $product['total_price_tax_incl'] = Tools::ps_round($product_tax_incl, $precision); - } else { - $product['unit_price_tax_incl'] = $price; - $product['unit_price_tax_excl'] = Tools::ps_round($tax_calculator->removeTaxes($price), $precision); - $product['total_price_tax_incl'] = Tools::ps_round($price * $quantity, $precision); - $product['total_price_tax_excl'] = Tools::ps_round($product_tax_incl, $precision); - } - } - - unset($product); - - foreach ($total_products as $key => $price) { - if ($this->configuration->get('PS_ROUND_TYPE') == Order::ROUND_TOTAL) { - $tmp = explode('_', $key); - $address = Address::initialize((int) $tmp[1], true); - $tax_calculator = TaxManagerFactory::getManager($address, (int) $tmp[0])->getTaxCalculator(); - - if ($add_tax) { - $orderSlip->total_products_tax_incl += Tools::ps_round($tax_calculator->addTaxes($price), $precision); - } else { - $orderSlip->total_products_tax_excl += Tools::ps_round($tax_calculator->removeTaxes($price), $precision); - } - } else { - if ($add_tax) { - $orderSlip->total_products_tax_incl += $price; - } else { - $orderSlip->total_products_tax_excl += $price; - } - } - } - - if ($add_tax) { - $orderSlip->total_products_tax_incl -= $amount && !$amount_choosen ? $amount : 0; - $orderSlip->amount = $amount_choosen ? $amount : $orderSlip->total_products_tax_excl; - } else { - $orderSlip->total_products_tax_excl -= $amount && !$amount_choosen ? $amount : 0; - $orderSlip->amount = $amount_choosen ? $amount : $orderSlip->total_products_tax_incl; - } - $orderSlip->shipping_cost_amount = $orderSlip->total_shipping_tax_incl; - - if ((float) $amount && !$amount_choosen) { - $orderSlip->order_slip_type = VoucherRefundType::PRODUCT_PRICES_EXCLUDING_VOUCHER_REFUND; - } - if (((float) $amount && $amount_choosen) || $orderSlip->shipping_cost_amount > 0) { - $orderSlip->order_slip_type = VoucherRefundType::SPECIFIC_AMOUNT_REFUND; - } - - if (!$orderSlip->add()) { - return false; - } - - $res = true; - - foreach ($product_list as $product) { - $res &= $this->addProductOrderSlip((int) $orderSlip->id, $product); - } - - return (bool) $res; - } - - /** - * @param array $product - * - * @return bool - * - * @throws PrestaShopDatabaseException - */ - private function addProductOrderSlip(int $orderSlipId, array $product): bool - { - return (bool) Db::getInstance()->insert('order_slip_detail', [ - 'id_order_slip' => $orderSlipId, - 'id_order_detail' => (int) $product['id_order_detail'], - 'product_quantity' => $product['quantity'], - 'unit_price_tax_excl' => $product['unit_price_tax_excl'], - 'unit_price_tax_incl' => $product['unit_price_tax_incl'], - 'total_price_tax_excl' => $product['total_price_tax_excl'], - 'total_price_tax_incl' => $product['total_price_tax_incl'], - 'amount_tax_excl' => $product['total_price_tax_excl'], - 'amount_tax_incl' => $product['total_price_tax_incl'], - ]); ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionShopDataDuplication.md b/modules/concepts/hooks/list-hooks/actionShopDataDuplication.md index b4cec2c92f..626b3cbe50 100644 --- a/modules/concepts/hooks/list-hooks/actionShopDataDuplication.md +++ b/modules/concepts/hooks/list-hooks/actionShopDataDuplication.md @@ -23,82 +23,4 @@ Hook::exec('actionShopDataDuplication', [ 'old_id_shop' => (int) $old_id, 'new_id_shop' => (int) $this->id, ], $m['id_module']); - } - } - } - } - - /** - * @param int $id - * - * @return array - */ - public static function getCategories($id = 0, $only_id = true) - { - // build query - $query = new DbQuery(); - if ($only_id) { - $query->select('cs.`id_category`'); - } else { - $query->select('DISTINCT cs.`id_category`, cl.`name`, cl.`link_rewrite`'); - } - $query->from('category_shop', 'cs'); - $query->leftJoin('category_lang', 'cl', 'cl.`id_category` = cs.`id_category` AND cl.`id_lang` = ' . (int) Context::getContext()->language->id); - $query->where('cs.`id_shop` = ' . (int) $id); - $result = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS($query); - - if ($only_id) { - $array = []; - foreach ($result as $row) { - $array[] = $row['id_category']; - } - $array = array_unique($array); - } else { - return $result; - } - - return $array; - } - - /** - * @param string $entity - * @param int $id_shop - * - * @return array|bool - */ - public static function getEntityIds($entity, $id_shop, $active = false, $delete = false) - { - if (!Shop::isTableAssociated($entity)) { - return false; - } - - return Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS( - 'SELECT entity.`id_' . bqSQL($entity) . '` - FROM `' . _DB_PREFIX_ . bqSQL($entity) . '_shop`es - LEFT JOIN ' . _DB_PREFIX_ . bqSQL($entity) . ' entity - ON (entity.`id_' . bqSQL($entity) . '` = es.`id_' . bqSQL($entity) . '`) - WHERE es.`id_shop` = ' . (int) $id_shop . - ($active ? ' AND entity.`active` = 1' : '') . - ($delete ? ' AND entity.deleted = 0' : '') - ); - } - - /** - * @param string $host - * - * @return array - * - * @throws PrestaShopDatabaseException - */ - private static function findShopByHost($host) - { - $sql = 'SELECT s.id_shop, CONCAT(su.physical_uri, su.virtual_uri) AS uri, su.domain, su.main - FROM ' . _DB_PREFIX_ . 'shop_url su - LEFT JOIN ' . _DB_PREFIX_ . 'shop s ON (s.id_shop = su.id_shop) - WHERE (su.domain = \'' . pSQL($host) . '\' OR su.domain_ssl = \'' . pSQL($host) . '\') - AND s.active = 1 - AND s.deleted = 0 - ORDER BY LENGTH(CONCAT(su.physical_uri, su.virtual_uri)) DESC'; - - $result = Db::getInstance()->executeS($sql); ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionValidateCustomerAddressForm.md b/modules/concepts/hooks/list-hooks/actionValidateCustomerAddressForm.md index 222019d115..0220f098f5 100644 --- a/modules/concepts/hooks/list-hooks/actionValidateCustomerAddressForm.md +++ b/modules/concepts/hooks/list-hooks/actionValidateCustomerAddressForm.md @@ -19,98 +19,5 @@ Located in : ## Parameters ```php -Hook::exec('actionValidateCustomerAddressForm', ['form' => $this])) !== '') { - $is_valid &= (bool) $hookReturn; - } - - return $is_valid && parent::validate(); - } - - public function submit() - { - if (!$this->validate()) { - return false; - } - - $address = new Address( - Tools::getValue('id_address'), - $this->language->id - ); - - foreach ($this->formFields as $formField) { - $address->{$formField->getName()} = $formField->getValue(); - } - - if (!isset($this->formFields['id_state'])) { - $address->id_state = 0; - } - - if (empty($address->alias)) { - $address->alias = $this->translator->trans('My Address', [], 'Shop.Theme.Checkout'); - } - - Hook::exec('actionSubmitCustomerAddressForm', ['address' => &$address]); - - $this->setAddress($address); - - return $this->getPersister()->save( - $address, - $this->getValue('token') - ); - } - - /** - * @return Address - */ - public function getAddress() - { - return $this->address; - } - - /** - * @return CustomerAddressPersister - */ - protected function getPersister() - { - return $this->persister; - } - - protected function setAddress(Address $address) - { - $this->address = $address; - } - - public function getTemplateVariables() - { - $context = Context::getContext(); - - if (!$this->formFields) { - // This is usually done by fillWith but the form may be - // rendered before fillWith is called. - // I don't want to assign formFields in the constructor - // because it accesses the DB and a constructor should not - // have side effects. - $this->formFields = $this->formatter->getFormat(); - } - - $this->setValue('token', $this->persister->getToken()); - $formFields = array_map( - function (FormField $item) { - return $item->toArray(); - }, - $this->formFields - ); - - if (empty($formFields['firstname']['value'])) { - $formFields['firstname']['value'] = $context->customer->firstname; - } - - if (empty($formFields['lastname']['value'])) { - $formFields['lastname']['value'] = $context->customer->lastname; - } - - return [ - 'id_address' => (isset($this->address->id)) ? $this->address->id : 0, - 'action' => $this->action, - 'errors' => $this->getErrors(), +Hook::exec('actionValidateCustomerAddressForm', ['form' => $this]) ``` \ No newline at end of file From 8c28aa90f5204949d0c408a483be25850c663320 Mon Sep 17 00:00:00 2001 From: Thomas Nares Date: Thu, 3 Nov 2022 11:49:00 +0100 Subject: [PATCH 153/310] Add shortcode --- modules/concepts/hooks/list-hooks/_index.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/modules/concepts/hooks/list-hooks/_index.md b/modules/concepts/hooks/list-hooks/_index.md index 7478d09c16..cf97335aaa 100644 --- a/modules/concepts/hooks/list-hooks/_index.md +++ b/modules/concepts/hooks/list-hooks/_index.md @@ -21,6 +21,4 @@ For example, `actionAdminCustomersFormModifier` is documented as `action -
-{{% children showhidden="true" %}} -
\ No newline at end of file +{{}} \ No newline at end of file From 4e1c0419b61aeade49aa5a2dcaf9ce451426934c Mon Sep 17 00:00:00 2001 From: Thomas Nares Date: Wed, 9 Nov 2022 11:30:01 +0100 Subject: [PATCH 154/310] New list of hooks --- ...ministrationControllerPostProcessBefore.md | 23 - .../actionAdminControllerSetMedia.md | 23 - .../hooks/list-hooks/actionAttributeDelete.md | 23 - .../list-hooks/actionAttributeGroupDelete.md | 23 - .../list-hooks/actionAttributeGroupSave.md | 23 - .../hooks/list-hooks/actionAttributeSave.md | 23 - .../hooks/list-hooks/actionAuthentication.md | 23 - .../list-hooks/actionBuildFrontEndObject.md | 25 - .../hooks/list-hooks/actionCartSave.md | 23 - .../hooks/list-hooks/actionCategoryAdd.md | 23 - .../hooks/list-hooks/actionCategoryDelete.md | 23 - .../hooks/list-hooks/actionCategoryUpdate.md | 23 - .../hooks/list-hooks/actionCheckoutRender.md | 23 - .../hooks/list-hooks/actionClearCache.md | 23 - .../list-hooks/actionClearCompileCache.md | 23 - .../hooks/list-hooks/actionClearSf2Cache.md | 23 - .../list-hooks/actionCustomerAccountAdd.md | 25 - .../list-hooks/actionCustomerAccountUpdate.md | 25 - .../list-hooks/actionCustomerLogoutAfter.md | 23 - .../list-hooks/actionCustomerLogoutBefore.md | 23 - .../hooks/list-hooks/actionDispatcherAfter.md | 23 - .../list-hooks/actionDispatcherBefore.md | 23 - .../hooks/list-hooks/actionFeatureDelete.md | 23 - .../hooks/list-hooks/actionFeatureSave.md | 23 - .../list-hooks/actionFeatureValueDelete.md | 23 - .../list-hooks/actionFeatureValueSave.md | 23 - .../hooks/list-hooks/actionHtaccessCreate.md | 23 - .../actionObjectProductInCartDeleteAfter.md | 24 - .../actionObjectProductInCartDeleteBefore.md | 24 - .../hooks/list-hooks/actionOrderReturn.md | 23 - .../hooks/list-hooks/actionOrderSlipAdd.md | 27 - .../list-hooks/actionOutputHTMLBefore.md | 23 - .../hooks/list-hooks/actionProductAdd.md | 23 - .../actionProductAttributeUpdate.md | 23 - .../hooks/list-hooks/actionProductDelete.md | 23 - .../hooks/list-hooks/actionProductSave.md | 23 - .../list-hooks/actionProductSearchAfter.md | 23 - ...ctionProductSearchProviderRunQueryAfter.md | 26 - ...tionProductSearchProviderRunQueryBefore.md | 25 - .../list-hooks/actionShopDataDuplication.md | 26 - .../hooks/list-hooks/actionUpdateLangAfter.md | 23 - .../actionValidateCustomerAddressForm.md | 23 - .../list-hooks/addWebserviceResources.md | 23 - .../additionalCustomerAddressFields.md | 23 - .../additionalCustomerFormFields.md | 23 - .../hooks/list-hooks/dashboardZoneThree.md | 23 - .../displayAdditionalCustomerAddressFields.md | 23 - .../hooks/list-hooks/displayAdminCustomers.md | 23 - .../list-hooks/displayAdminEndContent.md | 23 - .../hooks/list-hooks/displayAdminOrder.md | 23 - ...ayAdminProductsMainStepLeftColumnBottom.md | 23 - ...ayAdminProductsMainStepLeftColumnMiddle.md | 23 - ...yAdminProductsMainStepRightColumnBottom.md | 23 - .../list-hooks/displayAfterBodyOpeningTag.md | 23 - .../list-hooks/displayAfterProductThumbs.md | 23 - .../hooks/list-hooks/displayAfterTitleTag.md | 23 - .../list-hooks/displayBackOfficeCategory.md | 23 - .../hooks/list-hooks/displayBackOfficeTop.md | 23 - .../hooks/list-hooks/displayBanner.md | 23 - .../list-hooks/displayBeforeBodyClosingTag.md | 23 - .../list-hooks/displayCarrierExtraContent.md | 23 - .../list-hooks/displayCartModalContent.md | 23 - .../list-hooks/displayCartModalFooter.md | 23 - .../displayCheckoutBeforeConfirmation.md | 23 - .../list-hooks/displayCustomerAccount.md | 23 - .../list-hooks/displayCustomerAccountForm.md | 23 - .../displayCustomerAccountFormTop.md | 23 - .../displayCustomerLoginFormAfter.md | 23 - .../displayDashboardToolbarIcons.md | 23 - .../displayDashboardToolbarTopMenu.md | 23 - .../displayEmptyModuleCategoryExtraMessage.md | 23 - .../hooks/list-hooks/displayFooter.md | 23 - .../hooks/list-hooks/displayHeader.md | 23 - .../concepts/hooks/list-hooks/displayHome.md | 23 - .../list-hooks/displayInvoiceLegalFreeText.md | 23 - .../list-hooks/displayLeftColumnProduct.md | 23 - .../hooks/list-hooks/displayMaintenance.md | 23 - .../hooks/list-hooks/displayNavFullWidth.md | 23 - .../list-hooks/displayOrderConfirmation.md | 23 - .../hooks/list-hooks/displayOrderDetail.md | 23 - .../list-hooks/displayPaymentByBinaries.md | 23 - .../hooks/list-hooks/displayPaymentTop.md | 23 - .../displayPersonalInformationTop.md | 23 - .../hooks/list-hooks/displayProductActions.md | 23 - .../list-hooks/displayRightColumnProduct.md | 23 - .../hooks/list-hooks/displayShoppingCart.md | 23 - .../list-hooks/displayShoppingCartFooter.md | 23 - .../concepts/hooks/list-hooks/displayTop.md | 23 - .../hooks/list-hooks/filterProductSearch.md | 23 - .../list-hooks/validateCustomerFormFields.md | 23 - modules/concepts/hooks/list-of-hooks.md | 2982 ----------------- .../{list-hooks => list-of-hooks}/_index.md | 6 +- .../actionAfter.md | 18 +- .../actionBefore.md | 18 +- ...actionListingFieldsModifier.md | 18 +- .../actionGridDataModifier.md | 33 + ...ionGridDefinitionModifier.md | 33 + ...ionGridFilterFormModifier.md | 33 + ...tionGridPresenterModifier.md | 33 + .../actionFormBuilderModifier.md | 36 + .../actionGridQueryBuilderModifier.md | 35 + ...acyControllerName>ListingFieldsModifier.md | 39 + ...cyControllerName>ListingResultsModifier.md | 34 + .../hooks/list-of-hooks/actionAdmin.md | 31 + .../actionAdminAfter.md | 18 +- .../actionAdminBefore.md | 18 +- ...rametersMetaControllerPostProcessBefore.md | 24 +- ...inWebserviceControllerPostProcessBefore.md | 18 +- ...ministrationControllerPostProcessBefore.md | 37 + ...sPerformanceControllerPostProcessBefore.md | 24 +- .../actionAdminControllerSetMedia.md | 38 + ...lGeolocationControllerPostProcessBefore.md | 24 +- ...LocalizationControllerPostProcessBefore.md | 24 +- ...ionAdminLogsControllerPostProcessBefore.md | 18 +- ...nMaintenanceControllerPostProcessBefore.md | 18 +- .../actionAdminMetaAfterWriteRobotsFile.md | 18 +- .../actionAdminOrdersTrackingNumberUpdate.md | 27 +- ...nPreferencesControllerPostProcessBefore.md | 18 +- ...ctionAdminProductsListingFieldsModifier.md | 18 +- ...tionAdminProductsListingResultsModifier.md | 18 +- ...dminSecurityControllerPostProcessBefore.md | 24 +- ...gPreferencesControllerPostProcessBefore.md | 24 +- ...rPreferencesControllerPostProcessBefore.md | 24 +- ...tPreferencesControllerPostProcessBefore.md | 18 +- .../actionAfterCreateFormHandler.md | 34 + .../actionAfterUpdateFormHandler.md | 34 + .../actionAjaxDie.md | 18 +- .../actionAjaxDieBefore.md | 18 +- .../actionAttributeCombinationDelete.md | 18 +- .../actionAttributeCombinationSave.md | 18 +- .../list-of-hooks/actionAttributeDelete.md | 37 + .../actionAttributeGroupDelete.md | 37 + .../list-of-hooks/actionAttributeGroupSave.md | 37 + .../list-of-hooks/actionAttributeSave.md | 37 + .../list-of-hooks/actionAuthentication.md | 37 + .../actionAuthenticationBefore.md | 18 +- .../actionBeforeAjaxDie.md} | 22 +- ...actionBeforeUpdateFormHandler.md | 34 + .../actionBuildFrontEndObject.md | 39 + .../actionCarrierProcess.md | 24 +- .../actionCarrierUpdate.md | 24 +- .../hooks/list-of-hooks/actionCartSave.md | 37 + .../actionCartSummary.md | 18 +- .../actionCartUpdateQuantityBefore.md | 18 +- .../hooks/list-of-hooks/actionCategoryAdd.md | 37 + .../list-of-hooks/actionCategoryDelete.md | 37 + .../list-of-hooks/actionCategoryUpdate.md | 37 + .../list-of-hooks/actionCheckoutRender.md | 37 + .../hooks/list-of-hooks/actionClearCache.md | 37 + .../list-of-hooks/actionClearCompileCache.md | 37 + .../list-of-hooks/actionClearSf2Cache.md | 37 + .../list-of-hooks/actionCustomerAccountAdd.md | 39 + .../actionCustomerAccountUpdate.md | 39 + .../actionCustomerAddGroups.md | 18 +- .../actionCustomerBeforeUpdateGroup.md | 18 +- .../actionCustomerLogoutAfter.md | 37 + .../actionCustomerLogoutBefore.md | 37 + .../actionDeleteGDPRCustomer.md | 18 +- .../actionDeliveryPriceByPrice.md | 18 +- .../actionDeliveryPriceByWeight.md | 18 +- .../actionDispatcher.md | 18 +- .../list-of-hooks/actionDispatcherAfter.md | 37 + .../list-of-hooks/actionDispatcherBefore.md | 37 + .../actionDownloadAttachment.md | 18 +- .../actionExportGDPRData.md | 18 +- .../list-of-hooks/actionFeatureDelete.md | 37 + .../hooks/list-of-hooks/actionFeatureSave.md | 37 + .../list-of-hooks/actionFeatureValueDelete.md | 37 + .../list-of-hooks/actionFeatureValueSave.md | 37 + .../actionFrontControllerSetMedia.md | 18 +- .../actionGetIDZoneByAddressID.md | 18 +- .../actionGetProductPropertiesAfter.md | 18 +- ...ctionGetProductPropertiesAfterUnitPrice.md | 24 +- .../actionGetProductPropertiesBefore.md | 18 +- .../list-of-hooks/actionHtaccessCreate.md | 37 + .../actionInvoiceNumberFormatted.md | 18 +- .../actionMailAlterMessageBeforeSend.md | 18 +- .../actionModuleInstallAfter.md | 24 +- .../actionModuleInstallBefore.md | 24 +- .../actionModuleUnRegisterHookBefore.md | 18 +- .../actionModuleUninstallAfter.md | 24 +- .../actionModuleUninstallBefore.md | 24 +- .../actionObjectAddAfter.md | 19 +- .../actionObjectAddBefore.md | 19 +- .../actionObjectDeleteAfter.md | 19 +- .../actionObjectDeleteBefore.md | 19 +- .../actionObjectUpdateAfter.md | 19 +- .../actionObjectUpdateBefore.md | 19 +- .../actionObjectAddAfter.md | 19 +- .../actionObjectAddBefore.md | 19 +- .../actionObjectAttributeAddBefore.md | 19 +- .../actionObjectAttributeGroupAddBefore.md | 19 +- .../actionObjectDeleteAfter.md | 19 +- .../actionObjectDeleteBefore.md | 19 +- ...actionObjectProductCommentValidateAfter.md | 19 +- .../actionObjectProductInCartDeleteAfter.md | 39 + .../actionObjectProductInCartDeleteBefore.md | 39 + .../actionObjectUpdateAfter.md | 19 +- .../actionObjectUpdateBefore.md | 19 +- .../actionOnImageCutAfter.md | 18 +- .../actionOnImageResizeAfter.md | 18 +- .../actionOrderEdited.md | 24 +- .../actionOrderHistoryAddAfter.md | 18 +- .../hooks/list-of-hooks/actionOrderReturn.md | 37 + .../hooks/list-of-hooks/actionOrderSlipAdd.md | 294 ++ .../list-of-hooks/actionOutputHTMLBefore.md | 37 + .../actionPDFInvoiceRender.md | 18 +- .../actionPasswordRenew.md | 18 +- .../actionPaymentCCAdd.md | 24 +- .../actionPaymentConfirmation.md | 24 +- .../list-of-hooks/actionProductActivation.md | 31 + .../hooks/list-of-hooks/actionProductAdd.md | 37 + .../actionProductAttributeDelete.md | 24 +- .../actionProductAttributeUpdate.md | 37 + .../actionProductCancel.md | 24 +- .../list-of-hooks/actionProductDelete.md | 37 + .../actionProductOutOfStock.md | 24 +- .../hooks/list-of-hooks/actionProductSave.md | 37 + .../list-of-hooks/actionProductSearchAfter.md | 37 + ...ctionProductSearchProviderRunQueryAfter.md | 40 + ...tionProductSearchProviderRunQueryBefore.md | 39 + .../actionProductUpdate.md | 24 +- .../actionSearch.md | 18 +- .../actionSetInvoice.md | 18 +- .../actionShopDataDuplication.md | 112 + .../actionSubmitAccountBefore.md | 18 +- .../actionSubmitCustomerAddressForm.md | 18 +- .../list-of-hooks/actionUpdateLangAfter.md | 37 + .../actionValidateCustomerAddressForm.md | 130 + .../actionValidateOrder.md | 24 +- .../actionWatermark.md | 24 +- .../actionWishlistAddProduct.md | 18 +- .../list-of-hooks/addWebserviceResources.md | 37 + .../additionalCustomerAddressFields.md | 37 + .../additionalCustomerFormFields.md | 37 + .../dashboardData.md | 18 +- .../dashboardZoneOne.md | 18 +- .../hooks/list-of-hooks/dashboardZoneThree.md | 37 + .../dashboardZoneTwo.md | 18 +- .../displayAdditionalCustomerAddressFields.md | 37 + .../displayAdminAfterHeader.md | 18 +- .../list-of-hooks/displayAdminCustomers.md | 37 + .../list-of-hooks/displayAdminEndContent.md | 37 + .../displayAdminForm.md | 18 +- .../displayAdminGridTableAfter.md | 24 +- .../displayAdminGridTableBefore.md | 24 +- .../displayAdminListAfter.md | 18 +- .../displayAdminListBefore.md | 18 +- .../displayAdminNavBarBeforeEnd.md | 18 +- .../displayAdminOptions.md | 18 +- .../hooks/list-of-hooks/displayAdminOrder.md | 37 + .../displayAdminOrderCreateExtraButtons.md | 24 +- .../displayAdminOrderMain.md | 24 +- .../displayAdminOrderMainBottom.md | 24 +- .../displayAdminOrderSide.md | 24 +- .../displayAdminOrderSideBottom.md | 18 +- .../displayAdminProductsCombinationBottom.md | 24 +- ...ayAdminProductsMainStepLeftColumnBottom.md | 37 + ...ayAdminProductsMainStepLeftColumnMiddle.md | 37 + ...yAdminProductsMainStepRightColumnBottom.md | 37 + .../displayAdminProductsOptionsStepBottom.md | 24 +- .../displayAdminProductsOptionsStepTop.md | 24 +- .../displayAdminProductsPriceStepBottom.md | 24 +- ...isplayAdminProductsQuantitiesStepBottom.md | 24 +- .../displayAdminProductsSeoStepBottom.md | 24 +- .../displayAdminProductsShippingStepBottom.md | 24 +- .../displayAdminStatsModules.md | 24 +- .../displayAdminThemesListAfter.md | 24 +- .../displayAdminView.md | 18 +- .../displayAfterBodyOpeningTag.md | 37 + .../displayAfterCarrier.md | 24 +- .../displayAfterProductThumbs.md | 37 + .../list-of-hooks/displayAfterTitleTag.md | 37 + .../displayBackOfficeCategory.md | 37 + .../list-of-hooks/displayBackOfficeTop.md | 37 + .../hooks/list-of-hooks/displayBanner.md | 37 + .../displayBeforeBodyClosingTag.md | 37 + .../displayBeforeCarrier.md | 24 +- .../displayCMSDisputeInformation.md | 18 +- .../displayCMSPrintButton.md | 18 +- .../displayCarrierExtraContent.md | 37 + .../displayCartExtraProductActions.md | 24 +- .../list-of-hooks/displayCartModalContent.md | 37 + .../list-of-hooks/displayCartModalFooter.md | 37 + .../displayCheckoutBeforeConfirmation.md | 37 + .../displayCheckoutSubtotalDetails.md | 18 +- .../displayCheckoutSummaryTop.md | 24 +- .../displayCrossSellingShoppingCart.md | 18 +- .../list-of-hooks/displayCustomerAccount.md | 37 + .../displayCustomerAccountForm.md | 37 + .../displayCustomerAccountFormTop.md | 37 + .../displayCustomerLoginFormAfter.md | 37 + .../displayCustomization.md | 18 +- .../displayDashboardToolbarIcons.md | 37 + .../displayDashboardToolbarTopMenu.md | 37 + .../displayDashboardTop.md | 24 +- .../displayEmptyModuleCategoryExtraMessage.md | 37 + .../displayExpressCheckout.md | 18 +- .../displayFeatureForm.md | 24 +- .../hooks/list-of-hooks/displayFooter.md | 37 + .../displayFooterAfter.md | 18 +- .../displayFooterBefore.md | 18 +- .../displayFooterProduct.md | 24 +- .../displayGDPRConsent.md | 18 +- .../hooks/list-of-hooks/displayHeader.md | 37 + .../hooks/list-of-hooks/displayHome.md | 37 + .../displayInvoiceLegalFreeText.md | 37 + .../list-of-hooks/displayLeftColumnProduct.md | 37 + .../hooks/list-of-hooks/displayMaintenance.md | 37 + .../displayMyAccountBlock.md | 24 +- .../displayNav1.md | 18 +- .../displayNav2.md | 18 +- .../list-of-hooks/displayNavFullWidth.md | 37 + .../displayNewsletterRegistration.md | 18 +- .../displayNotFound.md | 18 +- .../list-of-hooks/displayOrderConfirmation.md | 37 + .../displayOrderConfirmation1.md | 18 +- .../displayOrderConfirmation2.md | 18 +- .../hooks/list-of-hooks/displayOrderDetail.md | 37 + .../displayOrderPreview.md | 18 +- .../list-of-hooks/displayPaymentByBinaries.md | 37 + .../displayPaymentReturn.md | 24 +- .../hooks/list-of-hooks/displayPaymentTop.md | 37 + .../displayPersonalInformationTop.md | 37 + .../list-of-hooks/displayProductActions.md | 37 + .../displayProductAdditionalInfo.md | 24 +- .../displayProductListReviews.md | 18 +- .../displayProductPriceBlock.md | 18 +- .../displayReassurance.md | 18 +- .../displayRightColumnProduct.md | 37 + .../displaySearch.md | 18 +- .../list-of-hooks/displayShoppingCart.md | 37 + .../displayShoppingCartFooter.md | 37 + .../hooks/list-of-hooks/displayTop.md | 37 + .../list-of-hooks/filterProductSearch.md | 37 + .../legacyblockkpi.md | 18 +- .../moduleRoutes.md | 18 +- .../overrideMinimalPurchasePrice.md | 18 +- .../termsAndConditions.md | 18 +- .../validateCustomerFormFields.md | 37 + 340 files changed, 6413 insertions(+), 5802 deletions(-) delete mode 100644 modules/concepts/hooks/list-hooks/actionAdminAdministrationControllerPostProcessBefore.md delete mode 100644 modules/concepts/hooks/list-hooks/actionAdminControllerSetMedia.md delete mode 100644 modules/concepts/hooks/list-hooks/actionAttributeDelete.md delete mode 100644 modules/concepts/hooks/list-hooks/actionAttributeGroupDelete.md delete mode 100644 modules/concepts/hooks/list-hooks/actionAttributeGroupSave.md delete mode 100644 modules/concepts/hooks/list-hooks/actionAttributeSave.md delete mode 100644 modules/concepts/hooks/list-hooks/actionAuthentication.md delete mode 100644 modules/concepts/hooks/list-hooks/actionBuildFrontEndObject.md delete mode 100644 modules/concepts/hooks/list-hooks/actionCartSave.md delete mode 100644 modules/concepts/hooks/list-hooks/actionCategoryAdd.md delete mode 100644 modules/concepts/hooks/list-hooks/actionCategoryDelete.md delete mode 100644 modules/concepts/hooks/list-hooks/actionCategoryUpdate.md delete mode 100644 modules/concepts/hooks/list-hooks/actionCheckoutRender.md delete mode 100644 modules/concepts/hooks/list-hooks/actionClearCache.md delete mode 100644 modules/concepts/hooks/list-hooks/actionClearCompileCache.md delete mode 100644 modules/concepts/hooks/list-hooks/actionClearSf2Cache.md delete mode 100644 modules/concepts/hooks/list-hooks/actionCustomerAccountAdd.md delete mode 100644 modules/concepts/hooks/list-hooks/actionCustomerAccountUpdate.md delete mode 100644 modules/concepts/hooks/list-hooks/actionCustomerLogoutAfter.md delete mode 100644 modules/concepts/hooks/list-hooks/actionCustomerLogoutBefore.md delete mode 100644 modules/concepts/hooks/list-hooks/actionDispatcherAfter.md delete mode 100644 modules/concepts/hooks/list-hooks/actionDispatcherBefore.md delete mode 100644 modules/concepts/hooks/list-hooks/actionFeatureDelete.md delete mode 100644 modules/concepts/hooks/list-hooks/actionFeatureSave.md delete mode 100644 modules/concepts/hooks/list-hooks/actionFeatureValueDelete.md delete mode 100644 modules/concepts/hooks/list-hooks/actionFeatureValueSave.md delete mode 100644 modules/concepts/hooks/list-hooks/actionHtaccessCreate.md delete mode 100644 modules/concepts/hooks/list-hooks/actionObjectProductInCartDeleteAfter.md delete mode 100644 modules/concepts/hooks/list-hooks/actionObjectProductInCartDeleteBefore.md delete mode 100644 modules/concepts/hooks/list-hooks/actionOrderReturn.md delete mode 100644 modules/concepts/hooks/list-hooks/actionOrderSlipAdd.md delete mode 100644 modules/concepts/hooks/list-hooks/actionOutputHTMLBefore.md delete mode 100644 modules/concepts/hooks/list-hooks/actionProductAdd.md delete mode 100644 modules/concepts/hooks/list-hooks/actionProductAttributeUpdate.md delete mode 100644 modules/concepts/hooks/list-hooks/actionProductDelete.md delete mode 100644 modules/concepts/hooks/list-hooks/actionProductSave.md delete mode 100644 modules/concepts/hooks/list-hooks/actionProductSearchAfter.md delete mode 100644 modules/concepts/hooks/list-hooks/actionProductSearchProviderRunQueryAfter.md delete mode 100644 modules/concepts/hooks/list-hooks/actionProductSearchProviderRunQueryBefore.md delete mode 100644 modules/concepts/hooks/list-hooks/actionShopDataDuplication.md delete mode 100644 modules/concepts/hooks/list-hooks/actionUpdateLangAfter.md delete mode 100644 modules/concepts/hooks/list-hooks/actionValidateCustomerAddressForm.md delete mode 100644 modules/concepts/hooks/list-hooks/addWebserviceResources.md delete mode 100644 modules/concepts/hooks/list-hooks/additionalCustomerAddressFields.md delete mode 100644 modules/concepts/hooks/list-hooks/additionalCustomerFormFields.md delete mode 100644 modules/concepts/hooks/list-hooks/dashboardZoneThree.md delete mode 100644 modules/concepts/hooks/list-hooks/displayAdditionalCustomerAddressFields.md delete mode 100644 modules/concepts/hooks/list-hooks/displayAdminCustomers.md delete mode 100644 modules/concepts/hooks/list-hooks/displayAdminEndContent.md delete mode 100644 modules/concepts/hooks/list-hooks/displayAdminOrder.md delete mode 100644 modules/concepts/hooks/list-hooks/displayAdminProductsMainStepLeftColumnBottom.md delete mode 100644 modules/concepts/hooks/list-hooks/displayAdminProductsMainStepLeftColumnMiddle.md delete mode 100644 modules/concepts/hooks/list-hooks/displayAdminProductsMainStepRightColumnBottom.md delete mode 100644 modules/concepts/hooks/list-hooks/displayAfterBodyOpeningTag.md delete mode 100644 modules/concepts/hooks/list-hooks/displayAfterProductThumbs.md delete mode 100644 modules/concepts/hooks/list-hooks/displayAfterTitleTag.md delete mode 100644 modules/concepts/hooks/list-hooks/displayBackOfficeCategory.md delete mode 100644 modules/concepts/hooks/list-hooks/displayBackOfficeTop.md delete mode 100644 modules/concepts/hooks/list-hooks/displayBanner.md delete mode 100644 modules/concepts/hooks/list-hooks/displayBeforeBodyClosingTag.md delete mode 100644 modules/concepts/hooks/list-hooks/displayCarrierExtraContent.md delete mode 100644 modules/concepts/hooks/list-hooks/displayCartModalContent.md delete mode 100644 modules/concepts/hooks/list-hooks/displayCartModalFooter.md delete mode 100644 modules/concepts/hooks/list-hooks/displayCheckoutBeforeConfirmation.md delete mode 100644 modules/concepts/hooks/list-hooks/displayCustomerAccount.md delete mode 100644 modules/concepts/hooks/list-hooks/displayCustomerAccountForm.md delete mode 100644 modules/concepts/hooks/list-hooks/displayCustomerAccountFormTop.md delete mode 100644 modules/concepts/hooks/list-hooks/displayCustomerLoginFormAfter.md delete mode 100644 modules/concepts/hooks/list-hooks/displayDashboardToolbarIcons.md delete mode 100644 modules/concepts/hooks/list-hooks/displayDashboardToolbarTopMenu.md delete mode 100644 modules/concepts/hooks/list-hooks/displayEmptyModuleCategoryExtraMessage.md delete mode 100644 modules/concepts/hooks/list-hooks/displayFooter.md delete mode 100644 modules/concepts/hooks/list-hooks/displayHeader.md delete mode 100644 modules/concepts/hooks/list-hooks/displayHome.md delete mode 100644 modules/concepts/hooks/list-hooks/displayInvoiceLegalFreeText.md delete mode 100644 modules/concepts/hooks/list-hooks/displayLeftColumnProduct.md delete mode 100644 modules/concepts/hooks/list-hooks/displayMaintenance.md delete mode 100644 modules/concepts/hooks/list-hooks/displayNavFullWidth.md delete mode 100644 modules/concepts/hooks/list-hooks/displayOrderConfirmation.md delete mode 100644 modules/concepts/hooks/list-hooks/displayOrderDetail.md delete mode 100644 modules/concepts/hooks/list-hooks/displayPaymentByBinaries.md delete mode 100644 modules/concepts/hooks/list-hooks/displayPaymentTop.md delete mode 100644 modules/concepts/hooks/list-hooks/displayPersonalInformationTop.md delete mode 100644 modules/concepts/hooks/list-hooks/displayProductActions.md delete mode 100644 modules/concepts/hooks/list-hooks/displayRightColumnProduct.md delete mode 100644 modules/concepts/hooks/list-hooks/displayShoppingCart.md delete mode 100644 modules/concepts/hooks/list-hooks/displayShoppingCartFooter.md delete mode 100644 modules/concepts/hooks/list-hooks/displayTop.md delete mode 100644 modules/concepts/hooks/list-hooks/filterProductSearch.md delete mode 100644 modules/concepts/hooks/list-hooks/validateCustomerFormFields.md delete mode 100644 modules/concepts/hooks/list-of-hooks.md rename modules/concepts/hooks/{list-hooks => list-of-hooks}/_index.md (91%) rename modules/concepts/hooks/{list-hooks => list-of-hooks}/actionAfter.md (67%) rename modules/concepts/hooks/{list-hooks => list-of-hooks}/actionBefore.md (66%) rename modules/concepts/hooks/{list-hooks => list-of-hooks}/actionListingFieldsModifier.md (67%) create mode 100644 modules/concepts/hooks/list-of-hooks/actionGridDataModifier.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionGridDefinitionModifier.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionGridFilterFormModifier.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionGridPresenterModifier.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionFormBuilderModifier.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionGridQueryBuilderModifier.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionListingFieldsModifier.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionListingResultsModifier.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionAdmin.md rename modules/concepts/hooks/{list-hooks => list-of-hooks}/actionAdminAfter.md (66%) rename modules/concepts/hooks/{list-hooks => list-of-hooks}/actionAdminBefore.md (65%) rename modules/concepts/hooks/{list-hooks => list-of-hooks}/actionAdminAdminShopParametersMetaControllerPostProcessBefore.md (51%) rename modules/concepts/hooks/{list-hooks => list-of-hooks}/actionAdminAdminWebserviceControllerPostProcessBefore.md (71%) create mode 100644 modules/concepts/hooks/list-of-hooks/actionAdminAdministrationControllerPostProcessBefore.md rename modules/concepts/hooks/{list-hooks => list-of-hooks}/actionAdminAdvancedParametersPerformanceControllerPostProcessBefore.md (51%) create mode 100644 modules/concepts/hooks/list-of-hooks/actionAdminControllerSetMedia.md rename modules/concepts/hooks/{list-hooks => list-of-hooks}/actionAdminInternationalGeolocationControllerPostProcessBefore.md (51%) rename modules/concepts/hooks/{list-hooks => list-of-hooks}/actionAdminInternationalLocalizationControllerPostProcessBefore.md (51%) rename modules/concepts/hooks/{list-hooks => list-of-hooks}/actionAdminLogsControllerPostProcessBefore.md (70%) rename modules/concepts/hooks/{list-hooks => list-of-hooks}/actionAdminMaintenanceControllerPostProcessBefore.md (70%) rename modules/concepts/hooks/{list-hooks => list-of-hooks}/actionAdminMetaAfterWriteRobotsFile.md (66%) rename modules/concepts/hooks/{list-hooks => list-of-hooks}/actionAdminOrdersTrackingNumberUpdate.md (52%) rename modules/concepts/hooks/{list-hooks => list-of-hooks}/actionAdminPreferencesControllerPostProcessBefore.md (70%) rename modules/concepts/hooks/{list-hooks => list-of-hooks}/actionAdminProductsListingFieldsModifier.md (77%) rename modules/concepts/hooks/{list-hooks => list-of-hooks}/actionAdminProductsListingResultsModifier.md (71%) rename modules/concepts/hooks/{list-hooks => list-of-hooks}/actionAdminSecurityControllerPostProcessBefore.md (53%) rename modules/concepts/hooks/{list-hooks => list-of-hooks}/actionAdminShippingPreferencesControllerPostProcessBefore.md (50%) rename modules/concepts/hooks/{list-hooks => list-of-hooks}/actionAdminShopParametersOrderPreferencesControllerPostProcessBefore.md (51%) rename modules/concepts/hooks/{list-hooks => list-of-hooks}/actionAdminShopParametersProductPreferencesControllerPostProcessBefore.md (73%) create mode 100644 modules/concepts/hooks/list-of-hooks/actionAfterCreateFormHandler.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionAfterUpdateFormHandler.md rename modules/concepts/hooks/{list-hooks => list-of-hooks}/actionAjaxDie.md (63%) rename modules/concepts/hooks/{list-hooks => list-of-hooks}/actionAjaxDieBefore.md (65%) rename modules/concepts/hooks/{list-hooks => list-of-hooks}/actionAttributeCombinationDelete.md (63%) rename modules/concepts/hooks/{list-hooks => list-of-hooks}/actionAttributeCombinationSave.md (65%) create mode 100644 modules/concepts/hooks/list-of-hooks/actionAttributeDelete.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionAttributeGroupDelete.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionAttributeGroupSave.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionAttributeSave.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionAuthentication.md rename modules/concepts/hooks/{list-hooks => list-of-hooks}/actionAuthenticationBefore.md (60%) rename modules/concepts/hooks/{list-hooks/actionBeforeAjaxDie.md => list-of-hooks/actionBeforeAjaxDie.md} (50%) create mode 100644 modules/concepts/hooks/list-of-hooks/actionBeforeUpdateFormHandler.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionBuildFrontEndObject.md rename modules/concepts/hooks/{list-hooks => list-of-hooks}/actionCarrierProcess.md (56%) rename modules/concepts/hooks/{list-hooks => list-of-hooks}/actionCarrierUpdate.md (61%) create mode 100644 modules/concepts/hooks/list-of-hooks/actionCartSave.md rename modules/concepts/hooks/{list-hooks => list-of-hooks}/actionCartSummary.md (58%) rename modules/concepts/hooks/{list-hooks => list-of-hooks}/actionCartUpdateQuantityBefore.md (58%) create mode 100644 modules/concepts/hooks/list-of-hooks/actionCategoryAdd.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionCategoryDelete.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionCategoryUpdate.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionCheckoutRender.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionClearCache.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionClearCompileCache.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionClearSf2Cache.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionCustomerAccountAdd.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionCustomerAccountUpdate.md rename modules/concepts/hooks/{list-hooks => list-of-hooks}/actionCustomerAddGroups.md (62%) rename modules/concepts/hooks/{list-hooks => list-of-hooks}/actionCustomerBeforeUpdateGroup.md (63%) create mode 100644 modules/concepts/hooks/list-of-hooks/actionCustomerLogoutAfter.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionCustomerLogoutBefore.md rename modules/concepts/hooks/{list-hooks => list-of-hooks}/actionDeleteGDPRCustomer.md (61%) rename modules/concepts/hooks/{list-hooks => list-of-hooks}/actionDeliveryPriceByPrice.md (65%) rename modules/concepts/hooks/{list-hooks => list-of-hooks}/actionDeliveryPriceByWeight.md (65%) rename modules/concepts/hooks/{list-hooks => list-of-hooks}/actionDispatcher.md (60%) create mode 100644 modules/concepts/hooks/list-of-hooks/actionDispatcherAfter.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionDispatcherBefore.md rename modules/concepts/hooks/{list-hooks => list-of-hooks}/actionDownloadAttachment.md (64%) rename modules/concepts/hooks/{list-hooks => list-of-hooks}/actionExportGDPRData.md (61%) create mode 100644 modules/concepts/hooks/list-of-hooks/actionFeatureDelete.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionFeatureSave.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionFeatureValueDelete.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionFeatureValueSave.md rename modules/concepts/hooks/{list-hooks => list-of-hooks}/actionFrontControllerSetMedia.md (62%) rename modules/concepts/hooks/{list-hooks => list-of-hooks}/actionGetIDZoneByAddressID.md (60%) rename modules/concepts/hooks/{list-hooks => list-of-hooks}/actionGetProductPropertiesAfter.md (67%) rename modules/concepts/hooks/{list-hooks => list-of-hooks}/actionGetProductPropertiesAfterUnitPrice.md (54%) rename modules/concepts/hooks/{list-hooks => list-of-hooks}/actionGetProductPropertiesBefore.md (67%) create mode 100644 modules/concepts/hooks/list-of-hooks/actionHtaccessCreate.md rename modules/concepts/hooks/{list-hooks => list-of-hooks}/actionInvoiceNumberFormatted.md (71%) rename modules/concepts/hooks/{list-hooks => list-of-hooks}/actionMailAlterMessageBeforeSend.md (63%) rename modules/concepts/hooks/{list-hooks => list-of-hooks}/actionModuleInstallAfter.md (50%) rename modules/concepts/hooks/{list-hooks => list-of-hooks}/actionModuleInstallBefore.md (50%) rename modules/concepts/hooks/{list-hooks => list-of-hooks}/actionModuleUnRegisterHookBefore.md (63%) rename modules/concepts/hooks/{list-hooks => list-of-hooks}/actionModuleUninstallAfter.md (50%) rename modules/concepts/hooks/{list-hooks => list-of-hooks}/actionModuleUninstallBefore.md (50%) rename modules/concepts/hooks/{list-hooks => list-of-hooks}/actionObjectAddAfter.md (62%) rename modules/concepts/hooks/{list-hooks => list-of-hooks}/actionObjectAddBefore.md (62%) rename modules/concepts/hooks/{list-hooks => list-of-hooks}/actionObjectDeleteAfter.md (63%) rename modules/concepts/hooks/{list-hooks => list-of-hooks}/actionObjectDeleteBefore.md (63%) rename modules/concepts/hooks/{list-hooks => list-of-hooks}/actionObjectUpdateAfter.md (63%) rename modules/concepts/hooks/{list-hooks => list-of-hooks}/actionObjectUpdateBefore.md (63%) rename modules/concepts/hooks/{list-hooks => list-of-hooks}/actionObjectAddAfter.md (59%) rename modules/concepts/hooks/{list-hooks => list-of-hooks}/actionObjectAddBefore.md (59%) rename modules/concepts/hooks/{list-hooks => list-of-hooks}/actionObjectAttributeAddBefore.md (63%) rename modules/concepts/hooks/{list-hooks => list-of-hooks}/actionObjectAttributeGroupAddBefore.md (63%) rename modules/concepts/hooks/{list-hooks => list-of-hooks}/actionObjectDeleteAfter.md (59%) rename modules/concepts/hooks/{list-hooks => list-of-hooks}/actionObjectDeleteBefore.md (59%) rename modules/concepts/hooks/{list-hooks => list-of-hooks}/actionObjectProductCommentValidateAfter.md (64%) create mode 100644 modules/concepts/hooks/list-of-hooks/actionObjectProductInCartDeleteAfter.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionObjectProductInCartDeleteBefore.md rename modules/concepts/hooks/{list-hooks => list-of-hooks}/actionObjectUpdateAfter.md (59%) rename modules/concepts/hooks/{list-hooks => list-of-hooks}/actionObjectUpdateBefore.md (59%) rename modules/concepts/hooks/{list-hooks => list-of-hooks}/actionOnImageCutAfter.md (63%) rename modules/concepts/hooks/{list-hooks => list-of-hooks}/actionOnImageResizeAfter.md (63%) rename modules/concepts/hooks/{list-hooks => list-of-hooks}/actionOrderEdited.md (53%) rename modules/concepts/hooks/{list-hooks => list-of-hooks}/actionOrderHistoryAddAfter.md (65%) create mode 100644 modules/concepts/hooks/list-of-hooks/actionOrderReturn.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionOrderSlipAdd.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionOutputHTMLBefore.md rename modules/concepts/hooks/{list-hooks => list-of-hooks}/actionPDFInvoiceRender.md (65%) rename modules/concepts/hooks/{list-hooks => list-of-hooks}/actionPasswordRenew.md (65%) rename modules/concepts/hooks/{list-hooks => list-of-hooks}/actionPaymentCCAdd.md (51%) rename modules/concepts/hooks/{list-hooks => list-of-hooks}/actionPaymentConfirmation.md (51%) create mode 100644 modules/concepts/hooks/list-of-hooks/actionProductActivation.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionProductAdd.md rename modules/concepts/hooks/{list-hooks => list-of-hooks}/actionProductAttributeDelete.md (50%) create mode 100644 modules/concepts/hooks/list-of-hooks/actionProductAttributeUpdate.md rename modules/concepts/hooks/{list-hooks => list-of-hooks}/actionProductCancel.md (63%) create mode 100644 modules/concepts/hooks/list-of-hooks/actionProductDelete.md rename modules/concepts/hooks/{list-hooks => list-of-hooks}/actionProductOutOfStock.md (50%) create mode 100644 modules/concepts/hooks/list-of-hooks/actionProductSave.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionProductSearchAfter.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionProductSearchProviderRunQueryAfter.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionProductSearchProviderRunQueryBefore.md rename modules/concepts/hooks/{list-hooks => list-of-hooks}/actionProductUpdate.md (52%) rename modules/concepts/hooks/{list-hooks => list-of-hooks}/actionSearch.md (73%) rename modules/concepts/hooks/{list-hooks => list-of-hooks}/actionSetInvoice.md (72%) create mode 100644 modules/concepts/hooks/list-of-hooks/actionShopDataDuplication.md rename modules/concepts/hooks/{list-hooks => list-of-hooks}/actionSubmitAccountBefore.md (63%) rename modules/concepts/hooks/{list-hooks => list-of-hooks}/actionSubmitCustomerAddressForm.md (63%) create mode 100644 modules/concepts/hooks/list-of-hooks/actionUpdateLangAfter.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionValidateCustomerAddressForm.md rename modules/concepts/hooks/{list-hooks => list-of-hooks}/actionValidateOrder.md (67%) rename modules/concepts/hooks/{list-hooks => list-of-hooks}/actionWatermark.md (58%) rename modules/concepts/hooks/{list-hooks => list-of-hooks}/actionWishlistAddProduct.md (74%) create mode 100644 modules/concepts/hooks/list-of-hooks/addWebserviceResources.md create mode 100644 modules/concepts/hooks/list-of-hooks/additionalCustomerAddressFields.md create mode 100644 modules/concepts/hooks/list-of-hooks/additionalCustomerFormFields.md rename modules/concepts/hooks/{list-hooks => list-of-hooks}/dashboardData.md (63%) rename modules/concepts/hooks/{list-hooks => list-of-hooks}/dashboardZoneOne.md (62%) create mode 100644 modules/concepts/hooks/list-of-hooks/dashboardZoneThree.md rename modules/concepts/hooks/{list-hooks => list-of-hooks}/dashboardZoneTwo.md (62%) create mode 100644 modules/concepts/hooks/list-of-hooks/displayAdditionalCustomerAddressFields.md rename modules/concepts/hooks/{list-hooks => list-of-hooks}/displayAdminAfterHeader.md (66%) create mode 100644 modules/concepts/hooks/list-of-hooks/displayAdminCustomers.md create mode 100644 modules/concepts/hooks/list-of-hooks/displayAdminEndContent.md rename modules/concepts/hooks/{list-hooks => list-of-hooks}/displayAdminForm.md (66%) rename modules/concepts/hooks/{list-hooks => list-of-hooks}/displayAdminGridTableAfter.md (62%) rename modules/concepts/hooks/{list-hooks => list-of-hooks}/displayAdminGridTableBefore.md (61%) rename modules/concepts/hooks/{list-hooks => list-of-hooks}/displayAdminListAfter.md (66%) rename modules/concepts/hooks/{list-hooks => list-of-hooks}/displayAdminListBefore.md (66%) rename modules/concepts/hooks/{list-hooks => list-of-hooks}/displayAdminNavBarBeforeEnd.md (67%) rename modules/concepts/hooks/{list-hooks => list-of-hooks}/displayAdminOptions.md (66%) create mode 100644 modules/concepts/hooks/list-of-hooks/displayAdminOrder.md rename modules/concepts/hooks/{list-hooks => list-of-hooks}/displayAdminOrderCreateExtraButtons.md (53%) rename modules/concepts/hooks/{list-hooks => list-of-hooks}/displayAdminOrderMain.md (51%) rename modules/concepts/hooks/{list-hooks => list-of-hooks}/displayAdminOrderMainBottom.md (52%) rename modules/concepts/hooks/{list-hooks => list-of-hooks}/displayAdminOrderSide.md (51%) rename modules/concepts/hooks/{list-hooks => list-of-hooks}/displayAdminOrderSideBottom.md (69%) rename modules/concepts/hooks/{list-hooks => list-of-hooks}/displayAdminProductsCombinationBottom.md (55%) create mode 100644 modules/concepts/hooks/list-of-hooks/displayAdminProductsMainStepLeftColumnBottom.md create mode 100644 modules/concepts/hooks/list-of-hooks/displayAdminProductsMainStepLeftColumnMiddle.md create mode 100644 modules/concepts/hooks/list-of-hooks/displayAdminProductsMainStepRightColumnBottom.md rename modules/concepts/hooks/{list-hooks => list-of-hooks}/displayAdminProductsOptionsStepBottom.md (51%) rename modules/concepts/hooks/{list-hooks => list-of-hooks}/displayAdminProductsOptionsStepTop.md (50%) rename modules/concepts/hooks/{list-hooks => list-of-hooks}/displayAdminProductsPriceStepBottom.md (51%) rename modules/concepts/hooks/{list-hooks => list-of-hooks}/displayAdminProductsQuantitiesStepBottom.md (50%) rename modules/concepts/hooks/{list-hooks => list-of-hooks}/displayAdminProductsSeoStepBottom.md (51%) rename modules/concepts/hooks/{list-hooks => list-of-hooks}/displayAdminProductsShippingStepBottom.md (51%) rename modules/concepts/hooks/{list-hooks => list-of-hooks}/displayAdminStatsModules.md (55%) rename modules/concepts/hooks/{list-hooks => list-of-hooks}/displayAdminThemesListAfter.md (55%) rename modules/concepts/hooks/{list-hooks => list-of-hooks}/displayAdminView.md (65%) create mode 100644 modules/concepts/hooks/list-of-hooks/displayAfterBodyOpeningTag.md rename modules/concepts/hooks/{list-hooks => list-of-hooks}/displayAfterCarrier.md (50%) create mode 100644 modules/concepts/hooks/list-of-hooks/displayAfterProductThumbs.md create mode 100644 modules/concepts/hooks/list-of-hooks/displayAfterTitleTag.md create mode 100644 modules/concepts/hooks/list-of-hooks/displayBackOfficeCategory.md create mode 100644 modules/concepts/hooks/list-of-hooks/displayBackOfficeTop.md create mode 100644 modules/concepts/hooks/list-of-hooks/displayBanner.md create mode 100644 modules/concepts/hooks/list-of-hooks/displayBeforeBodyClosingTag.md rename modules/concepts/hooks/{list-hooks => list-of-hooks}/displayBeforeCarrier.md (50%) rename modules/concepts/hooks/{list-hooks => list-of-hooks}/displayCMSDisputeInformation.md (61%) rename modules/concepts/hooks/{list-hooks => list-of-hooks}/displayCMSPrintButton.md (60%) create mode 100644 modules/concepts/hooks/list-of-hooks/displayCarrierExtraContent.md rename modules/concepts/hooks/{list-hooks => list-of-hooks}/displayCartExtraProductActions.md (51%) create mode 100644 modules/concepts/hooks/list-of-hooks/displayCartModalContent.md create mode 100644 modules/concepts/hooks/list-of-hooks/displayCartModalFooter.md create mode 100644 modules/concepts/hooks/list-of-hooks/displayCheckoutBeforeConfirmation.md rename modules/concepts/hooks/{list-hooks => list-of-hooks}/displayCheckoutSubtotalDetails.md (67%) rename modules/concepts/hooks/{list-hooks => list-of-hooks}/displayCheckoutSummaryTop.md (50%) rename modules/concepts/hooks/{list-hooks => list-of-hooks}/displayCrossSellingShoppingCart.md (62%) create mode 100644 modules/concepts/hooks/list-of-hooks/displayCustomerAccount.md create mode 100644 modules/concepts/hooks/list-of-hooks/displayCustomerAccountForm.md create mode 100644 modules/concepts/hooks/list-of-hooks/displayCustomerAccountFormTop.md create mode 100644 modules/concepts/hooks/list-of-hooks/displayCustomerLoginFormAfter.md rename modules/concepts/hooks/{list-hooks => list-of-hooks}/displayCustomization.md (62%) create mode 100644 modules/concepts/hooks/list-of-hooks/displayDashboardToolbarIcons.md create mode 100644 modules/concepts/hooks/list-of-hooks/displayDashboardToolbarTopMenu.md rename modules/concepts/hooks/{list-hooks => list-of-hooks}/displayDashboardTop.md (53%) create mode 100644 modules/concepts/hooks/list-of-hooks/displayEmptyModuleCategoryExtraMessage.md rename modules/concepts/hooks/{list-hooks => list-of-hooks}/displayExpressCheckout.md (65%) rename modules/concepts/hooks/{list-hooks => list-of-hooks}/displayFeatureForm.md (54%) create mode 100644 modules/concepts/hooks/list-of-hooks/displayFooter.md rename modules/concepts/hooks/{list-hooks => list-of-hooks}/displayFooterAfter.md (61%) rename modules/concepts/hooks/{list-hooks => list-of-hooks}/displayFooterBefore.md (61%) rename modules/concepts/hooks/{list-hooks => list-of-hooks}/displayFooterProduct.md (50%) rename modules/concepts/hooks/{list-hooks => list-of-hooks}/displayGDPRConsent.md (69%) create mode 100644 modules/concepts/hooks/list-of-hooks/displayHeader.md create mode 100644 modules/concepts/hooks/list-of-hooks/displayHome.md create mode 100644 modules/concepts/hooks/list-of-hooks/displayInvoiceLegalFreeText.md create mode 100644 modules/concepts/hooks/list-of-hooks/displayLeftColumnProduct.md create mode 100644 modules/concepts/hooks/list-of-hooks/displayMaintenance.md rename modules/concepts/hooks/{list-hooks => list-of-hooks}/displayMyAccountBlock.md (51%) rename modules/concepts/hooks/{list-hooks => list-of-hooks}/displayNav1.md (62%) rename modules/concepts/hooks/{list-hooks => list-of-hooks}/displayNav2.md (62%) create mode 100644 modules/concepts/hooks/list-of-hooks/displayNavFullWidth.md rename modules/concepts/hooks/{list-hooks => list-of-hooks}/displayNewsletterRegistration.md (68%) rename modules/concepts/hooks/{list-hooks => list-of-hooks}/displayNotFound.md (61%) create mode 100644 modules/concepts/hooks/list-of-hooks/displayOrderConfirmation.md rename modules/concepts/hooks/{list-hooks => list-of-hooks}/displayOrderConfirmation1.md (64%) rename modules/concepts/hooks/{list-hooks => list-of-hooks}/displayOrderConfirmation2.md (64%) create mode 100644 modules/concepts/hooks/list-of-hooks/displayOrderDetail.md rename modules/concepts/hooks/{list-hooks => list-of-hooks}/displayOrderPreview.md (68%) create mode 100644 modules/concepts/hooks/list-of-hooks/displayPaymentByBinaries.md rename modules/concepts/hooks/{list-hooks => list-of-hooks}/displayPaymentReturn.md (57%) create mode 100644 modules/concepts/hooks/list-of-hooks/displayPaymentTop.md create mode 100644 modules/concepts/hooks/list-of-hooks/displayPersonalInformationTop.md create mode 100644 modules/concepts/hooks/list-of-hooks/displayProductActions.md rename modules/concepts/hooks/{list-hooks => list-of-hooks}/displayProductAdditionalInfo.md (50%) rename modules/concepts/hooks/{list-hooks => list-of-hooks}/displayProductListReviews.md (66%) rename modules/concepts/hooks/{list-hooks => list-of-hooks}/displayProductPriceBlock.md (68%) rename modules/concepts/hooks/{list-hooks => list-of-hooks}/displayReassurance.md (61%) create mode 100644 modules/concepts/hooks/list-of-hooks/displayRightColumnProduct.md rename modules/concepts/hooks/{list-hooks => list-of-hooks}/displaySearch.md (60%) create mode 100644 modules/concepts/hooks/list-of-hooks/displayShoppingCart.md create mode 100644 modules/concepts/hooks/list-of-hooks/displayShoppingCartFooter.md create mode 100644 modules/concepts/hooks/list-of-hooks/displayTop.md create mode 100644 modules/concepts/hooks/list-of-hooks/filterProductSearch.md rename modules/concepts/hooks/{list-hooks => list-of-hooks}/legacyblockkpi.md (70%) rename modules/concepts/hooks/{list-hooks => list-of-hooks}/moduleRoutes.md (60%) rename modules/concepts/hooks/{list-hooks => list-of-hooks}/overrideMinimalPurchasePrice.md (67%) rename modules/concepts/hooks/{list-hooks => list-of-hooks}/termsAndConditions.md (63%) create mode 100644 modules/concepts/hooks/list-of-hooks/validateCustomerFormFields.md diff --git a/modules/concepts/hooks/list-hooks/actionAdminAdministrationControllerPostProcessBefore.md b/modules/concepts/hooks/list-hooks/actionAdminAdministrationControllerPostProcessBefore.md deleted file mode 100644 index 5247d7d162..0000000000 --- a/modules/concepts/hooks/list-hooks/actionAdminAdministrationControllerPostProcessBefore.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -menuTitle: actionAdminAdministrationControllerPostProcessBefore -title: actionAdminAdministrationControllerPostProcessBefore -hidden: true -files: - - src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/AdministrationController.php -types: - - backoffice -hookTypes: - - symfony ---- - -# Hook : actionAdminAdministrationControllerPostProcessBefore - -Located in : - - - src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/AdministrationController.php - -## Parameters - -```php -dispatchHook('actionAdminAdministrationControllerPostProcessBefore', ['controller' => $this]); -``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionAdminControllerSetMedia.md b/modules/concepts/hooks/list-hooks/actionAdminControllerSetMedia.md deleted file mode 100644 index 67f329be30..0000000000 --- a/modules/concepts/hooks/list-hooks/actionAdminControllerSetMedia.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -menuTitle: actionAdminControllerSetMedia -title: actionAdminControllerSetMedia -hidden: true -files: - - classes/controller/AdminController.php -types: - - backoffice -hookTypes: - - legacy ---- - -# Hook : actionAdminControllerSetMedia - -Located in : - - - classes/controller/AdminController.php - -## Parameters - -```php -Hook::exec('actionAdminControllerSetMedia'); -``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionAttributeDelete.md b/modules/concepts/hooks/list-hooks/actionAttributeDelete.md deleted file mode 100644 index e074a0ccdd..0000000000 --- a/modules/concepts/hooks/list-hooks/actionAttributeDelete.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -menuTitle: actionAttributeDelete -title: actionAttributeDelete -hidden: true -files: - - classes/ProductAttribute.php -types: - - frontoffice -hookTypes: - - legacy ---- - -# Hook : actionAttributeDelete - -Located in : - - - classes/ProductAttribute.php - -## Parameters - -```php -Hook::exec('actionAttributeDelete', ['id_attribute' => $this->id]); -``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionAttributeGroupDelete.md b/modules/concepts/hooks/list-hooks/actionAttributeGroupDelete.md deleted file mode 100644 index 0997e4853a..0000000000 --- a/modules/concepts/hooks/list-hooks/actionAttributeGroupDelete.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -menuTitle: actionAttributeGroupDelete -title: actionAttributeGroupDelete -hidden: true -files: - - classes/AttributeGroup.php -types: - - frontoffice -hookTypes: - - legacy ---- - -# Hook : actionAttributeGroupDelete - -Located in : - - - classes/AttributeGroup.php - -## Parameters - -```php -Hook::exec('actionAttributeGroupDelete', ['id_attribute_group' => $this->id]); -``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionAttributeGroupSave.md b/modules/concepts/hooks/list-hooks/actionAttributeGroupSave.md deleted file mode 100644 index 61a89eaba3..0000000000 --- a/modules/concepts/hooks/list-hooks/actionAttributeGroupSave.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -menuTitle: actionAttributeGroupSave -title: actionAttributeGroupSave -hidden: true -files: - - classes/AttributeGroup.php -types: - - frontoffice -hookTypes: - - legacy ---- - -# Hook : actionAttributeGroupSave - -Located in : - - - classes/AttributeGroup.php - -## Parameters - -```php -Hook::exec('actionAttributeGroupSave', ['id_attribute_group' => $this->id]); -``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionAttributeSave.md b/modules/concepts/hooks/list-hooks/actionAttributeSave.md deleted file mode 100644 index 810c8ad565..0000000000 --- a/modules/concepts/hooks/list-hooks/actionAttributeSave.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -menuTitle: actionAttributeSave -title: actionAttributeSave -hidden: true -files: - - classes/ProductAttribute.php -types: - - frontoffice -hookTypes: - - legacy ---- - -# Hook : actionAttributeSave - -Located in : - - - classes/ProductAttribute.php - -## Parameters - -```php -Hook::exec('actionAttributeSave', ['id_attribute' => $this->id]); -``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionAuthentication.md b/modules/concepts/hooks/list-hooks/actionAuthentication.md deleted file mode 100644 index ec5d84b2fa..0000000000 --- a/modules/concepts/hooks/list-hooks/actionAuthentication.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -menuTitle: actionAuthentication -title: actionAuthentication -hidden: true -files: - - classes/form/CustomerLoginForm.php -types: - - frontoffice -hookTypes: - - legacy ---- - -# Hook : actionAuthentication - -Located in : - - - classes/form/CustomerLoginForm.php - -## Parameters - -```php -Hook::exec('actionAuthentication', ['customer' => $this->context->customer]); -``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionBuildFrontEndObject.md b/modules/concepts/hooks/list-hooks/actionBuildFrontEndObject.md deleted file mode 100644 index 2efc65d1be..0000000000 --- a/modules/concepts/hooks/list-hooks/actionBuildFrontEndObject.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -menuTitle: actionBuildFrontEndObject -title: actionBuildFrontEndObject -hidden: true -files: - - classes/controller/FrontController.php -types: - - frontoffice -hookTypes: - - legacy ---- - -# Hook : actionBuildFrontEndObject - -Located in : - - - classes/controller/FrontController.php - -## Parameters - -```php -Hook::exec('actionBuildFrontEndObject', [ - 'obj' => &$object, - ]); -``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionCartSave.md b/modules/concepts/hooks/list-hooks/actionCartSave.md deleted file mode 100644 index d645b8f4c9..0000000000 --- a/modules/concepts/hooks/list-hooks/actionCartSave.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -menuTitle: actionCartSave -title: actionCartSave -hidden: true -files: - - classes/Cart.php -types: - - frontoffice -hookTypes: - - legacy ---- - -# Hook : actionCartSave - -Located in : - - - classes/Cart.php - -## Parameters - -```php -Hook::exec('actionCartSave', ['cart' => $this]); -``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionCategoryAdd.md b/modules/concepts/hooks/list-hooks/actionCategoryAdd.md deleted file mode 100644 index ad46e8d3fe..0000000000 --- a/modules/concepts/hooks/list-hooks/actionCategoryAdd.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -menuTitle: actionCategoryAdd -title: actionCategoryAdd -hidden: true -files: - - classes/Category.php -types: - - frontoffice -hookTypes: - - legacy ---- - -# Hook : actionCategoryAdd - -Located in : - - - classes/Category.php - -## Parameters - -```php -Hook::exec('actionCategoryAdd', ['category' => $this]); -``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionCategoryDelete.md b/modules/concepts/hooks/list-hooks/actionCategoryDelete.md deleted file mode 100644 index d69c3fd2fd..0000000000 --- a/modules/concepts/hooks/list-hooks/actionCategoryDelete.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -menuTitle: actionCategoryDelete -title: actionCategoryDelete -hidden: true -files: - - classes/Category.php -types: - - frontoffice -hookTypes: - - legacy ---- - -# Hook : actionCategoryDelete - -Located in : - - - classes/Category.php - -## Parameters - -```php -Hook::exec('actionCategoryDelete', ['category' => $this, 'deleted_children' => $deletedChildren]); -``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionCategoryUpdate.md b/modules/concepts/hooks/list-hooks/actionCategoryUpdate.md deleted file mode 100644 index 928aded0fd..0000000000 --- a/modules/concepts/hooks/list-hooks/actionCategoryUpdate.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -menuTitle: actionCategoryUpdate -title: actionCategoryUpdate -hidden: true -files: - - controllers/admin/AdminProductsController.php -types: - - backoffice -hookTypes: - - legacy ---- - -# Hook : actionCategoryUpdate - -Located in : - - - controllers/admin/AdminProductsController.php - -## Parameters - -```php -Hook::exec('actionCategoryUpdate', ['category' => $category]); -``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionCheckoutRender.md b/modules/concepts/hooks/list-hooks/actionCheckoutRender.md deleted file mode 100644 index 99bc8b6e06..0000000000 --- a/modules/concepts/hooks/list-hooks/actionCheckoutRender.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -menuTitle: actionCheckoutRender -title: actionCheckoutRender -hidden: true -files: - - controllers/front/OrderController.php -types: - - frontoffice -hookTypes: - - legacy ---- - -# Hook : actionCheckoutRender - -Located in : - - - controllers/front/OrderController.php - -## Parameters - -```php -Hook::exec('actionCheckoutRender', ['checkoutProcess' => &$this->checkoutProcess]); -``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionClearCache.md b/modules/concepts/hooks/list-hooks/actionClearCache.md deleted file mode 100644 index 07c9c860c2..0000000000 --- a/modules/concepts/hooks/list-hooks/actionClearCache.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -menuTitle: actionClearCache -title: actionClearCache -hidden: true -files: - - classes/Tools.php -types: - - frontoffice -hookTypes: - - legacy ---- - -# Hook : actionClearCache - -Located in : - - - classes/Tools.php - -## Parameters - -```php -Hook::exec('actionClearCache'); -``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionClearCompileCache.md b/modules/concepts/hooks/list-hooks/actionClearCompileCache.md deleted file mode 100644 index 1b55b04848..0000000000 --- a/modules/concepts/hooks/list-hooks/actionClearCompileCache.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -menuTitle: actionClearCompileCache -title: actionClearCompileCache -hidden: true -files: - - classes/Tools.php -types: - - frontoffice -hookTypes: - - legacy ---- - -# Hook : actionClearCompileCache - -Located in : - - - classes/Tools.php - -## Parameters - -```php -Hook::exec('actionClearCompileCache'); -``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionClearSf2Cache.md b/modules/concepts/hooks/list-hooks/actionClearSf2Cache.md deleted file mode 100644 index 2b13a3914a..0000000000 --- a/modules/concepts/hooks/list-hooks/actionClearSf2Cache.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -menuTitle: actionClearSf2Cache -title: actionClearSf2Cache -hidden: true -files: - - src/Adapter/Cache/Clearer/SymfonyCacheClearer.php -types: - - frontoffice -hookTypes: - - legacy ---- - -# Hook : actionClearSf2Cache - -Located in : - - - src/Adapter/Cache/Clearer/SymfonyCacheClearer.php - -## Parameters - -```php -Hook::exec('actionClearSf2Cache'); -``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionCustomerAccountAdd.md b/modules/concepts/hooks/list-hooks/actionCustomerAccountAdd.md deleted file mode 100644 index 49c36d00a3..0000000000 --- a/modules/concepts/hooks/list-hooks/actionCustomerAccountAdd.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -menuTitle: actionCustomerAccountAdd -title: actionCustomerAccountAdd -hidden: true -files: - - classes/form/CustomerPersister.php -types: - - frontoffice -hookTypes: - - legacy ---- - -# Hook : actionCustomerAccountAdd - -Located in : - - - classes/form/CustomerPersister.php - -## Parameters - -```php -Hook::exec('actionCustomerAccountAdd', [ - 'newCustomer' => $customer, - ]); -``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionCustomerAccountUpdate.md b/modules/concepts/hooks/list-hooks/actionCustomerAccountUpdate.md deleted file mode 100644 index 488d517e27..0000000000 --- a/modules/concepts/hooks/list-hooks/actionCustomerAccountUpdate.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -menuTitle: actionCustomerAccountUpdate -title: actionCustomerAccountUpdate -hidden: true -files: - - classes/form/CustomerPersister.php -types: - - frontoffice -hookTypes: - - legacy ---- - -# Hook : actionCustomerAccountUpdate - -Located in : - - - classes/form/CustomerPersister.php - -## Parameters - -```php -Hook::exec('actionCustomerAccountUpdate', [ - 'customer' => $customer, - ]); -``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionCustomerLogoutAfter.md b/modules/concepts/hooks/list-hooks/actionCustomerLogoutAfter.md deleted file mode 100644 index 0d3538da65..0000000000 --- a/modules/concepts/hooks/list-hooks/actionCustomerLogoutAfter.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -menuTitle: actionCustomerLogoutAfter -title: actionCustomerLogoutAfter -hidden: true -files: - - classes/Customer.php -types: - - frontoffice -hookTypes: - - legacy ---- - -# Hook : actionCustomerLogoutAfter - -Located in : - - - classes/Customer.php - -## Parameters - -```php -Hook::exec('actionCustomerLogoutAfter', ['customer' => $this]); -``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionCustomerLogoutBefore.md b/modules/concepts/hooks/list-hooks/actionCustomerLogoutBefore.md deleted file mode 100644 index 854f82e76e..0000000000 --- a/modules/concepts/hooks/list-hooks/actionCustomerLogoutBefore.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -menuTitle: actionCustomerLogoutBefore -title: actionCustomerLogoutBefore -hidden: true -files: - - classes/Customer.php -types: - - frontoffice -hookTypes: - - legacy ---- - -# Hook : actionCustomerLogoutBefore - -Located in : - - - classes/Customer.php - -## Parameters - -```php -Hook::exec('actionCustomerLogoutBefore', ['customer' => $this]); -``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionDispatcherAfter.md b/modules/concepts/hooks/list-hooks/actionDispatcherAfter.md deleted file mode 100644 index 765c4e8279..0000000000 --- a/modules/concepts/hooks/list-hooks/actionDispatcherAfter.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -menuTitle: actionDispatcherAfter -title: actionDispatcherAfter -hidden: true -files: - - classes/Dispatcher.php -types: - - frontoffice -hookTypes: - - legacy ---- - -# Hook : actionDispatcherAfter - -Located in : - - - classes/Dispatcher.php - -## Parameters - -```php -Hook::exec('actionDispatcherAfter', $params_hook_action_dispatcher); -``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionDispatcherBefore.md b/modules/concepts/hooks/list-hooks/actionDispatcherBefore.md deleted file mode 100644 index fce3f69bdb..0000000000 --- a/modules/concepts/hooks/list-hooks/actionDispatcherBefore.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -menuTitle: actionDispatcherBefore -title: actionDispatcherBefore -hidden: true -files: - - classes/Dispatcher.php -types: - - frontoffice -hookTypes: - - legacy ---- - -# Hook : actionDispatcherBefore - -Located in : - - - classes/Dispatcher.php - -## Parameters - -```php -Hook::exec('actionDispatcherBefore', ['controller_type' => $this->front_controller]); -``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionFeatureDelete.md b/modules/concepts/hooks/list-hooks/actionFeatureDelete.md deleted file mode 100644 index 07017008ec..0000000000 --- a/modules/concepts/hooks/list-hooks/actionFeatureDelete.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -menuTitle: actionFeatureDelete -title: actionFeatureDelete -hidden: true -files: - - classes/Feature.php -types: - - frontoffice -hookTypes: - - legacy ---- - -# Hook : actionFeatureDelete - -Located in : - - - classes/Feature.php - -## Parameters - -```php -Hook::exec('actionFeatureDelete', ['id_feature' => $this->id]); -``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionFeatureSave.md b/modules/concepts/hooks/list-hooks/actionFeatureSave.md deleted file mode 100644 index 60c1227c40..0000000000 --- a/modules/concepts/hooks/list-hooks/actionFeatureSave.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -menuTitle: actionFeatureSave -title: actionFeatureSave -hidden: true -files: - - classes/Feature.php -types: - - frontoffice -hookTypes: - - legacy ---- - -# Hook : actionFeatureSave - -Located in : - - - classes/Feature.php - -## Parameters - -```php -Hook::exec('actionFeatureSave', ['id_feature' => $this->id]); -``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionFeatureValueDelete.md b/modules/concepts/hooks/list-hooks/actionFeatureValueDelete.md deleted file mode 100644 index fc1244e5ab..0000000000 --- a/modules/concepts/hooks/list-hooks/actionFeatureValueDelete.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -menuTitle: actionFeatureValueDelete -title: actionFeatureValueDelete -hidden: true -files: - - classes/FeatureValue.php -types: - - frontoffice -hookTypes: - - legacy ---- - -# Hook : actionFeatureValueDelete - -Located in : - - - classes/FeatureValue.php - -## Parameters - -```php -Hook::exec('actionFeatureValueDelete', ['id_feature_value' => $this->id]); -``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionFeatureValueSave.md b/modules/concepts/hooks/list-hooks/actionFeatureValueSave.md deleted file mode 100644 index eab6cd8e34..0000000000 --- a/modules/concepts/hooks/list-hooks/actionFeatureValueSave.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -menuTitle: actionFeatureValueSave -title: actionFeatureValueSave -hidden: true -files: - - classes/FeatureValue.php -types: - - frontoffice -hookTypes: - - legacy ---- - -# Hook : actionFeatureValueSave - -Located in : - - - classes/FeatureValue.php - -## Parameters - -```php -Hook::exec('actionFeatureValueSave', ['id_feature_value' => $this->id]); -``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionHtaccessCreate.md b/modules/concepts/hooks/list-hooks/actionHtaccessCreate.md deleted file mode 100644 index d18c82893a..0000000000 --- a/modules/concepts/hooks/list-hooks/actionHtaccessCreate.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -menuTitle: actionHtaccessCreate -title: actionHtaccessCreate -hidden: true -files: - - classes/Tools.php -types: - - frontoffice -hookTypes: - - legacy ---- - -# Hook : actionHtaccessCreate - -Located in : - - - classes/Tools.php - -## Parameters - -```php -Hook::exec('actionHtaccessCreate'); -``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionObjectProductInCartDeleteAfter.md b/modules/concepts/hooks/list-hooks/actionObjectProductInCartDeleteAfter.md deleted file mode 100644 index 0e20241ca6..0000000000 --- a/modules/concepts/hooks/list-hooks/actionObjectProductInCartDeleteAfter.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -menuTitle: actionObjectProductInCartDeleteAfter -title: actionObjectProductInCartDeleteAfter -hidden: true -files: - - controllers/front/CartController.php -types: - - backoffice - - frontoffice -hookTypes: - - legacy ---- - -# Hook : actionObjectProductInCartDeleteAfter - -Located in : - - - controllers/front/CartController.php - -## Parameters - -```php -Hook::exec('actionObjectProductInCartDeleteAfter', $data); -``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionObjectProductInCartDeleteBefore.md b/modules/concepts/hooks/list-hooks/actionObjectProductInCartDeleteBefore.md deleted file mode 100644 index 9c15df9e74..0000000000 --- a/modules/concepts/hooks/list-hooks/actionObjectProductInCartDeleteBefore.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -menuTitle: actionObjectProductInCartDeleteBefore -title: actionObjectProductInCartDeleteBefore -hidden: true -files: - - controllers/front/CartController.php -types: - - backoffice - - frontoffice -hookTypes: - - legacy ---- - -# Hook : actionObjectProductInCartDeleteBefore - -Located in : - - - controllers/front/CartController.php - -## Parameters - -```php -Hook::exec('actionObjectProductInCartDeleteBefore', $data, null, true); -``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionOrderReturn.md b/modules/concepts/hooks/list-hooks/actionOrderReturn.md deleted file mode 100644 index 5c7cccfa58..0000000000 --- a/modules/concepts/hooks/list-hooks/actionOrderReturn.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -menuTitle: actionOrderReturn -title: actionOrderReturn -hidden: true -files: - - controllers/front/OrderFollowController.php -types: - - frontoffice -hookTypes: - - legacy ---- - -# Hook : actionOrderReturn - -Located in : - - - controllers/front/OrderFollowController.php - -## Parameters - -```php -Hook::exec('actionOrderReturn', ['orderReturn' => $orderReturn]); -``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionOrderSlipAdd.md b/modules/concepts/hooks/list-hooks/actionOrderSlipAdd.md deleted file mode 100644 index 70aa20a093..0000000000 --- a/modules/concepts/hooks/list-hooks/actionOrderSlipAdd.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -menuTitle: actionOrderSlipAdd -title: actionOrderSlipAdd -hidden: true -files: - - src/Adapter/Order/Refund/OrderSlipCreator.php -types: - - frontoffice -hookTypes: - - legacy ---- - -# Hook : actionOrderSlipAdd - -Located in : - - - src/Adapter/Order/Refund/OrderSlipCreator.php - -## Parameters - -```php -Hook::exec('actionOrderSlipAdd', [ - 'order' => $order, - 'productList' => $orderRefundSummary->getProductRefunds(), - 'qtyList' => $fullQuantityList, - ], null, false, true, false, $order->id_shop); -``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionOutputHTMLBefore.md b/modules/concepts/hooks/list-hooks/actionOutputHTMLBefore.md deleted file mode 100644 index 1fb36e1533..0000000000 --- a/modules/concepts/hooks/list-hooks/actionOutputHTMLBefore.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -menuTitle: actionOutputHTMLBefore -title: actionOutputHTMLBefore -hidden: true -files: - - classes/controller/FrontController.php -types: - - frontoffice -hookTypes: - - legacy ---- - -# Hook : actionOutputHTMLBefore - -Located in : - - - classes/controller/FrontController.php - -## Parameters - -```php -Hook::exec('actionOutputHTMLBefore', ['html' => &$html]); -``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionProductAdd.md b/modules/concepts/hooks/list-hooks/actionProductAdd.md deleted file mode 100644 index a68e22c9a1..0000000000 --- a/modules/concepts/hooks/list-hooks/actionProductAdd.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -menuTitle: actionProductAdd -title: actionProductAdd -hidden: true -files: - - controllers/admin/AdminProductsController.php -types: - - backoffice -hookTypes: - - legacy ---- - -# Hook : actionProductAdd - -Located in : - - - controllers/admin/AdminProductsController.php - -## Parameters - -```php -Hook::exec('actionProductAdd', ['id_product_old' => $id_product_old, 'id_product' => (int) $product->id, 'product' => $product]); -``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionProductAttributeUpdate.md b/modules/concepts/hooks/list-hooks/actionProductAttributeUpdate.md deleted file mode 100644 index d09a97ef41..0000000000 --- a/modules/concepts/hooks/list-hooks/actionProductAttributeUpdate.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -menuTitle: actionProductAttributeUpdate -title: actionProductAttributeUpdate -hidden: true -files: - - classes/Product.php -types: - - frontoffice -hookTypes: - - legacy ---- - -# Hook : actionProductAttributeUpdate - -Located in : - - - classes/Product.php - -## Parameters - -```php -Hook::exec('actionProductAttributeUpdate', ['id_product_attribute' => (int) $id_product_attribute]); -``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionProductDelete.md b/modules/concepts/hooks/list-hooks/actionProductDelete.md deleted file mode 100644 index ed751bf882..0000000000 --- a/modules/concepts/hooks/list-hooks/actionProductDelete.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -menuTitle: actionProductDelete -title: actionProductDelete -hidden: true -files: - - classes/Product.php -types: - - frontoffice -hookTypes: - - legacy ---- - -# Hook : actionProductDelete - -Located in : - - - classes/Product.php - -## Parameters - -```php -Hook::exec('actionProductDelete', ['id_product' => (int) $this->id, 'product' => $this]); -``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionProductSave.md b/modules/concepts/hooks/list-hooks/actionProductSave.md deleted file mode 100644 index b107aa1f6b..0000000000 --- a/modules/concepts/hooks/list-hooks/actionProductSave.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -menuTitle: actionProductSave -title: actionProductSave -hidden: true -files: - - classes/Product.php -types: - - frontoffice -hookTypes: - - legacy ---- - -# Hook : actionProductSave - -Located in : - - - classes/Product.php - -## Parameters - -```php -Hook::exec('actionProductSave', ['id_product' => (int) $this->id, 'product' => $this]); -``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionProductSearchAfter.md b/modules/concepts/hooks/list-hooks/actionProductSearchAfter.md deleted file mode 100644 index 18adbd779e..0000000000 --- a/modules/concepts/hooks/list-hooks/actionProductSearchAfter.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -menuTitle: actionProductSearchAfter -title: actionProductSearchAfter -hidden: true -files: - - modules/blockwishlist/controllers/front/view.php -types: - - frontoffice -hookTypes: - - legacy ---- - -# Hook : actionProductSearchAfter - -Located in : - - - modules/blockwishlist/controllers/front/view.php - -## Parameters - -```php -Hook::exec('actionProductSearchAfter', $searchVariables); -``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionProductSearchProviderRunQueryAfter.md b/modules/concepts/hooks/list-hooks/actionProductSearchProviderRunQueryAfter.md deleted file mode 100644 index 06a226f6a5..0000000000 --- a/modules/concepts/hooks/list-hooks/actionProductSearchProviderRunQueryAfter.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -menuTitle: actionProductSearchProviderRunQueryAfter -title: actionProductSearchProviderRunQueryAfter -hidden: true -files: - - classes/controller/ProductListingFrontController.php -types: - - frontoffice -hookTypes: - - legacy ---- - -# Hook : actionProductSearchProviderRunQueryAfter - -Located in : - - - classes/controller/ProductListingFrontController.php - -## Parameters - -```php -Hook::exec('actionProductSearchProviderRunQueryAfter', [ - 'query' => $query, - 'result' => $result, - ]); -``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionProductSearchProviderRunQueryBefore.md b/modules/concepts/hooks/list-hooks/actionProductSearchProviderRunQueryBefore.md deleted file mode 100644 index e28d4cbc8b..0000000000 --- a/modules/concepts/hooks/list-hooks/actionProductSearchProviderRunQueryBefore.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -menuTitle: actionProductSearchProviderRunQueryBefore -title: actionProductSearchProviderRunQueryBefore -hidden: true -files: - - classes/controller/ProductListingFrontController.php -types: - - frontoffice -hookTypes: - - legacy ---- - -# Hook : actionProductSearchProviderRunQueryBefore - -Located in : - - - classes/controller/ProductListingFrontController.php - -## Parameters - -```php -Hook::exec('actionProductSearchProviderRunQueryBefore', [ - 'query' => $query, - ]); -``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionShopDataDuplication.md b/modules/concepts/hooks/list-hooks/actionShopDataDuplication.md deleted file mode 100644 index 626b3cbe50..0000000000 --- a/modules/concepts/hooks/list-hooks/actionShopDataDuplication.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -menuTitle: actionShopDataDuplication -title: actionShopDataDuplication -hidden: true -files: - - classes/shop/Shop.php -types: - - frontoffice -hookTypes: - - legacy ---- - -# Hook : actionShopDataDuplication - -Located in : - - - classes/shop/Shop.php - -## Parameters - -```php -Hook::exec('actionShopDataDuplication', [ - 'old_id_shop' => (int) $old_id, - 'new_id_shop' => (int) $this->id, - ], $m['id_module']); -``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionUpdateLangAfter.md b/modules/concepts/hooks/list-hooks/actionUpdateLangAfter.md deleted file mode 100644 index 3b50006c66..0000000000 --- a/modules/concepts/hooks/list-hooks/actionUpdateLangAfter.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -menuTitle: actionUpdateLangAfter -title: actionUpdateLangAfter -hidden: true -files: - - classes/Language.php -types: - - frontoffice -hookTypes: - - legacy ---- - -# Hook : actionUpdateLangAfter - -Located in : - - - classes/Language.php - -## Parameters - -```php -Hook::exec('actionUpdateLangAfter', ['lang' => $language]); -``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionValidateCustomerAddressForm.md b/modules/concepts/hooks/list-hooks/actionValidateCustomerAddressForm.md deleted file mode 100644 index 0220f098f5..0000000000 --- a/modules/concepts/hooks/list-hooks/actionValidateCustomerAddressForm.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -menuTitle: actionValidateCustomerAddressForm -title: actionValidateCustomerAddressForm -hidden: true -files: - - classes/form/CustomerAddressForm.php -types: - - frontoffice -hookTypes: - - legacy ---- - -# Hook : actionValidateCustomerAddressForm - -Located in : - - - classes/form/CustomerAddressForm.php - -## Parameters - -```php -Hook::exec('actionValidateCustomerAddressForm', ['form' => $this]) -``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/addWebserviceResources.md b/modules/concepts/hooks/list-hooks/addWebserviceResources.md deleted file mode 100644 index ff1ec2c469..0000000000 --- a/modules/concepts/hooks/list-hooks/addWebserviceResources.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -menuTitle: addWebserviceResources -title: addWebserviceResources -hidden: true -files: - - classes/webservice/WebserviceRequest.php -types: - - frontoffice -hookTypes: - - legacy ---- - -# Hook : addWebserviceResources - -Located in : - - - classes/webservice/WebserviceRequest.php - -## Parameters - -```php -Hook::exec('addWebserviceResources', ['resources' => $resources], null, true, false); -``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/additionalCustomerAddressFields.md b/modules/concepts/hooks/list-hooks/additionalCustomerAddressFields.md deleted file mode 100644 index 428f457f40..0000000000 --- a/modules/concepts/hooks/list-hooks/additionalCustomerAddressFields.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -menuTitle: additionalCustomerAddressFields -title: additionalCustomerAddressFields -hidden: true -files: - - classes/form/CustomerAddressFormatter.php -types: - - frontoffice -hookTypes: - - legacy ---- - -# Hook : additionalCustomerAddressFields - -Located in : - - - classes/form/CustomerAddressFormatter.php - -## Parameters - -```php -Hook::exec('additionalCustomerAddressFields', ['fields' => &$format], null, true); -``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/additionalCustomerFormFields.md b/modules/concepts/hooks/list-hooks/additionalCustomerFormFields.md deleted file mode 100644 index ba773a90e4..0000000000 --- a/modules/concepts/hooks/list-hooks/additionalCustomerFormFields.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -menuTitle: additionalCustomerFormFields -title: additionalCustomerFormFields -hidden: true -files: - - classes/form/CustomerFormatter.php -types: - - frontoffice -hookTypes: - - legacy ---- - -# Hook : additionalCustomerFormFields - -Located in : - - - classes/form/CustomerFormatter.php - -## Parameters - -```php -Hook::exec('additionalCustomerFormFields', ['fields' => &$format], null, true); -``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/dashboardZoneThree.md b/modules/concepts/hooks/list-hooks/dashboardZoneThree.md deleted file mode 100644 index 56db879a5b..0000000000 --- a/modules/concepts/hooks/list-hooks/dashboardZoneThree.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -menuTitle: dashboardZoneThree -title: dashboardZoneThree -hidden: true -files: - - controllers/admin/AdminDashboardController.php -types: - - backoffice -hookTypes: - - legacy ---- - -# Hook : dashboardZoneThree - -Located in : - - - controllers/admin/AdminDashboardController.php - -## Parameters - -```php -Hook::exec('dashboardZoneThree', $params), -``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayAdditionalCustomerAddressFields.md b/modules/concepts/hooks/list-hooks/displayAdditionalCustomerAddressFields.md deleted file mode 100644 index af5b058bd2..0000000000 --- a/modules/concepts/hooks/list-hooks/displayAdditionalCustomerAddressFields.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -menuTitle: displayAdditionalCustomerAddressFields -title: displayAdditionalCustomerAddressFields -hidden: true -files: - - themes/classic/templates/customer/_partials/block-address.tpl -types: - - frontoffice -hookTypes: - - smarty ---- - -# Hook : displayAdditionalCustomerAddressFields - -Located in : - - - themes/classic/templates/customer/_partials/block-address.tpl - -## Parameters - -```php -{hook h='displayAdditionalCustomerAddressFields' address=$address} -``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayAdminCustomers.md b/modules/concepts/hooks/list-hooks/displayAdminCustomers.md deleted file mode 100644 index 44535b3d3c..0000000000 --- a/modules/concepts/hooks/list-hooks/displayAdminCustomers.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -menuTitle: displayAdminCustomers -title: displayAdminCustomers -hidden: true -files: - - src/PrestaShopBundle/Resources/views/Admin/Sell/Customer/view.html.twig -types: - - backoffice -hookTypes: - - twig ---- - -# Hook : displayAdminCustomers - -Located in : - - - src/PrestaShopBundle/Resources/views/Admin/Sell/Customer/view.html.twig - -## Parameters - -```php -{{ renderhook('displayAdminCustomers', {'id_customer': customerInformation.customerId.value}) }} -``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayAdminEndContent.md b/modules/concepts/hooks/list-hooks/displayAdminEndContent.md deleted file mode 100644 index ca84ee8bde..0000000000 --- a/modules/concepts/hooks/list-hooks/displayAdminEndContent.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -menuTitle: displayAdminEndContent -title: displayAdminEndContent -hidden: true -files: - - admin784x07v4swfhm9fgvc0/themes/new-theme/template/light_display_layout.tpl -types: - - backoffice -hookTypes: - - smarty ---- - -# Hook : displayAdminEndContent - -Located in : - - - admin784x07v4swfhm9fgvc0/themes/new-theme/template/light_display_layout.tpl - -## Parameters - -```php -{hook h='displayAdminEndContent'} -``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayAdminOrder.md b/modules/concepts/hooks/list-hooks/displayAdminOrder.md deleted file mode 100644 index b3e020d7d7..0000000000 --- a/modules/concepts/hooks/list-hooks/displayAdminOrder.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -menuTitle: displayAdminOrder -title: displayAdminOrder -hidden: true -files: - - src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/view.html.twig -types: - - backoffice -hookTypes: - - twig ---- - -# Hook : displayAdminOrder - -Located in : - - - src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/view.html.twig - -## Parameters - -```php -{{ renderhook('displayAdminOrder', {'id_order': orderForViewing.id}) }} -``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayAdminProductsMainStepLeftColumnBottom.md b/modules/concepts/hooks/list-hooks/displayAdminProductsMainStepLeftColumnBottom.md deleted file mode 100644 index 07e0cf3eb4..0000000000 --- a/modules/concepts/hooks/list-hooks/displayAdminProductsMainStepLeftColumnBottom.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -menuTitle: displayAdminProductsMainStepLeftColumnBottom -title: displayAdminProductsMainStepLeftColumnBottom -hidden: true -files: - - src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/essentials.html.twig -types: - - backoffice -hookTypes: - - twig ---- - -# Hook : displayAdminProductsMainStepLeftColumnBottom - -Located in : - - - src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/essentials.html.twig - -## Parameters - -```php -{{ renderhook('displayAdminProductsMainStepLeftColumnBottom', { 'id_product': productId }) }} -``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayAdminProductsMainStepLeftColumnMiddle.md b/modules/concepts/hooks/list-hooks/displayAdminProductsMainStepLeftColumnMiddle.md deleted file mode 100644 index 8ecafdc68b..0000000000 --- a/modules/concepts/hooks/list-hooks/displayAdminProductsMainStepLeftColumnMiddle.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -menuTitle: displayAdminProductsMainStepLeftColumnMiddle -title: displayAdminProductsMainStepLeftColumnMiddle -hidden: true -files: - - src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/essentials.html.twig -types: - - backoffice -hookTypes: - - twig ---- - -# Hook : displayAdminProductsMainStepLeftColumnMiddle - -Located in : - - - src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/essentials.html.twig - -## Parameters - -```php -{{ renderhook('displayAdminProductsMainStepLeftColumnMiddle', { 'id_product': productId }) }} -``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayAdminProductsMainStepRightColumnBottom.md b/modules/concepts/hooks/list-hooks/displayAdminProductsMainStepRightColumnBottom.md deleted file mode 100644 index c27ec2d38b..0000000000 --- a/modules/concepts/hooks/list-hooks/displayAdminProductsMainStepRightColumnBottom.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -menuTitle: displayAdminProductsMainStepRightColumnBottom -title: displayAdminProductsMainStepRightColumnBottom -hidden: true -files: - - src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/essentials.html.twig -types: - - backoffice -hookTypes: - - twig ---- - -# Hook : displayAdminProductsMainStepRightColumnBottom - -Located in : - - - src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/essentials.html.twig - -## Parameters - -```php -{{ renderhook('displayAdminProductsMainStepRightColumnBottom', { 'id_product': productId }) }} -``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayAfterBodyOpeningTag.md b/modules/concepts/hooks/list-hooks/displayAfterBodyOpeningTag.md deleted file mode 100644 index e2d41865e1..0000000000 --- a/modules/concepts/hooks/list-hooks/displayAfterBodyOpeningTag.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -menuTitle: displayAfterBodyOpeningTag -title: displayAfterBodyOpeningTag -hidden: true -files: - - themes/classic/templates/layouts/layout-both-columns.tpl -types: - - frontoffice -hookTypes: - - smarty ---- - -# Hook : displayAfterBodyOpeningTag - -Located in : - - - themes/classic/templates/layouts/layout-both-columns.tpl - -## Parameters - -```php -{hook h='displayAfterBodyOpeningTag'} -``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayAfterProductThumbs.md b/modules/concepts/hooks/list-hooks/displayAfterProductThumbs.md deleted file mode 100644 index b94b80ab53..0000000000 --- a/modules/concepts/hooks/list-hooks/displayAfterProductThumbs.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -menuTitle: displayAfterProductThumbs -title: displayAfterProductThumbs -hidden: true -files: - - themes/classic/templates/catalog/_partials/product-cover-thumbnails.tpl -types: - - frontoffice -hookTypes: - - smarty ---- - -# Hook : displayAfterProductThumbs - -Located in : - - - themes/classic/templates/catalog/_partials/product-cover-thumbnails.tpl - -## Parameters - -```php -{hook h='displayAfterProductThumbs' product=$product} -``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayAfterTitleTag.md b/modules/concepts/hooks/list-hooks/displayAfterTitleTag.md deleted file mode 100644 index 2c29b75f7f..0000000000 --- a/modules/concepts/hooks/list-hooks/displayAfterTitleTag.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -menuTitle: displayAfterTitleTag -title: displayAfterTitleTag -hidden: true -files: - - themes/classic/templates/_partials/head.tpl -types: - - frontoffice -hookTypes: - - smarty ---- - -# Hook : displayAfterTitleTag - -Located in : - - - themes/classic/templates/_partials/head.tpl - -## Parameters - -```php -{hook h='displayAfterTitleTag'} -``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayBackOfficeCategory.md b/modules/concepts/hooks/list-hooks/displayBackOfficeCategory.md deleted file mode 100644 index 61b7425c76..0000000000 --- a/modules/concepts/hooks/list-hooks/displayBackOfficeCategory.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -menuTitle: displayBackOfficeCategory -title: displayBackOfficeCategory -hidden: true -files: - - src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Categories/Blocks/form.html.twig -types: - - backoffice -hookTypes: - - twig ---- - -# Hook : displayBackOfficeCategory - -Located in : - - - src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Categories/Blocks/form.html.twig - -## Parameters - -```php -{{ renderhook('displayBackOfficeCategory') }} -``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayBackOfficeTop.md b/modules/concepts/hooks/list-hooks/displayBackOfficeTop.md deleted file mode 100644 index 7488184da0..0000000000 --- a/modules/concepts/hooks/list-hooks/displayBackOfficeTop.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -menuTitle: displayBackOfficeTop -title: displayBackOfficeTop -hidden: true -files: - - classes/controller/AdminController.php -types: - - backoffice -hookTypes: - - legacy ---- - -# Hook : displayBackOfficeTop - -Located in : - - - classes/controller/AdminController.php - -## Parameters - -```php -Hook::exec('displayBackOfficeTop'), -``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayBanner.md b/modules/concepts/hooks/list-hooks/displayBanner.md deleted file mode 100644 index 21fbe1ddfd..0000000000 --- a/modules/concepts/hooks/list-hooks/displayBanner.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -menuTitle: displayBanner -title: displayBanner -hidden: true -files: - - themes/classic/templates/_partials/header.tpl -types: - - frontoffice -hookTypes: - - smarty ---- - -# Hook : displayBanner - -Located in : - - - themes/classic/templates/_partials/header.tpl - -## Parameters - -```php -{hook h='displayBanner'} -``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayBeforeBodyClosingTag.md b/modules/concepts/hooks/list-hooks/displayBeforeBodyClosingTag.md deleted file mode 100644 index 89f71b393e..0000000000 --- a/modules/concepts/hooks/list-hooks/displayBeforeBodyClosingTag.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -menuTitle: displayBeforeBodyClosingTag -title: displayBeforeBodyClosingTag -hidden: true -files: - - themes/classic/templates/layouts/layout-both-columns.tpl -types: - - frontoffice -hookTypes: - - smarty ---- - -# Hook : displayBeforeBodyClosingTag - -Located in : - - - themes/classic/templates/layouts/layout-both-columns.tpl - -## Parameters - -```php -{hook h='displayBeforeBodyClosingTag'} -``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayCarrierExtraContent.md b/modules/concepts/hooks/list-hooks/displayCarrierExtraContent.md deleted file mode 100644 index 57f72a93f7..0000000000 --- a/modules/concepts/hooks/list-hooks/displayCarrierExtraContent.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -menuTitle: displayCarrierExtraContent -title: displayCarrierExtraContent -hidden: true -files: - - classes/checkout/DeliveryOptionsFinder.php -types: - - frontoffice -hookTypes: - - legacy ---- - -# Hook : displayCarrierExtraContent - -Located in : - - - classes/checkout/DeliveryOptionsFinder.php - -## Parameters - -```php -Hook::exec('displayCarrierExtraContent', ['carrier' => $carrier], $moduleId); -``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayCartModalContent.md b/modules/concepts/hooks/list-hooks/displayCartModalContent.md deleted file mode 100644 index 9e3b791f63..0000000000 --- a/modules/concepts/hooks/list-hooks/displayCartModalContent.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -menuTitle: displayCartModalContent -title: displayCartModalContent -hidden: true -files: - - themes/classic/modules/ps_shoppingcart/modal.tpl -types: - - frontoffice -hookTypes: - - smarty ---- - -# Hook : displayCartModalContent - -Located in : - - - themes/classic/modules/ps_shoppingcart/modal.tpl - -## Parameters - -```php -{hook h='displayCartModalContent' product=$product} -``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayCartModalFooter.md b/modules/concepts/hooks/list-hooks/displayCartModalFooter.md deleted file mode 100644 index 13c17de21f..0000000000 --- a/modules/concepts/hooks/list-hooks/displayCartModalFooter.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -menuTitle: displayCartModalFooter -title: displayCartModalFooter -hidden: true -files: - - themes/classic/modules/ps_shoppingcart/modal.tpl -types: - - frontoffice -hookTypes: - - smarty ---- - -# Hook : displayCartModalFooter - -Located in : - - - themes/classic/modules/ps_shoppingcart/modal.tpl - -## Parameters - -```php -{hook h='displayCartModalFooter' product=$product} -``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayCheckoutBeforeConfirmation.md b/modules/concepts/hooks/list-hooks/displayCheckoutBeforeConfirmation.md deleted file mode 100644 index d0001ed11f..0000000000 --- a/modules/concepts/hooks/list-hooks/displayCheckoutBeforeConfirmation.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -menuTitle: displayCheckoutBeforeConfirmation -title: displayCheckoutBeforeConfirmation -hidden: true -files: - - themes/classic/templates/checkout/_partials/steps/payment.tpl -types: - - frontoffice -hookTypes: - - smarty ---- - -# Hook : displayCheckoutBeforeConfirmation - -Located in : - - - themes/classic/templates/checkout/_partials/steps/payment.tpl - -## Parameters - -```php -{hook h='displayCheckoutBeforeConfirmation'} -``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayCustomerAccount.md b/modules/concepts/hooks/list-hooks/displayCustomerAccount.md deleted file mode 100644 index 2858d68677..0000000000 --- a/modules/concepts/hooks/list-hooks/displayCustomerAccount.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -menuTitle: displayCustomerAccount -title: displayCustomerAccount -hidden: true -files: - - themes/classic/templates/customer/my-account.tpl -types: - - frontoffice -hookTypes: - - smarty ---- - -# Hook : displayCustomerAccount - -Located in : - - - themes/classic/templates/customer/my-account.tpl - -## Parameters - -```php -{hook h='displayCustomerAccount'} -``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayCustomerAccountForm.md b/modules/concepts/hooks/list-hooks/displayCustomerAccountForm.md deleted file mode 100644 index 344d6531f9..0000000000 --- a/modules/concepts/hooks/list-hooks/displayCustomerAccountForm.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -menuTitle: displayCustomerAccountForm -title: displayCustomerAccountForm -hidden: true -files: - - classes/form/CustomerForm.php -types: - - frontoffice -hookTypes: - - legacy ---- - -# Hook : displayCustomerAccountForm - -Located in : - - - classes/form/CustomerForm.php - -## Parameters - -```php -Hook::exec('displayCustomerAccountForm'), -``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayCustomerAccountFormTop.md b/modules/concepts/hooks/list-hooks/displayCustomerAccountFormTop.md deleted file mode 100644 index dbda592c49..0000000000 --- a/modules/concepts/hooks/list-hooks/displayCustomerAccountFormTop.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -menuTitle: displayCustomerAccountFormTop -title: displayCustomerAccountFormTop -hidden: true -files: - - controllers/front/RegistrationController.php -types: - - frontoffice -hookTypes: - - legacy ---- - -# Hook : displayCustomerAccountFormTop - -Located in : - - - controllers/front/RegistrationController.php - -## Parameters - -```php -Hook::exec('displayCustomerAccountFormTop'), -``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayCustomerLoginFormAfter.md b/modules/concepts/hooks/list-hooks/displayCustomerLoginFormAfter.md deleted file mode 100644 index 94cd554f2d..0000000000 --- a/modules/concepts/hooks/list-hooks/displayCustomerLoginFormAfter.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -menuTitle: displayCustomerLoginFormAfter -title: displayCustomerLoginFormAfter -hidden: true -files: - - themes/classic/templates/customer/authentication.tpl -types: - - frontoffice -hookTypes: - - smarty ---- - -# Hook : displayCustomerLoginFormAfter - -Located in : - - - themes/classic/templates/customer/authentication.tpl - -## Parameters - -```php -{hook h='displayCustomerLoginFormAfter'} -``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayDashboardToolbarIcons.md b/modules/concepts/hooks/list-hooks/displayDashboardToolbarIcons.md deleted file mode 100644 index 64eafad31c..0000000000 --- a/modules/concepts/hooks/list-hooks/displayDashboardToolbarIcons.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -menuTitle: displayDashboardToolbarIcons -title: displayDashboardToolbarIcons -hidden: true -files: - - src/PrestaShopBundle/Resources/views/Admin/Product/CatalogPage/Blocks/tools.html.twig -types: - - backoffice -hookTypes: - - twig ---- - -# Hook : displayDashboardToolbarIcons - -Located in : - - - src/PrestaShopBundle/Resources/views/Admin/Product/CatalogPage/Blocks/tools.html.twig - -## Parameters - -```php -{{ renderhook('displayDashboardToolbarIcons', {}) }} -``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayDashboardToolbarTopMenu.md b/modules/concepts/hooks/list-hooks/displayDashboardToolbarTopMenu.md deleted file mode 100644 index 0ef19591df..0000000000 --- a/modules/concepts/hooks/list-hooks/displayDashboardToolbarTopMenu.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -menuTitle: displayDashboardToolbarTopMenu -title: displayDashboardToolbarTopMenu -hidden: true -files: - - admin784x07v4swfhm9fgvc0/themes/new-theme/template/page_header_toolbar.tpl -types: - - frontoffice -hookTypes: - - smarty ---- - -# Hook : displayDashboardToolbarTopMenu - -Located in : - - - admin784x07v4swfhm9fgvc0/themes/new-theme/template/page_header_toolbar.tpl - -## Parameters - -```php -{hook h='displayDashboardToolbarTopMenu'} -``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayEmptyModuleCategoryExtraMessage.md b/modules/concepts/hooks/list-hooks/displayEmptyModuleCategoryExtraMessage.md deleted file mode 100644 index a78da26e63..0000000000 --- a/modules/concepts/hooks/list-hooks/displayEmptyModuleCategoryExtraMessage.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -menuTitle: displayEmptyModuleCategoryExtraMessage -title: displayEmptyModuleCategoryExtraMessage -hidden: true -files: - - src/PrestaShopBundle/Resources/views/Admin/Module/Includes/grid_manage_empty.html.twig -types: - - backoffice -hookTypes: - - twig ---- - -# Hook : displayEmptyModuleCategoryExtraMessage - -Located in : - - - src/PrestaShopBundle/Resources/views/Admin/Module/Includes/grid_manage_empty.html.twig - -## Parameters - -```php -{{ renderhook('displayEmptyModuleCategoryExtraMessage', {'category_name': category.name}) }} -``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayFooter.md b/modules/concepts/hooks/list-hooks/displayFooter.md deleted file mode 100644 index b7a68042b8..0000000000 --- a/modules/concepts/hooks/list-hooks/displayFooter.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -menuTitle: displayFooter -title: displayFooter -hidden: true -files: - - themes/classic/templates/_partials/footer.tpl -types: - - frontoffice -hookTypes: - - smarty ---- - -# Hook : displayFooter - -Located in : - - - themes/classic/templates/_partials/footer.tpl - -## Parameters - -```php -{hook h='displayFooter'} -``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayHeader.md b/modules/concepts/hooks/list-hooks/displayHeader.md deleted file mode 100644 index 39cf0e5abd..0000000000 --- a/modules/concepts/hooks/list-hooks/displayHeader.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -menuTitle: displayHeader -title: displayHeader -hidden: true -files: - - classes/controller/FrontController.php -types: - - frontoffice -hookTypes: - - legacy ---- - -# Hook : displayHeader - -Located in : - - - classes/controller/FrontController.php - -## Parameters - -```php -Hook::exec('displayHeader'), -``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayHome.md b/modules/concepts/hooks/list-hooks/displayHome.md deleted file mode 100644 index 52fda502a4..0000000000 --- a/modules/concepts/hooks/list-hooks/displayHome.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -menuTitle: displayHome -title: displayHome -hidden: true -files: - - controllers/front/IndexController.php -types: - - frontoffice -hookTypes: - - legacy ---- - -# Hook : displayHome - -Located in : - - - controllers/front/IndexController.php - -## Parameters - -```php -Hook::exec('displayHome'), -``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayInvoiceLegalFreeText.md b/modules/concepts/hooks/list-hooks/displayInvoiceLegalFreeText.md deleted file mode 100644 index c97396143d..0000000000 --- a/modules/concepts/hooks/list-hooks/displayInvoiceLegalFreeText.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -menuTitle: displayInvoiceLegalFreeText -title: displayInvoiceLegalFreeText -hidden: true -files: - - classes/pdf/HTMLTemplateInvoice.php -types: - - frontoffice -hookTypes: - - legacy ---- - -# Hook : displayInvoiceLegalFreeText - -Located in : - - - classes/pdf/HTMLTemplateInvoice.php - -## Parameters - -```php -Hook::exec('displayInvoiceLegalFreeText', ['order' => $this->order]); -``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayLeftColumnProduct.md b/modules/concepts/hooks/list-hooks/displayLeftColumnProduct.md deleted file mode 100644 index c8d760615e..0000000000 --- a/modules/concepts/hooks/list-hooks/displayLeftColumnProduct.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -menuTitle: displayLeftColumnProduct -title: displayLeftColumnProduct -hidden: true -files: - - themes/classic/templates/layouts/layout-both-columns.tpl -types: - - frontoffice -hookTypes: - - smarty ---- - -# Hook : displayLeftColumnProduct - -Located in : - - - themes/classic/templates/layouts/layout-both-columns.tpl - -## Parameters - -```php -{hook h='displayLeftColumnProduct' product=$product category=$category} -``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayMaintenance.md b/modules/concepts/hooks/list-hooks/displayMaintenance.md deleted file mode 100644 index 5ee0c10330..0000000000 --- a/modules/concepts/hooks/list-hooks/displayMaintenance.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -menuTitle: displayMaintenance -title: displayMaintenance -hidden: true -files: - - classes/controller/FrontController.php -types: - - frontoffice -hookTypes: - - legacy ---- - -# Hook : displayMaintenance - -Located in : - - - classes/controller/FrontController.php - -## Parameters - -```php -Hook::exec('displayMaintenance', []), -``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayNavFullWidth.md b/modules/concepts/hooks/list-hooks/displayNavFullWidth.md deleted file mode 100644 index 6aba15f3b8..0000000000 --- a/modules/concepts/hooks/list-hooks/displayNavFullWidth.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -menuTitle: displayNavFullWidth -title: displayNavFullWidth -hidden: true -files: - - themes/classic/templates/checkout/_partials/header.tpl -types: - - frontoffice -hookTypes: - - smarty ---- - -# Hook : displayNavFullWidth - -Located in : - - - themes/classic/templates/checkout/_partials/header.tpl - -## Parameters - -```php -{hook h='displayNavFullWidth'} -``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayOrderConfirmation.md b/modules/concepts/hooks/list-hooks/displayOrderConfirmation.md deleted file mode 100644 index 7f7ee33e46..0000000000 --- a/modules/concepts/hooks/list-hooks/displayOrderConfirmation.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -menuTitle: displayOrderConfirmation -title: displayOrderConfirmation -hidden: true -files: - - controllers/front/OrderConfirmationController.php -types: - - frontoffice -hookTypes: - - legacy ---- - -# Hook : displayOrderConfirmation - -Located in : - - - controllers/front/OrderConfirmationController.php - -## Parameters - -```php -Hook::exec('displayOrderConfirmation', ['order' => $order]); -``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayOrderDetail.md b/modules/concepts/hooks/list-hooks/displayOrderDetail.md deleted file mode 100644 index b5adae179e..0000000000 --- a/modules/concepts/hooks/list-hooks/displayOrderDetail.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -menuTitle: displayOrderDetail -title: displayOrderDetail -hidden: true -files: - - controllers/front/OrderDetailController.php -types: - - frontoffice -hookTypes: - - legacy ---- - -# Hook : displayOrderDetail - -Located in : - - - controllers/front/OrderDetailController.php - -## Parameters - -```php -Hook::exec('displayOrderDetail', ['order' => $order]), -``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayPaymentByBinaries.md b/modules/concepts/hooks/list-hooks/displayPaymentByBinaries.md deleted file mode 100644 index b304684888..0000000000 --- a/modules/concepts/hooks/list-hooks/displayPaymentByBinaries.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -menuTitle: displayPaymentByBinaries -title: displayPaymentByBinaries -hidden: true -files: - - themes/classic/templates/checkout/_partials/steps/payment.tpl -types: - - frontoffice -hookTypes: - - smarty ---- - -# Hook : displayPaymentByBinaries - -Located in : - - - themes/classic/templates/checkout/_partials/steps/payment.tpl - -## Parameters - -```php -{hook h='displayPaymentByBinaries'} -``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayPaymentTop.md b/modules/concepts/hooks/list-hooks/displayPaymentTop.md deleted file mode 100644 index a1c88491f3..0000000000 --- a/modules/concepts/hooks/list-hooks/displayPaymentTop.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -menuTitle: displayPaymentTop -title: displayPaymentTop -hidden: true -files: - - themes/classic/templates/checkout/_partials/steps/payment.tpl -types: - - frontoffice -hookTypes: - - smarty ---- - -# Hook : displayPaymentTop - -Located in : - - - themes/classic/templates/checkout/_partials/steps/payment.tpl - -## Parameters - -```php -{hook h='displayPaymentTop'} -``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayPersonalInformationTop.md b/modules/concepts/hooks/list-hooks/displayPersonalInformationTop.md deleted file mode 100644 index df73e51567..0000000000 --- a/modules/concepts/hooks/list-hooks/displayPersonalInformationTop.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -menuTitle: displayPersonalInformationTop -title: displayPersonalInformationTop -hidden: true -files: - - themes/classic/templates/checkout/_partials/steps/personal-information.tpl -types: - - frontoffice -hookTypes: - - smarty ---- - -# Hook : displayPersonalInformationTop - -Located in : - - - themes/classic/templates/checkout/_partials/steps/personal-information.tpl - -## Parameters - -```php -{hook h='displayPersonalInformationTop' customer=$customer} -``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayProductActions.md b/modules/concepts/hooks/list-hooks/displayProductActions.md deleted file mode 100644 index ac9ee3fa24..0000000000 --- a/modules/concepts/hooks/list-hooks/displayProductActions.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -menuTitle: displayProductActions -title: displayProductActions -hidden: true -files: - - themes/classic/templates/catalog/_partials/product-add-to-cart.tpl -types: - - frontoffice -hookTypes: - - smarty ---- - -# Hook : displayProductActions - -Located in : - - - themes/classic/templates/catalog/_partials/product-add-to-cart.tpl - -## Parameters - -```php -{hook h='displayProductActions' product=$product} -``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayRightColumnProduct.md b/modules/concepts/hooks/list-hooks/displayRightColumnProduct.md deleted file mode 100644 index fb269b03e6..0000000000 --- a/modules/concepts/hooks/list-hooks/displayRightColumnProduct.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -menuTitle: displayRightColumnProduct -title: displayRightColumnProduct -hidden: true -files: - - themes/classic/templates/layouts/layout-both-columns.tpl -types: - - frontoffice -hookTypes: - - smarty ---- - -# Hook : displayRightColumnProduct - -Located in : - - - themes/classic/templates/layouts/layout-both-columns.tpl - -## Parameters - -```php -{hook h='displayRightColumnProduct'} -``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayShoppingCart.md b/modules/concepts/hooks/list-hooks/displayShoppingCart.md deleted file mode 100644 index 61540a13c6..0000000000 --- a/modules/concepts/hooks/list-hooks/displayShoppingCart.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -menuTitle: displayShoppingCart -title: displayShoppingCart -hidden: true -files: - - themes/classic/templates/checkout/cart.tpl -types: - - frontoffice -hookTypes: - - smarty ---- - -# Hook : displayShoppingCart - -Located in : - - - themes/classic/templates/checkout/cart.tpl - -## Parameters - -```php -{hook h='displayShoppingCart'} -``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayShoppingCartFooter.md b/modules/concepts/hooks/list-hooks/displayShoppingCartFooter.md deleted file mode 100644 index 029bf9c3ac..0000000000 --- a/modules/concepts/hooks/list-hooks/displayShoppingCartFooter.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -menuTitle: displayShoppingCartFooter -title: displayShoppingCartFooter -hidden: true -files: - - themes/classic/templates/checkout/cart.tpl -types: - - frontoffice -hookTypes: - - smarty ---- - -# Hook : displayShoppingCartFooter - -Located in : - - - themes/classic/templates/checkout/cart.tpl - -## Parameters - -```php -{hook h='displayShoppingCartFooter'} -``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayTop.md b/modules/concepts/hooks/list-hooks/displayTop.md deleted file mode 100644 index 3f7b3fe4dc..0000000000 --- a/modules/concepts/hooks/list-hooks/displayTop.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -menuTitle: displayTop -title: displayTop -hidden: true -files: - - themes/classic/templates/checkout/_partials/header.tpl -types: - - frontoffice -hookTypes: - - smarty ---- - -# Hook : displayTop - -Located in : - - - themes/classic/templates/checkout/_partials/header.tpl - -## Parameters - -```php -{hook h='displayTop'} -``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/filterProductSearch.md b/modules/concepts/hooks/list-hooks/filterProductSearch.md deleted file mode 100644 index a1f97268c2..0000000000 --- a/modules/concepts/hooks/list-hooks/filterProductSearch.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -menuTitle: filterProductSearch -title: filterProductSearch -hidden: true -files: - - modules/blockwishlist/controllers/front/view.php -types: - - frontoffice -hookTypes: - - legacy ---- - -# Hook : filterProductSearch - -Located in : - - - modules/blockwishlist/controllers/front/view.php - -## Parameters - -```php -Hook::exec('filterProductSearch', ['searchVariables' => &$searchVariables]); -``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/validateCustomerFormFields.md b/modules/concepts/hooks/list-hooks/validateCustomerFormFields.md deleted file mode 100644 index 0340f9833e..0000000000 --- a/modules/concepts/hooks/list-hooks/validateCustomerFormFields.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -menuTitle: validateCustomerFormFields -title: validateCustomerFormFields -hidden: true -files: - - classes/form/CustomerForm.php -types: - - frontoffice -hookTypes: - - legacy ---- - -# Hook : validateCustomerFormFields - -Located in : - - - classes/form/CustomerForm.php - -## Parameters - -```php -Hook::exec('validateCustomerFormFields', ['fields' => $formFields], $moduleId, true); -``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks.md b/modules/concepts/hooks/list-of-hooks.md deleted file mode 100644 index a30357c582..0000000000 --- a/modules/concepts/hooks/list-of-hooks.md +++ /dev/null @@ -1,2982 +0,0 @@ ---- -title: List of hooks -weight: 2 ---- - -# List of hooks in PrestaShop 8 - -## Full list - -{{% notice tip %}} -**Search tip:** Some hooks are generated dynamically, so their names are documented in a generic way. - -For example, `actionAdminCustomersFormModifier` is documented as `actionFormModifier`, so you won't find it if you search for the exact name. When you see a controller name or action in the hook name and you can't find it, try searching for a part of the hook name, like `FormModifier`. -{{% /notice %}} - -{{% funcdef %}} - -
- - -

No hooks found

-
- - - -action<AdminControllerClassName><Action>After -: - Called after performing <Action> in any <AdminController> - - Located in: /classes/controller/AdminController.php - - Parameters: - ```php - (AdminController), - 'return' => (mixed) - ); - ``` - -action<AdminControllerClassName><Action>Before -: - Called before performing <Action> in any <AdminController> - - Located in: /classes/controller/AdminController.php - - Parameters: - ```php - (AdminController) - ); - ``` - -action<AdminControllerClassName>FormModifier -: - Called when rendering a form in any <AdminController> - - Located in: /classes/controller/AdminController.php - - Parameters: - ```php - &(ObjectModel), - 'fields' => &(array), - 'fields_value' => &(array), - 'form_vars' => &(array), - ); - ``` - -action<AdminControllerClassName>ListingFieldsModifier -: - Located in: /classes/controller/AdminController.php - - Parameters: - ```php - &(string), 'join' => &(string), - 'where' => &(string), - 'group_by' => &(string), - 'order_by' => &(string), - 'order_way' => &(string), - 'fields' => &(array) - ); - ``` - -action<AdminControllerClassName>OptionsModifier -: - Located in: /classes/controller/AdminController.php - - Parameters: - ```php - &(array), - 'option_vars' => &(array), - ); - ``` - -actionAdmin<Action>After -: - Called after performing <Action> in any admin controller - - Located in: /classes/controller/AdminController.php - - Parameters: - ```php - (AdminController), - 'return' => (mixed) - ); - ``` - -actionAdmin<Action>Before -: - Called before performing <Action> in any admin controller - - Located in: /classes/controller/AdminController.php - - Parameters: - ```php - (AdminController) - ); - ``` - -actionAdminControllerSetMedia -: - Located in: /classes/controller/AdminController.php - - Parameters: N/A - -actionAdminLoginControllerSetMedia -: - Called after adding media to admin login page header - - Located in: /controllers/admin/AdminLoginController.php - - Parameters: N/A - -actionAdminMetaAfterWriteRobotsFile -: - Called after generating the robots.txt file - - Located in: /classes/Tools.php - - Parameters: - ```php - (array) File data, - 'write_fd' => &(resource) File handle - ); - ``` - -actionAdminMetaBeforeWriteRobotsFile -: - Called before generating the robots.txt file - - Located in: /classes/Tools.php - - Parameters: - ```php - &(array) File data - ); - ``` - -actionAdminMetaSave -: - Called after saving the configuration in AdminMeta - - Located in: /controllers/admin/AdminMetaController.php for PrestaShop < 1.7.6 - - Parameters: N/A - - Removed in PrestaShop 1.7.6, replacement hooks are `action(Form|Save)` - -actionAdminOrdersTrackingNumberUpdate -: - Located in: /controllers/admin/AdminOrdersController.php for PrestaShop < 1.7.7 - Located in: /src/Adapter/Order/CommandHandler/UpdateOrderShippingDetailsHandler.php since 1.7.7 - - Parameters: - ```php - (Order), - 'customer' => (Customer), - 'carrier' => (Carrier) - ); - ``` - -displayAdminOrderCreateExtraButtons -: - Available since: {{< minver v="1.7.8" >}} - - Add buttons on the create order page dropdown - - Located in: src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/Create/summary.html.twig - -actionAdminProductsListingFieldsModifier -: - Located in: /src/Adapter/Product/AdminProductDataProvider.php - - Parameters: - ```php - (string) PrestaShop version, - 'sql_select' => &(array), - 'sql_table' => &(array), - 'sql_where' => &(array), - 'sql_order' => &(array), - 'sql_limit' => &(string), - ); - ``` - -actionAdminProductsListingResultsModifier -: - Located in: /src/Adapter/Product/AdminProductDataProvider.php - - Parameters: - ```php - (string) PrestaShop version, - 'products' => &(PDOStatement), - 'total' => (int), - ); - ``` - -actionAdminThemesControllerUpdate_optionsAfter -: - Located in: /controllers/admin/AdminThemesController.php for PrestaShop < 1.7.6 - - Parameters: N/A - - Removed in PrestaShop 1.7.6, replacement hooks are `action(Before|After)(Create|Update)FormHandler` - -actionAjaxDie<ControllerName><Method>Before -: - Located in: /classes/controller/Controller.php - - Parameters: - ```php - (string) - ); - ``` - -actionAjaxDieBefore -: - **(deprecated since 1.6.1.1)** - - Located in: /classes/controller/Controller.php - - -actionAttributeCombinationDelete -: - Located in: /classes/Combination.php - - -actionAttributeCombinationSave -: - Located in: /classes/Combination.php - - -actionAttributeDelete -: - Called when deleting an attributes features value - - Located in: /classes/Attribute.php - - -actionAttributeGroupDelete -: - Called while deleting an attributes group - - Located in: /classes/AttributeGroup.php - - -actionAttributeGroupSave -: - Called while saving an attributes group - - Located in: /classes/AttributeGroup.php - - -actionAttributeSave -: - Called while saving an attributes features value - - Located in: /classes/Attribute.php - - -actionAuthentication -: - After successful customer authentication - - Located in: /classes/form/CustomerLoginForm.php - - -actionAuthenticationBefore -: - Before a customer successfully signs in - - Located in: /classes/form/CustomerLoginForm.php - - -actionBeforeAjaxDie<ControllerName><Method> -: - **(deprecated since 1.6.1.1)** - → `actionAjaxDieBefore` - - Located in: /classes/controller/Controller.php - - -actionBeforeCartUpdateQty -: - **(deprecated since 1.6.1.1)** - → `actionCartUpdateQuantityBefore` - - Located in: /classes/Cart.php - - -actionCarrierProcess -: - Carrier process - - Located in: /classes/checkout/CheckoutDeliveryStep.php - - -actionCarrierUpdate -: - This hook is called when a carrier is updated - - Located in: - - - /controllers/admin/AdminCarrierWizardController.php - - /controllers/admin/AdminCarriersController.php - - -actionCartSave -: - After a product is added to the cart or if the cart's content is modified - - Located in: /classes/Cart.php - - -actionCartSummary -: - Located in: /classes/Cart.php - - -actionCartUpdateQuantityBefore -: - Located in: /classes/Cart.php - - -actionCategoryAdd -: - Invoked when a category is created - - Located in: /classes/Category.php - - -actionCategoryDelete -: - Invoked when a category is deleted - - Located in: /classes/Category.php - - -actionCategoryUpdate -: - Invoked when a category is modified - - Located in: - - - /classes/Category.php - - /controllers/admin/AdminProductsController.php - - -actionClearCache -: - Available since: {{< minver v="1.7.1" >}} - - Invoked when the smarty cache is cleared - - Located in: /classes/Tools.php - - -actionClearCompileCache -: - Available since: {{< minver v="1.7.1" >}} - - Invoked when the smarty compile cache is cleared - - Located in: /classes/Tools.php - - -actionClearSf2Cache -: - Available since: {{< minver v="1.7.1" >}} - - Invoked when the Symfony cache is cleared - - Located in: /classes/Tools.php - - -actionCustomerAccountAdd -: - Invoked when a new customer creates an account successfully - - Located in: /classes/form/CustomerPersister.php - - Parameters: - ```php - (object) Customer object - ); - ``` - -actionCustomerAccountUpdate -: - Invoked when a customer updates its account successfully - - Located in: /classes/form/CustomerPersister.php - - -actionCustomerAddGroups -: - Located in: /classes/Customer.php - - -actionCustomerBeforeUpdateGroup -: - Located in: /classes/Customer.php - - -actionCustomerLogoutAfter -: - Located in: /classes/Customer.php - - -actionCustomerLogoutBefore -: - Located in: /classes/Customer.php - - -actionDeliveryPriceByPrice -: - Located in: /classes/Carrier.php - - -actionDeliveryPriceByWeight -: - Located in: /classes/Carrier.php - - -actionDispatcher -: - Located in: /classes/Dispatcher.php - - -actionDispatcherAfter -: - Available since: {{< minver v="1.7.1" >}} - - This hook is called at the end of the dispatch method of the Dispatcher - - Located in: /classes/Dispatcher.php - - -actionDispatcherBefore -: - Available since: {{< minver v="1.7.1" >}} - - This hook is called at the beginning of the dispatch method of the Dispatcher - - Located in: /classes/Dispatcher.php - - -actionDownloadAttachment -: - Located in: /controllers/front/AttachmentController.php - - -actionEmailAddAfterContent -: - Add extra content after mail content - This hook is called just after fetching mail template - - Located in: /classes/Mail.php - - -actionEmailAddBeforeContent -: - Add extra content before mail content - This hook is called just before fetching mail template - - Located in: /classes/Mail.php - - -actionEmailSendBefore -: - Before sending an email - This hook is used to filter the content or the metadata of an email before sending it or even prevent its sending - - Located in: /classes/Mail.php - - -actionFeatureDelete -: - This hook is called while deleting an attributes features - - Located in: /classes/Feature.php - - -actionFeatureSave -: - This hook is called while saving an attributes features - - Located in: /classes/Feature.php - - -actionFeatureValueDelete -: - This hook is called while deleting an attributes features value - - Located in: /classes/FeatureValue.php - - -actionFeatureValueSave -: - This hook is called while saving an attributes features value - - Located in: /classes/FeatureValue.php - -actionFrontControllerAfterInit -: - **(Deprecated in 1.7.7 in favor of)** - → `actionFrontControllerInitAfter` - -actionFrontControllerInitAfter -: - Available since: {{< minver v="1.7.7" >}} - - Located in: /classes/controller/FrontController.php - -actionFrontControllerInitBefore -: - Available since: {{< minver v="1.7.7" >}} - - Located in: /classes/controller/FrontController.php - - -actionFrontControllerSetMedia -: - Located in: /classes/controller/FrontController.php - -actionFrontControllerSetVariables -: - Available since: {{< minver v="1.7.5" >}} - - Add global variables to `javascript` object and `smarty` templates. Available in Front Office only. - - Located in: /classes/controller/FrontController.php - - Parameters since {{< minver v="1.7.7" >}} - - ```php - &(array) - ); - ``` - - Example usage: - - Your hook implementation should return array of values that will be added to `prestashop` object in `javascript` and `$modules` object in `smarty`. - - ```php - 'Your variable value', - ]; - } - ``` - - In Front Office you can access it globally using: - - ```js - console.log(prestashop.modules.your_module_name.your_variable_name); - "Hello world" - ``` - - with smarty - - ```smarty - {$modules.your_module_name.your_variable_name} - ``` - -actionGetAlternativeSearchPanels -: - This hook allows to add an additional search panel for external providers in PrestaShop back office - - ```php - (array) Existing search panels, - 'bo_query' => (array) Searched expression, - ); - ``` - - Located in: /controllers/admin/AdminSearchController.php - -actionGetExtraMailTemplateVars -: - Located in: /classes/Mail.php - - -actionGetIDZoneByAddressID -: - Located in: /classes/Address.php - - -actionGetProductPropertiesAfter -: - Located in: /classes/Product.php - - -actionGetProductPropertiesBefore -: - Located in: /classes/Product.php - - -actionHtaccessCreate -: - After .htaccess creation - - Located in: /classes/Tools.php - - -actionInvoiceNumberFormatted -: - Located in: /classes/order/OrderInvoice.php - - -actionModuleInstallAfter -: - Located in: /classes/module/Module.php - - -actionModuleInstallBefore -: - Located in: /classes/module/Module.php - - -actionModuleRegisterHookAfter -: - Located in: /classes/Hook.php - - -actionModuleRegisterHookBefore -: - Located in: /classes/Hook.php - - -actionModuleUnRegisterHookAfter -: - Located in: /classes/Hook.php - - -actionModuleUnRegisterHookBefore -: - Located in: /classes/Hook.php - - -actionObject -: - Located in: /classes/ObjectModel.php - - -actionObjectAddAfter -: - Located in: /classes/ObjectModel.php - - -actionObjectAddBefore -: - Located in: /classes/ObjectModel.php - - -actionObjectAttributeAddBefore -: - Located in: /controllers/admin/AdminAttributesGroupsController.php - - -actionObjectAttributeGroupAddBefore -: - Located in: /controllers/admin/AdminAttributesGroupsController.php - - -actionObjectDeleteAfter -: - Located in: /classes/ObjectModel.php - - -actionObjectDeleteBefore -: - Located in: /classes/ObjectModel.php - - -actionObject<ObjectName>AddBefore -: - Located in: /classes/ObjectModel.php - -actionObject<ObjectName>AddAfter -: - Located in: /classes/ObjectModel.php - - -actionObject<ObjectName>UpdateBefore -: - Located in: /classes/ObjectModel.php - - -actionObject<ObjectName>UpdateAfter -: - Located in: /classes/ObjectModel.php - - -actionObject<ObjectName>DeleteBefore -: - Located in: /classes/ObjectModel.php - - -actionObject<ObjectName>DeleteAfter -: - Located in: /classes/ObjectModel.php - - -actionObjectProductInCartDeleteAfter -: - Available since: {{< minver v="1.7.1" >}} - - This hook is called after a product is removed from a cart - - Located in: /controllers/front/CartController.php - - -actionObjectProductInCartDeleteBefore -: - Available since: {{< minver v="1.7.1" >}} - - This hook is called before a product is removed from a cart - - Located in: /controllers/front/CartController.php - - -actionObjectUpdateAfter -: - Located in: /classes/ObjectModel.php - - -actionObjectUpdateBefore -: - Located in: /classes/ObjectModel.php - - -actionOnImageCutAfter -: - Located in: /classes/ImageManager.php - - -actionOnImageResizeAfter -: - Located in: /classes/ImageManager.php - - -actionOrderEdited -: - This hook is called when an order is edited - - Located in: /controllers/admin/AdminOrdersController.php - - Parameters: - ```php - (object) Order - ); - ``` - -actionOrderHistoryAddAfter -: - This hook is displayed when a customer returns a product - - Located in: /classes/order/OrderHistory.php - - -actionOrderReturn -: - Called after a new Order Return has been made. - - Located in: /controllers/front/OrderFollowController.php - - Parameters: - ```php - (object) OrderReturn - ); - ``` - -actionOrderSlipAdd -: - Called when the quantity of a product changes in an order. - WARNING: only invoked when a product is actually removed from an order. - - Located in: /controllers/admin/AdminOrdersController.php - - Parameters: - ```php - Order, - 'productList' => array( - (int) product ID 1, - (int) product ID 2, - ..., - (int) product ID n - ), - 'qtyList' => array( - (int) quantity 1, - (int) quantity 2, - ..., - (int) quantity n - ) - ); - The order of IDs and quantities is important! - ``` - -actionOrderStatusPostUpdate -: - Called after the status of an order changes. - - **Note:** This hook is fired BEFORE the new OrderStatus is saved into the database. - If you need to register after this insertion, use `actionOrderHistoryAddAfter` or `actionObjectOrderHistoryAddAfter` instead. - - Located in: /classes/order/OrderHistory.php - - Parameters: - ```php - (object) OrderState, - 'oldOrderStatus' => (object) OrderState, - 'id_order' => (int) Order ID - ); - ``` - -actionOrderStatusUpdate -: - Called before the status of an order changes. - - Located in: /classes/order/OrderHistory.php - - Parameters: - ```php - (object) OrderState, - 'oldOrderStatus' => (object) OrderState, - 'id_order' => (int) Order ID - ); - ``` - -actionOutputHTMLBefore -: - Available since: {{< minver v="1.7.1" >}} - - Before HTML output - This hook is used to filter the whole HTML page before it is rendered (only front) - - Located in: /classes/controller/FrontController.php - - -actionPasswordRenew -: - Located in: /controllers/front/PasswordController.php - - -actionPaymentCCAdd -: - Payment CC added - - Located in: /classes/order/OrderPayment.php - - Parameters: - ```php - (object) OrderPayment object - ); - ``` - -actionPaymentConfirmation -: - Called after a payment has been validated - - Located in: /classes/order/OrderHistory.php - - Parameters: - ```php - (int) Order ID - ); - ``` - -actionPDFInvoiceRender -: - Located in: - - - /classes/PaymentModule.php - - /classes/order/OrderHistory.php - - /controllers/admin/AdminPdfController.php - - /controllers/front/PdfInvoiceController.php - - -actionProductAdd -: - This hook is displayed after a product is created - - Located in: /controllers/admin/AdminProductsController.php - - -actionProductAttributeDelete -: - This hook is displayed when a product's attribute is deleted - - Located in: /classes/Product.php - - -actionProductAttributeUpdate -: - This hook is displayed when a product's attribute is updated - - Located in: /classes/Product.php - - -actionProductCancel -: - This hook is called when you cancel a product in an order - - Located in: /controllers/admin/AdminOrdersController.php - - -actionProductCoverage -: - Located in: /classes/stock/StockManager.php - - -actionProductDelete -: - This hook is called when a product is deleted - - Located in: /classes/Product.php - - -actionProductOutOfStock -: - This hook displays new action buttons if a product is out of stock - - Located in: - - - /themes/classic/templates/catalog/_partials/product-details.tpl - - /themes/classic/templates/catalog/product.tpl - - -actionProductSave -: - This hook is called while saving products - - Located in: /classes/Product.php - - -actionProductSearchAfter -: - Available since: {{< minver v="1.7.1" >}} - - This hook is called after the product search. Parameters are already filter - - Located in: /classes/controller/ProductListingFrontController.php - - -actionProductUpdate -: - This hook is displayed after a product has been updated - - Located in: - - - /classes/Product.php - - /controllers/admin/AdminProductsController.php - - -actionProductFlagsModifier -: - Available since: {{< minver v="1.7.6" >}} - - Add and remove product labels available on product list - - Located in: /src/Adapter/Presenter/Product/ProductLazyArray.php - - Parameters: - ```php - (array) &$flags, - 'product' => (Product) $product, - ), - ``` - - -actionSearch -: - Available since: {{< minver v="1.7.1" >}} - - After the search in the store. Includes both instant and normal search. - - Located in: /src/Adapter/Search/SearchProductSearchProvider.php - - Parameters: - ```php - (string) Search query, - 'total' => (int) Amount of search results - ); - ``` - -actionSetInvoice -: - Located in: /classes/order/Order.php - Parameters: - ```php - order object, - 'OrderInvoice' => order invoice object, - 'use_existing_payment' => (bool) - ); - ``` - - -actionShopDataDuplication -: - After duplicating a shop. - - Located in: /classes/shop/Shop.php - - Parameters: - ```php - (int) Old shop ID, - 'new_id_shop' => (int) New shop ID - ); - ``` - -actionSubmitAccountBefore -: - Available since: {{< minver v="1.7.1" >}} - - Located in: /controllers/front/AuthController.php - - -actionUpdateLangAfter -: - Available since: {{< minver v="1.7.1" >}} - - Update "lang" tables after adding or updating a language - - Located in: /classes/Language.php - - -actionUpdateQuantity -: - After updating the quantity of a product. - Quantity is updated only when a customer effectively places their order - - Located in: /classes/stock/StockAvailable.php - - Parameters: - ```php - (int) Product ID, - 'id_product_attribute' => (int) Product attribute ID, - 'quantity' => (int) New product quantity - ); - ``` - -actionValidateCustomerAddressForm -: - This hook is called when a customer submit its address form - - Located in: /classes/form/CustomerAddressForm.php - - Parameters: - ```php - (object) CustomerAddressForm - ); - ``` - -actionValidateOrder -: - After an order has been validated. - Doesn't necessarily have to be paid. - - Located in: /classes/PaymentModule.php - - Parameters: - ```php - (object) Cart, - 'order' => (object) Order, - 'customer' => (object) Customer, - 'currency' => (object) Currency, - 'orderStatus' => (object) OrderState - ); - ``` - -actionValidateOrderAfter -: - Available since: {{< minver v="8.0.0" >}} - - This hook is called after validating an order by core - - Located in: /classes/PaymentModule.php - - Parameters: - ```php - (object) Cart, - 'order' => (object) Order, - 'orders' => (array) $order_list, - 'customer' => (object) Customer, - 'currency' => (object) Currency, - 'orderStatus' => (object) OrderState - ); - ``` - -actionValidateStepComplete -: - This hook is called on checkout page, when confirming delivery section. Carrier modules that display extra content to the customer can hook here and prevent him from advancing further, if he didn't enter required information. - - Be aware that the hook will only be called for a module specified in `external_module_name` property of the carrier. - - Located in: /classes/checkout/CheckoutDeliveryStep.php - - Parameters: - ```php - 'delivery', - 'request_params' => $requestParams, - 'completed' => &$isComplete, - ); - ``` - - Usage: - ```php - context->controller->errors[] = $this->l('Please select a pickup branch!'); - $params['completed'] = false; - } - } - ``` - -actionWatermark -: - After a watermark has been added to an image. - - Located in: - - - /classes/FileUploader.php - - /classes/webservice/WebserviceSpecificManagementImages.php - - /controllers/admin/AdminImportController.php - - /controllers/admin/AdminProductsController.php - - Parameters: - ```php - (int) Image ID, - 'id_product' => (int) Product ID - ); - ``` - -actionGetAdminOrderButtons -: - Available since: {{< minver v="1.7.7" >}} - - This hook is used to generate the buttons collection on the order view page (see ActionsBarButtonsCollection) - - Located in: /src/PrestaShopBundle/Controller/Admin/Sell/Order/OrderController.php - - Parameters: - ```php - (OrderController) Symfony controller, - 'id_order' => (int) Order ID, - 'actions_bar_buttons_collection' => (ActionsBarButtonsCollection) Collection of ActionsBarButtonInterface - ); - ``` - - -actionAdminAdminPreferencesControllerPostProcessBefore -: - Available since: {{< minver v="1.7.7" >}} - - This hook is called on Admin Preferences post-process before processing the form - - Located in: /src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/AdministrationController.php - - Parameters: - ```php - (AdministrationController) Symfony controller, - ] - ``` - - -additionalCustomerFormFields -: - Add fields to the Customer form - This hook returns an array of FormFields to add them to the customer registration form - - Located in: /classes/form/CustomerFormatter.php - - -addWebserviceResources -: - This hook is called when webservice resources list in webservice controller - - Located in: /classes/webservice/WebserviceRequest.php - - -dashboardData -: - Located in: /controllers/admin/AdminDashboardController.php - - -dashboardZoneOne -: - Located in: /controllers/admin/AdminDashboardController.php - - Parameters: - ```php - (string|null) $statsDateFrom, - 'date_to' => (string|null) $statsDateTo, - ] - -dashboardZoneTwo -: - Located in: /controllers/admin/AdminDashboardController.php - - Parameters: - ```php - (string|null) $statsDateFrom, - 'date_to' => (string|null) $statsDateTo, - ] - -dashboardZoneThree -: - Available since: {{< minver v="8.0.0" >}} - Located in: /controllers/admin/AdminDashboardController.php - - Parameters: - ```php - (string|null) $statsDateFrom, - 'date_to' => (string|null) $statsDateTo, - ] - ``` - -displayAdminAfterHeader -: - Located in: - - - admin-dev/themes/default/template/header.tpl - - admin-dev/themes/new-theme/template/layout.tpl - - -displayAdminCustomers -: - Display new elements in the Back Office, tab AdminCustomers - This hook launches modules when the AdminCustomers tab is displayed in the Back Office - - Located in: admin-dev/themes/default/template/controllers/customers/helpers/view/view.tpl - - Parameters: - ```php - }} - - Display new elements in the Back Office, tab AdminCustomers, Addresses actions. - This hook launches modules when the Addresses list into the AdminCustomers tab is displayed in the Back Office - - Located in: /admin-dev/themes/default/template/controllers/customers/helpers/view/view.tpl - - Parameters: - ```php - (int) Address ID - ) - ``` - -displayAdminEndContent -: - Available since: {{< minver v="1.7.4" >}} - - Administration end of content. - This hook is displayed at the end of the main content, before the footer - - Located in: - - /admin-dev/themes/default/template/footer.tpl - - /admin-dev/themes/new-theme/template/layout.tpl - - -displayAdminForm -: - Located in: admin-dev/themes/default/template/helpers/form/form.tpl - -displayAdminGridTableBefore -: - Available since: {{< minver v="1.7.7.2" >}} - - This hook adds new blocks before Grid component table. - - Located in: templates/bundles/PrestaShopBundle/views/Admin/Common/Grid/Blocks/table.html.twig - - Parameters: - ```php - (string) $controller - 'legacy_controller' => (string) $legacyController - ); - ``` - -displayAdminGridTableAfter -: - Available since: {{< minver v="1.7.7.2" >}} - - This hook adds new blocks after Grid component table. - - Located in: templates/bundles/PrestaShopBundle/views/Admin/Common/Grid/Blocks/table.html.twig - - Parameters: - ```php - (string) $controller - 'legacy_controller' => (string) $legacyController - ); - ``` - - -displayAdminListAfter -: - Located in: - - - admin-dev/themes/default/template/controllers/countries/helpers/list/list_footer.tpl - - admin-dev/themes/default/template/controllers/tax_rules/helpers/list/list_footer.tpl - - admin-dev/themes/default/template/helpers/list/list_footer.tpl - - -displayAdminListBefore -: - Located in: - - - admin-dev/themes/default/template/controllers/tax_rules/helpers/list/list_header.tpl - - admin-dev/themes/default/template/helpers/list/list_header.tpl - - -displayAdminLogin -: - Located in: admin-dev/themes/default/template/controllers/login/content.tpl - - -displayAdminNavBarBeforeEnd -: - Display new elements in the Back Office, tab AdminCustomers - This hook launches modules when the AdminCustomers tab is displayed in the Back Office - - Located in: - - - admin-dev/themes/default/template/nav.tpl - - admin-dev/themes/new-theme/template/components/layout/nav_bar.tpl - - -displayAdminOptions -: - Located in: admin-dev/themes/default/template/helpers/options/options.tpl - - -displayAdminOrder -: - Display new elements in the Back Office, tab AdminOrder - This hook launches modules when the AdminOrder tab is displayed in the Back Office - - Located in: - - - admin-dev/themes/default/template/controllers/orders/helpers/view/view.tpl - - templates/bundles/PrestaShopBundle/views/Admin/Sell/Order/Order/view.html.twig - - Parameters: - ```php - }} - - This hook displays new tab contents on the order view page - - Located in: /templates/bundles/PrestaShopBundle/views/Admin/Sell/Order/Order/Blocks/View/details.html.twig - - Parameters: - ```php - (int) Order ID - ); - ``` - - -displayAdminOrderLeft -: - **(removed in 1.7.7 in favor of)** - → `displayAdminOrderMain` - - Located in: admin-dev/themes/default/template/controllers/orders/helpers/view/view.tpl - - -displayAdminOrderMain -: - Available since: {{< minver v="1.7.7" >}} - - This hook displays content in the order view page in the main column under the details view - - Located in: /templates/bundles/PrestaShopBundle/views/Admin/Sell/Order/Order/view.html.twig - - Parameters: - ```php - (int) Order ID - ); - ``` - - -displayAdminOrderMainBottom -: - Available since: {{< minver v="1.7.7" >}} - - This hook displays content in the order view page at the bottom of the main column - - Located in: /templates/bundles/PrestaShopBundle/views/Admin/Sell/Order/Order/view.html.twig - - Parameters: - ```php - (int) Order ID - ); - ``` - - -displayAdminOrderRight -: - **(removed in 1.7.7 in favor of)** - → `displayAdminOrderSide` - - Located in: admin-dev/themes/default/template/controllers/orders/helpers/view/view.tpl - - -displayAdminOrderSide -: - Available since: {{< minver v="1.7.7" >}} - - This hook displays content in the order view page in the side column under the customer view - - Located in: /templates/bundles/PrestaShopBundle/views/Admin/Sell/Order/Order/view.html.twig - - Parameters: - ```php - (int) Order ID - ); - ``` - - -displayAdminOrderSideBottom -: - Available since: {{< minver v="1.7.7" >}} - - This hook displays content in the order view page at the bottom of the side column - - Located in: /templates/bundles/PrestaShopBundle/views/Admin/Sell/Order/Order/view.html.twig - - Parameters: - ```php - (int) Order ID - ); - ``` - - -displayAdminOrderTabOrder -: - **(removed in 1.7.7 in favor of)** - → `displayAdminOrderTabLink` - - Display new elements in Back Office, AdminOrder, panel Order - This hook launches modules when the AdminOrder tab is displayed in the Back Office and extends / override Order panel tabs - - Located in: /controllers/admin/AdminOrdersController.php - - -displayAdminOrderTabShip -: - **(removed in 1.7.7 in favor of)** - → `displayAdminOrderTabLink` - - Display new elements in Back Office, AdminOrder, panel Shipping - This hook launches modules when the AdminOrder tab is displayed in the Back Office and extends / override Shipping panel tabs - - Located in: /controllers/admin/AdminOrdersController.php - -displayAdminOrderTabLink -: - Available since: {{< minver v="1.7.7" >}} - - This hook displays new tab links on the order view page - - Located in: /templates/bundles/PrestaShopBundle/views/Admin/Sell/Order/Order/Blocks/View/details.html.twig - - Parameters: - ```php - (int) Order ID - ); - ``` - - -displayAdminProductsExtra -: - Located in: /src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/product.html.twig - - -displayAdminProductsCombinationBottom -: - Located in: /templates/bundles/PrestaShopBundle/views/Admin/Product/Include/form_combination.html.twig - - -displayAdminProductsMainStepLeftColumnBottom -: - Display new elements in back office product page, left column of - This hook launches modules when the back office product page is displayed - - Located in: /templates/bundles/PrestaShopBundle/views/Admin/Product/ProductPage/Panels/essentials.html.twig - - -displayAdminProductsMainStepLeftColumnMiddle -: - Display new elements in back office product page, left column of - This hook launches modules when the back office product page is displayed - - Located in: /templates/bundles/PrestaShopBundle/views/Admin/Product/ProductPage/Panels/essentials.html.twig - - -displayAdminProductsMainStepRightColumnBottom -: - Display new elements in back office product page, right column of - This hook launches modules when the back office product page is displayed - - Located in: /templates/bundles/PrestaShopBundle/views/Admin/Product/ProductPage/Panels/essentials.html.twig - - -displayAdminProductsOptionsStepBottom -: - Display new elements in back office product page, Options tab - This hook launches modules when the back office product page is displayed - - Located in: /templates/bundles/PrestaShopBundle/views/Admin/Product/form.html.twig - - -displayAdminProductsOptionsStepTop -: - Display new elements in back office product page, Options tab - This hook launches modules when the back office product page is displayed - - Located in: /templates/bundles/PrestaShopBundle/views/Admin/Product/form.html.twig - - -displayAdminProductsPriceStepBottom -: - Display new elements in back office product page, Price tab - This hook launches modules when the back office product page is displayed - - Located in: /templates/bundles/PrestaShopBundle/views/Admin/Product/form.html.twig - - -displayAdminProductsQuantitiesStepBottom -: - Display new elements in back office product page, Quantities/Com - This hook launches modules when the back office product page is displayed - - Located in: /templates/bundles/PrestaShopBundle/views/Admin/Product/form.html.twig - - -displayAdminProductsSeoStepBottom -: - Display new elements in back office product page, SEO tab - This hook launches modules when the back office product page is displayed - - Located in: /templates/bundles/PrestaShopBundle/views/Admin/Product/Include/form_seo.html.twig - - -displayAdminProductsShippingStepBottom -: - Display new elements in back office product page, Shipping tab - This hook launches modules when the back office product page is displayed - - Located in: /templates/bundles/PrestaShopBundle/views/Admin/Product/Include/form_shipping.html.twig - - -displayAdminStatsModules -: - Located in: /controllers/admin/AdminStatsTabController.php - -displayAdminThemesListAfter -: - Located in: /src/PrestaShopBundle/Resources/views/Admin/Improve/Design/Theme/index.html.twig - - Parameters: - ```php - (string) Name of the currently used theme - ); - ``` - - -displayAdminView -: - Located in: admin-dev/themes/default/template/helpers/view/view.tpl - -displayAfterTitleTag -: - Available since: {{< minver v="1.7.8" >}} - - In html header - Use this hook to add content after title tag - - Located in: - - - /themes/classic/templates/_partials/head.tpl - - -displayAfterBodyOpeningTag -: - Very top of pages - Use this hook for advertisement or modals you want to load first - - Located in: - - - /themes/classic/templates/checkout/checkout.tpl - - /themes/classic/templates/layouts/layout-both-columns.tpl - - -displayAfterCarrier -: - After carriers list - This hook is displayed after the carrier list in Front Office - - Located in: /classes/checkout/CheckoutDeliveryStep.php - - -displayAfterProductThumbs -: - Available since: {{< minver v="1.7.1" >}} - - Display extra content below product thumbs - This hook displays new elements below product images ex. additional media - - Located in: /themes/classic/templates/catalog/_partials/product-cover-thumbnails.tpl - - -displayAfterThemeInstallation -: - Located in: admin-dev/themes/default/template/controllers/themes/helpers/view/view.tpl - - -displayAttributeForm -: - Add fields to the form 'attribute value' - This hook adds fields to the form 'attribute value' - - Located in: admin-dev/themes/default/template/controllers/attributes/helpers/form/form.tpl - - -displayAttributeGroupForm -: - Add fields to the form 'attribute group' - This hook adds fields to the form 'attribute group' - - Located in: admin-dev/themes/default/template/controllers/attributes_groups/helpers/form/form.tpl - - -displayBackOfficeCategory -: - Display new elements in the Back Office, tab AdminCategories - This hook launches modules when the AdminCategories tab is displayed in the Back Office - - Located in: /controllers/admin/AdminCategoriesController.php - - -displayBackOfficeEmployeeMenu -: - Displays new elements in the Back Office employee menu - - Located in: /classes/controller/AdminController.php - - Parameters: - ```php - (ActionsBarButtonsCollection) Collection of ActionsBarButtonInterface - ); - ``` - - -displayBackOfficeFooter -: - **(deprecated since 1.7.0.0)** - - Displayed within the admin panel's footer - - Located in: - - - admin-dev/themes/default/template/footer.tpl - - admin-dev/themes/new-theme/template/footer.tpl - - -displayBackOfficeHeader -: - Displayed between the <head></head> tags on every Back Office page (when logged in). - - Located in: /classes/controller/AdminController.php - - -displayBackOfficeOrderActions -: - **(deprecated since 1.7.7)** - → `actionGetAdminOrderButtons` - - This hook displays content in the order view page after action buttons - - Since the version **1.7.7** this hook no longer exists, an alias on the new `displayAdminOrderSide` exists but it is not displayed the same way, so it is recommended to use the dedicated `actionGetAdminOrderButtons` hook to add buttons - - Located in: admin-dev/themes/default/template/controllers/orders/helpers/view/view.tpl - - -displayBackOfficeTop -: - Shown above the actual content of a Back Office page - - Located in: /classes/controller/AdminController.php - - -displayBanner -: - Available since: {{< minver v="1.7.1" >}} - - Located in: /themes/classic/templates/_partials/header.tpl - - -displayBeforeBodyClosingTag -: - Very bottom of pages - Use this hook for your modals or any content you want to load at the very end - - Located in: - - - /themes/classic/templates/checkout/checkout.tpl - - /themes/classic/templates/layouts/layout-both-columns.tpl - - -displayBeforeCarrier -: - This hook is displayed before the carrier list on the Front Office - - Located in: /classes/checkout/CheckoutDeliveryStep.php - - Parameters: - ```php - array( - array( - 'name' => (string) Name, - 'img' => (string) Image URL, - 'delay' => (string) Delay text, - 'price' => (float) Total price with tax, - 'price_tax_exc' => (float) Total price without tax, - 'id_carrier' => (int) intified option delivery identifier, - 'id_module' => (int) Module ID - )), - 'checked' => (int) intified selected carriers, - 'delivery_option_list' => array(array( - 0 => array( // First address - '12,' => array( // First delivery option available for this address - carrier_list => array( - 12 => array( // First carrier for this option - 'instance' => Carrier Object, - 'logo' => , - 'price_with_tax' => 12.4, // Example - 'price_without_tax' => 12.4, // Example - 'package_list' => array( - 1, // Example - 3, // Example - ), - ), - ), - is_best_grade => true, // Does this option have the biggest grade (quick shipping) for this shipping address - is_best_price => true, // Does this option have the lower price for this shipping address - unique_carrier => true, // Does this option use a unique carrier - total_price_with_tax => 12.5, - total_price_without_tax => 12.5, - position => 5, // Average of the carrier position - ), - ), - )), - 'delivery_option' => array( - '' => Delivery option, - ... - ) - ); - ``` - - NOTE: intified means an array of integers 'intified' by Cart::intifier - -displayCarrierExtraContent -: - Displays additional content for a carrier. It can be used for selecting pickup points, delivery time etc. This hook calls only the module related to the carrier, in order to add options only when needed. Your module name must be specified in `external_module_name` property of the carrier, otherwise it won't be called. - - Located in: /classes/checkout/DeliveryOptionsFinder.php - - -displayCarrierList -: - **(deprecated since 1.7.0.0)** - - Display extra carriers in the carrier list. - - Located in: /classes/Cart.php - - Parameters: - ```php - (object) Address object - ); - ``` - -displayCartExtraProductActions -: - Extra buttons in shopping cart - This hook adds extra buttons to the product lines, in the shopping cart - - Located in: /themes/classic/templates/checkout/_partials/cart-detailed-product-line.tpl - -displayCartModalContent -: - Available since: {{< minver v="1.7.8" >}} - - Content of Add-to-cart modal - This hook displays content in the middle of the window that appears after adding product to cart - - Located in: /themes/classic/modules/ps_shoppingcart/modal.tpl - -displayCartModalFooter -: - Available since: {{< minver v="1.7.8" >}} - - Bottom of Add-to-cart modal - This hook displays content in the bottom of window that appears after adding product to cart - - Located in: /themes/classic/modules/ps_shoppingcart/modal.tpl - -displayCheckoutSubtotalDetails -: - Located in: /themes/classic/templates/checkout/_partials/cart-detailed-totals.tpl - - -displayCheckoutSummaryTop -: - Located in: /themes/classic/templates/checkout/_partials/cart-summary.tpl - - -displayCMSDisputeInformation -: - Located in: /themes/classic/templates/cms/page.tpl - - -displayCMSPrintButton -: - Located in: /themes/classic/templates/cms/page.tpl - - -displayContentWrapperBottom -: - Content wrapper section (bottom) - This hook displays new elements in the bottom of the content wrapper - - Located in: - - - themes/classic/templates/layouts/layout-both-columns.tpl - - themes/classic/templates/layouts/layout-content-only.tpl - - themes/classic/templates/layouts/layout-full-width.tpl - - themes/classic/templates/layouts/layout-left-column.tpl - - themes/classic/templates/layouts/layout-right-column.tpl - - -displayContentWrapperTop -: - Content wrapper section (top) - This hook displays new elements in the top of the content wrapper - - Located in: - - - themes/classic/templates/layouts/layout-both-columns.tpl - - themes/classic/templates/layouts/layout-content-only.tpl - - themes/classic/templates/layouts/layout-full-width.tpl - - themes/classic/templates/layouts/layout-left-column.tpl - - themes/classic/templates/layouts/layout-right-column.tpl - - -displayCrossSellingShoppingCart -: - Located in: /themes/classic/templates/checkout/cart-empty.tpl - - -displayCustomerAccount -: - Displays new elements on the customer account page in Front Office - - Located in: /themes/classic/templates/customer/my-account.tpl - - -displayCustomerAccountForm -: - Displays information on the customer account creation form - - Located in: /classes/form/CustomerForm.php - - -displayCustomerAccountFormTop -: - Displayed above the customer's account creation form - - Located in: /controllers/front/AuthController.php - - -displayCustomerLoginFormAfter -: - Displays new elements after the login form - - Located in: /themes/classic/templates/customer/authentication.tpl - - -displayCustomization -: - Located in: /classes/Product.php - - -displayDashboardToolbarIcons -: - Available since: {{< minver v="1.7.3" >}} - - Display new elements in back office page with dashboard, on icons list. - This hook launches modules when the back office with dashboard is displayed - - Located in: - - /templates/bundles/PrestaShopBundle/views/Admin/Configure/AdvancedParameters/LogsPage/Blocks/actions.html.twig - - /templates/bundles/PrestaShopBundle/views/Admin/Product/CatalogPage/Blocks/tools.html.twig - - -displayDashboardToolbarTopMenu -: - Available since: {{< minver v="1.7.3" >}} - - Display new elements in back office page with a dashboard, on top Menu. - This hook launches modules when a page with a dashboard is displayed - - Located in: - - /admin-dev/themes/default/template/page_header_toolbar.tpl - - /admin-dev/themes/new-theme/template/page_header_toolbar.tpl - - -displayDashboardTop -: - Dashboard Top - Displays the content in the dashboard's top area - - Located in: admin-dev/themes/default/template/page_header_toolbar.tpl - - -displayExpressCheckout -: - Located in: /themes/classic/templates/checkout/_partials/cart-detailed-actions.tpl - - -displayFeatureForm -: - Add fields to the form 'feature' - This hook adds fields to the form 'feature' - - Located in: admin-dev/themes/default/template/controllers/features/helpers/form/form.tpl - - -displayFeaturePostProcess -: - On post-process in admin feature - This hook is called on post-process in admin feature - - Located in: /controllers/admin/AdminFeaturesController.php - - -displayFeatureValueForm -: - Add fields to the form 'feature value' - This hook adds fields to the form 'feature value' - - Located in: admin-dev/themes/default/template/controllers/feature_value/helpers/form/form.tpl - - -displayFeatureValuePostProcess -: - On post-process in admin feature value - This hook is called on post-process in admin feature value - - Located in: /controllers/admin/AdminFeaturesController.php - - -displayFooter -: - Displays new blocks in the footer - - Located in: /themes/classic/templates/_partials/footer.tpl - - -displayFooterAfter -: - Located in: /themes/classic/templates/_partials/footer.tpl - - -displayFooterBefore -: - Located in: /themes/classic/templates/_partials/footer.tpl - - -displayFooterProduct -: - Added under the product's description - - Located in: /themes/classic/templates/catalog/product.tpl - - -displayHeader -: - Added in the header of every Front Office page - - Located in: /classes/controller/FrontController.php - - -displayHome -: - Displayed on the content of the home page. - - Located in: /controllers/front/IndexController.php - - -displayInvoice -: - **(deprecated since 1.7.7)** - → `displayAdminOrderTop` - - Invoice - This hook displays new blocks on the invoice (order) - - Located in: admin-dev/themes/default/template/controllers/orders/helpers/view/view.tpl - - -displayAdminOrderTop -: - Available since: {{< minver v="1.7.7" >}} - - This hook displays content at the top of the order view page - - Located in: /templates/bundles/PrestaShopBundle/views/Admin/Sell/Order/Order/view.html.twig - - Parameters: - ```php - (int) Order ID - ); - ``` - - -displayInvoiceLegalFreeText -: - PDF Invoice - Legal Free Text - This hook allows you to modify the legal free text on PDF invoices - - Located in: /classes/pdf/HTMLTemplateInvoice.php - - -displayLeftColumn -: - Displays new elements in the left-hand column - - Located in: /themes/classic/templates/layouts/layout-both-columns.tpl - - -displayLeftColumnProduct -: - Displays new elements in the left-hand column of the product page - - Located in: /themes/classic/templates/layouts/layout-both-columns.tpl - - -displayMaintenance -: - Maintenance Page - This hook displays new elements on the maintenance page - - Located in: /classes/controller/FrontController.php - - -displayMyAccountBlock -: - Displays extra information within the "my account: block - - Located in: /themes/classic/modules/ps_customeraccountlinks/ps_customeraccountlinks.tpl - - -displayNav1 -: - Located in: - - - /themes/classic/templates/_partials/header.tpl - - /themes/classic/templates/checkout/_partials/header.tpl - - -displayNav2 -: - Located in: - - - /themes/classic/templates/_partials/header.tpl - - /themes/classic/templates/checkout/_partials/header.tpl - - -displayNavFullWidth -: - Navigation - This hook displays full width navigation menu at the top of your pages - - Located in: - - - /themes/classic/templates/_partials/header.tpl - - /themes/classic/templates/checkout/_partials/header.tpl - - -displayNotFound -: - Located in: /themes/classic/templates/errors/not-found.tpl - - -displayOrderConfirmation -: - Called within an order's confirmation page - - Located in: /controllers/front/OrderConfirmationController.php - - Parameters: - ```php - (object) Order - ); - ``` - - -displayOrderConfirmation1 -: - Located in: /themes/classic/templates/checkout/order-confirmation.tpl - - -displayOrderConfirmation2 -: - Located in: /themes/classic/templates/checkout/order-confirmation.tpl - - -displayOrderDetail -: - Displayed within the order's details in Front Office - - Located in: - - - /controllers/front/GuestTrackingController.php - - /controllers/front/OrderDetailController.php - - Parameters: - ```php - (object) Order object - ); - ``` - - -displayOrderPreview -: - Available since: {{< minver v="1.7.7" >}} - - Displayed at the bottom of the order's preview on the order's listing page in Back Office - - Located in: /templates/bundles/PrestaShopBundle/views/Admin/Sell/Order/Order/preview.html.twig - - Parameters: - ```php - (integer) Order Id - ); - ``` - - -displayPaymentByBinaries -: - Payment form generated by binaries - This hook displays form generated by binaries during the checkout - - Located in: /themes/classic/templates/checkout/_partials/steps/payment.tpl - - -displayPaymentEU -: - Located in: /modules/ps_legalcompliance/ps_legalcompliance.php - - -displayPaymentReturn -: - Payment return - - Located in: /controllers/front/OrderConfirmationController.php - - -displayPaymentTop -: - Top of payment page - This hook is displayed at the top of the payment page - - Located in: /themes/classic/templates/checkout/_partials/steps/payment.tpl - - -displayPersonalInformationTop -: - Available since: {{< minver v="1.7.6" >}} - - Display actions or additional content in the personal details tab of the checkout funnel. - - Located in: /themes/classic/templates/checkout/_partials/steps/personal-information.tpl - - -displayProductActions -: - Available since: {{< minver v="1.7.6" >}} - - This hook allow additional actions to be displayed & triggered, close to the add to cart button. - - Located in: /themes/classic/templates/catalog/_partials/product-add-to-cart.tpl - - -displayProductAdditionalInfo -: - Available since: {{< minver v="1.7.1" >}} - - Product page additional info - This hook adds additional information on the product page - - Located in: - - - /themes/classic/templates/catalog/_partials/product-additional-info.tpl - - /themes/classic/templates/catalog/_partials/quickview.tpl - - -displayProductExtraContent -: - Available since: {{< minver v="1.7.0" >}} - - Display extra content on the product page. - This hook expects ProductExtraContent instances, which will be properly displayed by the template on the product page - - Located in: /controllers/front/ProductController.php - - Parameters: - ```php - (object) Product object - ), - ``` - - -displayProductListReviews -: - Available since: {{< minver v="1.7.1" >}} - - Located in: /themes/classic/templates/catalog/_partials/miniatures/product.tpl - - -displayProductPageDrawer -: - Available since: {{< minver v="1.7.1" >}} - - Product Page Drawer. - This hook displays content in the right sidebar of the product page - - Located in: /src/PrestaShopBundle/Controller/Admin/ProductController.php - - Parameters: - ```php - (object) Product object - ), - ``` - - -displayProductPriceBlock -: - Located in: - - - /themes/classic/templates/catalog/_partials/miniatures/product.tpl - - /themes/classic/templates/catalog/_partials/product-prices.tpl - - /themes/classic/templates/checkout/_partials/cart-summary-product-line.tpl - - /themes/classic/templates/checkout/_partials/order-confirmation-table.tpl - - -displayReassurance -: - Located in: - - - /themes/classic/templates/catalog/product.tpl - - /themes/classic/templates/checkout/cart.tpl - - /themes/classic/templates/checkout/checkout.tpl - - -displayRightColumn -: - Displays new elements in the right-hand column - - Located in: /themes/classic/templates/layouts/layout-both-columns.tpl - - Parameters: - ```php - (object) Cart object - ); - ``` - - Note that the Cart object can also be retrieved from the current Context. - -displayRightColumnProduct -: - Displays new elements in the right-hand column of the product page - - Located in: /themes/classic/templates/layouts/layout-both-columns.tpl - - -displaySearch -: - Located in: /themes/classic/templates/errors/not-found.tpl - - -displayShoppingCart -: - Displays new action buttons within the shopping cart - - Located in: /themes/classic/templates/checkout/cart.tpl - - -displayShoppingCartFooter -: - Shopping cart footer - This hook displays some specific information on the shopping cart's page - - Located in: /themes/classic/templates/checkout/cart.tpl - - -displayTop -: - Top of pages - This hook displays additional elements at the top of your pages - - Located in: - - - /themes/classic/templates/_partials/header.tpl - - /themes/classic/templates/checkout/_partials/header.tpl - - -displayWrapperBottom -: - Main wrapper section (bottom) - This hook displays new elements in the bottom of the main wrapper - - Located in: - - - themes/classic/templates/checkout/checkout.tpl - - themes/classic/templates/layouts/layout-both-columns.tpl - - -displayWrapperTop -: - Main wrapper section (top) - This hook displays new elements in the top of the main wrapper - - Located in: - - - themes/classic/templates/checkout/checkout.tpl - - themes/classic/templates/layouts/layout-both-columns.tpl - - -displayAdditionalCustomerAddressFields -: - Available since: {{< minver v="1.7.7" >}} - - This hook allows to display extra field values added in an address form using hook 'additionalCustomerAddressFields' - - Located in: /themes/classic/templates/customer/_partials/block-address.tpl - - -displayFooterCategory -: - Available since: {{< minver v="1.7.7" >}} - - This hook adds new blocks under all product listings - in a category, on search page, on bestsellers page etc. - - Located in: /themes/classic/templates/catalog/listing/product-list.tpl - - -displayHeaderCategory -: - Available since: {{< minver v="1.7.8" >}} - - This hook adds new blocks above all product listings - in a category, on search page, on bestsellers page etc. - - Located in: /themes/classic/templates/catalog/listing/product-list.tpl - - -filterCategoryContent -: - Available since: {{< minver v="1.7.1" >}} - - Filter the content page category. - This hook is called just before fetching content page category - - Located in: /controllers/front/listing/CategoryController.php - - Parameters: - ```php - (object) Category object - ), - ``` - - -filterCmsCategoryContent -: - Filter the content page category - This hook is called just before fetching content page category - - Located in: /controllers/front/CmsController.php - - -filterCmsContent -: - Filter the content page - This hook is called just before fetching content page - - Located in: /controllers/front/CmsController.php - - -filterHtmlContent -: - Filter HTML field before rending a page - This hook is called just before fetching a page on HTML field - - Located in: /src/Adapter/ObjectPresenter.php - - -filterManufacturerContent -: - Filter the content page manufacturer - This hook is called just before fetching content page manufacturer - - Located in: /controllers/front/listing/ManufacturerController.php - - -filterProductContent -: - Filter the content page product - This hook is called just before fetching content page product - - Located in: /controllers/front/ProductController.php - - -filterProductSearch -: - Available since: {{< minver v="1.7.1" >}} - - Located in: /classes/controller/ProductListingFrontController.php - - -filterSupplierContent -: - Located in: /controllers/front/listing/SupplierController.php - - -moduleRoutes -: - Located in: /classes/Dispatcher.php - - -overrideMinimalPurchasePrice -: - Located in: - - - /classes/controller/ModuleFrontController.php - - /src/Adapter/Cart/CartPresenter.php - - -sendMailAlterTemplateVars -: - Located in: /classes/Mail.php - - -termsAndConditions -: - Located in: /classes/checkout/ConditionsToApproveFinder.php - - -updateProduct -: - Located in: - - - /classes/Product.php - - /classes/webservice/WebserviceSpecificManagementImages.php - - -validateCustomerFormFields -: - Located in: /classes/form/CustomerForm.php - - -action<KpiIdentifier>KpiRowModifier -: - Available since: {{< minver v="1.7.6" >}} - - This hook allow to alter the list of Kpis used in a Kpi row. - This hook is called just before the validation and the building of the KpiRow. - - Located in: /src/Core/Kpi/Row/HookableKpiRowFactory.php - - Parameters: - ```php - KpiInterface[] $kpis - ), - ``` - - -action<HookName>Form -: - Available since: {{< minver v="1.7.4" >}} - - This hook allows to modify options form content - - Located in: /src/Core/Form/Handler.php - - Parameters: - ```php - (FormBuilderInterface) $this->formBuilder, - ] - ``` - - -action<HookName>Save -: - Available since: {{< minver v="1.7.4" >}} - - This hook allows to modify data of options form after it was saved - - Located in: /src/Core/Form/Handler.php - - Parameters: - ```php - (array) &$errors, - 'form_data' => (array) &$data, - ] - ``` - - -action<GridDefinitionId>GridDefinitionModifier -: - Available since: {{< minver v="1.7.5" >}} - Located in: /src/Core/Grid/Definition/Factory/AbstractGridDefinitionFactory.php - - Parameters: - ```php - (GridDefinition) $definition, - ] - ``` - - -action<GridDefinitionId>GridQueryBuilderModifier -: - Available since: {{< minver v="1.7.5" >}} - Located in: /src/Core/Grid/Data/Factory/DoctrineGridDataFactory.php - - Parameters: - ```php - (QueryBuilder) $searchQueryBuilder, - 'count_query_builder' => (QueryBuilder) $countQueryBuilder, - 'search_criteria' => (SearchCriteriaInterface) $searchCriteria, - ] - ``` - - -action<GridDefinitionId>GridDataModifier -: - Available since: {{< minver v="1.7.5" >}} - Located in: /src/Core/Grid/GridFactory.php - - Parameters: - ```php - (GridData) $data, - ] - ``` - - -action<GridDefinitionId>GridFilterFormModifier -: - Available since: {{< minver v="1.7.5" >}} - Located in: /src/Core/Grid/Filter/GridFilterFormFactory.php - - Parameters: - ```php - (FormBuilderInterface) $formBuilder, - ] - ``` - - -action<GridDefinitionId>GridPresenterModifier -: - Available since: {{< minver v="1.7.5" >}} - Located in: /src/Core/Grid/Presenter/GridPresenter.php - - Parameters: - ```php - (array) &$presentedGrid, - ] - ``` - - -action<FormName>FormBuilderModifier -: - Available since: {{< minver v="1.7.6" >}} - Located in: /src/Core/Form/IdentifiableObject/Builder/FormBuilder.php - - Parameters: - ```php - (FormBuilderInterface) $formBuilder, - 'data' => (array) &$data, - 'id' => (int|null) $id, - ] - ``` - - -action<FormName>FormDataProviderDefaultData, -: - Available since: {{< minver v="8.0.0" >}} - Located in: /src/Core/Form/IdentifiableObject/Builder/FormBuilder.php - - Parameters: - ```php - (array) &$data, - 'options' => (array) &$options, - ] - ``` - - -action<FormName>FormDataProviderData, -: - Available since: {{< minver v="8.0.0" >}} - Located in: /src/Core/Form/IdentifiableObject/Builder/FormBuilder.php - - Parameters: - ```php - (array) &$data, - 'id' => (int) $id, - 'options' => (array) &$options, - ] - ``` - - -actionBeforeUpdate<FormName>FormHandler -: - Available since: {{< minver v="1.7.6" >}} - Located in: /src/Core/Form/IdentifiableObject/Handler/FormHandler.php - - Parameters: - ```php - &$data, - 'id' => (int) $id, - ] - ``` - - -actionAfterUpdate<FormName>FormHandler -: - Available since: {{< minver v="1.7.6" >}} - Located in: /src/Core/Form/IdentifiableObject/Handler/FormHandler.php - - Parameters: - ```php - (int) $id, - ] - ``` - - -actionBeforeCreate<FormName>FormHandler -: - Available since: {{< minver v="1.7.6" >}} - Located in: /src/Core/Form/IdentifiableObject/Handler/FormHandler.php - - Parameters: - ```php - &$data, - ] - ``` - - -actionAfterCreate<FormName>FormHandler -: - Available since: {{< minver v="1.7.6" >}} - Located in: /src/Core/Form/IdentifiableObject/Handler/FormHandler.php - - Parameters: - ```php - $id, - ] - ``` - - -actionFilterDeliveryOptionList -: - Available since: {{< minver v="8.0.0" >}} - Located in: /classes/Cart.php - - Parameters: - ```php - (array) &$delivery_option_list, - ] - ``` - - -actionValidateOrderAfter -: - Available since: {{< minver v="8.0.0" >}} - Located in: /classes/PaymentModule.php - - Parameters: - ```php - (Cart|null) $contextCart, - 'order' => (Order|null) $order, - 'orders' => (array) $orderList, - 'customer' => (Customer) $contextCustomer, - 'currency' => (Currency) $contextCurrency, - 'orderStatus' => (OrderState) $orderState, - ] - ``` - - -actionPresentPaymentOptions -: - Available since: {{< minver v="8.0.0" >}} - Located in: /classes/checkout/PaymentOptionsFinder.php - - Parameters: - ```php - (array) &$paymentOptions, - ] - ``` - - -actionGetAdminToolbarButtons -: - Available since: {{< minver v="8.0.0" >}} - Located in: /classes/controller/AdminController.php - - Parameters: - ```php - (AdminController) $currentController, - 'toolbar_extra_buttons_collection' => (ActionsBarButtonsCollection) $toolbarButtonsCollection, - ] - ``` - - -actionGetAlternativeSearchPanels -: - Available since: {{< minver v="8.0.0" >}} - Located in: /controllers/admin/AdminSearchController.php - - Parameters: - ```php - (array) $searchPanels, - 'bo_query' => (string) $searchedExpression, - ] - ``` - - -displayBackOfficeEmployeeMenu -: - Available since: {{< minver v="8.0.0" >}} - Located in: /src/PrestaShopBundle/Bridge/Smarty/HeaderConfigurator.php - - Parameters: - ```php - (ActionsBarButtonsCollection) $menuLinksCollections, - ] - ``` - - -displayEmptyModuleCategoryExtraMessage -: - Available since: {{< minver v="8.0.0" >}} - Located in: /src/PrestaShopBundle/Resources/views/Admin/Module/Includes/grid_manage_empty.html.twig - - Parameters: - ```html.twig - { - 'category_name': (string) categoryName - } - ``` - - -{{% /funcdef %}} diff --git a/modules/concepts/hooks/list-hooks/_index.md b/modules/concepts/hooks/list-of-hooks/_index.md similarity index 91% rename from modules/concepts/hooks/list-hooks/_index.md rename to modules/concepts/hooks/list-of-hooks/_index.md index cf97335aaa..c0131d0cde 100644 --- a/modules/concepts/hooks/list-hooks/_index.md +++ b/modules/concepts/hooks/list-of-hooks/_index.md @@ -1,11 +1,11 @@ --- -menuTitle: List of hooks bis -title: List of hooks bis +menuTitle: List of hooks +title: List of hooks type: chapter: false --- -# List of hooks bis +# List of hooks {{% notice tip %}} **Search tip:** Some hooks are generated dynamically, so their names are documented in a generic way. diff --git a/modules/concepts/hooks/list-hooks/actionAfter.md b/modules/concepts/hooks/list-of-hooks/actionAfter.md similarity index 67% rename from modules/concepts/hooks/list-hooks/actionAfter.md rename to modules/concepts/hooks/list-of-hooks/actionAfter.md index e0176077ca..5efa96b3f3 100644 --- a/modules/concepts/hooks/list-hooks/actionAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionAfter.md @@ -1,22 +1,30 @@ --- menuTitle: actionAfter -title: actionAfter +Title: actionAfter hidden: true +hookTitle: files: - classes/controller/AdminController.php -types: +locations: - backoffice -hookTypes: +types: - legacy --- # Hook : actionAfter -Located in : +## Informations + +Hook locations: + - backoffice + +Hook types: + - legacy +Located in: - classes/controller/AdminController.php -## Parameters +## Hook call with parameters ```php Hook::exec('action' . get_class($this) . ucfirst($this->action) . 'After', ['controller' => $this, 'return' => $return]); diff --git a/modules/concepts/hooks/list-hooks/actionBefore.md b/modules/concepts/hooks/list-of-hooks/actionBefore.md similarity index 66% rename from modules/concepts/hooks/list-hooks/actionBefore.md rename to modules/concepts/hooks/list-of-hooks/actionBefore.md index 5519ba6349..aa409a0838 100644 --- a/modules/concepts/hooks/list-hooks/actionBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionBefore.md @@ -1,22 +1,30 @@ --- menuTitle: actionBefore -title: actionBefore +Title: actionBefore hidden: true +hookTitle: files: - classes/controller/AdminController.php -types: +locations: - backoffice -hookTypes: +types: - legacy --- # Hook : actionBefore -Located in : +## Informations + +Hook locations: + - backoffice + +Hook types: + - legacy +Located in: - classes/controller/AdminController.php -## Parameters +## Hook call with parameters ```php Hook::exec('action' . get_class($this) . ucfirst($this->action) . 'Before', ['controller' => $this]); diff --git a/modules/concepts/hooks/list-hooks/actionListingFieldsModifier.md b/modules/concepts/hooks/list-of-hooks/actionListingFieldsModifier.md similarity index 67% rename from modules/concepts/hooks/list-hooks/actionListingFieldsModifier.md rename to modules/concepts/hooks/list-of-hooks/actionListingFieldsModifier.md index 692062dfc0..073c5cc454 100644 --- a/modules/concepts/hooks/list-hooks/actionListingFieldsModifier.md +++ b/modules/concepts/hooks/list-of-hooks/actionListingFieldsModifier.md @@ -1,22 +1,30 @@ --- menuTitle: actionListingFieldsModifier -title: actionListingFieldsModifier +Title: actionListingFieldsModifier hidden: true +hookTitle: files: - classes/controller/AdminController.php -types: +locations: - backoffice -hookTypes: +types: - legacy --- # Hook : actionListingFieldsModifier -Located in : +## Informations + +Hook locations: + - backoffice + +Hook types: + - legacy +Located in: - classes/controller/AdminController.php -## Parameters +## Hook call with parameters ```php Hook::exec('action' . $this->controller_name . 'ListingFieldsModifier', [ diff --git a/modules/concepts/hooks/list-of-hooks/actionGridDataModifier.md b/modules/concepts/hooks/list-of-hooks/actionGridDataModifier.md new file mode 100644 index 0000000000..c1783c8244 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionGridDataModifier.md @@ -0,0 +1,33 @@ +--- +menuTitle: actionGridDataModifier +Title: actionGridDataModifier +hidden: true +hookTitle: +files: + - src/Core/Grid/GridFactory.php +locations: + - frontoffice +types: + - symfony +--- + +# Hook : actionGridDataModifier + +## Informations + +Hook locations: + - frontoffice + +Hook types: + - symfony + +Located in: + - src/Core/Grid/GridFactory.php + +## Hook call with parameters + +```php +dispatchWithParameters('action' . Container::camelize($definition->getId()) . 'GridDataModifier', [ + 'data' => &$data, + ]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionGridDefinitionModifier.md b/modules/concepts/hooks/list-of-hooks/actionGridDefinitionModifier.md new file mode 100644 index 0000000000..79cda00b85 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionGridDefinitionModifier.md @@ -0,0 +1,33 @@ +--- +menuTitle: actionGridDefinitionModifier +Title: actionGridDefinitionModifier +hidden: true +hookTitle: +files: + - src/Core/Grid/Definition/Factory/AbstractGridDefinitionFactory.php +locations: + - frontoffice +types: + - symfony +--- + +# Hook : actionGridDefinitionModifier + +## Informations + +Hook locations: + - frontoffice + +Hook types: + - symfony + +Located in: + - src/Core/Grid/Definition/Factory/AbstractGridDefinitionFactory.php + +## Hook call with parameters + +```php +dispatchWithParameters('action' . Container::camelize($definition->getId()) . 'GridDefinitionModifier', [ + 'definition' => $definition, + ]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionGridFilterFormModifier.md b/modules/concepts/hooks/list-of-hooks/actionGridFilterFormModifier.md new file mode 100644 index 0000000000..7f740d5e31 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionGridFilterFormModifier.md @@ -0,0 +1,33 @@ +--- +menuTitle: actionGridFilterFormModifier +Title: actionGridFilterFormModifier +hidden: true +hookTitle: +files: + - src/Core/Grid/Filter/GridFilterFormFactory.php +locations: + - frontoffice +types: + - symfony +--- + +# Hook : actionGridFilterFormModifier + +## Informations + +Hook locations: + - frontoffice + +Hook types: + - symfony + +Located in: + - src/Core/Grid/Filter/GridFilterFormFactory.php + +## Hook call with parameters + +```php +dispatchWithParameters('action' . Container::camelize($definition->getId()) . 'GridFilterFormModifier', [ + 'filter_form_builder' => $formBuilder, + ]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionGridPresenterModifier.md b/modules/concepts/hooks/list-of-hooks/actionGridPresenterModifier.md new file mode 100644 index 0000000000..e8311b37a4 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionGridPresenterModifier.md @@ -0,0 +1,33 @@ +--- +menuTitle: actionGridPresenterModifier +Title: actionGridPresenterModifier +hidden: true +hookTitle: +files: + - src/Core/Grid/Presenter/GridPresenter.php +locations: + - frontoffice +types: + - symfony +--- + +# Hook : actionGridPresenterModifier + +## Informations + +Hook locations: + - frontoffice + +Hook types: + - symfony + +Located in: + - src/Core/Grid/Presenter/GridPresenter.php + +## Hook call with parameters + +```php +dispatchWithParameters('action' . Container::camelize($definition->getId()) . 'GridPresenterModifier', [ + 'presented_grid' => &$presentedGrid, + ]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionFormBuilderModifier.md b/modules/concepts/hooks/list-of-hooks/actionFormBuilderModifier.md new file mode 100644 index 0000000000..390b52c5dd --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionFormBuilderModifier.md @@ -0,0 +1,36 @@ +--- +menuTitle: actionFormBuilderModifier +Title: actionFormBuilderModifier +hidden: true +hookTitle: +files: + - src/Core/Form/IdentifiableObject/Builder/FormBuilder.php +locations: + - frontoffice +types: + - symfony +--- + +# Hook : actionFormBuilderModifier + +## Informations + +Hook locations: + - frontoffice + +Hook types: + - symfony + +Located in: + - src/Core/Form/IdentifiableObject/Builder/FormBuilder.php + +## Hook call with parameters + +```php +dispatchWithParameters('action' . $this->camelize($formBuilder->getName()) . 'FormBuilderModifier', [ + 'form_builder' => $formBuilder, + 'data' => &$data, + 'options' => &$options, + 'id' => $id, + ]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionGridQueryBuilderModifier.md b/modules/concepts/hooks/list-of-hooks/actionGridQueryBuilderModifier.md new file mode 100644 index 0000000000..aaeb056126 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionGridQueryBuilderModifier.md @@ -0,0 +1,35 @@ +--- +menuTitle: actionGridQueryBuilderModifier +Title: actionGridQueryBuilderModifier +hidden: true +hookTitle: +files: + - src/Core/Grid/Data/Factory/DoctrineGridDataFactory.php +locations: + - frontoffice +types: + - symfony +--- + +# Hook : actionGridQueryBuilderModifier + +## Informations + +Hook locations: + - frontoffice + +Hook types: + - symfony + +Located in: + - src/Core/Grid/Data/Factory/DoctrineGridDataFactory.php + +## Hook call with parameters + +```php +dispatchWithParameters('action' . Container::camelize($this->gridId) . 'GridQueryBuilderModifier', [ + 'search_query_builder' => $searchQueryBuilder, + 'count_query_builder' => $countQueryBuilder, + 'search_criteria' => $searchCriteria, + ]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionListingFieldsModifier.md b/modules/concepts/hooks/list-of-hooks/actionListingFieldsModifier.md new file mode 100644 index 0000000000..0d2ec90af0 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionListingFieldsModifier.md @@ -0,0 +1,39 @@ +--- +menuTitle: actionListingFieldsModifier +Title: actionListingFieldsModifier +hidden: true +hookTitle: +files: + - src/PrestaShopBundle/Bridge/Helper/Listing/HelperBridge/HelperListBridge.php +locations: + - frontoffice +types: + - symfony +--- + +# Hook : actionListingFieldsModifier + +## Informations + +Hook locations: + - frontoffice + +Hook types: + - symfony + +Located in: + - src/PrestaShopBundle/Bridge/Helper/Listing/HelperBridge/HelperListBridge.php + +## Hook call with parameters + +```php +dispatchWithParameters('action' . $helperListConfiguration->legacyControllerName . 'ListingFieldsModifier', [ + 'select' => &$helperListConfiguration->select, + 'join' => &$helperListConfiguration->join, + 'where' => &$helperListConfiguration->where, + 'group_by' => &$helperListConfiguration->group, + 'order_by' => &$helperListConfiguration->orderBy, + 'order_way' => &$helperListConfiguration->orderWay, + 'fields' => &$helperListConfiguration->fieldsList, + ]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionListingResultsModifier.md b/modules/concepts/hooks/list-of-hooks/actionListingResultsModifier.md new file mode 100644 index 0000000000..6e8b1659bc --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionListingResultsModifier.md @@ -0,0 +1,34 @@ +--- +menuTitle: actionListingResultsModifier +Title: actionListingResultsModifier +hidden: true +hookTitle: +files: + - src/PrestaShopBundle/Bridge/Helper/Listing/HelperBridge/HelperListBridge.php +locations: + - frontoffice +types: + - symfony +--- + +# Hook : actionListingResultsModifier + +## Informations + +Hook locations: + - frontoffice + +Hook types: + - symfony + +Located in: + - src/PrestaShopBundle/Bridge/Helper/Listing/HelperBridge/HelperListBridge.php + +## Hook call with parameters + +```php +dispatchWithParameters('action' . $helperListConfiguration->legacyControllerName . 'ListingResultsModifier', [ + 'list' => &$helperListConfiguration->list, + 'list_total' => &$helperListConfiguration->listTotal, + ]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdmin.md b/modules/concepts/hooks/list-of-hooks/actionAdmin.md new file mode 100644 index 0000000000..ce9ea38f5c --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionAdmin.md @@ -0,0 +1,31 @@ +--- +menuTitle: actionAdmin +Title: actionAdmin +hidden: true +hookTitle: +files: + - classes/controller/AdminController.php +locations: + - backoffice +types: + - legacy +--- + +# Hook : actionAdmin + +## Informations + +Hook locations: + - backoffice + +Hook types: + - legacy + +Located in: + - classes/controller/AdminController.php + +## Hook call with parameters + +```php +Hook::exec('actionAdmin' . ucfirst($this->action) . 'Before', ['controller' => $this]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionAdminAfter.md b/modules/concepts/hooks/list-of-hooks/actionAdminAfter.md similarity index 66% rename from modules/concepts/hooks/list-hooks/actionAdminAfter.md rename to modules/concepts/hooks/list-of-hooks/actionAdminAfter.md index 3148d3a572..bca9f07b95 100644 --- a/modules/concepts/hooks/list-hooks/actionAdminAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminAfter.md @@ -1,22 +1,30 @@ --- menuTitle: actionAdminAfter -title: actionAdminAfter +Title: actionAdminAfter hidden: true +hookTitle: files: - classes/controller/AdminController.php -types: +locations: - backoffice -hookTypes: +types: - legacy --- # Hook : actionAdminAfter -Located in : +## Informations + +Hook locations: + - backoffice + +Hook types: + - legacy +Located in: - classes/controller/AdminController.php -## Parameters +## Hook call with parameters ```php Hook::exec('actionAdmin' . ucfirst($this->action) . 'After', ['controller' => $this, 'return' => $return]); diff --git a/modules/concepts/hooks/list-hooks/actionAdminBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminBefore.md similarity index 65% rename from modules/concepts/hooks/list-hooks/actionAdminBefore.md rename to modules/concepts/hooks/list-of-hooks/actionAdminBefore.md index 48c3ae402a..e35f9d8266 100644 --- a/modules/concepts/hooks/list-hooks/actionAdminBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminBefore.md @@ -1,22 +1,30 @@ --- menuTitle: actionAdminBefore -title: actionAdminBefore +Title: actionAdminBefore hidden: true +hookTitle: files: - classes/controller/AdminController.php -types: +locations: - backoffice -hookTypes: +types: - legacy --- # Hook : actionAdminBefore -Located in : +## Informations + +Hook locations: + - backoffice + +Hook types: + - legacy +Located in: - classes/controller/AdminController.php -## Parameters +## Hook call with parameters ```php Hook::exec('actionAdmin' . ucfirst($this->action) . 'Before', ['controller' => $this]); diff --git a/modules/concepts/hooks/list-hooks/actionAdminAdminShopParametersMetaControllerPostProcessBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminAdminShopParametersMetaControllerPostProcessBefore.md similarity index 51% rename from modules/concepts/hooks/list-hooks/actionAdminAdminShopParametersMetaControllerPostProcessBefore.md rename to modules/concepts/hooks/list-of-hooks/actionAdminAdminShopParametersMetaControllerPostProcessBefore.md index c84d0b84ac..60bbc359c4 100644 --- a/modules/concepts/hooks/list-hooks/actionAdminAdminShopParametersMetaControllerPostProcessBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminAdminShopParametersMetaControllerPostProcessBefore.md @@ -1,22 +1,36 @@ --- menuTitle: actionAdminAdminShopParametersMetaControllerPostProcessBefore -title: actionAdminAdminShopParametersMetaControllerPostProcessBefore +Title: actionAdminAdminShopParametersMetaControllerPostProcessBefore hidden: true +hookTitle: On post-process in Admin Configure Shop Parameters Meta Controller files: - src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/MetaController.php -types: +locations: - backoffice -hookTypes: +types: - symfony --- # Hook : actionAdminAdminShopParametersMetaControllerPostProcessBefore -Located in : +## Informations + +{{% notice tip %}} +**On post-process in Admin Configure Shop Parameters Meta Controller:** + +This hook is called on Admin Configure Shop Parameters Meta post-process before processing any form +{{% /notice %}} + +Hook locations: + - backoffice + +Hook types: + - symfony +Located in: - src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/MetaController.php -## Parameters +## Hook call with parameters ```php dispatchHook('actionAdminAdminShopParametersMetaControllerPostProcessBefore', ['controller' => $this]); diff --git a/modules/concepts/hooks/list-hooks/actionAdminAdminWebserviceControllerPostProcessBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminAdminWebserviceControllerPostProcessBefore.md similarity index 71% rename from modules/concepts/hooks/list-hooks/actionAdminAdminWebserviceControllerPostProcessBefore.md rename to modules/concepts/hooks/list-of-hooks/actionAdminAdminWebserviceControllerPostProcessBefore.md index 0896967049..45b98dc7a9 100644 --- a/modules/concepts/hooks/list-hooks/actionAdminAdminWebserviceControllerPostProcessBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminAdminWebserviceControllerPostProcessBefore.md @@ -1,22 +1,30 @@ --- menuTitle: actionAdminAdminWebserviceControllerPostProcessBefore -title: actionAdminAdminWebserviceControllerPostProcessBefore +Title: actionAdminAdminWebserviceControllerPostProcessBefore hidden: true +hookTitle: files: - src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/WebserviceController.php -types: +locations: - backoffice -hookTypes: +types: - symfony --- # Hook : actionAdminAdminWebserviceControllerPostProcessBefore -Located in : +## Informations + +Hook locations: + - backoffice + +Hook types: + - symfony +Located in: - src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/WebserviceController.php -## Parameters +## Hook call with parameters ```php dispatchHook('actionAdminAdminWebserviceControllerPostProcessBefore', ['controller' => $this]); diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminAdministrationControllerPostProcessBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminAdministrationControllerPostProcessBefore.md new file mode 100644 index 0000000000..4483c5875f --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionAdminAdministrationControllerPostProcessBefore.md @@ -0,0 +1,37 @@ +--- +menuTitle: actionAdminAdministrationControllerPostProcessBefore +Title: actionAdminAdministrationControllerPostProcessBefore +hidden: true +hookTitle: On post-process in Admin Configure Advanced Parameters Administration Controller +files: + - src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/AdministrationController.php +locations: + - backoffice +types: + - symfony +--- + +# Hook : actionAdminAdministrationControllerPostProcessBefore + +## Informations + +{{% notice tip %}} +**On post-process in Admin Configure Advanced Parameters Administration Controller:** + +This hook is called on Admin Configure Advanced Parameters Administration post-process before processing any form +{{% /notice %}} + +Hook locations: + - backoffice + +Hook types: + - symfony + +Located in: + - src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/AdministrationController.php + +## Hook call with parameters + +```php +dispatchHook('actionAdminAdministrationControllerPostProcessBefore', ['controller' => $this]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionAdminAdvancedParametersPerformanceControllerPostProcessBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminAdvancedParametersPerformanceControllerPostProcessBefore.md similarity index 51% rename from modules/concepts/hooks/list-hooks/actionAdminAdvancedParametersPerformanceControllerPostProcessBefore.md rename to modules/concepts/hooks/list-of-hooks/actionAdminAdvancedParametersPerformanceControllerPostProcessBefore.md index 795e9060ea..e330d1a0d9 100644 --- a/modules/concepts/hooks/list-hooks/actionAdminAdvancedParametersPerformanceControllerPostProcessBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminAdvancedParametersPerformanceControllerPostProcessBefore.md @@ -1,22 +1,36 @@ --- menuTitle: actionAdminAdvancedParametersPerformanceControllerPostProcessBefore -title: actionAdminAdvancedParametersPerformanceControllerPostProcessBefore +Title: actionAdminAdvancedParametersPerformanceControllerPostProcessBefore hidden: true +hookTitle: On post-process in Admin Configure Advanced Parameters Performance Controller files: - src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/PerformanceController.php -types: +locations: - backoffice -hookTypes: +types: - symfony --- # Hook : actionAdminAdvancedParametersPerformanceControllerPostProcessBefore -Located in : +## Informations + +{{% notice tip %}} +**On post-process in Admin Configure Advanced Parameters Performance Controller:** + +This hook is called on Admin Configure Advanced Parameters Performance post-process before processing any form +{{% /notice %}} + +Hook locations: + - backoffice + +Hook types: + - symfony +Located in: - src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/PerformanceController.php -## Parameters +## Hook call with parameters ```php dispatchHook('actionAdminAdvancedParametersPerformanceControllerPostProcessBefore', ['controller' => $this]); diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminControllerSetMedia.md b/modules/concepts/hooks/list-of-hooks/actionAdminControllerSetMedia.md new file mode 100644 index 0000000000..57892032a1 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionAdminControllerSetMedia.md @@ -0,0 +1,38 @@ +--- +menuTitle: actionAdminControllerSetMedia +Title: actionAdminControllerSetMedia +hidden: true +hookTitle: +files: + - classes/controller/AdminController.php + - src/PrestaShopBundle/Bridge/AdminController/LegacyControllerBridge.php +locations: + - backoffice +types: + - legacy + - symfony +--- + +# Hook : actionAdminControllerSetMedia + +## Informations + +Hook locations: + - backoffice + +Hook types: + - legacy + +Located in: + - classes/controller/AdminController.php + - src/PrestaShopBundle/Bridge/AdminController/LegacyControllerBridge.php + +## Hook call with parameters + +```php +Hook::exec('actionAdminControllerSetMedia'); +``` + +```php +dispatchWithParameters('actionAdminControllerSetMedia'); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionAdminInternationalGeolocationControllerPostProcessBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminInternationalGeolocationControllerPostProcessBefore.md similarity index 51% rename from modules/concepts/hooks/list-hooks/actionAdminInternationalGeolocationControllerPostProcessBefore.md rename to modules/concepts/hooks/list-of-hooks/actionAdminInternationalGeolocationControllerPostProcessBefore.md index e43be3fc36..dc9dba396b 100644 --- a/modules/concepts/hooks/list-hooks/actionAdminInternationalGeolocationControllerPostProcessBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminInternationalGeolocationControllerPostProcessBefore.md @@ -1,22 +1,36 @@ --- menuTitle: actionAdminInternationalGeolocationControllerPostProcessBefore -title: actionAdminInternationalGeolocationControllerPostProcessBefore +Title: actionAdminInternationalGeolocationControllerPostProcessBefore hidden: true +hookTitle: On post-process in Admin Improve International Geolocation Controller files: - src/PrestaShopBundle/Controller/Admin/Improve/International/GeolocationController.php -types: +locations: - backoffice -hookTypes: +types: - symfony --- # Hook : actionAdminInternationalGeolocationControllerPostProcessBefore -Located in : +## Informations + +{{% notice tip %}} +**On post-process in Admin Improve International Geolocation Controller:** + +This hook is called on Admin Improve International Geolocation post-process before processing any form +{{% /notice %}} + +Hook locations: + - backoffice + +Hook types: + - symfony +Located in: - src/PrestaShopBundle/Controller/Admin/Improve/International/GeolocationController.php -## Parameters +## Hook call with parameters ```php dispatchHook('actionAdminInternationalGeolocationControllerPostProcessBefore', ['controller' => $this]); diff --git a/modules/concepts/hooks/list-hooks/actionAdminInternationalLocalizationControllerPostProcessBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminInternationalLocalizationControllerPostProcessBefore.md similarity index 51% rename from modules/concepts/hooks/list-hooks/actionAdminInternationalLocalizationControllerPostProcessBefore.md rename to modules/concepts/hooks/list-of-hooks/actionAdminInternationalLocalizationControllerPostProcessBefore.md index 45c8df3639..557c4eae13 100644 --- a/modules/concepts/hooks/list-hooks/actionAdminInternationalLocalizationControllerPostProcessBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminInternationalLocalizationControllerPostProcessBefore.md @@ -1,22 +1,36 @@ --- menuTitle: actionAdminInternationalLocalizationControllerPostProcessBefore -title: actionAdminInternationalLocalizationControllerPostProcessBefore +Title: actionAdminInternationalLocalizationControllerPostProcessBefore hidden: true +hookTitle: On post-process in Admin Improve International Localization Controller files: - src/PrestaShopBundle/Controller/Admin/Improve/International/LocalizationController.php -types: +locations: - backoffice -hookTypes: +types: - symfony --- # Hook : actionAdminInternationalLocalizationControllerPostProcessBefore -Located in : +## Informations + +{{% notice tip %}} +**On post-process in Admin Improve International Localization Controller:** + +This hook is called on Admin Improve International Localization post-process before processing any form +{{% /notice %}} + +Hook locations: + - backoffice + +Hook types: + - symfony +Located in: - src/PrestaShopBundle/Controller/Admin/Improve/International/LocalizationController.php -## Parameters +## Hook call with parameters ```php dispatchHook('actionAdminInternationalLocalizationControllerPostProcessBefore', ['controller' => $this]); diff --git a/modules/concepts/hooks/list-hooks/actionAdminLogsControllerPostProcessBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminLogsControllerPostProcessBefore.md similarity index 70% rename from modules/concepts/hooks/list-hooks/actionAdminLogsControllerPostProcessBefore.md rename to modules/concepts/hooks/list-of-hooks/actionAdminLogsControllerPostProcessBefore.md index d0ba008141..19f192d4f1 100644 --- a/modules/concepts/hooks/list-hooks/actionAdminLogsControllerPostProcessBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminLogsControllerPostProcessBefore.md @@ -1,22 +1,30 @@ --- menuTitle: actionAdminLogsControllerPostProcessBefore -title: actionAdminLogsControllerPostProcessBefore +Title: actionAdminLogsControllerPostProcessBefore hidden: true +hookTitle: files: - src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/LogsController.php -types: +locations: - backoffice -hookTypes: +types: - symfony --- # Hook : actionAdminLogsControllerPostProcessBefore -Located in : +## Informations + +Hook locations: + - backoffice + +Hook types: + - symfony +Located in: - src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/LogsController.php -## Parameters +## Hook call with parameters ```php dispatchHook('actionAdminLogsControllerPostProcessBefore', ['controller' => $this]); diff --git a/modules/concepts/hooks/list-hooks/actionAdminMaintenanceControllerPostProcessBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminMaintenanceControllerPostProcessBefore.md similarity index 70% rename from modules/concepts/hooks/list-hooks/actionAdminMaintenanceControllerPostProcessBefore.md rename to modules/concepts/hooks/list-of-hooks/actionAdminMaintenanceControllerPostProcessBefore.md index d785405fd6..b307903ed7 100644 --- a/modules/concepts/hooks/list-hooks/actionAdminMaintenanceControllerPostProcessBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminMaintenanceControllerPostProcessBefore.md @@ -1,22 +1,30 @@ --- menuTitle: actionAdminMaintenanceControllerPostProcessBefore -title: actionAdminMaintenanceControllerPostProcessBefore +Title: actionAdminMaintenanceControllerPostProcessBefore hidden: true +hookTitle: files: - src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/MaintenanceController.php -types: +locations: - backoffice -hookTypes: +types: - symfony --- # Hook : actionAdminMaintenanceControllerPostProcessBefore -Located in : +## Informations + +Hook locations: + - backoffice + +Hook types: + - symfony +Located in: - src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/MaintenanceController.php -## Parameters +## Hook call with parameters ```php dispatchHook('actionAdminMaintenanceControllerPostProcessBefore', ['controller' => $this]); diff --git a/modules/concepts/hooks/list-hooks/actionAdminMetaAfterWriteRobotsFile.md b/modules/concepts/hooks/list-of-hooks/actionAdminMetaAfterWriteRobotsFile.md similarity index 66% rename from modules/concepts/hooks/list-hooks/actionAdminMetaAfterWriteRobotsFile.md rename to modules/concepts/hooks/list-of-hooks/actionAdminMetaAfterWriteRobotsFile.md index 9bbfa65beb..3b80bc0d98 100644 --- a/modules/concepts/hooks/list-hooks/actionAdminMetaAfterWriteRobotsFile.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminMetaAfterWriteRobotsFile.md @@ -1,22 +1,30 @@ --- menuTitle: actionAdminMetaAfterWriteRobotsFile -title: actionAdminMetaAfterWriteRobotsFile +Title: actionAdminMetaAfterWriteRobotsFile hidden: true +hookTitle: files: - classes/Tools.php -types: +locations: - backoffice -hookTypes: +types: - legacy --- # Hook : actionAdminMetaAfterWriteRobotsFile -Located in : +## Informations + +Hook locations: + - backoffice + +Hook types: + - legacy +Located in: - classes/Tools.php -## Parameters +## Hook call with parameters ```php Hook::exec('actionAdminMetaAfterWriteRobotsFile', [ diff --git a/modules/concepts/hooks/list-hooks/actionAdminOrdersTrackingNumberUpdate.md b/modules/concepts/hooks/list-of-hooks/actionAdminOrdersTrackingNumberUpdate.md similarity index 52% rename from modules/concepts/hooks/list-hooks/actionAdminOrdersTrackingNumberUpdate.md rename to modules/concepts/hooks/list-of-hooks/actionAdminOrdersTrackingNumberUpdate.md index 3e7d6f3b68..3e4d313a6b 100644 --- a/modules/concepts/hooks/list-hooks/actionAdminOrdersTrackingNumberUpdate.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminOrdersTrackingNumberUpdate.md @@ -1,22 +1,36 @@ --- menuTitle: actionAdminOrdersTrackingNumberUpdate -title: actionAdminOrdersTrackingNumberUpdate +Title: actionAdminOrdersTrackingNumberUpdate hidden: true +hookTitle: After setting the tracking number for the order files: - src/Adapter/Order/CommandHandler/UpdateOrderShippingDetailsHandler.php -types: +locations: - backoffice -hookTypes: +types: - legacy --- # Hook : actionAdminOrdersTrackingNumberUpdate -Located in : +## Informations + +{{% notice tip %}} +**After setting the tracking number for the order:** + +This hook allows you to execute code after the unique tracking number for the order was added +{{% /notice %}} + +Hook locations: + - backoffice + +Hook types: + - legacy +Located in: - src/Adapter/Order/CommandHandler/UpdateOrderShippingDetailsHandler.php -## Parameters +## Hook call with parameters ```php Hook::exec('actionAdminOrdersTrackingNumberUpdate', [ @@ -24,4 +38,7 @@ Hook::exec('actionAdminOrdersTrackingNumberUpdate', [ 'customer' => $customer, 'carrier' => $carrier, ], null, false, true, false, $order->id_shop); + } + } finally { + $this->contextStateManager->restorePreviousContext(); ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionAdminPreferencesControllerPostProcessBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminPreferencesControllerPostProcessBefore.md similarity index 70% rename from modules/concepts/hooks/list-hooks/actionAdminPreferencesControllerPostProcessBefore.md rename to modules/concepts/hooks/list-of-hooks/actionAdminPreferencesControllerPostProcessBefore.md index cf727d859b..e856c80699 100644 --- a/modules/concepts/hooks/list-hooks/actionAdminPreferencesControllerPostProcessBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminPreferencesControllerPostProcessBefore.md @@ -1,22 +1,30 @@ --- menuTitle: actionAdminPreferencesControllerPostProcessBefore -title: actionAdminPreferencesControllerPostProcessBefore +Title: actionAdminPreferencesControllerPostProcessBefore hidden: true +hookTitle: files: - src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/PreferencesController.php -types: +locations: - backoffice -hookTypes: +types: - symfony --- # Hook : actionAdminPreferencesControllerPostProcessBefore -Located in : +## Informations + +Hook locations: + - backoffice + +Hook types: + - symfony +Located in: - src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/PreferencesController.php -## Parameters +## Hook call with parameters ```php dispatchHook('actionAdminPreferencesControllerPostProcessBefore', ['controller' => $this]); diff --git a/modules/concepts/hooks/list-hooks/actionAdminProductsListingFieldsModifier.md b/modules/concepts/hooks/list-of-hooks/actionAdminProductsListingFieldsModifier.md similarity index 77% rename from modules/concepts/hooks/list-hooks/actionAdminProductsListingFieldsModifier.md rename to modules/concepts/hooks/list-of-hooks/actionAdminProductsListingFieldsModifier.md index 456cb47e4c..b91b69ba94 100644 --- a/modules/concepts/hooks/list-hooks/actionAdminProductsListingFieldsModifier.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminProductsListingFieldsModifier.md @@ -1,22 +1,30 @@ --- menuTitle: actionAdminProductsListingFieldsModifier -title: actionAdminProductsListingFieldsModifier +Title: actionAdminProductsListingFieldsModifier hidden: true +hookTitle: files: - src/Adapter/Product/AdminProductDataProvider.php -types: +locations: - backoffice -hookTypes: +types: - legacy --- # Hook : actionAdminProductsListingFieldsModifier -Located in : +## Informations + +Hook locations: + - backoffice + +Hook types: + - legacy +Located in: - src/Adapter/Product/AdminProductDataProvider.php -## Parameters +## Hook call with parameters ```php Hook::exec('actionAdminProductsListingFieldsModifier', [ diff --git a/modules/concepts/hooks/list-hooks/actionAdminProductsListingResultsModifier.md b/modules/concepts/hooks/list-of-hooks/actionAdminProductsListingResultsModifier.md similarity index 71% rename from modules/concepts/hooks/list-hooks/actionAdminProductsListingResultsModifier.md rename to modules/concepts/hooks/list-of-hooks/actionAdminProductsListingResultsModifier.md index 73bf423016..965e519e53 100644 --- a/modules/concepts/hooks/list-hooks/actionAdminProductsListingResultsModifier.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminProductsListingResultsModifier.md @@ -1,22 +1,30 @@ --- menuTitle: actionAdminProductsListingResultsModifier -title: actionAdminProductsListingResultsModifier +Title: actionAdminProductsListingResultsModifier hidden: true +hookTitle: files: - src/Adapter/Product/AdminProductDataProvider.php -types: +locations: - backoffice -hookTypes: +types: - legacy --- # Hook : actionAdminProductsListingResultsModifier -Located in : +## Informations + +Hook locations: + - backoffice + +Hook types: + - legacy +Located in: - src/Adapter/Product/AdminProductDataProvider.php -## Parameters +## Hook call with parameters ```php Hook::exec('actionAdminProductsListingResultsModifier', [ diff --git a/modules/concepts/hooks/list-hooks/actionAdminSecurityControllerPostProcessBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminSecurityControllerPostProcessBefore.md similarity index 53% rename from modules/concepts/hooks/list-hooks/actionAdminSecurityControllerPostProcessBefore.md rename to modules/concepts/hooks/list-of-hooks/actionAdminSecurityControllerPostProcessBefore.md index bffc0fc0cc..3d066b5d4a 100644 --- a/modules/concepts/hooks/list-hooks/actionAdminSecurityControllerPostProcessBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminSecurityControllerPostProcessBefore.md @@ -1,22 +1,36 @@ --- menuTitle: actionAdminSecurityControllerPostProcessBefore -title: actionAdminSecurityControllerPostProcessBefore +Title: actionAdminSecurityControllerPostProcessBefore hidden: true +hookTitle: On post-process in Admin Security Controller files: - src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/SecurityController.php -types: +locations: - backoffice -hookTypes: +types: - symfony --- # Hook : actionAdminSecurityControllerPostProcessBefore -Located in : +## Informations + +{{% notice tip %}} +**On post-process in Admin Security Controller:** + +This hook is called on Admin Security Controller post-process before processing any form +{{% /notice %}} + +Hook locations: + - backoffice + +Hook types: + - symfony +Located in: - src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/SecurityController.php -## Parameters +## Hook call with parameters ```php dispatchHook('actionAdminSecurityControllerPostProcessBefore', ['controller' => $this]); diff --git a/modules/concepts/hooks/list-hooks/actionAdminShippingPreferencesControllerPostProcessBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminShippingPreferencesControllerPostProcessBefore.md similarity index 50% rename from modules/concepts/hooks/list-hooks/actionAdminShippingPreferencesControllerPostProcessBefore.md rename to modules/concepts/hooks/list-of-hooks/actionAdminShippingPreferencesControllerPostProcessBefore.md index e3dcc94bcc..3ee6cae526 100644 --- a/modules/concepts/hooks/list-hooks/actionAdminShippingPreferencesControllerPostProcessBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminShippingPreferencesControllerPostProcessBefore.md @@ -1,22 +1,36 @@ --- menuTitle: actionAdminShippingPreferencesControllerPostProcessBefore -title: actionAdminShippingPreferencesControllerPostProcessBefore +Title: actionAdminShippingPreferencesControllerPostProcessBefore hidden: true +hookTitle: On post-process in Admin Improve Shipping Preferences Controller files: - src/PrestaShopBundle/Controller/Admin/Improve/Shipping/PreferencesController.php -types: +locations: - backoffice -hookTypes: +types: - symfony --- # Hook : actionAdminShippingPreferencesControllerPostProcessBefore -Located in : +## Informations + +{{% notice tip %}} +**On post-process in Admin Improve Shipping Preferences Controller:** + +This hook is called on Admin Improve Shipping Preferences post-process before processing any form +{{% /notice %}} + +Hook locations: + - backoffice + +Hook types: + - symfony +Located in: - src/PrestaShopBundle/Controller/Admin/Improve/Shipping/PreferencesController.php -## Parameters +## Hook call with parameters ```php dispatchHook('actionAdminShippingPreferencesControllerPostProcessBefore', ['controller' => $this]); diff --git a/modules/concepts/hooks/list-hooks/actionAdminShopParametersOrderPreferencesControllerPostProcessBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminShopParametersOrderPreferencesControllerPostProcessBefore.md similarity index 51% rename from modules/concepts/hooks/list-hooks/actionAdminShopParametersOrderPreferencesControllerPostProcessBefore.md rename to modules/concepts/hooks/list-of-hooks/actionAdminShopParametersOrderPreferencesControllerPostProcessBefore.md index 6c468be66a..77194098c6 100644 --- a/modules/concepts/hooks/list-hooks/actionAdminShopParametersOrderPreferencesControllerPostProcessBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminShopParametersOrderPreferencesControllerPostProcessBefore.md @@ -1,22 +1,36 @@ --- menuTitle: actionAdminShopParametersOrderPreferencesControllerPostProcessBefore -title: actionAdminShopParametersOrderPreferencesControllerPostProcessBefore +Title: actionAdminShopParametersOrderPreferencesControllerPostProcessBefore hidden: true +hookTitle: On post-process in Admin Configure Shop Parameters Order Preferences Controller files: - src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/OrderPreferencesController.php -types: +locations: - backoffice -hookTypes: +types: - symfony --- # Hook : actionAdminShopParametersOrderPreferencesControllerPostProcessBefore -Located in : +## Informations + +{{% notice tip %}} +**On post-process in Admin Configure Shop Parameters Order Preferences Controller:** + +This hook is called on Admin Configure Shop Parameters Order Preferences post-process before processing any form +{{% /notice %}} + +Hook locations: + - backoffice + +Hook types: + - symfony +Located in: - src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/OrderPreferencesController.php -## Parameters +## Hook call with parameters ```php dispatchHook('actionAdminShopParametersOrderPreferencesControllerPostProcessBefore', ['controller' => $this]); diff --git a/modules/concepts/hooks/list-hooks/actionAdminShopParametersProductPreferencesControllerPostProcessBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminShopParametersProductPreferencesControllerPostProcessBefore.md similarity index 73% rename from modules/concepts/hooks/list-hooks/actionAdminShopParametersProductPreferencesControllerPostProcessBefore.md rename to modules/concepts/hooks/list-of-hooks/actionAdminShopParametersProductPreferencesControllerPostProcessBefore.md index 5b888629ad..06d1ffcc47 100644 --- a/modules/concepts/hooks/list-hooks/actionAdminShopParametersProductPreferencesControllerPostProcessBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminShopParametersProductPreferencesControllerPostProcessBefore.md @@ -1,22 +1,30 @@ --- menuTitle: actionAdminShopParametersProductPreferencesControllerPostProcessBefore -title: actionAdminShopParametersProductPreferencesControllerPostProcessBefore +Title: actionAdminShopParametersProductPreferencesControllerPostProcessBefore hidden: true +hookTitle: files: - src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/ProductPreferencesController.php -types: +locations: - backoffice -hookTypes: +types: - symfony --- # Hook : actionAdminShopParametersProductPreferencesControllerPostProcessBefore -Located in : +## Informations + +Hook locations: + - backoffice + +Hook types: + - symfony +Located in: - src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/ProductPreferencesController.php -## Parameters +## Hook call with parameters ```php dispatchHook('actionAdminShopParametersProductPreferencesControllerPostProcessBefore', ['controller' => $this]); diff --git a/modules/concepts/hooks/list-of-hooks/actionAfterCreateFormHandler.md b/modules/concepts/hooks/list-of-hooks/actionAfterCreateFormHandler.md new file mode 100644 index 0000000000..bc4877679f --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionAfterCreateFormHandler.md @@ -0,0 +1,34 @@ +--- +menuTitle: actionAfterCreateFormHandler +Title: actionAfterCreateFormHandler +hidden: true +hookTitle: +files: + - src/Core/Form/IdentifiableObject/Handler/FormHandler.php +locations: + - frontoffice +types: + - symfony +--- + +# Hook : actionAfterCreateFormHandler + +## Informations + +Hook locations: + - frontoffice + +Hook types: + - symfony + +Located in: + - src/Core/Form/IdentifiableObject/Handler/FormHandler.php + +## Hook call with parameters + +```php +dispatchWithParameters('actionAfterCreate' . Container::camelize($form->getName()) . 'FormHandler', [ + 'id' => $id, + 'form_data' => &$data, + ]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionAfterUpdateFormHandler.md b/modules/concepts/hooks/list-of-hooks/actionAfterUpdateFormHandler.md new file mode 100644 index 0000000000..31bbd1acc3 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionAfterUpdateFormHandler.md @@ -0,0 +1,34 @@ +--- +menuTitle: actionAfterUpdateFormHandler +Title: actionAfterUpdateFormHandler +hidden: true +hookTitle: +files: + - src/Core/Form/IdentifiableObject/Handler/FormHandler.php +locations: + - frontoffice +types: + - symfony +--- + +# Hook : actionAfterUpdateFormHandler + +## Informations + +Hook locations: + - frontoffice + +Hook types: + - symfony + +Located in: + - src/Core/Form/IdentifiableObject/Handler/FormHandler.php + +## Hook call with parameters + +```php +dispatchWithParameters('actionAfterUpdate' . Container::camelize($form->getName()) . 'FormHandler', [ + 'id' => $id, + 'form_data' => &$data, + ]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionAjaxDie.md b/modules/concepts/hooks/list-of-hooks/actionAjaxDie.md similarity index 63% rename from modules/concepts/hooks/list-hooks/actionAjaxDie.md rename to modules/concepts/hooks/list-of-hooks/actionAjaxDie.md index dad29cb8a1..1ba7f44f58 100644 --- a/modules/concepts/hooks/list-hooks/actionAjaxDie.md +++ b/modules/concepts/hooks/list-of-hooks/actionAjaxDie.md @@ -1,22 +1,30 @@ --- menuTitle: actionAjaxDie -title: actionAjaxDie +Title: actionAjaxDie hidden: true +hookTitle: files: - classes/controller/Controller.php -types: +locations: - frontoffice -hookTypes: +types: - legacy --- # Hook : actionAjaxDie -Located in : +## Informations + +Hook locations: + - frontoffice + +Hook types: + - legacy +Located in: - classes/controller/Controller.php -## Parameters +## Hook call with parameters ```php Hook::exec('actionAjaxDie' . $controller . $method . 'Before', ['value' => $value]); diff --git a/modules/concepts/hooks/list-hooks/actionAjaxDieBefore.md b/modules/concepts/hooks/list-of-hooks/actionAjaxDieBefore.md similarity index 65% rename from modules/concepts/hooks/list-hooks/actionAjaxDieBefore.md rename to modules/concepts/hooks/list-of-hooks/actionAjaxDieBefore.md index 0f0c2a12d7..823dfe191c 100644 --- a/modules/concepts/hooks/list-hooks/actionAjaxDieBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAjaxDieBefore.md @@ -1,22 +1,30 @@ --- menuTitle: actionAjaxDieBefore -title: actionAjaxDieBefore +Title: actionAjaxDieBefore hidden: true +hookTitle: files: - classes/controller/Controller.php -types: +locations: - frontoffice -hookTypes: +types: - legacy --- # Hook : actionAjaxDieBefore -Located in : +## Informations + +Hook locations: + - frontoffice + +Hook types: + - legacy +Located in: - classes/controller/Controller.php -## Parameters +## Hook call with parameters ```php Hook::exec('actionAjaxDieBefore', ['controller' => $controller, 'method' => $method, 'value' => $value]); diff --git a/modules/concepts/hooks/list-hooks/actionAttributeCombinationDelete.md b/modules/concepts/hooks/list-of-hooks/actionAttributeCombinationDelete.md similarity index 63% rename from modules/concepts/hooks/list-hooks/actionAttributeCombinationDelete.md rename to modules/concepts/hooks/list-of-hooks/actionAttributeCombinationDelete.md index 830d873d60..03beda0743 100644 --- a/modules/concepts/hooks/list-hooks/actionAttributeCombinationDelete.md +++ b/modules/concepts/hooks/list-of-hooks/actionAttributeCombinationDelete.md @@ -1,22 +1,30 @@ --- menuTitle: actionAttributeCombinationDelete -title: actionAttributeCombinationDelete +Title: actionAttributeCombinationDelete hidden: true +hookTitle: files: - classes/Combination.php -types: +locations: - frontoffice -hookTypes: +types: - legacy --- # Hook : actionAttributeCombinationDelete -Located in : +## Informations + +Hook locations: + - frontoffice + +Hook types: + - legacy +Located in: - classes/Combination.php -## Parameters +## Hook call with parameters ```php Hook::exec('actionAttributeCombinationDelete', ['id_product_attribute' => (int) $this->id]); diff --git a/modules/concepts/hooks/list-hooks/actionAttributeCombinationSave.md b/modules/concepts/hooks/list-of-hooks/actionAttributeCombinationSave.md similarity index 65% rename from modules/concepts/hooks/list-hooks/actionAttributeCombinationSave.md rename to modules/concepts/hooks/list-of-hooks/actionAttributeCombinationSave.md index 9cea40632c..ec7dbb1345 100644 --- a/modules/concepts/hooks/list-hooks/actionAttributeCombinationSave.md +++ b/modules/concepts/hooks/list-of-hooks/actionAttributeCombinationSave.md @@ -1,22 +1,30 @@ --- menuTitle: actionAttributeCombinationSave -title: actionAttributeCombinationSave +Title: actionAttributeCombinationSave hidden: true +hookTitle: files: - classes/Combination.php -types: +locations: - frontoffice -hookTypes: +types: - legacy --- # Hook : actionAttributeCombinationSave -Located in : +## Informations + +Hook locations: + - frontoffice + +Hook types: + - legacy +Located in: - classes/Combination.php -## Parameters +## Hook call with parameters ```php Hook::exec('actionAttributeCombinationSave', ['id_product_attribute' => (int) $this->id, 'id_attributes' => $idsAttribute]); diff --git a/modules/concepts/hooks/list-of-hooks/actionAttributeDelete.md b/modules/concepts/hooks/list-of-hooks/actionAttributeDelete.md new file mode 100644 index 0000000000..04272d02cf --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionAttributeDelete.md @@ -0,0 +1,37 @@ +--- +menuTitle: actionAttributeDelete +Title: actionAttributeDelete +hidden: true +hookTitle: Deleting an attributes features value +files: + - classes/ProductAttribute.php +locations: + - frontoffice +types: + - legacy +--- + +# Hook : actionAttributeDelete + +## Informations + +{{% notice tip %}} +**Deleting an attributes features value:** + +This hook is called while deleting an attributes features value +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook types: + - legacy + +Located in: + - classes/ProductAttribute.php + +## Hook call with parameters + +```php +Hook::exec('actionAttributeDelete', ['id_attribute' => $this->id]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionAttributeGroupDelete.md b/modules/concepts/hooks/list-of-hooks/actionAttributeGroupDelete.md new file mode 100644 index 0000000000..b13bb0e5d3 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionAttributeGroupDelete.md @@ -0,0 +1,37 @@ +--- +menuTitle: actionAttributeGroupDelete +Title: actionAttributeGroupDelete +hidden: true +hookTitle: Deleting attribute group +files: + - classes/AttributeGroup.php +locations: + - frontoffice +types: + - legacy +--- + +# Hook : actionAttributeGroupDelete + +## Informations + +{{% notice tip %}} +**Deleting attribute group:** + +This hook is called while deleting an attributes group +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook types: + - legacy + +Located in: + - classes/AttributeGroup.php + +## Hook call with parameters + +```php +Hook::exec('actionAttributeGroupDelete', ['id_attribute_group' => $this->id]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionAttributeGroupSave.md b/modules/concepts/hooks/list-of-hooks/actionAttributeGroupSave.md new file mode 100644 index 0000000000..38d693a23d --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionAttributeGroupSave.md @@ -0,0 +1,37 @@ +--- +menuTitle: actionAttributeGroupSave +Title: actionAttributeGroupSave +hidden: true +hookTitle: Saving an attribute group +files: + - classes/AttributeGroup.php +locations: + - frontoffice +types: + - legacy +--- + +# Hook : actionAttributeGroupSave + +## Informations + +{{% notice tip %}} +**Saving an attribute group:** + +This hook is called while saving an attributes group +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook types: + - legacy + +Located in: + - classes/AttributeGroup.php + +## Hook call with parameters + +```php +Hook::exec('actionAttributeGroupSave', ['id_attribute_group' => $this->id]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionAttributeSave.md b/modules/concepts/hooks/list-of-hooks/actionAttributeSave.md new file mode 100644 index 0000000000..c3c1204aef --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionAttributeSave.md @@ -0,0 +1,37 @@ +--- +menuTitle: actionAttributeSave +Title: actionAttributeSave +hidden: true +hookTitle: Saving an attributes features value +files: + - classes/ProductAttribute.php +locations: + - frontoffice +types: + - legacy +--- + +# Hook : actionAttributeSave + +## Informations + +{{% notice tip %}} +**Saving an attributes features value:** + +This hook is called while saving an attributes features value +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook types: + - legacy + +Located in: + - classes/ProductAttribute.php + +## Hook call with parameters + +```php +Hook::exec('actionAttributeSave', ['id_attribute' => $this->id]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionAuthentication.md b/modules/concepts/hooks/list-of-hooks/actionAuthentication.md new file mode 100644 index 0000000000..845335e947 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionAuthentication.md @@ -0,0 +1,37 @@ +--- +menuTitle: actionAuthentication +Title: actionAuthentication +hidden: true +hookTitle: Successful customer authentication +files: + - classes/form/CustomerLoginForm.php +locations: + - frontoffice +types: + - legacy +--- + +# Hook : actionAuthentication + +## Informations + +{{% notice tip %}} +**Successful customer authentication:** + +This hook is displayed after a customer successfully signs in +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook types: + - legacy + +Located in: + - classes/form/CustomerLoginForm.php + +## Hook call with parameters + +```php +Hook::exec('actionAuthentication', ['customer' => $this->context->customer]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionAuthenticationBefore.md b/modules/concepts/hooks/list-of-hooks/actionAuthenticationBefore.md similarity index 60% rename from modules/concepts/hooks/list-hooks/actionAuthenticationBefore.md rename to modules/concepts/hooks/list-of-hooks/actionAuthenticationBefore.md index 2e242904bf..68a82e8a97 100644 --- a/modules/concepts/hooks/list-hooks/actionAuthenticationBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAuthenticationBefore.md @@ -1,22 +1,30 @@ --- menuTitle: actionAuthenticationBefore -title: actionAuthenticationBefore +Title: actionAuthenticationBefore hidden: true +hookTitle: files: - classes/form/CustomerLoginForm.php -types: +locations: - frontoffice -hookTypes: +types: - legacy --- # Hook : actionAuthenticationBefore -Located in : +## Informations + +Hook locations: + - frontoffice + +Hook types: + - legacy +Located in: - classes/form/CustomerLoginForm.php -## Parameters +## Hook call with parameters ```php Hook::exec('actionAuthenticationBefore'); diff --git a/modules/concepts/hooks/list-hooks/actionBeforeAjaxDie.md b/modules/concepts/hooks/list-of-hooks/actionBeforeAjaxDie.md similarity index 50% rename from modules/concepts/hooks/list-hooks/actionBeforeAjaxDie.md rename to modules/concepts/hooks/list-of-hooks/actionBeforeAjaxDie.md index e3c966d4cd..8ec3745c85 100644 --- a/modules/concepts/hooks/list-hooks/actionBeforeAjaxDie.md +++ b/modules/concepts/hooks/list-of-hooks/actionBeforeAjaxDie.md @@ -1,22 +1,30 @@ --- -menuTitle: actionBeforeAjaxDie -title: actionBeforeAjaxDie +menuTitle: actionBeforeAjaxDie +Title: actionBeforeAjaxDie hidden: true +hookTitle: files: - classes/controller/Controller.php -types: +locations: - frontoffice -hookTypes: +types: - legacy --- -# Hook : actionBeforeAjaxDie +# Hook : actionBeforeAjaxDie + +## Informations -Located in : +Hook locations: + - frontoffice + +Hook types: + - legacy +Located in: - classes/controller/Controller.php -## Parameters +## Hook call with parameters ```php Hook::exec('actionBeforeAjaxDie' . $controller . $method, ['value' => $value]); diff --git a/modules/concepts/hooks/list-of-hooks/actionBeforeUpdateFormHandler.md b/modules/concepts/hooks/list-of-hooks/actionBeforeUpdateFormHandler.md new file mode 100644 index 0000000000..73976ccd58 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionBeforeUpdateFormHandler.md @@ -0,0 +1,34 @@ +--- +menuTitle: actionBeforeUpdateFormHandler +Title: actionBeforeUpdateFormHandler +hidden: true +hookTitle: +files: + - src/Core/Form/IdentifiableObject/Handler/FormHandler.php +locations: + - frontoffice +types: + - symfony +--- + +# Hook : actionBeforeUpdateFormHandler + +## Informations + +Hook locations: + - frontoffice + +Hook types: + - symfony + +Located in: + - src/Core/Form/IdentifiableObject/Handler/FormHandler.php + +## Hook call with parameters + +```php +dispatchWithParameters('actionBeforeUpdate' . Container::camelize($form->getName()) . 'FormHandler', [ + 'form_data' => &$data, + 'id' => $id, + ]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionBuildFrontEndObject.md b/modules/concepts/hooks/list-of-hooks/actionBuildFrontEndObject.md new file mode 100644 index 0000000000..6cba9dc923 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionBuildFrontEndObject.md @@ -0,0 +1,39 @@ +--- +menuTitle: actionBuildFrontEndObject +Title: actionBuildFrontEndObject +hidden: true +hookTitle: Manage elements added to the "prestashop" javascript object +files: + - classes/controller/FrontController.php +locations: + - frontoffice +types: + - legacy +--- + +# Hook : actionBuildFrontEndObject + +## Informations + +{{% notice tip %}} +**Manage elements added to the "prestashop" javascript object:** + +This hook allows you to customize the "prestashop" javascript object that is included in all front office pages +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook types: + - legacy + +Located in: + - classes/controller/FrontController.php + +## Hook call with parameters + +```php +Hook::exec('actionBuildFrontEndObject', [ + 'obj' => &$object, + ]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionCarrierProcess.md b/modules/concepts/hooks/list-of-hooks/actionCarrierProcess.md similarity index 56% rename from modules/concepts/hooks/list-hooks/actionCarrierProcess.md rename to modules/concepts/hooks/list-of-hooks/actionCarrierProcess.md index 9cb8cd425e..ba41e22b20 100644 --- a/modules/concepts/hooks/list-hooks/actionCarrierProcess.md +++ b/modules/concepts/hooks/list-of-hooks/actionCarrierProcess.md @@ -1,22 +1,36 @@ --- menuTitle: actionCarrierProcess -title: actionCarrierProcess +Title: actionCarrierProcess hidden: true +hookTitle: Carrier process files: - classes/checkout/CheckoutDeliveryStep.php -types: +locations: - frontoffice -hookTypes: +types: - legacy --- # Hook : actionCarrierProcess -Located in : +## Informations + +{{% notice tip %}} +**Carrier process:** + + +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook types: + - legacy +Located in: - classes/checkout/CheckoutDeliveryStep.php -## Parameters +## Hook call with parameters ```php Hook::exec('actionCarrierProcess', ['cart' => $this->getCheckoutSession()->getCart()]); diff --git a/modules/concepts/hooks/list-hooks/actionCarrierUpdate.md b/modules/concepts/hooks/list-of-hooks/actionCarrierUpdate.md similarity index 61% rename from modules/concepts/hooks/list-hooks/actionCarrierUpdate.md rename to modules/concepts/hooks/list-of-hooks/actionCarrierUpdate.md index 0cc596a8dd..fe51964663 100644 --- a/modules/concepts/hooks/list-hooks/actionCarrierUpdate.md +++ b/modules/concepts/hooks/list-of-hooks/actionCarrierUpdate.md @@ -1,22 +1,36 @@ --- menuTitle: actionCarrierUpdate -title: actionCarrierUpdate +Title: actionCarrierUpdate hidden: true +hookTitle: Carrier Update files: - controllers/admin/AdminCarriersController.php -types: +locations: - backoffice -hookTypes: +types: - legacy --- # Hook : actionCarrierUpdate -Located in : +## Informations + +{{% notice tip %}} +**Carrier Update:** + +This hook is called when a carrier is updated +{{% /notice %}} + +Hook locations: + - backoffice + +Hook types: + - legacy +Located in: - controllers/admin/AdminCarriersController.php -## Parameters +## Hook call with parameters ```php Hook::exec('actionCarrierUpdate', [ diff --git a/modules/concepts/hooks/list-of-hooks/actionCartSave.md b/modules/concepts/hooks/list-of-hooks/actionCartSave.md new file mode 100644 index 0000000000..06bb1038b7 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionCartSave.md @@ -0,0 +1,37 @@ +--- +menuTitle: actionCartSave +Title: actionCartSave +hidden: true +hookTitle: Cart creation and update +files: + - classes/Cart.php +locations: + - frontoffice +types: + - legacy +--- + +# Hook : actionCartSave + +## Informations + +{{% notice tip %}} +**Cart creation and update:** + +This hook is displayed when a product is added to the cart or if the cart's content is modified +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook types: + - legacy + +Located in: + - classes/Cart.php + +## Hook call with parameters + +```php +Hook::exec('actionCartSave', ['cart' => $this]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionCartSummary.md b/modules/concepts/hooks/list-of-hooks/actionCartSummary.md similarity index 58% rename from modules/concepts/hooks/list-hooks/actionCartSummary.md rename to modules/concepts/hooks/list-of-hooks/actionCartSummary.md index cba2867361..97cab9e26b 100644 --- a/modules/concepts/hooks/list-hooks/actionCartSummary.md +++ b/modules/concepts/hooks/list-of-hooks/actionCartSummary.md @@ -1,22 +1,30 @@ --- menuTitle: actionCartSummary -title: actionCartSummary +Title: actionCartSummary hidden: true +hookTitle: files: - classes/Cart.php -types: +locations: - frontoffice -hookTypes: +types: - legacy --- # Hook : actionCartSummary -Located in : +## Informations + +Hook locations: + - frontoffice + +Hook types: + - legacy +Located in: - classes/Cart.php -## Parameters +## Hook call with parameters ```php Hook::exec('actionCartSummary', $summary, null, true); diff --git a/modules/concepts/hooks/list-hooks/actionCartUpdateQuantityBefore.md b/modules/concepts/hooks/list-of-hooks/actionCartUpdateQuantityBefore.md similarity index 58% rename from modules/concepts/hooks/list-hooks/actionCartUpdateQuantityBefore.md rename to modules/concepts/hooks/list-of-hooks/actionCartUpdateQuantityBefore.md index df673bcdc3..ee0e241fd3 100644 --- a/modules/concepts/hooks/list-hooks/actionCartUpdateQuantityBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionCartUpdateQuantityBefore.md @@ -1,22 +1,30 @@ --- menuTitle: actionCartUpdateQuantityBefore -title: actionCartUpdateQuantityBefore +Title: actionCartUpdateQuantityBefore hidden: true +hookTitle: files: - classes/Cart.php -types: +locations: - frontoffice -hookTypes: +types: - legacy --- # Hook : actionCartUpdateQuantityBefore -Located in : +## Informations + +Hook locations: + - frontoffice + +Hook types: + - legacy +Located in: - classes/Cart.php -## Parameters +## Hook call with parameters ```php Hook::exec('actionCartUpdateQuantityBefore', $data); diff --git a/modules/concepts/hooks/list-of-hooks/actionCategoryAdd.md b/modules/concepts/hooks/list-of-hooks/actionCategoryAdd.md new file mode 100644 index 0000000000..c099f6a309 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionCategoryAdd.md @@ -0,0 +1,37 @@ +--- +menuTitle: actionCategoryAdd +Title: actionCategoryAdd +hidden: true +hookTitle: Category creation +files: + - classes/Category.php +locations: + - frontoffice +types: + - legacy +--- + +# Hook : actionCategoryAdd + +## Informations + +{{% notice tip %}} +**Category creation:** + +This hook is displayed when a category is created +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook types: + - legacy + +Located in: + - classes/Category.php + +## Hook call with parameters + +```php +Hook::exec('actionCategoryAdd', ['category' => $this]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionCategoryDelete.md b/modules/concepts/hooks/list-of-hooks/actionCategoryDelete.md new file mode 100644 index 0000000000..2bb9d1abe3 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionCategoryDelete.md @@ -0,0 +1,37 @@ +--- +menuTitle: actionCategoryDelete +Title: actionCategoryDelete +hidden: true +hookTitle: Category deletion +files: + - classes/Category.php +locations: + - frontoffice +types: + - legacy +--- + +# Hook : actionCategoryDelete + +## Informations + +{{% notice tip %}} +**Category deletion:** + +This hook is displayed when a category is deleted +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook types: + - legacy + +Located in: + - classes/Category.php + +## Hook call with parameters + +```php +Hook::exec('actionCategoryDelete', ['category' => $this, 'deleted_children' => $deletedChildren]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionCategoryUpdate.md b/modules/concepts/hooks/list-of-hooks/actionCategoryUpdate.md new file mode 100644 index 0000000000..23a6411bf2 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionCategoryUpdate.md @@ -0,0 +1,37 @@ +--- +menuTitle: actionCategoryUpdate +Title: actionCategoryUpdate +hidden: true +hookTitle: Category modification +files: + - controllers/admin/AdminProductsController.php +locations: + - backoffice +types: + - legacy +--- + +# Hook : actionCategoryUpdate + +## Informations + +{{% notice tip %}} +**Category modification:** + +This hook is displayed when a category is modified +{{% /notice %}} + +Hook locations: + - backoffice + +Hook types: + - legacy + +Located in: + - controllers/admin/AdminProductsController.php + +## Hook call with parameters + +```php +Hook::exec('actionCategoryUpdate', ['category' => $category]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionCheckoutRender.md b/modules/concepts/hooks/list-of-hooks/actionCheckoutRender.md new file mode 100644 index 0000000000..37abf965be --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionCheckoutRender.md @@ -0,0 +1,37 @@ +--- +menuTitle: actionCheckoutRender +Title: actionCheckoutRender +hidden: true +hookTitle: Modify checkout process +files: + - controllers/front/OrderController.php +locations: + - frontoffice +types: + - legacy +--- + +# Hook : actionCheckoutRender + +## Informations + +{{% notice tip %}} +**Modify checkout process:** + +This hook is called when constructing the checkout process +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook types: + - legacy + +Located in: + - controllers/front/OrderController.php + +## Hook call with parameters + +```php +Hook::exec('actionCheckoutRender', ['checkoutProcess' => &$this->checkoutProcess]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionClearCache.md b/modules/concepts/hooks/list-of-hooks/actionClearCache.md new file mode 100644 index 0000000000..7deb463d51 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionClearCache.md @@ -0,0 +1,37 @@ +--- +menuTitle: actionClearCache +Title: actionClearCache +hidden: true +hookTitle: Clear smarty cache +files: + - classes/Tools.php +locations: + - frontoffice +types: + - legacy +--- + +# Hook : actionClearCache + +## Informations + +{{% notice tip %}} +**Clear smarty cache:** + +This hook is called when smarty's cache is cleared +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook types: + - legacy + +Located in: + - classes/Tools.php + +## Hook call with parameters + +```php +Hook::exec('actionClearCache'); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionClearCompileCache.md b/modules/concepts/hooks/list-of-hooks/actionClearCompileCache.md new file mode 100644 index 0000000000..c81bfd2f1f --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionClearCompileCache.md @@ -0,0 +1,37 @@ +--- +menuTitle: actionClearCompileCache +Title: actionClearCompileCache +hidden: true +hookTitle: Clear smarty compile cache +files: + - classes/Tools.php +locations: + - frontoffice +types: + - legacy +--- + +# Hook : actionClearCompileCache + +## Informations + +{{% notice tip %}} +**Clear smarty compile cache:** + +This hook is called when smarty's compile cache is cleared +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook types: + - legacy + +Located in: + - classes/Tools.php + +## Hook call with parameters + +```php +Hook::exec('actionClearCompileCache'); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionClearSf2Cache.md b/modules/concepts/hooks/list-of-hooks/actionClearSf2Cache.md new file mode 100644 index 0000000000..fb7e991be7 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionClearSf2Cache.md @@ -0,0 +1,37 @@ +--- +menuTitle: actionClearSf2Cache +Title: actionClearSf2Cache +hidden: true +hookTitle: Clear Sf2 cache +files: + - src/Adapter/Cache/Clearer/SymfonyCacheClearer.php +locations: + - frontoffice +types: + - legacy +--- + +# Hook : actionClearSf2Cache + +## Informations + +{{% notice tip %}} +**Clear Sf2 cache:** + +This hook is called when the Symfony cache is cleared +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook types: + - legacy + +Located in: + - src/Adapter/Cache/Clearer/SymfonyCacheClearer.php + +## Hook call with parameters + +```php +Hook::exec('actionClearSf2Cache'); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionCustomerAccountAdd.md b/modules/concepts/hooks/list-of-hooks/actionCustomerAccountAdd.md new file mode 100644 index 0000000000..77cb3df4d6 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionCustomerAccountAdd.md @@ -0,0 +1,39 @@ +--- +menuTitle: actionCustomerAccountAdd +Title: actionCustomerAccountAdd +hidden: true +hookTitle: Successful customer account creation +files: + - classes/form/CustomerPersister.php +locations: + - frontoffice +types: + - legacy +--- + +# Hook : actionCustomerAccountAdd + +## Informations + +{{% notice tip %}} +**Successful customer account creation:** + +This hook is called when a new customer creates an account successfully +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook types: + - legacy + +Located in: + - classes/form/CustomerPersister.php + +## Hook call with parameters + +```php +Hook::exec('actionCustomerAccountAdd', [ + 'newCustomer' => $customer, + ]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionCustomerAccountUpdate.md b/modules/concepts/hooks/list-of-hooks/actionCustomerAccountUpdate.md new file mode 100644 index 0000000000..cdeb43ead1 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionCustomerAccountUpdate.md @@ -0,0 +1,39 @@ +--- +menuTitle: actionCustomerAccountUpdate +Title: actionCustomerAccountUpdate +hidden: true +hookTitle: Successful customer account update +files: + - classes/form/CustomerPersister.php +locations: + - frontoffice +types: + - legacy +--- + +# Hook : actionCustomerAccountUpdate + +## Informations + +{{% notice tip %}} +**Successful customer account update:** + +This hook is called when a customer updates its account successfully +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook types: + - legacy + +Located in: + - classes/form/CustomerPersister.php + +## Hook call with parameters + +```php +Hook::exec('actionCustomerAccountUpdate', [ + 'customer' => $customer, + ]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionCustomerAddGroups.md b/modules/concepts/hooks/list-of-hooks/actionCustomerAddGroups.md similarity index 62% rename from modules/concepts/hooks/list-hooks/actionCustomerAddGroups.md rename to modules/concepts/hooks/list-of-hooks/actionCustomerAddGroups.md index d9435fb589..3678e0336d 100644 --- a/modules/concepts/hooks/list-hooks/actionCustomerAddGroups.md +++ b/modules/concepts/hooks/list-of-hooks/actionCustomerAddGroups.md @@ -1,22 +1,30 @@ --- menuTitle: actionCustomerAddGroups -title: actionCustomerAddGroups +Title: actionCustomerAddGroups hidden: true +hookTitle: files: - classes/Customer.php -types: +locations: - frontoffice -hookTypes: +types: - legacy --- # Hook : actionCustomerAddGroups -Located in : +## Informations + +Hook locations: + - frontoffice + +Hook types: + - legacy +Located in: - classes/Customer.php -## Parameters +## Hook call with parameters ```php Hook::exec('actionCustomerAddGroups', ['id_customer' => $this->id, 'groups' => $groups]); diff --git a/modules/concepts/hooks/list-hooks/actionCustomerBeforeUpdateGroup.md b/modules/concepts/hooks/list-of-hooks/actionCustomerBeforeUpdateGroup.md similarity index 63% rename from modules/concepts/hooks/list-hooks/actionCustomerBeforeUpdateGroup.md rename to modules/concepts/hooks/list-of-hooks/actionCustomerBeforeUpdateGroup.md index 627aa76cd6..8dd140208e 100644 --- a/modules/concepts/hooks/list-hooks/actionCustomerBeforeUpdateGroup.md +++ b/modules/concepts/hooks/list-of-hooks/actionCustomerBeforeUpdateGroup.md @@ -1,22 +1,30 @@ --- menuTitle: actionCustomerBeforeUpdateGroup -title: actionCustomerBeforeUpdateGroup +Title: actionCustomerBeforeUpdateGroup hidden: true +hookTitle: files: - classes/Customer.php -types: +locations: - frontoffice -hookTypes: +types: - legacy --- # Hook : actionCustomerBeforeUpdateGroup -Located in : +## Informations + +Hook locations: + - frontoffice + +Hook types: + - legacy +Located in: - classes/Customer.php -## Parameters +## Hook call with parameters ```php Hook::exec('actionCustomerBeforeUpdateGroup', ['id_customer' => $this->id, 'groups' => $list]); diff --git a/modules/concepts/hooks/list-of-hooks/actionCustomerLogoutAfter.md b/modules/concepts/hooks/list-of-hooks/actionCustomerLogoutAfter.md new file mode 100644 index 0000000000..d0d2372d70 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionCustomerLogoutAfter.md @@ -0,0 +1,37 @@ +--- +menuTitle: actionCustomerLogoutAfter +Title: actionCustomerLogoutAfter +hidden: true +hookTitle: After customer logout +files: + - classes/Customer.php +locations: + - frontoffice +types: + - legacy +--- + +# Hook : actionCustomerLogoutAfter + +## Informations + +{{% notice tip %}} +**After customer logout:** + +This hook allows you to execute code after customer logout +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook types: + - legacy + +Located in: + - classes/Customer.php + +## Hook call with parameters + +```php +Hook::exec('actionCustomerLogoutAfter', ['customer' => $this]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionCustomerLogoutBefore.md b/modules/concepts/hooks/list-of-hooks/actionCustomerLogoutBefore.md new file mode 100644 index 0000000000..f50e03a6ea --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionCustomerLogoutBefore.md @@ -0,0 +1,37 @@ +--- +menuTitle: actionCustomerLogoutBefore +Title: actionCustomerLogoutBefore +hidden: true +hookTitle: Before customer logout +files: + - classes/Customer.php +locations: + - frontoffice +types: + - legacy +--- + +# Hook : actionCustomerLogoutBefore + +## Informations + +{{% notice tip %}} +**Before customer logout:** + +This hook allows you to execute code before customer logout +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook types: + - legacy + +Located in: + - classes/Customer.php + +## Hook call with parameters + +```php +Hook::exec('actionCustomerLogoutBefore', ['customer' => $this]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionDeleteGDPRCustomer.md b/modules/concepts/hooks/list-of-hooks/actionDeleteGDPRCustomer.md similarity index 61% rename from modules/concepts/hooks/list-hooks/actionDeleteGDPRCustomer.md rename to modules/concepts/hooks/list-of-hooks/actionDeleteGDPRCustomer.md index c3664c8d6c..dafbf606c1 100644 --- a/modules/concepts/hooks/list-hooks/actionDeleteGDPRCustomer.md +++ b/modules/concepts/hooks/list-of-hooks/actionDeleteGDPRCustomer.md @@ -1,22 +1,30 @@ --- menuTitle: actionDeleteGDPRCustomer -title: actionDeleteGDPRCustomer +Title: actionDeleteGDPRCustomer hidden: true +hookTitle: files: - modules/psgdpr/psgdpr.php -types: +locations: - frontoffice -hookTypes: +types: - legacy --- # Hook : actionDeleteGDPRCustomer -Located in : +## Informations + +Hook locations: + - frontoffice + +Hook types: + - legacy +Located in: - modules/psgdpr/psgdpr.php -## Parameters +## Hook call with parameters ```php Hook::exec('actionDeleteGDPRCustomer', $customer, $module['id_module']); diff --git a/modules/concepts/hooks/list-hooks/actionDeliveryPriceByPrice.md b/modules/concepts/hooks/list-of-hooks/actionDeliveryPriceByPrice.md similarity index 65% rename from modules/concepts/hooks/list-hooks/actionDeliveryPriceByPrice.md rename to modules/concepts/hooks/list-of-hooks/actionDeliveryPriceByPrice.md index a252868537..93702e04fb 100644 --- a/modules/concepts/hooks/list-hooks/actionDeliveryPriceByPrice.md +++ b/modules/concepts/hooks/list-of-hooks/actionDeliveryPriceByPrice.md @@ -1,22 +1,30 @@ --- menuTitle: actionDeliveryPriceByPrice -title: actionDeliveryPriceByPrice +Title: actionDeliveryPriceByPrice hidden: true +hookTitle: files: - classes/Carrier.php -types: +locations: - frontoffice -hookTypes: +types: - legacy --- # Hook : actionDeliveryPriceByPrice -Located in : +## Informations + +Hook locations: + - frontoffice + +Hook types: + - legacy +Located in: - classes/Carrier.php -## Parameters +## Hook call with parameters ```php Hook::exec('actionDeliveryPriceByPrice', ['id_carrier' => $id_carrier, 'order_total' => $order_total, 'id_zone' => $id_zone]); diff --git a/modules/concepts/hooks/list-hooks/actionDeliveryPriceByWeight.md b/modules/concepts/hooks/list-of-hooks/actionDeliveryPriceByWeight.md similarity index 65% rename from modules/concepts/hooks/list-hooks/actionDeliveryPriceByWeight.md rename to modules/concepts/hooks/list-of-hooks/actionDeliveryPriceByWeight.md index 7a0afe4a54..2020a57583 100644 --- a/modules/concepts/hooks/list-hooks/actionDeliveryPriceByWeight.md +++ b/modules/concepts/hooks/list-of-hooks/actionDeliveryPriceByWeight.md @@ -1,22 +1,30 @@ --- menuTitle: actionDeliveryPriceByWeight -title: actionDeliveryPriceByWeight +Title: actionDeliveryPriceByWeight hidden: true +hookTitle: files: - classes/Carrier.php -types: +locations: - frontoffice -hookTypes: +types: - legacy --- # Hook : actionDeliveryPriceByWeight -Located in : +## Informations + +Hook locations: + - frontoffice + +Hook types: + - legacy +Located in: - classes/Carrier.php -## Parameters +## Hook call with parameters ```php Hook::exec('actionDeliveryPriceByWeight', ['id_carrier' => $id_carrier, 'total_weight' => $total_weight, 'id_zone' => $id_zone]); diff --git a/modules/concepts/hooks/list-hooks/actionDispatcher.md b/modules/concepts/hooks/list-of-hooks/actionDispatcher.md similarity index 60% rename from modules/concepts/hooks/list-hooks/actionDispatcher.md rename to modules/concepts/hooks/list-of-hooks/actionDispatcher.md index 7d5d8ec86f..539b8f2ef0 100644 --- a/modules/concepts/hooks/list-hooks/actionDispatcher.md +++ b/modules/concepts/hooks/list-of-hooks/actionDispatcher.md @@ -1,22 +1,30 @@ --- menuTitle: actionDispatcher -title: actionDispatcher +Title: actionDispatcher hidden: true +hookTitle: files: - classes/Dispatcher.php -types: +locations: - frontoffice -hookTypes: +types: - legacy --- # Hook : actionDispatcher -Located in : +## Informations + +Hook locations: + - frontoffice + +Hook types: + - legacy +Located in: - classes/Dispatcher.php -## Parameters +## Hook call with parameters ```php Hook::exec('actionDispatcher', $params_hook_action_dispatcher); diff --git a/modules/concepts/hooks/list-of-hooks/actionDispatcherAfter.md b/modules/concepts/hooks/list-of-hooks/actionDispatcherAfter.md new file mode 100644 index 0000000000..58f932d9c5 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionDispatcherAfter.md @@ -0,0 +1,37 @@ +--- +menuTitle: actionDispatcherAfter +Title: actionDispatcherAfter +hidden: true +hookTitle: After dispatch +files: + - classes/Dispatcher.php +locations: + - frontoffice +types: + - legacy +--- + +# Hook : actionDispatcherAfter + +## Informations + +{{% notice tip %}} +**After dispatch:** + +This hook is called at the end of the dispatch method of the Dispatcher +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook types: + - legacy + +Located in: + - classes/Dispatcher.php + +## Hook call with parameters + +```php +Hook::exec('actionDispatcherAfter', $params_hook_action_dispatcher); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionDispatcherBefore.md b/modules/concepts/hooks/list-of-hooks/actionDispatcherBefore.md new file mode 100644 index 0000000000..8d11b65a5c --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionDispatcherBefore.md @@ -0,0 +1,37 @@ +--- +menuTitle: actionDispatcherBefore +Title: actionDispatcherBefore +hidden: true +hookTitle: Before dispatch +files: + - classes/Dispatcher.php +locations: + - frontoffice +types: + - legacy +--- + +# Hook : actionDispatcherBefore + +## Informations + +{{% notice tip %}} +**Before dispatch:** + +This hook is called at the beginning of the dispatch method of the Dispatcher +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook types: + - legacy + +Located in: + - classes/Dispatcher.php + +## Hook call with parameters + +```php +Hook::exec('actionDispatcherBefore', ['controller_type' => $this->front_controller]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionDownloadAttachment.md b/modules/concepts/hooks/list-of-hooks/actionDownloadAttachment.md similarity index 64% rename from modules/concepts/hooks/list-hooks/actionDownloadAttachment.md rename to modules/concepts/hooks/list-of-hooks/actionDownloadAttachment.md index abc7a838a6..7152d40ff7 100644 --- a/modules/concepts/hooks/list-hooks/actionDownloadAttachment.md +++ b/modules/concepts/hooks/list-of-hooks/actionDownloadAttachment.md @@ -1,22 +1,30 @@ --- menuTitle: actionDownloadAttachment -title: actionDownloadAttachment +Title: actionDownloadAttachment hidden: true +hookTitle: files: - controllers/front/AttachmentController.php -types: +locations: - frontoffice -hookTypes: +types: - legacy --- # Hook : actionDownloadAttachment -Located in : +## Informations + +Hook locations: + - frontoffice + +Hook types: + - legacy +Located in: - controllers/front/AttachmentController.php -## Parameters +## Hook call with parameters ```php Hook::exec('actionDownloadAttachment', ['attachment' => &$attachment]); diff --git a/modules/concepts/hooks/list-hooks/actionExportGDPRData.md b/modules/concepts/hooks/list-of-hooks/actionExportGDPRData.md similarity index 61% rename from modules/concepts/hooks/list-hooks/actionExportGDPRData.md rename to modules/concepts/hooks/list-of-hooks/actionExportGDPRData.md index db6b5b5bb1..fe2b4d14d5 100644 --- a/modules/concepts/hooks/list-hooks/actionExportGDPRData.md +++ b/modules/concepts/hooks/list-of-hooks/actionExportGDPRData.md @@ -1,22 +1,30 @@ --- menuTitle: actionExportGDPRData -title: actionExportGDPRData +Title: actionExportGDPRData hidden: true +hookTitle: files: - modules/psgdpr/psgdpr.php -types: +locations: - frontoffice -hookTypes: +types: - legacy --- # Hook : actionExportGDPRData -Located in : +## Informations + +Hook locations: + - frontoffice + +Hook types: + - legacy +Located in: - modules/psgdpr/psgdpr.php -## Parameters +## Hook call with parameters ```php Hook::exec('actionExportGDPRData', $customer, $module['id_module']); diff --git a/modules/concepts/hooks/list-of-hooks/actionFeatureDelete.md b/modules/concepts/hooks/list-of-hooks/actionFeatureDelete.md new file mode 100644 index 0000000000..c1e7147d5c --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionFeatureDelete.md @@ -0,0 +1,37 @@ +--- +menuTitle: actionFeatureDelete +Title: actionFeatureDelete +hidden: true +hookTitle: Deleting attributes' features +files: + - classes/Feature.php +locations: + - frontoffice +types: + - legacy +--- + +# Hook : actionFeatureDelete + +## Informations + +{{% notice tip %}} +**Deleting attributes' features:** + +This hook is called while deleting an attributes features +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook types: + - legacy + +Located in: + - classes/Feature.php + +## Hook call with parameters + +```php +Hook::exec('actionFeatureDelete', ['id_feature' => $this->id]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionFeatureSave.md b/modules/concepts/hooks/list-of-hooks/actionFeatureSave.md new file mode 100644 index 0000000000..2393401a5e --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionFeatureSave.md @@ -0,0 +1,37 @@ +--- +menuTitle: actionFeatureSave +Title: actionFeatureSave +hidden: true +hookTitle: Saving attributes' features +files: + - classes/Feature.php +locations: + - frontoffice +types: + - legacy +--- + +# Hook : actionFeatureSave + +## Informations + +{{% notice tip %}} +**Saving attributes' features:** + +This hook is called while saving an attributes features +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook types: + - legacy + +Located in: + - classes/Feature.php + +## Hook call with parameters + +```php +Hook::exec('actionFeatureSave', ['id_feature' => $this->id]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionFeatureValueDelete.md b/modules/concepts/hooks/list-of-hooks/actionFeatureValueDelete.md new file mode 100644 index 0000000000..5d1af182f7 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionFeatureValueDelete.md @@ -0,0 +1,37 @@ +--- +menuTitle: actionFeatureValueDelete +Title: actionFeatureValueDelete +hidden: true +hookTitle: Deleting attributes' features' values +files: + - classes/FeatureValue.php +locations: + - frontoffice +types: + - legacy +--- + +# Hook : actionFeatureValueDelete + +## Informations + +{{% notice tip %}} +**Deleting attributes' features' values:** + +This hook is called while deleting an attributes features value +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook types: + - legacy + +Located in: + - classes/FeatureValue.php + +## Hook call with parameters + +```php +Hook::exec('actionFeatureValueDelete', ['id_feature_value' => $this->id]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionFeatureValueSave.md b/modules/concepts/hooks/list-of-hooks/actionFeatureValueSave.md new file mode 100644 index 0000000000..664c4716b9 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionFeatureValueSave.md @@ -0,0 +1,37 @@ +--- +menuTitle: actionFeatureValueSave +Title: actionFeatureValueSave +hidden: true +hookTitle: Saving an attributes features value +files: + - classes/FeatureValue.php +locations: + - frontoffice +types: + - legacy +--- + +# Hook : actionFeatureValueSave + +## Informations + +{{% notice tip %}} +**Saving an attributes features value:** + +This hook is called while saving an attributes features value +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook types: + - legacy + +Located in: + - classes/FeatureValue.php + +## Hook call with parameters + +```php +Hook::exec('actionFeatureValueSave', ['id_feature_value' => $this->id]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionFrontControllerSetMedia.md b/modules/concepts/hooks/list-of-hooks/actionFrontControllerSetMedia.md similarity index 62% rename from modules/concepts/hooks/list-hooks/actionFrontControllerSetMedia.md rename to modules/concepts/hooks/list-of-hooks/actionFrontControllerSetMedia.md index 5dc05c0a19..acc4c5272f 100644 --- a/modules/concepts/hooks/list-hooks/actionFrontControllerSetMedia.md +++ b/modules/concepts/hooks/list-of-hooks/actionFrontControllerSetMedia.md @@ -1,22 +1,30 @@ --- menuTitle: actionFrontControllerSetMedia -title: actionFrontControllerSetMedia +Title: actionFrontControllerSetMedia hidden: true +hookTitle: files: - classes/controller/FrontController.php -types: +locations: - frontoffice -hookTypes: +types: - legacy --- # Hook : actionFrontControllerSetMedia -Located in : +## Informations + +Hook locations: + - frontoffice + +Hook types: + - legacy +Located in: - classes/controller/FrontController.php -## Parameters +## Hook call with parameters ```php Hook::exec('actionFrontControllerSetMedia', []); diff --git a/modules/concepts/hooks/list-hooks/actionGetIDZoneByAddressID.md b/modules/concepts/hooks/list-of-hooks/actionGetIDZoneByAddressID.md similarity index 60% rename from modules/concepts/hooks/list-hooks/actionGetIDZoneByAddressID.md rename to modules/concepts/hooks/list-of-hooks/actionGetIDZoneByAddressID.md index 9dcccaffc8..a426052d9b 100644 --- a/modules/concepts/hooks/list-hooks/actionGetIDZoneByAddressID.md +++ b/modules/concepts/hooks/list-of-hooks/actionGetIDZoneByAddressID.md @@ -1,22 +1,30 @@ --- menuTitle: actionGetIDZoneByAddressID -title: actionGetIDZoneByAddressID +Title: actionGetIDZoneByAddressID hidden: true +hookTitle: files: - classes/Address.php -types: +locations: - frontoffice -hookTypes: +types: - legacy --- # Hook : actionGetIDZoneByAddressID -Located in : +## Informations + +Hook locations: + - frontoffice + +Hook types: + - legacy +Located in: - classes/Address.php -## Parameters +## Hook call with parameters ```php Hook::exec('actionGetIDZoneByAddressID', ['id_address' => $id_address]); diff --git a/modules/concepts/hooks/list-hooks/actionGetProductPropertiesAfter.md b/modules/concepts/hooks/list-of-hooks/actionGetProductPropertiesAfter.md similarity index 67% rename from modules/concepts/hooks/list-hooks/actionGetProductPropertiesAfter.md rename to modules/concepts/hooks/list-of-hooks/actionGetProductPropertiesAfter.md index 982d52c6c2..c183600933 100644 --- a/modules/concepts/hooks/list-hooks/actionGetProductPropertiesAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionGetProductPropertiesAfter.md @@ -1,22 +1,30 @@ --- menuTitle: actionGetProductPropertiesAfter -title: actionGetProductPropertiesAfter +Title: actionGetProductPropertiesAfter hidden: true +hookTitle: files: - classes/Product.php -types: +locations: - frontoffice -hookTypes: +types: - legacy --- # Hook : actionGetProductPropertiesAfter -Located in : +## Informations + +Hook locations: + - frontoffice + +Hook types: + - legacy +Located in: - classes/Product.php -## Parameters +## Hook call with parameters ```php Hook::exec('actionGetProductPropertiesAfter', [ diff --git a/modules/concepts/hooks/list-hooks/actionGetProductPropertiesAfterUnitPrice.md b/modules/concepts/hooks/list-of-hooks/actionGetProductPropertiesAfterUnitPrice.md similarity index 54% rename from modules/concepts/hooks/list-hooks/actionGetProductPropertiesAfterUnitPrice.md rename to modules/concepts/hooks/list-of-hooks/actionGetProductPropertiesAfterUnitPrice.md index 53bd4c5215..579002c27a 100644 --- a/modules/concepts/hooks/list-hooks/actionGetProductPropertiesAfterUnitPrice.md +++ b/modules/concepts/hooks/list-of-hooks/actionGetProductPropertiesAfterUnitPrice.md @@ -1,22 +1,36 @@ --- menuTitle: actionGetProductPropertiesAfterUnitPrice -title: actionGetProductPropertiesAfterUnitPrice +Title: actionGetProductPropertiesAfterUnitPrice hidden: true +hookTitle: Product Properties files: - classes/Product.php -types: +locations: - frontoffice -hookTypes: +types: - legacy --- # Hook : actionGetProductPropertiesAfterUnitPrice -Located in : +## Informations + +{{% notice tip %}} +**Product Properties:** + +This hook is called after defining the properties of a product +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook types: + - legacy +Located in: - classes/Product.php -## Parameters +## Hook call with parameters ```php Hook::exec('actionGetProductPropertiesAfterUnitPrice', [ diff --git a/modules/concepts/hooks/list-hooks/actionGetProductPropertiesBefore.md b/modules/concepts/hooks/list-of-hooks/actionGetProductPropertiesBefore.md similarity index 67% rename from modules/concepts/hooks/list-hooks/actionGetProductPropertiesBefore.md rename to modules/concepts/hooks/list-of-hooks/actionGetProductPropertiesBefore.md index c26d7a9093..c9b6b9df69 100644 --- a/modules/concepts/hooks/list-hooks/actionGetProductPropertiesBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionGetProductPropertiesBefore.md @@ -1,22 +1,30 @@ --- menuTitle: actionGetProductPropertiesBefore -title: actionGetProductPropertiesBefore +Title: actionGetProductPropertiesBefore hidden: true +hookTitle: files: - classes/Product.php -types: +locations: - frontoffice -hookTypes: +types: - legacy --- # Hook : actionGetProductPropertiesBefore -Located in : +## Informations + +Hook locations: + - frontoffice + +Hook types: + - legacy +Located in: - classes/Product.php -## Parameters +## Hook call with parameters ```php Hook::exec('actionGetProductPropertiesBefore', [ diff --git a/modules/concepts/hooks/list-of-hooks/actionHtaccessCreate.md b/modules/concepts/hooks/list-of-hooks/actionHtaccessCreate.md new file mode 100644 index 0000000000..b07e6fb969 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionHtaccessCreate.md @@ -0,0 +1,37 @@ +--- +menuTitle: actionHtaccessCreate +Title: actionHtaccessCreate +hidden: true +hookTitle: After htaccess creation +files: + - classes/Tools.php +locations: + - frontoffice +types: + - legacy +--- + +# Hook : actionHtaccessCreate + +## Informations + +{{% notice tip %}} +**After htaccess creation:** + +This hook is displayed after the htaccess creation +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook types: + - legacy + +Located in: + - classes/Tools.php + +## Hook call with parameters + +```php +Hook::exec('actionHtaccessCreate'); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionInvoiceNumberFormatted.md b/modules/concepts/hooks/list-of-hooks/actionInvoiceNumberFormatted.md similarity index 71% rename from modules/concepts/hooks/list-hooks/actionInvoiceNumberFormatted.md rename to modules/concepts/hooks/list-of-hooks/actionInvoiceNumberFormatted.md index bdf12763f5..a1c273bf2e 100644 --- a/modules/concepts/hooks/list-hooks/actionInvoiceNumberFormatted.md +++ b/modules/concepts/hooks/list-of-hooks/actionInvoiceNumberFormatted.md @@ -1,22 +1,30 @@ --- menuTitle: actionInvoiceNumberFormatted -title: actionInvoiceNumberFormatted +Title: actionInvoiceNumberFormatted hidden: true +hookTitle: files: - classes/order/OrderInvoice.php -types: +locations: - frontoffice -hookTypes: +types: - legacy --- # Hook : actionInvoiceNumberFormatted -Located in : +## Informations + +Hook locations: + - frontoffice + +Hook types: + - legacy +Located in: - classes/order/OrderInvoice.php -## Parameters +## Hook call with parameters ```php Hook::exec('actionInvoiceNumberFormatted', [ diff --git a/modules/concepts/hooks/list-hooks/actionMailAlterMessageBeforeSend.md b/modules/concepts/hooks/list-of-hooks/actionMailAlterMessageBeforeSend.md similarity index 63% rename from modules/concepts/hooks/list-hooks/actionMailAlterMessageBeforeSend.md rename to modules/concepts/hooks/list-of-hooks/actionMailAlterMessageBeforeSend.md index 8f079d06b3..06ab8754cc 100644 --- a/modules/concepts/hooks/list-hooks/actionMailAlterMessageBeforeSend.md +++ b/modules/concepts/hooks/list-of-hooks/actionMailAlterMessageBeforeSend.md @@ -1,22 +1,30 @@ --- menuTitle: actionMailAlterMessageBeforeSend -title: actionMailAlterMessageBeforeSend +Title: actionMailAlterMessageBeforeSend hidden: true +hookTitle: files: - classes/Mail.php -types: +locations: - frontoffice -hookTypes: +types: - legacy --- # Hook : actionMailAlterMessageBeforeSend -Located in : +## Informations + +Hook locations: + - frontoffice + +Hook types: + - legacy +Located in: - classes/Mail.php -## Parameters +## Hook call with parameters ```php Hook::exec('actionMailAlterMessageBeforeSend', [ diff --git a/modules/concepts/hooks/list-hooks/actionModuleInstallAfter.md b/modules/concepts/hooks/list-of-hooks/actionModuleInstallAfter.md similarity index 50% rename from modules/concepts/hooks/list-hooks/actionModuleInstallAfter.md rename to modules/concepts/hooks/list-of-hooks/actionModuleInstallAfter.md index 9a404ef81f..cf1ddde90f 100644 --- a/modules/concepts/hooks/list-hooks/actionModuleInstallAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionModuleInstallAfter.md @@ -1,22 +1,36 @@ --- menuTitle: actionModuleInstallAfter -title: actionModuleInstallAfter +Title: actionModuleInstallAfter hidden: true +hookTitle: actionModuleInstallAfter files: - classes/module/Module.php -types: +locations: - frontoffice -hookTypes: +types: - legacy --- # Hook : actionModuleInstallAfter -Located in : +## Informations + +{{% notice tip %}} +**actionModuleInstallAfter:** + + +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook types: + - legacy +Located in: - classes/module/Module.php -## Parameters +## Hook call with parameters ```php Hook::exec('actionModuleInstallAfter', ['object' => $this]); diff --git a/modules/concepts/hooks/list-hooks/actionModuleInstallBefore.md b/modules/concepts/hooks/list-of-hooks/actionModuleInstallBefore.md similarity index 50% rename from modules/concepts/hooks/list-hooks/actionModuleInstallBefore.md rename to modules/concepts/hooks/list-of-hooks/actionModuleInstallBefore.md index 4edbe6002a..b276268e9c 100644 --- a/modules/concepts/hooks/list-hooks/actionModuleInstallBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionModuleInstallBefore.md @@ -1,22 +1,36 @@ --- menuTitle: actionModuleInstallBefore -title: actionModuleInstallBefore +Title: actionModuleInstallBefore hidden: true +hookTitle: actionModuleInstallBefore files: - classes/module/Module.php -types: +locations: - frontoffice -hookTypes: +types: - legacy --- # Hook : actionModuleInstallBefore -Located in : +## Informations + +{{% notice tip %}} +**actionModuleInstallBefore:** + + +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook types: + - legacy +Located in: - classes/module/Module.php -## Parameters +## Hook call with parameters ```php Hook::exec('actionModuleInstallBefore', ['object' => $this]); diff --git a/modules/concepts/hooks/list-hooks/actionModuleUnRegisterHookBefore.md b/modules/concepts/hooks/list-of-hooks/actionModuleUnRegisterHookBefore.md similarity index 63% rename from modules/concepts/hooks/list-hooks/actionModuleUnRegisterHookBefore.md rename to modules/concepts/hooks/list-of-hooks/actionModuleUnRegisterHookBefore.md index 0d6dd83a86..df84a1c572 100644 --- a/modules/concepts/hooks/list-hooks/actionModuleUnRegisterHookBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionModuleUnRegisterHookBefore.md @@ -1,22 +1,30 @@ --- menuTitle: actionModuleUnRegisterHookBefore -title: actionModuleUnRegisterHookBefore +Title: actionModuleUnRegisterHookBefore hidden: true +hookTitle: files: - classes/Hook.php -types: +locations: - frontoffice -hookTypes: +types: - legacy --- # Hook : actionModuleUnRegisterHookBefore -Located in : +## Informations + +Hook locations: + - frontoffice + +Hook types: + - legacy +Located in: - classes/Hook.php -## Parameters +## Hook call with parameters ```php Hook::exec('actionModuleUnRegisterHookBefore', ['object' => $module_instance, 'hook_name' => $hook_name]); diff --git a/modules/concepts/hooks/list-hooks/actionModuleUninstallAfter.md b/modules/concepts/hooks/list-of-hooks/actionModuleUninstallAfter.md similarity index 50% rename from modules/concepts/hooks/list-hooks/actionModuleUninstallAfter.md rename to modules/concepts/hooks/list-of-hooks/actionModuleUninstallAfter.md index 9a6465e88f..9888cfc241 100644 --- a/modules/concepts/hooks/list-hooks/actionModuleUninstallAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionModuleUninstallAfter.md @@ -1,22 +1,36 @@ --- menuTitle: actionModuleUninstallAfter -title: actionModuleUninstallAfter +Title: actionModuleUninstallAfter hidden: true +hookTitle: actionModuleUninstallAfter files: - classes/module/Module.php -types: +locations: - frontoffice -hookTypes: +types: - legacy --- # Hook : actionModuleUninstallAfter -Located in : +## Informations + +{{% notice tip %}} +**actionModuleUninstallAfter:** + + +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook types: + - legacy +Located in: - classes/module/Module.php -## Parameters +## Hook call with parameters ```php Hook::exec('actionModuleUninstallAfter', ['object' => $this]); diff --git a/modules/concepts/hooks/list-hooks/actionModuleUninstallBefore.md b/modules/concepts/hooks/list-of-hooks/actionModuleUninstallBefore.md similarity index 50% rename from modules/concepts/hooks/list-hooks/actionModuleUninstallBefore.md rename to modules/concepts/hooks/list-of-hooks/actionModuleUninstallBefore.md index d684244632..aa49beea24 100644 --- a/modules/concepts/hooks/list-hooks/actionModuleUninstallBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionModuleUninstallBefore.md @@ -1,22 +1,36 @@ --- menuTitle: actionModuleUninstallBefore -title: actionModuleUninstallBefore +Title: actionModuleUninstallBefore hidden: true +hookTitle: actionModuleUninstallBefore files: - classes/module/Module.php -types: +locations: - frontoffice -hookTypes: +types: - legacy --- # Hook : actionModuleUninstallBefore -Located in : +## Informations + +{{% notice tip %}} +**actionModuleUninstallBefore:** + + +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook types: + - legacy +Located in: - classes/module/Module.php -## Parameters +## Hook call with parameters ```php Hook::exec('actionModuleUninstallBefore', ['object' => $this]); diff --git a/modules/concepts/hooks/list-hooks/actionObjectAddAfter.md b/modules/concepts/hooks/list-of-hooks/actionObjectAddAfter.md similarity index 62% rename from modules/concepts/hooks/list-hooks/actionObjectAddAfter.md rename to modules/concepts/hooks/list-of-hooks/actionObjectAddAfter.md index ca68474454..adb2d70481 100644 --- a/modules/concepts/hooks/list-hooks/actionObjectAddAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionObjectAddAfter.md @@ -1,23 +1,32 @@ --- menuTitle: actionObjectAddAfter -title: actionObjectAddAfter +Title: actionObjectAddAfter hidden: true +hookTitle: files: - classes/ObjectModel.php -types: +locations: - backoffice - frontoffice -hookTypes: +types: - legacy --- # Hook : actionObjectAddAfter -Located in : +## Informations + +Hook locations: + - backoffice + - frontoffice + +Hook types: + - legacy +Located in: - classes/ObjectModel.php -## Parameters +## Hook call with parameters ```php Hook::exec('actionObject' . $this->getFullyQualifiedName() . 'AddAfter', ['object' => $this]); diff --git a/modules/concepts/hooks/list-hooks/actionObjectAddBefore.md b/modules/concepts/hooks/list-of-hooks/actionObjectAddBefore.md similarity index 62% rename from modules/concepts/hooks/list-hooks/actionObjectAddBefore.md rename to modules/concepts/hooks/list-of-hooks/actionObjectAddBefore.md index 98d74e205e..2777964319 100644 --- a/modules/concepts/hooks/list-hooks/actionObjectAddBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionObjectAddBefore.md @@ -1,23 +1,32 @@ --- menuTitle: actionObjectAddBefore -title: actionObjectAddBefore +Title: actionObjectAddBefore hidden: true +hookTitle: files: - classes/ObjectModel.php -types: +locations: - backoffice - frontoffice -hookTypes: +types: - legacy --- # Hook : actionObjectAddBefore -Located in : +## Informations + +Hook locations: + - backoffice + - frontoffice + +Hook types: + - legacy +Located in: - classes/ObjectModel.php -## Parameters +## Hook call with parameters ```php Hook::exec('actionObject' . $this->getFullyQualifiedName() . 'AddBefore', ['object' => $this]); diff --git a/modules/concepts/hooks/list-hooks/actionObjectDeleteAfter.md b/modules/concepts/hooks/list-of-hooks/actionObjectDeleteAfter.md similarity index 63% rename from modules/concepts/hooks/list-hooks/actionObjectDeleteAfter.md rename to modules/concepts/hooks/list-of-hooks/actionObjectDeleteAfter.md index 224669360a..a2a1ed839b 100644 --- a/modules/concepts/hooks/list-hooks/actionObjectDeleteAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionObjectDeleteAfter.md @@ -1,23 +1,32 @@ --- menuTitle: actionObjectDeleteAfter -title: actionObjectDeleteAfter +Title: actionObjectDeleteAfter hidden: true +hookTitle: files: - classes/ObjectModel.php -types: +locations: - backoffice - frontoffice -hookTypes: +types: - legacy --- # Hook : actionObjectDeleteAfter -Located in : +## Informations + +Hook locations: + - backoffice + - frontoffice + +Hook types: + - legacy +Located in: - classes/ObjectModel.php -## Parameters +## Hook call with parameters ```php Hook::exec('actionObject' . $this->getFullyQualifiedName() . 'DeleteAfter', ['object' => $this]); diff --git a/modules/concepts/hooks/list-hooks/actionObjectDeleteBefore.md b/modules/concepts/hooks/list-of-hooks/actionObjectDeleteBefore.md similarity index 63% rename from modules/concepts/hooks/list-hooks/actionObjectDeleteBefore.md rename to modules/concepts/hooks/list-of-hooks/actionObjectDeleteBefore.md index ce8ad44866..79f1f787e0 100644 --- a/modules/concepts/hooks/list-hooks/actionObjectDeleteBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionObjectDeleteBefore.md @@ -1,23 +1,32 @@ --- menuTitle: actionObjectDeleteBefore -title: actionObjectDeleteBefore +Title: actionObjectDeleteBefore hidden: true +hookTitle: files: - classes/ObjectModel.php -types: +locations: - backoffice - frontoffice -hookTypes: +types: - legacy --- # Hook : actionObjectDeleteBefore -Located in : +## Informations + +Hook locations: + - backoffice + - frontoffice + +Hook types: + - legacy +Located in: - classes/ObjectModel.php -## Parameters +## Hook call with parameters ```php Hook::exec('actionObject' . $this->getFullyQualifiedName() . 'DeleteBefore', ['object' => $this]); diff --git a/modules/concepts/hooks/list-hooks/actionObjectUpdateAfter.md b/modules/concepts/hooks/list-of-hooks/actionObjectUpdateAfter.md similarity index 63% rename from modules/concepts/hooks/list-hooks/actionObjectUpdateAfter.md rename to modules/concepts/hooks/list-of-hooks/actionObjectUpdateAfter.md index 9e131d1570..38c1f65a18 100644 --- a/modules/concepts/hooks/list-hooks/actionObjectUpdateAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionObjectUpdateAfter.md @@ -1,23 +1,32 @@ --- menuTitle: actionObjectUpdateAfter -title: actionObjectUpdateAfter +Title: actionObjectUpdateAfter hidden: true +hookTitle: files: - classes/ObjectModel.php -types: +locations: - backoffice - frontoffice -hookTypes: +types: - legacy --- # Hook : actionObjectUpdateAfter -Located in : +## Informations + +Hook locations: + - backoffice + - frontoffice + +Hook types: + - legacy +Located in: - classes/ObjectModel.php -## Parameters +## Hook call with parameters ```php Hook::exec('actionObject' . $this->getFullyQualifiedName() . 'UpdateAfter', ['object' => $this]); diff --git a/modules/concepts/hooks/list-hooks/actionObjectUpdateBefore.md b/modules/concepts/hooks/list-of-hooks/actionObjectUpdateBefore.md similarity index 63% rename from modules/concepts/hooks/list-hooks/actionObjectUpdateBefore.md rename to modules/concepts/hooks/list-of-hooks/actionObjectUpdateBefore.md index 5042e5f9ba..838167d436 100644 --- a/modules/concepts/hooks/list-hooks/actionObjectUpdateBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionObjectUpdateBefore.md @@ -1,23 +1,32 @@ --- menuTitle: actionObjectUpdateBefore -title: actionObjectUpdateBefore +Title: actionObjectUpdateBefore hidden: true +hookTitle: files: - classes/ObjectModel.php -types: +locations: - backoffice - frontoffice -hookTypes: +types: - legacy --- # Hook : actionObjectUpdateBefore -Located in : +## Informations + +Hook locations: + - backoffice + - frontoffice + +Hook types: + - legacy +Located in: - classes/ObjectModel.php -## Parameters +## Hook call with parameters ```php Hook::exec('actionObject' . $this->getFullyQualifiedName() . 'UpdateBefore', ['object' => $this]); diff --git a/modules/concepts/hooks/list-hooks/actionObjectAddAfter.md b/modules/concepts/hooks/list-of-hooks/actionObjectAddAfter.md similarity index 59% rename from modules/concepts/hooks/list-hooks/actionObjectAddAfter.md rename to modules/concepts/hooks/list-of-hooks/actionObjectAddAfter.md index 957c2cfc8b..c2521a32e9 100644 --- a/modules/concepts/hooks/list-hooks/actionObjectAddAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionObjectAddAfter.md @@ -1,23 +1,32 @@ --- menuTitle: actionObjectAddAfter -title: actionObjectAddAfter +Title: actionObjectAddAfter hidden: true +hookTitle: files: - classes/ObjectModel.php -types: +locations: - backoffice - frontoffice -hookTypes: +types: - legacy --- # Hook : actionObjectAddAfter -Located in : +## Informations + +Hook locations: + - backoffice + - frontoffice + +Hook types: + - legacy +Located in: - classes/ObjectModel.php -## Parameters +## Hook call with parameters ```php Hook::exec('actionObjectAddAfter', ['object' => $this]); diff --git a/modules/concepts/hooks/list-hooks/actionObjectAddBefore.md b/modules/concepts/hooks/list-of-hooks/actionObjectAddBefore.md similarity index 59% rename from modules/concepts/hooks/list-hooks/actionObjectAddBefore.md rename to modules/concepts/hooks/list-of-hooks/actionObjectAddBefore.md index 4f11373f27..a66babd485 100644 --- a/modules/concepts/hooks/list-hooks/actionObjectAddBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionObjectAddBefore.md @@ -1,23 +1,32 @@ --- menuTitle: actionObjectAddBefore -title: actionObjectAddBefore +Title: actionObjectAddBefore hidden: true +hookTitle: files: - classes/ObjectModel.php -types: +locations: - backoffice - frontoffice -hookTypes: +types: - legacy --- # Hook : actionObjectAddBefore -Located in : +## Informations + +Hook locations: + - backoffice + - frontoffice + +Hook types: + - legacy +Located in: - classes/ObjectModel.php -## Parameters +## Hook call with parameters ```php Hook::exec('actionObjectAddBefore', ['object' => $this]); diff --git a/modules/concepts/hooks/list-hooks/actionObjectAttributeAddBefore.md b/modules/concepts/hooks/list-of-hooks/actionObjectAttributeAddBefore.md similarity index 63% rename from modules/concepts/hooks/list-hooks/actionObjectAttributeAddBefore.md rename to modules/concepts/hooks/list-of-hooks/actionObjectAttributeAddBefore.md index 9985de9247..422966916d 100644 --- a/modules/concepts/hooks/list-hooks/actionObjectAttributeAddBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionObjectAttributeAddBefore.md @@ -1,23 +1,32 @@ --- menuTitle: actionObjectAttributeAddBefore -title: actionObjectAttributeAddBefore +Title: actionObjectAttributeAddBefore hidden: true +hookTitle: files: - controllers/admin/AdminAttributesGroupsController.php -types: +locations: - backoffice - frontoffice -hookTypes: +types: - legacy --- # Hook : actionObjectAttributeAddBefore -Located in : +## Informations + +Hook locations: + - backoffice + - frontoffice + +Hook types: + - legacy +Located in: - controllers/admin/AdminAttributesGroupsController.php -## Parameters +## Hook call with parameters ```php Hook::exec('actionObjectAttributeAddBefore'); diff --git a/modules/concepts/hooks/list-hooks/actionObjectAttributeGroupAddBefore.md b/modules/concepts/hooks/list-of-hooks/actionObjectAttributeGroupAddBefore.md similarity index 63% rename from modules/concepts/hooks/list-hooks/actionObjectAttributeGroupAddBefore.md rename to modules/concepts/hooks/list-of-hooks/actionObjectAttributeGroupAddBefore.md index e932b0b7ad..4498b65252 100644 --- a/modules/concepts/hooks/list-hooks/actionObjectAttributeGroupAddBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionObjectAttributeGroupAddBefore.md @@ -1,23 +1,32 @@ --- menuTitle: actionObjectAttributeGroupAddBefore -title: actionObjectAttributeGroupAddBefore +Title: actionObjectAttributeGroupAddBefore hidden: true +hookTitle: files: - controllers/admin/AdminAttributesGroupsController.php -types: +locations: - backoffice - frontoffice -hookTypes: +types: - legacy --- # Hook : actionObjectAttributeGroupAddBefore -Located in : +## Informations + +Hook locations: + - backoffice + - frontoffice + +Hook types: + - legacy +Located in: - controllers/admin/AdminAttributesGroupsController.php -## Parameters +## Hook call with parameters ```php Hook::exec('actionObjectAttributeGroupAddBefore'); diff --git a/modules/concepts/hooks/list-hooks/actionObjectDeleteAfter.md b/modules/concepts/hooks/list-of-hooks/actionObjectDeleteAfter.md similarity index 59% rename from modules/concepts/hooks/list-hooks/actionObjectDeleteAfter.md rename to modules/concepts/hooks/list-of-hooks/actionObjectDeleteAfter.md index ba49362186..004762e044 100644 --- a/modules/concepts/hooks/list-hooks/actionObjectDeleteAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionObjectDeleteAfter.md @@ -1,23 +1,32 @@ --- menuTitle: actionObjectDeleteAfter -title: actionObjectDeleteAfter +Title: actionObjectDeleteAfter hidden: true +hookTitle: files: - classes/ObjectModel.php -types: +locations: - backoffice - frontoffice -hookTypes: +types: - legacy --- # Hook : actionObjectDeleteAfter -Located in : +## Informations + +Hook locations: + - backoffice + - frontoffice + +Hook types: + - legacy +Located in: - classes/ObjectModel.php -## Parameters +## Hook call with parameters ```php Hook::exec('actionObjectDeleteAfter', ['object' => $this]); diff --git a/modules/concepts/hooks/list-hooks/actionObjectDeleteBefore.md b/modules/concepts/hooks/list-of-hooks/actionObjectDeleteBefore.md similarity index 59% rename from modules/concepts/hooks/list-hooks/actionObjectDeleteBefore.md rename to modules/concepts/hooks/list-of-hooks/actionObjectDeleteBefore.md index 2201c39583..1d5753c699 100644 --- a/modules/concepts/hooks/list-hooks/actionObjectDeleteBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionObjectDeleteBefore.md @@ -1,23 +1,32 @@ --- menuTitle: actionObjectDeleteBefore -title: actionObjectDeleteBefore +Title: actionObjectDeleteBefore hidden: true +hookTitle: files: - classes/ObjectModel.php -types: +locations: - backoffice - frontoffice -hookTypes: +types: - legacy --- # Hook : actionObjectDeleteBefore -Located in : +## Informations + +Hook locations: + - backoffice + - frontoffice + +Hook types: + - legacy +Located in: - classes/ObjectModel.php -## Parameters +## Hook call with parameters ```php Hook::exec('actionObjectDeleteBefore', ['object' => $this]); diff --git a/modules/concepts/hooks/list-hooks/actionObjectProductCommentValidateAfter.md b/modules/concepts/hooks/list-of-hooks/actionObjectProductCommentValidateAfter.md similarity index 64% rename from modules/concepts/hooks/list-hooks/actionObjectProductCommentValidateAfter.md rename to modules/concepts/hooks/list-of-hooks/actionObjectProductCommentValidateAfter.md index 79b6d0b7ce..94e9de49d8 100644 --- a/modules/concepts/hooks/list-hooks/actionObjectProductCommentValidateAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionObjectProductCommentValidateAfter.md @@ -1,23 +1,32 @@ --- menuTitle: actionObjectProductCommentValidateAfter -title: actionObjectProductCommentValidateAfter +Title: actionObjectProductCommentValidateAfter hidden: true +hookTitle: files: - modules/productcomments/ProductComment.php -types: +locations: - backoffice - frontoffice -hookTypes: +types: - legacy --- # Hook : actionObjectProductCommentValidateAfter -Located in : +## Informations + +Hook locations: + - backoffice + - frontoffice + +Hook types: + - legacy +Located in: - modules/productcomments/ProductComment.php -## Parameters +## Hook call with parameters ```php Hook::exec('actionObjectProductCommentValidateAfter', ['object' => $this]); diff --git a/modules/concepts/hooks/list-of-hooks/actionObjectProductInCartDeleteAfter.md b/modules/concepts/hooks/list-of-hooks/actionObjectProductInCartDeleteAfter.md new file mode 100644 index 0000000000..cb8a104542 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionObjectProductInCartDeleteAfter.md @@ -0,0 +1,39 @@ +--- +menuTitle: actionObjectProductInCartDeleteAfter +Title: actionObjectProductInCartDeleteAfter +hidden: true +hookTitle: Cart product removal +files: + - controllers/front/CartController.php +locations: + - backoffice + - frontoffice +types: + - legacy +--- + +# Hook : actionObjectProductInCartDeleteAfter + +## Informations + +{{% notice tip %}} +**Cart product removal:** + +This hook is called after a product is removed from a cart +{{% /notice %}} + +Hook locations: + - backoffice + - frontoffice + +Hook types: + - legacy + +Located in: + - controllers/front/CartController.php + +## Hook call with parameters + +```php +Hook::exec('actionObjectProductInCartDeleteAfter', $data); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionObjectProductInCartDeleteBefore.md b/modules/concepts/hooks/list-of-hooks/actionObjectProductInCartDeleteBefore.md new file mode 100644 index 0000000000..c88253f405 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionObjectProductInCartDeleteBefore.md @@ -0,0 +1,39 @@ +--- +menuTitle: actionObjectProductInCartDeleteBefore +Title: actionObjectProductInCartDeleteBefore +hidden: true +hookTitle: Cart product removal +files: + - controllers/front/CartController.php +locations: + - backoffice + - frontoffice +types: + - legacy +--- + +# Hook : actionObjectProductInCartDeleteBefore + +## Informations + +{{% notice tip %}} +**Cart product removal:** + +This hook is called before a product is removed from a cart +{{% /notice %}} + +Hook locations: + - backoffice + - frontoffice + +Hook types: + - legacy + +Located in: + - controllers/front/CartController.php + +## Hook call with parameters + +```php +Hook::exec('actionObjectProductInCartDeleteBefore', $data, null, true); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionObjectUpdateAfter.md b/modules/concepts/hooks/list-of-hooks/actionObjectUpdateAfter.md similarity index 59% rename from modules/concepts/hooks/list-hooks/actionObjectUpdateAfter.md rename to modules/concepts/hooks/list-of-hooks/actionObjectUpdateAfter.md index c6ae847920..cafd8abcb9 100644 --- a/modules/concepts/hooks/list-hooks/actionObjectUpdateAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionObjectUpdateAfter.md @@ -1,23 +1,32 @@ --- menuTitle: actionObjectUpdateAfter -title: actionObjectUpdateAfter +Title: actionObjectUpdateAfter hidden: true +hookTitle: files: - classes/ObjectModel.php -types: +locations: - backoffice - frontoffice -hookTypes: +types: - legacy --- # Hook : actionObjectUpdateAfter -Located in : +## Informations + +Hook locations: + - backoffice + - frontoffice + +Hook types: + - legacy +Located in: - classes/ObjectModel.php -## Parameters +## Hook call with parameters ```php Hook::exec('actionObjectUpdateAfter', ['object' => $this]); diff --git a/modules/concepts/hooks/list-hooks/actionObjectUpdateBefore.md b/modules/concepts/hooks/list-of-hooks/actionObjectUpdateBefore.md similarity index 59% rename from modules/concepts/hooks/list-hooks/actionObjectUpdateBefore.md rename to modules/concepts/hooks/list-of-hooks/actionObjectUpdateBefore.md index ccc93560d1..78b4b17a10 100644 --- a/modules/concepts/hooks/list-hooks/actionObjectUpdateBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionObjectUpdateBefore.md @@ -1,23 +1,32 @@ --- menuTitle: actionObjectUpdateBefore -title: actionObjectUpdateBefore +Title: actionObjectUpdateBefore hidden: true +hookTitle: files: - classes/ObjectModel.php -types: +locations: - backoffice - frontoffice -hookTypes: +types: - legacy --- # Hook : actionObjectUpdateBefore -Located in : +## Informations + +Hook locations: + - backoffice + - frontoffice + +Hook types: + - legacy +Located in: - classes/ObjectModel.php -## Parameters +## Hook call with parameters ```php Hook::exec('actionObjectUpdateBefore', ['object' => $this]); diff --git a/modules/concepts/hooks/list-hooks/actionOnImageCutAfter.md b/modules/concepts/hooks/list-of-hooks/actionOnImageCutAfter.md similarity index 63% rename from modules/concepts/hooks/list-hooks/actionOnImageCutAfter.md rename to modules/concepts/hooks/list-of-hooks/actionOnImageCutAfter.md index 804a65bda7..5620cf4fcc 100644 --- a/modules/concepts/hooks/list-hooks/actionOnImageCutAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionOnImageCutAfter.md @@ -1,22 +1,30 @@ --- menuTitle: actionOnImageCutAfter -title: actionOnImageCutAfter +Title: actionOnImageCutAfter hidden: true +hookTitle: files: - classes/ImageManager.php -types: +locations: - frontoffice -hookTypes: +types: - legacy --- # Hook : actionOnImageCutAfter -Located in : +## Informations + +Hook locations: + - frontoffice + +Hook types: + - legacy +Located in: - classes/ImageManager.php -## Parameters +## Hook call with parameters ```php Hook::exec('actionOnImageCutAfter', ['dst_file' => $dstFile, 'file_type' => $fileType]); diff --git a/modules/concepts/hooks/list-hooks/actionOnImageResizeAfter.md b/modules/concepts/hooks/list-of-hooks/actionOnImageResizeAfter.md similarity index 63% rename from modules/concepts/hooks/list-hooks/actionOnImageResizeAfter.md rename to modules/concepts/hooks/list-of-hooks/actionOnImageResizeAfter.md index ebaaa3c225..d64c93638b 100644 --- a/modules/concepts/hooks/list-hooks/actionOnImageResizeAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionOnImageResizeAfter.md @@ -1,22 +1,30 @@ --- menuTitle: actionOnImageResizeAfter -title: actionOnImageResizeAfter +Title: actionOnImageResizeAfter hidden: true +hookTitle: files: - classes/ImageManager.php -types: +locations: - frontoffice -hookTypes: +types: - legacy --- # Hook : actionOnImageResizeAfter -Located in : +## Informations + +Hook locations: + - frontoffice + +Hook types: + - legacy +Located in: - classes/ImageManager.php -## Parameters +## Hook call with parameters ```php Hook::exec('actionOnImageResizeAfter', ['dst_file' => $destinationFile, 'file_type' => $fileType]); diff --git a/modules/concepts/hooks/list-hooks/actionOrderEdited.md b/modules/concepts/hooks/list-of-hooks/actionOrderEdited.md similarity index 53% rename from modules/concepts/hooks/list-hooks/actionOrderEdited.md rename to modules/concepts/hooks/list-of-hooks/actionOrderEdited.md index 03cfa78bd5..1c1e56f6b5 100644 --- a/modules/concepts/hooks/list-hooks/actionOrderEdited.md +++ b/modules/concepts/hooks/list-of-hooks/actionOrderEdited.md @@ -1,22 +1,36 @@ --- menuTitle: actionOrderEdited -title: actionOrderEdited +Title: actionOrderEdited hidden: true +hookTitle: Order edited files: - src/Adapter/Order/CommandHandler/UpdateProductInOrderHandler.php -types: +locations: - frontoffice -hookTypes: +types: - legacy --- # Hook : actionOrderEdited -Located in : +## Informations + +{{% notice tip %}} +**Order edited:** + +This hook is called when an order is edited +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook types: + - legacy +Located in: - src/Adapter/Order/CommandHandler/UpdateProductInOrderHandler.php -## Parameters +## Hook call with parameters ```php Hook::exec('actionOrderEdited', ['order' => $order]); diff --git a/modules/concepts/hooks/list-hooks/actionOrderHistoryAddAfter.md b/modules/concepts/hooks/list-of-hooks/actionOrderHistoryAddAfter.md similarity index 65% rename from modules/concepts/hooks/list-hooks/actionOrderHistoryAddAfter.md rename to modules/concepts/hooks/list-of-hooks/actionOrderHistoryAddAfter.md index 91edcbcc81..dbdeb52f28 100644 --- a/modules/concepts/hooks/list-hooks/actionOrderHistoryAddAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionOrderHistoryAddAfter.md @@ -1,22 +1,30 @@ --- menuTitle: actionOrderHistoryAddAfter -title: actionOrderHistoryAddAfter +Title: actionOrderHistoryAddAfter hidden: true +hookTitle: files: - classes/order/OrderHistory.php -types: +locations: - frontoffice -hookTypes: +types: - legacy --- # Hook : actionOrderHistoryAddAfter -Located in : +## Informations + +Hook locations: + - frontoffice + +Hook types: + - legacy +Located in: - classes/order/OrderHistory.php -## Parameters +## Hook call with parameters ```php Hook::exec('actionOrderHistoryAddAfter', ['order_history' => $this], null, false, true, false, $order->id_shop); diff --git a/modules/concepts/hooks/list-of-hooks/actionOrderReturn.md b/modules/concepts/hooks/list-of-hooks/actionOrderReturn.md new file mode 100644 index 0000000000..e998d13089 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionOrderReturn.md @@ -0,0 +1,37 @@ +--- +menuTitle: actionOrderReturn +Title: actionOrderReturn +hidden: true +hookTitle: Returned product +files: + - controllers/front/OrderFollowController.php +locations: + - frontoffice +types: + - legacy +--- + +# Hook : actionOrderReturn + +## Informations + +{{% notice tip %}} +**Returned product:** + +This hook is displayed when a customer returns a product +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook types: + - legacy + +Located in: + - controllers/front/OrderFollowController.php + +## Hook call with parameters + +```php +Hook::exec('actionOrderReturn', ['orderReturn' => $orderReturn]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionOrderSlipAdd.md b/modules/concepts/hooks/list-of-hooks/actionOrderSlipAdd.md new file mode 100644 index 0000000000..9318090da5 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionOrderSlipAdd.md @@ -0,0 +1,294 @@ +--- +menuTitle: actionOrderSlipAdd +Title: actionOrderSlipAdd +hidden: true +hookTitle: Order slip creation +files: + - src/Adapter/Order/Refund/OrderSlipCreator.php +locations: + - frontoffice +types: + - legacy +--- + +# Hook : actionOrderSlipAdd + +## Informations + +{{% notice tip %}} +**Order slip creation:** + +This hook is called when a new credit slip is added regarding client order +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook types: + - legacy + +Located in: + - src/Adapter/Order/Refund/OrderSlipCreator.php + +## Hook call with parameters + +```php +Hook::exec('actionOrderSlipAdd', [ + 'order' => $order, + 'productList' => $orderRefundSummary->getProductRefunds(), + 'qtyList' => $fullQuantityList, + ], null, false, true, false, $order->id_shop); + + $customer = new Customer((int) $order->id_customer); + + // @todo: use private method to send mail + $params = [ + '{lastname}' => $customer->lastname, + '{firstname}' => $customer->firstname, + '{id_order}' => $order->id, + '{order_name}' => $order->getUniqReference(), + ]; + + $orderLanguage = $order->getAssociatedLanguage(); + + // @todo: use a dedicated Mail class (see #13945) + // @todo: remove this @and have a proper error handling + @Mail::Send( + (int) $orderLanguage->getId(), + 'credit_slip', + $this->translator->trans( + 'New credit slip regarding your order', + [], + 'Emails.Subject', + $orderLanguage->locale + ), + $params, + $customer->email, + $customer->firstname . ' ' . $customer->lastname, + null, + null, + null, + null, + _PS_MAIL_DIR_, + true, + (int) $order->id_shop + ); + + /** @var OrderDetail $orderDetail */ + foreach ($orderRefundSummary->getOrderDetails() as $orderDetail) { + if ($this->configuration->get('PS_ADVANCED_STOCK_MANAGEMENT')) { + StockAvailable::synchronize($orderDetail->product_id); + } + } + } else { + throw new InvalidCancelProductException(InvalidCancelProductException::INVALID_AMOUNT); + } + } + + /** + * This is a copy of OrderSlip::create except the OrderDetail modification has been removed + * since it's now managed in the handler, this allows to update order details even without + * generating a credit slip + * + * @todo this copy uses array data but could probably be refactored to use OrderDetailRefund objects + * + * @param Order $order + * @param array $product_list + * @param float $shipping_cost + * @param float $amount + * @param bool $amount_choosen + * @param bool $add_tax + * @param int $precision + * + * @return bool + * + * @throws PrestaShopDatabaseException + * @throws PrestaShopException + */ + private function createOrderSlip( + Order $order, + array $product_list, + float $shipping_cost = 0, + float $amount = 0, + bool $amount_choosen = false, + bool $add_tax = true, + int $precision = 6 + ) { + $currency = new Currency((int) $order->id_currency); + $orderSlip = new OrderSlip(); + $orderSlip->id_customer = (int) $order->id_customer; + $orderSlip->id_order = (int) $order->id; + $orderSlip->conversion_rate = $currency->conversion_rate; + + $orderSlip->total_shipping_tax_excl = 0; + $orderSlip->total_shipping_tax_incl = 0; + $orderSlip->partial = 0; + + if ($shipping_cost > 0) { + $orderSlip->shipping_cost = true; + $carrier = new Carrier((int) $order->id_carrier); + // @todo: define if we use invoice or delivery address, or we use configuration PS_TAX_ADDRESS_TYPE + $address = Address::initialize($order->id_address_delivery, false); + $tax_calculator = $carrier->getTaxCalculator($address); + + if ($add_tax) { + $orderSlip->total_shipping_tax_excl = $shipping_cost; + if ($tax_calculator instanceof TaxCalculator) { + $orderSlip->total_shipping_tax_incl = Tools::ps_round($tax_calculator->addTaxes($orderSlip->total_shipping_tax_excl), $precision); + } else { + $orderSlip->total_shipping_tax_incl = $orderSlip->total_shipping_tax_excl; + } + } else { + $orderSlip->total_shipping_tax_incl = $shipping_cost; + if ($tax_calculator instanceof TaxCalculator) { + $orderSlip->total_shipping_tax_excl = Tools::ps_round($tax_calculator->removeTaxes($orderSlip->total_shipping_tax_incl), $precision); + } else { + $orderSlip->total_shipping_tax_excl = $orderSlip->total_shipping_tax_incl; + } + } + } else { + $orderSlip->shipping_cost = false; + } + + $orderSlip->amount = 0; + $orderSlip->total_products_tax_excl = 0; + $orderSlip->total_products_tax_incl = 0; + $total_products = []; + foreach ($product_list as &$product) { + $order_detail = new OrderDetail((int) $product['id_order_detail']); + $price = (float) $product['unit_price']; + $quantity = (int) $product['quantity']; + + // @todo: define if we use invoice or delivery address, or we use configuration PS_TAX_ADDRESS_TYPE + $address = Address::initialize($order->id_address_invoice, false); + $id_address = (int) $address->id; + $id_tax_rules_group = (int) $order_detail->id_tax_rules_group; + $tax_calculator = $order_detail->getTaxCalculator(); + + if ($add_tax) { + $orderSlip->total_products_tax_excl += $price * $quantity; + } else { + $orderSlip->total_products_tax_incl += $price * $quantity; + } + + if (in_array($this->configuration->get('PS_ROUND_TYPE'), [Order::ROUND_ITEM, Order::ROUND_LINE])) { + if (!isset($total_products[$id_tax_rules_group])) { + $total_products[$id_tax_rules_group] = 0; + } + } else { + if (!isset($total_products[$id_tax_rules_group . '_' . $id_address])) { + $total_products[$id_tax_rules_group . '_' . $id_address] = 0; + } + } + + if ($add_tax) { + $product_tax_incl_line = Tools::ps_round($tax_calculator->addTaxes($price) * $quantity, $precision); + } else { + $product_tax_incl_line = Tools::ps_round($tax_calculator->removeTaxes($price) * $quantity, $precision); + } + switch ($this->configuration->get('PS_ROUND_TYPE')) { + case Order::ROUND_ITEM: + if ($add_tax) { + $product_tax_incl = Tools::ps_round($tax_calculator->addTaxes($price), $precision) * $quantity; + } else { + $product_tax_incl = Tools::ps_round($tax_calculator->removeTaxes($price), $precision) * $quantity; + } + $total_products[$id_tax_rules_group] += $product_tax_incl; + break; + case Order::ROUND_LINE: + $product_tax_incl = $product_tax_incl_line; + $total_products[$id_tax_rules_group] += $product_tax_incl; + break; + case Order::ROUND_TOTAL: + $product_tax_incl = $product_tax_incl_line; + $total_products[$id_tax_rules_group . '_' . $id_address] += $price * $quantity; + break; + default: + $product_tax_incl = 0; + } + + if ($add_tax) { + $product['unit_price_tax_excl'] = $price; + $product['unit_price_tax_incl'] = Tools::ps_round($tax_calculator->addTaxes($price), $precision); + $product['total_price_tax_excl'] = Tools::ps_round($price * $quantity, $precision); + $product['total_price_tax_incl'] = Tools::ps_round($product_tax_incl, $precision); + } else { + $product['unit_price_tax_incl'] = $price; + $product['unit_price_tax_excl'] = Tools::ps_round($tax_calculator->removeTaxes($price), $precision); + $product['total_price_tax_incl'] = Tools::ps_round($price * $quantity, $precision); + $product['total_price_tax_excl'] = Tools::ps_round($product_tax_incl, $precision); + } + } + + unset($product); + + foreach ($total_products as $key => $price) { + if ($this->configuration->get('PS_ROUND_TYPE') == Order::ROUND_TOTAL) { + $tmp = explode('_', $key); + $address = Address::initialize((int) $tmp[1], true); + $tax_calculator = TaxManagerFactory::getManager($address, (int) $tmp[0])->getTaxCalculator(); + + if ($add_tax) { + $orderSlip->total_products_tax_incl += Tools::ps_round($tax_calculator->addTaxes($price), $precision); + } else { + $orderSlip->total_products_tax_excl += Tools::ps_round($tax_calculator->removeTaxes($price), $precision); + } + } else { + if ($add_tax) { + $orderSlip->total_products_tax_incl += $price; + } else { + $orderSlip->total_products_tax_excl += $price; + } + } + } + + if ($add_tax) { + $orderSlip->total_products_tax_incl -= $amount && !$amount_choosen ? $amount : 0; + $orderSlip->amount = $amount_choosen ? $amount : $orderSlip->total_products_tax_excl; + } else { + $orderSlip->total_products_tax_excl -= $amount && !$amount_choosen ? $amount : 0; + $orderSlip->amount = $amount_choosen ? $amount : $orderSlip->total_products_tax_incl; + } + $orderSlip->shipping_cost_amount = $orderSlip->total_shipping_tax_incl; + + if ((float) $amount && !$amount_choosen) { + $orderSlip->order_slip_type = VoucherRefundType::PRODUCT_PRICES_EXCLUDING_VOUCHER_REFUND; + } + if (((float) $amount && $amount_choosen) || $orderSlip->shipping_cost_amount > 0) { + $orderSlip->order_slip_type = VoucherRefundType::SPECIFIC_AMOUNT_REFUND; + } + + if (!$orderSlip->add()) { + return false; + } + + $res = true; + + foreach ($product_list as $product) { + $res &= $this->addProductOrderSlip((int) $orderSlip->id, $product); + } + + return (bool) $res; + } + + /** + * @param array $product + * + * @return bool + * + * @throws PrestaShopDatabaseException + */ + private function addProductOrderSlip(int $orderSlipId, array $product): bool + { + return (bool) Db::getInstance()->insert('order_slip_detail', [ + 'id_order_slip' => $orderSlipId, + 'id_order_detail' => (int) $product['id_order_detail'], + 'product_quantity' => $product['quantity'], + 'unit_price_tax_excl' => $product['unit_price_tax_excl'], + 'unit_price_tax_incl' => $product['unit_price_tax_incl'], + 'total_price_tax_excl' => $product['total_price_tax_excl'], + 'total_price_tax_incl' => $product['total_price_tax_incl'], + 'amount_tax_excl' => $product['total_price_tax_excl'], + 'amount_tax_incl' => $product['total_price_tax_incl'], + ]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionOutputHTMLBefore.md b/modules/concepts/hooks/list-of-hooks/actionOutputHTMLBefore.md new file mode 100644 index 0000000000..372ff8bdfd --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionOutputHTMLBefore.md @@ -0,0 +1,37 @@ +--- +menuTitle: actionOutputHTMLBefore +Title: actionOutputHTMLBefore +hidden: true +hookTitle: Before HTML output +files: + - classes/controller/FrontController.php +locations: + - frontoffice +types: + - legacy +--- + +# Hook : actionOutputHTMLBefore + +## Informations + +{{% notice tip %}} +**Before HTML output:** + +This hook is used to filter the whole HTML page before it is rendered (only front) +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook types: + - legacy + +Located in: + - classes/controller/FrontController.php + +## Hook call with parameters + +```php +Hook::exec('actionOutputHTMLBefore', ['html' => &$html]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionPDFInvoiceRender.md b/modules/concepts/hooks/list-of-hooks/actionPDFInvoiceRender.md similarity index 65% rename from modules/concepts/hooks/list-hooks/actionPDFInvoiceRender.md rename to modules/concepts/hooks/list-of-hooks/actionPDFInvoiceRender.md index fa30fac4db..b61a964a4c 100644 --- a/modules/concepts/hooks/list-hooks/actionPDFInvoiceRender.md +++ b/modules/concepts/hooks/list-of-hooks/actionPDFInvoiceRender.md @@ -1,22 +1,30 @@ --- menuTitle: actionPDFInvoiceRender -title: actionPDFInvoiceRender +Title: actionPDFInvoiceRender hidden: true +hookTitle: files: - src/Adapter/PDF/OrderInvoicePdfGenerator.php -types: +locations: - frontoffice -hookTypes: +types: - legacy --- # Hook : actionPDFInvoiceRender -Located in : +## Informations + +Hook locations: + - frontoffice + +Hook types: + - legacy +Located in: - src/Adapter/PDF/OrderInvoicePdfGenerator.php -## Parameters +## Hook call with parameters ```php Hook::exec('actionPDFInvoiceRender', ['order_invoice_list' => $order_invoice_list]); diff --git a/modules/concepts/hooks/list-hooks/actionPasswordRenew.md b/modules/concepts/hooks/list-of-hooks/actionPasswordRenew.md similarity index 65% rename from modules/concepts/hooks/list-hooks/actionPasswordRenew.md rename to modules/concepts/hooks/list-of-hooks/actionPasswordRenew.md index 33609ec37f..8e6d363f25 100644 --- a/modules/concepts/hooks/list-hooks/actionPasswordRenew.md +++ b/modules/concepts/hooks/list-of-hooks/actionPasswordRenew.md @@ -1,22 +1,30 @@ --- menuTitle: actionPasswordRenew -title: actionPasswordRenew +Title: actionPasswordRenew hidden: true +hookTitle: files: - controllers/front/PasswordController.php -types: +locations: - frontoffice -hookTypes: +types: - legacy --- # Hook : actionPasswordRenew -Located in : +## Informations + +Hook locations: + - frontoffice + +Hook types: + - legacy +Located in: - controllers/front/PasswordController.php -## Parameters +## Hook call with parameters ```php Hook::exec('actionPasswordRenew', ['customer' => $customer, 'password' => $password]); diff --git a/modules/concepts/hooks/list-hooks/actionPaymentCCAdd.md b/modules/concepts/hooks/list-of-hooks/actionPaymentCCAdd.md similarity index 51% rename from modules/concepts/hooks/list-hooks/actionPaymentCCAdd.md rename to modules/concepts/hooks/list-of-hooks/actionPaymentCCAdd.md index 7f784ac466..75f455b860 100644 --- a/modules/concepts/hooks/list-hooks/actionPaymentCCAdd.md +++ b/modules/concepts/hooks/list-of-hooks/actionPaymentCCAdd.md @@ -1,22 +1,36 @@ --- menuTitle: actionPaymentCCAdd -title: actionPaymentCCAdd +Title: actionPaymentCCAdd hidden: true +hookTitle: Payment CC added files: - classes/order/OrderPayment.php -types: +locations: - frontoffice -hookTypes: +types: - legacy --- # Hook : actionPaymentCCAdd -Located in : +## Informations + +{{% notice tip %}} +**Payment CC added:** + + +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook types: + - legacy +Located in: - classes/order/OrderPayment.php -## Parameters +## Hook call with parameters ```php Hook::exec('actionPaymentCCAdd', ['paymentCC' => $this]); diff --git a/modules/concepts/hooks/list-hooks/actionPaymentConfirmation.md b/modules/concepts/hooks/list-of-hooks/actionPaymentConfirmation.md similarity index 51% rename from modules/concepts/hooks/list-hooks/actionPaymentConfirmation.md rename to modules/concepts/hooks/list-of-hooks/actionPaymentConfirmation.md index 2f4da97d69..a925d25f50 100644 --- a/modules/concepts/hooks/list-hooks/actionPaymentConfirmation.md +++ b/modules/concepts/hooks/list-of-hooks/actionPaymentConfirmation.md @@ -1,22 +1,36 @@ --- menuTitle: actionPaymentConfirmation -title: actionPaymentConfirmation +Title: actionPaymentConfirmation hidden: true +hookTitle: Payment confirmation files: - classes/order/OrderHistory.php -types: +locations: - frontoffice -hookTypes: +types: - legacy --- # Hook : actionPaymentConfirmation -Located in : +## Informations + +{{% notice tip %}} +**Payment confirmation:** + +This hook displays new elements after the payment is validated +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook types: + - legacy +Located in: - classes/order/OrderHistory.php -## Parameters +## Hook call with parameters ```php Hook::exec('actionPaymentConfirmation', ['id_order' => (int) $order->id], null, false, true, false, $order->id_shop); diff --git a/modules/concepts/hooks/list-of-hooks/actionProductActivation.md b/modules/concepts/hooks/list-of-hooks/actionProductActivation.md new file mode 100644 index 0000000000..16d3ef1e7f --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionProductActivation.md @@ -0,0 +1,31 @@ +--- +menuTitle: actionProductActivation +Title: actionProductActivation +hidden: true +hookTitle: +files: + - src/Adapter/Product/AdminProductDataUpdater.php +locations: + - backoffice +types: + - symfony +--- + +# Hook : actionProductActivation + +## Informations + +Hook locations: + - backoffice + +Hook types: + - symfony + +Located in: + - src/Adapter/Product/AdminProductDataUpdater.php + +## Hook call with parameters + +```php +dispatchWithParameters('actionProductActivation', ['id_product' => (int) $product->id, 'product' => $product, 'activated' => $activate]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionProductAdd.md b/modules/concepts/hooks/list-of-hooks/actionProductAdd.md new file mode 100644 index 0000000000..9408f8e5f6 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionProductAdd.md @@ -0,0 +1,37 @@ +--- +menuTitle: actionProductAdd +Title: actionProductAdd +hidden: true +hookTitle: Product creation +files: + - src/Adapter/Product/AdminProductDataUpdater.php +locations: + - backoffice +types: + - symfony +--- + +# Hook : actionProductAdd + +## Informations + +{{% notice tip %}} +**Product creation:** + +This hook is displayed after a product is created +{{% /notice %}} + +Hook locations: + - backoffice + +Hook types: + - symfony + +Located in: + - src/Adapter/Product/AdminProductDataUpdater.php + +## Hook call with parameters + +```php +dispatchWithParameters('actionProductAdd', ['id_product_old' => $id_product_old, 'id_product' => (int) $product->id, 'product' => $product]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionProductAttributeDelete.md b/modules/concepts/hooks/list-of-hooks/actionProductAttributeDelete.md similarity index 50% rename from modules/concepts/hooks/list-hooks/actionProductAttributeDelete.md rename to modules/concepts/hooks/list-of-hooks/actionProductAttributeDelete.md index 641c9a7157..8163bd06e5 100644 --- a/modules/concepts/hooks/list-hooks/actionProductAttributeDelete.md +++ b/modules/concepts/hooks/list-of-hooks/actionProductAttributeDelete.md @@ -1,22 +1,36 @@ --- menuTitle: actionProductAttributeDelete -title: actionProductAttributeDelete +Title: actionProductAttributeDelete hidden: true +hookTitle: Product attribute deletion files: - classes/Product.php -types: +locations: - frontoffice -hookTypes: +types: - legacy --- # Hook : actionProductAttributeDelete -Located in : +## Informations + +{{% notice tip %}} +**Product attribute deletion:** + +This hook is displayed when a product's attribute is deleted +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook types: + - legacy +Located in: - classes/Product.php -## Parameters +## Hook call with parameters ```php Hook::exec('actionProductAttributeDelete', ['id_product_attribute' => 0, 'id_product' => (int) $this->id, 'deleteAllAttributes' => true]); diff --git a/modules/concepts/hooks/list-of-hooks/actionProductAttributeUpdate.md b/modules/concepts/hooks/list-of-hooks/actionProductAttributeUpdate.md new file mode 100644 index 0000000000..382a98c21b --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionProductAttributeUpdate.md @@ -0,0 +1,37 @@ +--- +menuTitle: actionProductAttributeUpdate +Title: actionProductAttributeUpdate +hidden: true +hookTitle: Product attribute update +files: + - classes/Product.php +locations: + - frontoffice +types: + - legacy +--- + +# Hook : actionProductAttributeUpdate + +## Informations + +{{% notice tip %}} +**Product attribute update:** + +This hook is displayed when a product's attribute is updated +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook types: + - legacy + +Located in: + - classes/Product.php + +## Hook call with parameters + +```php +Hook::exec('actionProductAttributeUpdate', ['id_product_attribute' => (int) $id_product_attribute]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionProductCancel.md b/modules/concepts/hooks/list-of-hooks/actionProductCancel.md similarity index 63% rename from modules/concepts/hooks/list-hooks/actionProductCancel.md rename to modules/concepts/hooks/list-of-hooks/actionProductCancel.md index f2fb50f308..86066ca4a4 100644 --- a/modules/concepts/hooks/list-hooks/actionProductCancel.md +++ b/modules/concepts/hooks/list-of-hooks/actionProductCancel.md @@ -1,22 +1,36 @@ --- menuTitle: actionProductCancel -title: actionProductCancel +Title: actionProductCancel hidden: true +hookTitle: Product cancelled files: - src/Adapter/Order/CommandHandler/IssueStandardRefundHandler.php -types: +locations: - frontoffice -hookTypes: +types: - legacy --- # Hook : actionProductCancel -Located in : +## Informations + +{{% notice tip %}} +**Product cancelled:** + +This hook is called when you cancel a product in an order +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook types: + - legacy +Located in: - src/Adapter/Order/CommandHandler/IssueStandardRefundHandler.php -## Parameters +## Hook call with parameters ```php Hook::exec('actionProductCancel', ['order' => $order, 'id_order_detail' => (int) $orderDetailId, 'cancel_quantity' => $productRefund['quantity'], 'action' => CancellationActionType::STANDARD_REFUND], null, false, true, false, $order->id_shop); diff --git a/modules/concepts/hooks/list-of-hooks/actionProductDelete.md b/modules/concepts/hooks/list-of-hooks/actionProductDelete.md new file mode 100644 index 0000000000..4976237fbf --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionProductDelete.md @@ -0,0 +1,37 @@ +--- +menuTitle: actionProductDelete +Title: actionProductDelete +hidden: true +hookTitle: Product deletion +files: + - classes/Product.php +locations: + - frontoffice +types: + - legacy +--- + +# Hook : actionProductDelete + +## Informations + +{{% notice tip %}} +**Product deletion:** + +This hook is called when a product is deleted +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook types: + - legacy + +Located in: + - classes/Product.php + +## Hook call with parameters + +```php +Hook::exec('actionProductDelete', ['id_product' => (int) $this->id, 'product' => $this]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionProductOutOfStock.md b/modules/concepts/hooks/list-of-hooks/actionProductOutOfStock.md similarity index 50% rename from modules/concepts/hooks/list-hooks/actionProductOutOfStock.md rename to modules/concepts/hooks/list-of-hooks/actionProductOutOfStock.md index 328ae58457..44ad46e0af 100644 --- a/modules/concepts/hooks/list-hooks/actionProductOutOfStock.md +++ b/modules/concepts/hooks/list-of-hooks/actionProductOutOfStock.md @@ -1,22 +1,36 @@ --- menuTitle: actionProductOutOfStock -title: actionProductOutOfStock +Title: actionProductOutOfStock hidden: true +hookTitle: Out-of-stock product files: - themes/classic/templates/catalog/_partials/product-details.tpl -types: +locations: - frontoffice -hookTypes: +types: - smarty --- # Hook : actionProductOutOfStock -Located in : +## Informations + +{{% notice tip %}} +**Out-of-stock product:** + +This hook displays new action buttons if a product is out of stock +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook types: + - smarty +Located in: - themes/classic/templates/catalog/_partials/product-details.tpl -## Parameters +## Hook call with parameters ```php {hook h='actionProductOutOfStock' product=$product} diff --git a/modules/concepts/hooks/list-of-hooks/actionProductSave.md b/modules/concepts/hooks/list-of-hooks/actionProductSave.md new file mode 100644 index 0000000000..6e8d784f1c --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionProductSave.md @@ -0,0 +1,37 @@ +--- +menuTitle: actionProductSave +Title: actionProductSave +hidden: true +hookTitle: Saving products +files: + - classes/Product.php +locations: + - frontoffice +types: + - legacy +--- + +# Hook : actionProductSave + +## Informations + +{{% notice tip %}} +**Saving products:** + +This hook is called while saving products +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook types: + - legacy + +Located in: + - classes/Product.php + +## Hook call with parameters + +```php +Hook::exec('actionProductSave', ['id_product' => (int) $this->id, 'product' => $this]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionProductSearchAfter.md b/modules/concepts/hooks/list-of-hooks/actionProductSearchAfter.md new file mode 100644 index 0000000000..06e7f1602c --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionProductSearchAfter.md @@ -0,0 +1,37 @@ +--- +menuTitle: actionProductSearchAfter +Title: actionProductSearchAfter +hidden: true +hookTitle: Event triggered after search product completed +files: + - modules/blockwishlist/controllers/front/view.php +locations: + - frontoffice +types: + - legacy +--- + +# Hook : actionProductSearchAfter + +## Informations + +{{% notice tip %}} +**Event triggered after search product completed:** + +This hook is called after the product search. Parameters are already filter +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook types: + - legacy + +Located in: + - modules/blockwishlist/controllers/front/view.php + +## Hook call with parameters + +```php +Hook::exec('actionProductSearchAfter', $searchVariables); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionProductSearchProviderRunQueryAfter.md b/modules/concepts/hooks/list-of-hooks/actionProductSearchProviderRunQueryAfter.md new file mode 100644 index 0000000000..bd7cffbfb8 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionProductSearchProviderRunQueryAfter.md @@ -0,0 +1,40 @@ +--- +menuTitle: actionProductSearchProviderRunQueryAfter +Title: actionProductSearchProviderRunQueryAfter +hidden: true +hookTitle: Runs an action after ProductSearchProviderInterface::RunQuery() +files: + - classes/controller/ProductListingFrontController.php +locations: + - frontoffice +types: + - legacy +--- + +# Hook : actionProductSearchProviderRunQueryAfter + +## Informations + +{{% notice tip %}} +**Runs an action after ProductSearchProviderInterface::RunQuery():** + +Required to return a previous state of an SQL query or/and to change a result of the SQL query after executing it +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook types: + - legacy + +Located in: + - classes/controller/ProductListingFrontController.php + +## Hook call with parameters + +```php +Hook::exec('actionProductSearchProviderRunQueryAfter', [ + 'query' => $query, + 'result' => $result, + ]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionProductSearchProviderRunQueryBefore.md b/modules/concepts/hooks/list-of-hooks/actionProductSearchProviderRunQueryBefore.md new file mode 100644 index 0000000000..b89e99e873 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionProductSearchProviderRunQueryBefore.md @@ -0,0 +1,39 @@ +--- +menuTitle: actionProductSearchProviderRunQueryBefore +Title: actionProductSearchProviderRunQueryBefore +hidden: true +hookTitle: Runs an action before ProductSearchProviderInterface::RunQuery() +files: + - classes/controller/ProductListingFrontController.php +locations: + - frontoffice +types: + - legacy +--- + +# Hook : actionProductSearchProviderRunQueryBefore + +## Informations + +{{% notice tip %}} +**Runs an action before ProductSearchProviderInterface::RunQuery():** + +Required to modify an SQL query before executing it +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook types: + - legacy + +Located in: + - classes/controller/ProductListingFrontController.php + +## Hook call with parameters + +```php +Hook::exec('actionProductSearchProviderRunQueryBefore', [ + 'query' => $query, + ]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionProductUpdate.md b/modules/concepts/hooks/list-of-hooks/actionProductUpdate.md similarity index 52% rename from modules/concepts/hooks/list-hooks/actionProductUpdate.md rename to modules/concepts/hooks/list-of-hooks/actionProductUpdate.md index 67534af0d4..a686786067 100644 --- a/modules/concepts/hooks/list-hooks/actionProductUpdate.md +++ b/modules/concepts/hooks/list-of-hooks/actionProductUpdate.md @@ -1,22 +1,36 @@ --- menuTitle: actionProductUpdate -title: actionProductUpdate +Title: actionProductUpdate hidden: true +hookTitle: Product update files: - src/Adapter/Product/AdminProductWrapper.php -types: +locations: - backoffice -hookTypes: +types: - legacy --- # Hook : actionProductUpdate -Located in : +## Informations + +{{% notice tip %}} +**Product update:** + +This hook is displayed after a product has been updated +{{% /notice %}} + +Hook locations: + - backoffice + +Hook types: + - legacy +Located in: - src/Adapter/Product/AdminProductWrapper.php -## Parameters +## Hook call with parameters ```php Hook::exec('actionProductUpdate', ['id_product' => (int) $product->id, 'product' => $product]); diff --git a/modules/concepts/hooks/list-hooks/actionSearch.md b/modules/concepts/hooks/list-of-hooks/actionSearch.md similarity index 73% rename from modules/concepts/hooks/list-hooks/actionSearch.md rename to modules/concepts/hooks/list-of-hooks/actionSearch.md index a091b74110..14eee00d2e 100644 --- a/modules/concepts/hooks/list-hooks/actionSearch.md +++ b/modules/concepts/hooks/list-of-hooks/actionSearch.md @@ -1,22 +1,30 @@ --- menuTitle: actionSearch -title: actionSearch +Title: actionSearch hidden: true +hookTitle: files: - src/Adapter/Search/SearchProductSearchProvider.php -types: +locations: - frontoffice -hookTypes: +types: - legacy --- # Hook : actionSearch -Located in : +## Informations + +Hook locations: + - frontoffice + +Hook types: + - legacy +Located in: - src/Adapter/Search/SearchProductSearchProvider.php -## Parameters +## Hook call with parameters ```php Hook::exec('actionSearch', [ diff --git a/modules/concepts/hooks/list-hooks/actionSetInvoice.md b/modules/concepts/hooks/list-of-hooks/actionSetInvoice.md similarity index 72% rename from modules/concepts/hooks/list-hooks/actionSetInvoice.md rename to modules/concepts/hooks/list-of-hooks/actionSetInvoice.md index 5f0e7e02aa..90630c8062 100644 --- a/modules/concepts/hooks/list-hooks/actionSetInvoice.md +++ b/modules/concepts/hooks/list-of-hooks/actionSetInvoice.md @@ -1,22 +1,30 @@ --- menuTitle: actionSetInvoice -title: actionSetInvoice +Title: actionSetInvoice hidden: true +hookTitle: files: - classes/order/Order.php -types: +locations: - frontoffice -hookTypes: +types: - legacy --- # Hook : actionSetInvoice -Located in : +## Informations + +Hook locations: + - frontoffice + +Hook types: + - legacy +Located in: - classes/order/Order.php -## Parameters +## Hook call with parameters ```php Hook::exec('actionSetInvoice', [ diff --git a/modules/concepts/hooks/list-of-hooks/actionShopDataDuplication.md b/modules/concepts/hooks/list-of-hooks/actionShopDataDuplication.md new file mode 100644 index 0000000000..626885f189 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionShopDataDuplication.md @@ -0,0 +1,112 @@ +--- +menuTitle: actionShopDataDuplication +Title: actionShopDataDuplication +hidden: true +hookTitle: +files: + - classes/shop/Shop.php +locations: + - frontoffice +types: + - legacy +--- + +# Hook : actionShopDataDuplication + +## Informations + +Hook locations: + - frontoffice + +Hook types: + - legacy + +Located in: + - classes/shop/Shop.php + +## Hook call with parameters + +```php +Hook::exec('actionShopDataDuplication', [ + 'old_id_shop' => (int) $old_id, + 'new_id_shop' => (int) $this->id, + ], $m['id_module']); + } + } + } + } + + /** + * @param int $id + * + * @return array + */ + public static function getCategories($id = 0, $only_id = true) + { + // build query + $query = new DbQuery(); + if ($only_id) { + $query->select('cs.`id_category`'); + } else { + $query->select('DISTINCT cs.`id_category`, cl.`name`, cl.`link_rewrite`'); + } + $query->from('category_shop', 'cs'); + $query->leftJoin('category_lang', 'cl', 'cl.`id_category` = cs.`id_category` AND cl.`id_lang` = ' . (int) Context::getContext()->language->id); + $query->where('cs.`id_shop` = ' . (int) $id); + $result = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS($query); + + if ($only_id) { + $array = []; + foreach ($result as $row) { + $array[] = $row['id_category']; + } + $array = array_unique($array); + } else { + return $result; + } + + return $array; + } + + /** + * @param string $entity + * @param int $id_shop + * + * @return array|bool + */ + public static function getEntityIds($entity, $id_shop, $active = false, $delete = false) + { + if (!Shop::isTableAssociated($entity)) { + return false; + } + + return Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS( + 'SELECT entity.`id_' . bqSQL($entity) . '` + FROM `' . _DB_PREFIX_ . bqSQL($entity) . '_shop`es + LEFT JOIN ' . _DB_PREFIX_ . bqSQL($entity) . ' entity + ON (entity.`id_' . bqSQL($entity) . '` = es.`id_' . bqSQL($entity) . '`) + WHERE es.`id_shop` = ' . (int) $id_shop . + ($active ? ' AND entity.`active` = 1' : '') . + ($delete ? ' AND entity.deleted = 0' : '') + ); + } + + /** + * @param string $host + * + * @return array + * + * @throws PrestaShopDatabaseException + */ + private static function findShopByHost($host) + { + $sql = 'SELECT s.id_shop, CONCAT(su.physical_uri, su.virtual_uri) AS uri, su.domain, su.main + FROM ' . _DB_PREFIX_ . 'shop_url su + LEFT JOIN ' . _DB_PREFIX_ . 'shop s ON (s.id_shop = su.id_shop) + WHERE (su.domain = \'' . pSQL($host) . '\' OR su.domain_ssl = \'' . pSQL($host) . '\') + AND s.active = 1 + AND s.deleted = 0 + ORDER BY LENGTH(CONCAT(su.physical_uri, su.virtual_uri)) DESC'; + + $result = Db::getInstance()->executeS($sql); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionSubmitAccountBefore.md b/modules/concepts/hooks/list-of-hooks/actionSubmitAccountBefore.md similarity index 63% rename from modules/concepts/hooks/list-hooks/actionSubmitAccountBefore.md rename to modules/concepts/hooks/list-of-hooks/actionSubmitAccountBefore.md index a13c8353b4..6499940a68 100644 --- a/modules/concepts/hooks/list-hooks/actionSubmitAccountBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionSubmitAccountBefore.md @@ -1,22 +1,30 @@ --- menuTitle: actionSubmitAccountBefore -title: actionSubmitAccountBefore +Title: actionSubmitAccountBefore hidden: true +hookTitle: files: - controllers/front/RegistrationController.php -types: +locations: - frontoffice -hookTypes: +types: - legacy --- # Hook : actionSubmitAccountBefore -Located in : +## Informations + +Hook locations: + - frontoffice + +Hook types: + - legacy +Located in: - controllers/front/RegistrationController.php -## Parameters +## Hook call with parameters ```php Hook::exec('actionSubmitAccountBefore', [], null, true), diff --git a/modules/concepts/hooks/list-hooks/actionSubmitCustomerAddressForm.md b/modules/concepts/hooks/list-of-hooks/actionSubmitCustomerAddressForm.md similarity index 63% rename from modules/concepts/hooks/list-hooks/actionSubmitCustomerAddressForm.md rename to modules/concepts/hooks/list-of-hooks/actionSubmitCustomerAddressForm.md index a4f243ecab..0c5d7452dd 100644 --- a/modules/concepts/hooks/list-hooks/actionSubmitCustomerAddressForm.md +++ b/modules/concepts/hooks/list-of-hooks/actionSubmitCustomerAddressForm.md @@ -1,22 +1,30 @@ --- menuTitle: actionSubmitCustomerAddressForm -title: actionSubmitCustomerAddressForm +Title: actionSubmitCustomerAddressForm hidden: true +hookTitle: files: - classes/form/CustomerAddressForm.php -types: +locations: - frontoffice -hookTypes: +types: - legacy --- # Hook : actionSubmitCustomerAddressForm -Located in : +## Informations + +Hook locations: + - frontoffice + +Hook types: + - legacy +Located in: - classes/form/CustomerAddressForm.php -## Parameters +## Hook call with parameters ```php Hook::exec('actionSubmitCustomerAddressForm', ['address' => &$address]); diff --git a/modules/concepts/hooks/list-of-hooks/actionUpdateLangAfter.md b/modules/concepts/hooks/list-of-hooks/actionUpdateLangAfter.md new file mode 100644 index 0000000000..3c340de9e3 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionUpdateLangAfter.md @@ -0,0 +1,37 @@ +--- +menuTitle: actionUpdateLangAfter +Title: actionUpdateLangAfter +hidden: true +hookTitle: Update "lang" tables +files: + - classes/Language.php +locations: + - frontoffice +types: + - legacy +--- + +# Hook : actionUpdateLangAfter + +## Informations + +{{% notice tip %}} +**Update "lang" tables:** + +Update "lang" tables after adding or updating a language +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook types: + - legacy + +Located in: + - classes/Language.php + +## Hook call with parameters + +```php +Hook::exec('actionUpdateLangAfter', ['lang' => $language]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionValidateCustomerAddressForm.md b/modules/concepts/hooks/list-of-hooks/actionValidateCustomerAddressForm.md new file mode 100644 index 0000000000..e753be0cab --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionValidateCustomerAddressForm.md @@ -0,0 +1,130 @@ +--- +menuTitle: actionValidateCustomerAddressForm +Title: actionValidateCustomerAddressForm +hidden: true +hookTitle: Customer address form validation +files: + - classes/form/CustomerAddressForm.php +locations: + - frontoffice +types: + - legacy +--- + +# Hook : actionValidateCustomerAddressForm + +## Informations + +{{% notice tip %}} +**Customer address form validation:** + +This hook is called when a customer submit its address form +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook types: + - legacy + +Located in: + - classes/form/CustomerAddressForm.php + +## Hook call with parameters + +```php +Hook::exec('actionValidateCustomerAddressForm', ['form' => $this])) !== '') { + $is_valid &= (bool) $hookReturn; + } + + return $is_valid && parent::validate(); + } + + public function submit() + { + if (!$this->validate()) { + return false; + } + + $address = new Address( + Tools::getValue('id_address'), + $this->language->id + ); + + foreach ($this->formFields as $formField) { + $address->{$formField->getName()} = $formField->getValue(); + } + + if (!isset($this->formFields['id_state'])) { + $address->id_state = 0; + } + + if (empty($address->alias)) { + $address->alias = $this->translator->trans('My Address', [], 'Shop.Theme.Checkout'); + } + + Hook::exec('actionSubmitCustomerAddressForm', ['address' => &$address]); + + $this->setAddress($address); + + return $this->getPersister()->save( + $address, + $this->getValue('token') + ); + } + + /** + * @return Address + */ + public function getAddress() + { + return $this->address; + } + + /** + * @return CustomerAddressPersister + */ + protected function getPersister() + { + return $this->persister; + } + + protected function setAddress(Address $address) + { + $this->address = $address; + } + + public function getTemplateVariables() + { + $context = Context::getContext(); + + if (!$this->formFields) { + // This is usually done by fillWith but the form may be + // rendered before fillWith is called. + // I don't want to assign formFields in the constructor + // because it accesses the DB and a constructor should not + // have side effects. + $this->formFields = $this->formatter->getFormat(); + } + + $this->setValue('token', $this->persister->getToken()); + $formFields = array_map( + function (FormField $item) { + return $item->toArray(); + }, + $this->formFields + ); + + if (empty($formFields['firstname']['value'])) { + $formFields['firstname']['value'] = $context->customer->firstname; + } + + if (empty($formFields['lastname']['value'])) { + $formFields['lastname']['value'] = $context->customer->lastname; + } + + return [ + 'id_address' => (isset($this->address->id)) ? $this->address->id : 0, + 'action' => $this->action, + 'errors' => $this->getErrors(), +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/actionValidateOrder.md b/modules/concepts/hooks/list-of-hooks/actionValidateOrder.md similarity index 67% rename from modules/concepts/hooks/list-hooks/actionValidateOrder.md rename to modules/concepts/hooks/list-of-hooks/actionValidateOrder.md index 5758f1452f..4d145ccc53 100644 --- a/modules/concepts/hooks/list-hooks/actionValidateOrder.md +++ b/modules/concepts/hooks/list-of-hooks/actionValidateOrder.md @@ -1,22 +1,36 @@ --- menuTitle: actionValidateOrder -title: actionValidateOrder +Title: actionValidateOrder hidden: true +hookTitle: New orders files: - classes/PaymentModule.php -types: +locations: - frontoffice -hookTypes: +types: - legacy --- # Hook : actionValidateOrder -Located in : +## Informations + +{{% notice tip %}} +**New orders:** + + +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook types: + - legacy +Located in: - classes/PaymentModule.php -## Parameters +## Hook call with parameters ```php Hook::exec('actionValidateOrder', [ diff --git a/modules/concepts/hooks/list-hooks/actionWatermark.md b/modules/concepts/hooks/list-of-hooks/actionWatermark.md similarity index 58% rename from modules/concepts/hooks/list-hooks/actionWatermark.md rename to modules/concepts/hooks/list-of-hooks/actionWatermark.md index df72b1ca0b..1ff9192006 100644 --- a/modules/concepts/hooks/list-hooks/actionWatermark.md +++ b/modules/concepts/hooks/list-of-hooks/actionWatermark.md @@ -1,22 +1,36 @@ --- menuTitle: actionWatermark -title: actionWatermark +Title: actionWatermark hidden: true +hookTitle: Watermark files: - controllers/admin/AdminProductsController.php -types: +locations: - backoffice -hookTypes: +types: - legacy --- # Hook : actionWatermark -Located in : +## Informations + +{{% notice tip %}} +**Watermark:** + + +{{% /notice %}} + +Hook locations: + - backoffice + +Hook types: + - legacy +Located in: - controllers/admin/AdminProductsController.php -## Parameters +## Hook call with parameters ```php Hook::exec('actionWatermark', ['id_image' => $id_image, 'id_product' => $id_product]); diff --git a/modules/concepts/hooks/list-hooks/actionWishlistAddProduct.md b/modules/concepts/hooks/list-of-hooks/actionWishlistAddProduct.md similarity index 74% rename from modules/concepts/hooks/list-hooks/actionWishlistAddProduct.md rename to modules/concepts/hooks/list-of-hooks/actionWishlistAddProduct.md index c00eb81005..8ed061b46e 100644 --- a/modules/concepts/hooks/list-hooks/actionWishlistAddProduct.md +++ b/modules/concepts/hooks/list-of-hooks/actionWishlistAddProduct.md @@ -1,22 +1,30 @@ --- menuTitle: actionWishlistAddProduct -title: actionWishlistAddProduct +Title: actionWishlistAddProduct hidden: true +hookTitle: files: - modules/blockwishlist/controllers/front/action.php -types: +locations: - frontoffice -hookTypes: +types: - legacy --- # Hook : actionWishlistAddProduct -Located in : +## Informations + +Hook locations: + - frontoffice + +Hook types: + - legacy +Located in: - modules/blockwishlist/controllers/front/action.php -## Parameters +## Hook call with parameters ```php Hook::exec('actionWishlistAddProduct', [ diff --git a/modules/concepts/hooks/list-of-hooks/addWebserviceResources.md b/modules/concepts/hooks/list-of-hooks/addWebserviceResources.md new file mode 100644 index 0000000000..252415eb54 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/addWebserviceResources.md @@ -0,0 +1,37 @@ +--- +menuTitle: addWebserviceResources +Title: addWebserviceResources +hidden: true +hookTitle: Add extra webservice resource +files: + - classes/webservice/WebserviceRequest.php +locations: + - frontoffice +types: + - legacy +--- + +# Hook : addWebserviceResources + +## Informations + +{{% notice tip %}} +**Add extra webservice resource:** + +This hook is called when webservice resources list in webservice controller +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook types: + - legacy + +Located in: + - classes/webservice/WebserviceRequest.php + +## Hook call with parameters + +```php +Hook::exec('addWebserviceResources', ['resources' => $resources], null, true, false); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/additionalCustomerAddressFields.md b/modules/concepts/hooks/list-of-hooks/additionalCustomerAddressFields.md new file mode 100644 index 0000000000..b867a51240 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/additionalCustomerAddressFields.md @@ -0,0 +1,37 @@ +--- +menuTitle: additionalCustomerAddressFields +Title: additionalCustomerAddressFields +hidden: true +hookTitle: Add fields to the Customer address form +files: + - classes/form/CustomerAddressFormatter.php +locations: + - frontoffice +types: + - legacy +--- + +# Hook : additionalCustomerAddressFields + +## Informations + +{{% notice tip %}} +**Add fields to the Customer address form:** + +This hook returns an array of FormFields to add them to the customer address registration form +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook types: + - legacy + +Located in: + - classes/form/CustomerAddressFormatter.php + +## Hook call with parameters + +```php +Hook::exec('additionalCustomerAddressFields', ['fields' => &$format], null, true); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/additionalCustomerFormFields.md b/modules/concepts/hooks/list-of-hooks/additionalCustomerFormFields.md new file mode 100644 index 0000000000..87006c916f --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/additionalCustomerFormFields.md @@ -0,0 +1,37 @@ +--- +menuTitle: additionalCustomerFormFields +Title: additionalCustomerFormFields +hidden: true +hookTitle: Add fields to the Customer form +files: + - classes/form/CustomerFormatter.php +locations: + - frontoffice +types: + - legacy +--- + +# Hook : additionalCustomerFormFields + +## Informations + +{{% notice tip %}} +**Add fields to the Customer form:** + +This hook returns an array of FormFields to add them to the customer registration form +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook types: + - legacy + +Located in: + - classes/form/CustomerFormatter.php + +## Hook call with parameters + +```php +Hook::exec('additionalCustomerFormFields', ['fields' => &$format], null, true); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/dashboardData.md b/modules/concepts/hooks/list-of-hooks/dashboardData.md similarity index 63% rename from modules/concepts/hooks/list-hooks/dashboardData.md rename to modules/concepts/hooks/list-of-hooks/dashboardData.md index 298878616e..573122ebf5 100644 --- a/modules/concepts/hooks/list-hooks/dashboardData.md +++ b/modules/concepts/hooks/list-of-hooks/dashboardData.md @@ -1,22 +1,30 @@ --- menuTitle: dashboardData -title: dashboardData +Title: dashboardData hidden: true +hookTitle: files: - controllers/admin/AdminDashboardController.php -types: +locations: - backoffice -hookTypes: +types: - legacy --- # Hook : dashboardData -Located in : +## Informations + +Hook locations: + - backoffice + +Hook types: + - legacy +Located in: - controllers/admin/AdminDashboardController.php -## Parameters +## Hook call with parameters ```php Hook::exec('dashboardData', $params, $id_module, true))); diff --git a/modules/concepts/hooks/list-hooks/dashboardZoneOne.md b/modules/concepts/hooks/list-of-hooks/dashboardZoneOne.md similarity index 62% rename from modules/concepts/hooks/list-hooks/dashboardZoneOne.md rename to modules/concepts/hooks/list-of-hooks/dashboardZoneOne.md index 0a0d4131f6..85bb563359 100644 --- a/modules/concepts/hooks/list-hooks/dashboardZoneOne.md +++ b/modules/concepts/hooks/list-of-hooks/dashboardZoneOne.md @@ -1,22 +1,30 @@ --- menuTitle: dashboardZoneOne -title: dashboardZoneOne +Title: dashboardZoneOne hidden: true +hookTitle: files: - controllers/admin/AdminDashboardController.php -types: +locations: - backoffice -hookTypes: +types: - legacy --- # Hook : dashboardZoneOne -Located in : +## Informations + +Hook locations: + - backoffice + +Hook types: + - legacy +Located in: - controllers/admin/AdminDashboardController.php -## Parameters +## Hook call with parameters ```php Hook::exec('dashboardZoneOne', $params), diff --git a/modules/concepts/hooks/list-of-hooks/dashboardZoneThree.md b/modules/concepts/hooks/list-of-hooks/dashboardZoneThree.md new file mode 100644 index 0000000000..a6db12a018 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/dashboardZoneThree.md @@ -0,0 +1,37 @@ +--- +menuTitle: dashboardZoneThree +Title: dashboardZoneThree +hidden: true +hookTitle: Dashboard column three +files: + - controllers/admin/AdminDashboardController.php +locations: + - backoffice +types: + - legacy +--- + +# Hook : dashboardZoneThree + +## Informations + +{{% notice tip %}} +**Dashboard column three:** + +This hook is displayed in the third column of the dashboard +{{% /notice %}} + +Hook locations: + - backoffice + +Hook types: + - legacy + +Located in: + - controllers/admin/AdminDashboardController.php + +## Hook call with parameters + +```php +Hook::exec('dashboardZoneThree', $params), +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/dashboardZoneTwo.md b/modules/concepts/hooks/list-of-hooks/dashboardZoneTwo.md similarity index 62% rename from modules/concepts/hooks/list-hooks/dashboardZoneTwo.md rename to modules/concepts/hooks/list-of-hooks/dashboardZoneTwo.md index 05c3a72b5d..51e86a11d0 100644 --- a/modules/concepts/hooks/list-hooks/dashboardZoneTwo.md +++ b/modules/concepts/hooks/list-of-hooks/dashboardZoneTwo.md @@ -1,22 +1,30 @@ --- menuTitle: dashboardZoneTwo -title: dashboardZoneTwo +Title: dashboardZoneTwo hidden: true +hookTitle: files: - controllers/admin/AdminDashboardController.php -types: +locations: - backoffice -hookTypes: +types: - legacy --- # Hook : dashboardZoneTwo -Located in : +## Informations + +Hook locations: + - backoffice + +Hook types: + - legacy +Located in: - controllers/admin/AdminDashboardController.php -## Parameters +## Hook call with parameters ```php Hook::exec('dashboardZoneTwo', $params), diff --git a/modules/concepts/hooks/list-of-hooks/displayAdditionalCustomerAddressFields.md b/modules/concepts/hooks/list-of-hooks/displayAdditionalCustomerAddressFields.md new file mode 100644 index 0000000000..f85e171835 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/displayAdditionalCustomerAddressFields.md @@ -0,0 +1,37 @@ +--- +menuTitle: displayAdditionalCustomerAddressFields +Title: displayAdditionalCustomerAddressFields +hidden: true +hookTitle: Display additional customer address fields +files: + - themes/classic/templates/customer/_partials/block-address.tpl +locations: + - frontoffice +types: + - smarty +--- + +# Hook : displayAdditionalCustomerAddressFields + +## Informations + +{{% notice tip %}} +**Display additional customer address fields:** + +This hook allows to display extra field values added in an address form using hook 'additionalCustomerAddressFields' +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook types: + - smarty + +Located in: + - themes/classic/templates/customer/_partials/block-address.tpl + +## Hook call with parameters + +```php +{hook h='displayAdditionalCustomerAddressFields' address=$address} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayAdminAfterHeader.md b/modules/concepts/hooks/list-of-hooks/displayAdminAfterHeader.md similarity index 66% rename from modules/concepts/hooks/list-hooks/displayAdminAfterHeader.md rename to modules/concepts/hooks/list-of-hooks/displayAdminAfterHeader.md index 9592c18de9..e7b6a00e75 100644 --- a/modules/concepts/hooks/list-hooks/displayAdminAfterHeader.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminAfterHeader.md @@ -1,22 +1,30 @@ --- menuTitle: displayAdminAfterHeader -title: displayAdminAfterHeader +Title: displayAdminAfterHeader hidden: true +hookTitle: files: - admin784x07v4swfhm9fgvc0/themes/new-theme/template/light_display_layout.tpl -types: +locations: - backoffice -hookTypes: +types: - smarty --- # Hook : displayAdminAfterHeader -Located in : +## Informations + +Hook locations: + - backoffice + +Hook types: + - smarty +Located in: - admin784x07v4swfhm9fgvc0/themes/new-theme/template/light_display_layout.tpl -## Parameters +## Hook call with parameters ```php {hook h='displayAdminAfterHeader'} diff --git a/modules/concepts/hooks/list-of-hooks/displayAdminCustomers.md b/modules/concepts/hooks/list-of-hooks/displayAdminCustomers.md new file mode 100644 index 0000000000..3adb40db8e --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/displayAdminCustomers.md @@ -0,0 +1,37 @@ +--- +menuTitle: displayAdminCustomers +Title: displayAdminCustomers +hidden: true +hookTitle: Display new elements in the Back Office, tab AdminCustomers +files: + - src/PrestaShopBundle/Resources/views/Admin/Sell/Customer/view.html.twig +locations: + - backoffice +types: + - twig +--- + +# Hook : displayAdminCustomers + +## Informations + +{{% notice tip %}} +**Display new elements in the Back Office, tab AdminCustomers:** + +This hook launches modules when the AdminCustomers tab is displayed in the Back Office +{{% /notice %}} + +Hook locations: + - backoffice + +Hook types: + - twig + +Located in: + - src/PrestaShopBundle/Resources/views/Admin/Sell/Customer/view.html.twig + +## Hook call with parameters + +```php +{{ renderhook('displayAdminCustomers', {'id_customer': customerInformation.customerId.value}) }} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/displayAdminEndContent.md b/modules/concepts/hooks/list-of-hooks/displayAdminEndContent.md new file mode 100644 index 0000000000..70f4690fcc --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/displayAdminEndContent.md @@ -0,0 +1,37 @@ +--- +menuTitle: displayAdminEndContent +Title: displayAdminEndContent +hidden: true +hookTitle: Administration end of content +files: + - admin784x07v4swfhm9fgvc0/themes/new-theme/template/light_display_layout.tpl +locations: + - backoffice +types: + - smarty +--- + +# Hook : displayAdminEndContent + +## Informations + +{{% notice tip %}} +**Administration end of content:** + +This hook is displayed at the end of the main content, before the footer +{{% /notice %}} + +Hook locations: + - backoffice + +Hook types: + - smarty + +Located in: + - admin784x07v4swfhm9fgvc0/themes/new-theme/template/light_display_layout.tpl + +## Hook call with parameters + +```php +{hook h='displayAdminEndContent'} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayAdminForm.md b/modules/concepts/hooks/list-of-hooks/displayAdminForm.md similarity index 66% rename from modules/concepts/hooks/list-hooks/displayAdminForm.md rename to modules/concepts/hooks/list-of-hooks/displayAdminForm.md index d4b85ccf3c..9ebe043ba2 100644 --- a/modules/concepts/hooks/list-hooks/displayAdminForm.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminForm.md @@ -1,22 +1,30 @@ --- menuTitle: displayAdminForm -title: displayAdminForm +Title: displayAdminForm hidden: true +hookTitle: files: - admin784x07v4swfhm9fgvc0/themes/default/template/helpers/form/form.tpl -types: +locations: - backoffice -hookTypes: +types: - smarty --- # Hook : displayAdminForm -Located in : +## Informations + +Hook locations: + - backoffice + +Hook types: + - smarty +Located in: - admin784x07v4swfhm9fgvc0/themes/default/template/helpers/form/form.tpl -## Parameters +## Hook call with parameters ```php {hook h='displayAdminForm' fieldset=$f} diff --git a/modules/concepts/hooks/list-hooks/displayAdminGridTableAfter.md b/modules/concepts/hooks/list-of-hooks/displayAdminGridTableAfter.md similarity index 62% rename from modules/concepts/hooks/list-hooks/displayAdminGridTableAfter.md rename to modules/concepts/hooks/list-of-hooks/displayAdminGridTableAfter.md index 7c81cf9fd8..d6a074b9c6 100644 --- a/modules/concepts/hooks/list-hooks/displayAdminGridTableAfter.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminGridTableAfter.md @@ -1,22 +1,36 @@ --- menuTitle: displayAdminGridTableAfter -title: displayAdminGridTableAfter +Title: displayAdminGridTableAfter hidden: true +hookTitle: Display after Grid table files: - src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Blocks/table.html.twig -types: +locations: - backoffice -hookTypes: +types: - twig --- # Hook : displayAdminGridTableAfter -Located in : +## Informations + +{{% notice tip %}} +**Display after Grid table:** + +This hook adds new blocks after Grid component table +{{% /notice %}} + +Hook locations: + - backoffice + +Hook types: + - twig +Located in: - src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Blocks/table.html.twig -## Parameters +## Hook call with parameters ```php {{ renderhook('displayAdminGridTableAfter', { diff --git a/modules/concepts/hooks/list-hooks/displayAdminGridTableBefore.md b/modules/concepts/hooks/list-of-hooks/displayAdminGridTableBefore.md similarity index 61% rename from modules/concepts/hooks/list-hooks/displayAdminGridTableBefore.md rename to modules/concepts/hooks/list-of-hooks/displayAdminGridTableBefore.md index bd03f74f40..3f473c55e7 100644 --- a/modules/concepts/hooks/list-hooks/displayAdminGridTableBefore.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminGridTableBefore.md @@ -1,22 +1,36 @@ --- menuTitle: displayAdminGridTableBefore -title: displayAdminGridTableBefore +Title: displayAdminGridTableBefore hidden: true +hookTitle: Display before Grid table files: - src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Blocks/table.html.twig -types: +locations: - backoffice -hookTypes: +types: - twig --- # Hook : displayAdminGridTableBefore -Located in : +## Informations + +{{% notice tip %}} +**Display before Grid table:** + +This hook adds new blocks before Grid component table +{{% /notice %}} + +Hook locations: + - backoffice + +Hook types: + - twig +Located in: - src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Blocks/table.html.twig -## Parameters +## Hook call with parameters ```php {{ renderhook('displayAdminGridTableBefore', { diff --git a/modules/concepts/hooks/list-hooks/displayAdminListAfter.md b/modules/concepts/hooks/list-of-hooks/displayAdminListAfter.md similarity index 66% rename from modules/concepts/hooks/list-hooks/displayAdminListAfter.md rename to modules/concepts/hooks/list-of-hooks/displayAdminListAfter.md index f143e66bc3..adfce7289c 100644 --- a/modules/concepts/hooks/list-hooks/displayAdminListAfter.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminListAfter.md @@ -1,22 +1,30 @@ --- menuTitle: displayAdminListAfter -title: displayAdminListAfter +Title: displayAdminListAfter hidden: true +hookTitle: files: - admin784x07v4swfhm9fgvc0/themes/default/template/helpers/list/list_footer.tpl -types: +locations: - backoffice -hookTypes: +types: - smarty --- # Hook : displayAdminListAfter -Located in : +## Informations + +Hook locations: + - backoffice + +Hook types: + - smarty +Located in: - admin784x07v4swfhm9fgvc0/themes/default/template/helpers/list/list_footer.tpl -## Parameters +## Hook call with parameters ```php {hook h='displayAdminListAfter'} diff --git a/modules/concepts/hooks/list-hooks/displayAdminListBefore.md b/modules/concepts/hooks/list-of-hooks/displayAdminListBefore.md similarity index 66% rename from modules/concepts/hooks/list-hooks/displayAdminListBefore.md rename to modules/concepts/hooks/list-of-hooks/displayAdminListBefore.md index b5bb4fa8f6..e7231df9df 100644 --- a/modules/concepts/hooks/list-hooks/displayAdminListBefore.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminListBefore.md @@ -1,22 +1,30 @@ --- menuTitle: displayAdminListBefore -title: displayAdminListBefore +Title: displayAdminListBefore hidden: true +hookTitle: files: - admin784x07v4swfhm9fgvc0/themes/default/template/helpers/list/list_header.tpl -types: +locations: - backoffice -hookTypes: +types: - smarty --- # Hook : displayAdminListBefore -Located in : +## Informations + +Hook locations: + - backoffice + +Hook types: + - smarty +Located in: - admin784x07v4swfhm9fgvc0/themes/default/template/helpers/list/list_header.tpl -## Parameters +## Hook call with parameters ```php {hook h='displayAdminListBefore'} diff --git a/modules/concepts/hooks/list-hooks/displayAdminNavBarBeforeEnd.md b/modules/concepts/hooks/list-of-hooks/displayAdminNavBarBeforeEnd.md similarity index 67% rename from modules/concepts/hooks/list-hooks/displayAdminNavBarBeforeEnd.md rename to modules/concepts/hooks/list-of-hooks/displayAdminNavBarBeforeEnd.md index 6765ad501e..9945d81910 100644 --- a/modules/concepts/hooks/list-hooks/displayAdminNavBarBeforeEnd.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminNavBarBeforeEnd.md @@ -1,22 +1,30 @@ --- menuTitle: displayAdminNavBarBeforeEnd -title: displayAdminNavBarBeforeEnd +Title: displayAdminNavBarBeforeEnd hidden: true +hookTitle: files: - admin784x07v4swfhm9fgvc0/themes/new-theme/template/components/layout/nav_bar.tpl -types: +locations: - backoffice -hookTypes: +types: - smarty --- # Hook : displayAdminNavBarBeforeEnd -Located in : +## Informations + +Hook locations: + - backoffice + +Hook types: + - smarty +Located in: - admin784x07v4swfhm9fgvc0/themes/new-theme/template/components/layout/nav_bar.tpl -## Parameters +## Hook call with parameters ```php {hook h='displayAdminNavBarBeforeEnd'} diff --git a/modules/concepts/hooks/list-hooks/displayAdminOptions.md b/modules/concepts/hooks/list-of-hooks/displayAdminOptions.md similarity index 66% rename from modules/concepts/hooks/list-hooks/displayAdminOptions.md rename to modules/concepts/hooks/list-of-hooks/displayAdminOptions.md index d2482c4962..d48b00a3ef 100644 --- a/modules/concepts/hooks/list-hooks/displayAdminOptions.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminOptions.md @@ -1,22 +1,30 @@ --- menuTitle: displayAdminOptions -title: displayAdminOptions +Title: displayAdminOptions hidden: true +hookTitle: files: - admin784x07v4swfhm9fgvc0/themes/default/template/helpers/options/options.tpl -types: +locations: - backoffice -hookTypes: +types: - smarty --- # Hook : displayAdminOptions -Located in : +## Informations + +Hook locations: + - backoffice + +Hook types: + - smarty +Located in: - admin784x07v4swfhm9fgvc0/themes/default/template/helpers/options/options.tpl -## Parameters +## Hook call with parameters ```php {hook h='displayAdminOptions'} diff --git a/modules/concepts/hooks/list-of-hooks/displayAdminOrder.md b/modules/concepts/hooks/list-of-hooks/displayAdminOrder.md new file mode 100644 index 0000000000..7cc17cf1cf --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/displayAdminOrder.md @@ -0,0 +1,37 @@ +--- +menuTitle: displayAdminOrder +Title: displayAdminOrder +hidden: true +hookTitle: Display new elements in the Back Office, tab AdminOrder +files: + - src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/view.html.twig +locations: + - backoffice +types: + - twig +--- + +# Hook : displayAdminOrder + +## Informations + +{{% notice tip %}} +**Display new elements in the Back Office, tab AdminOrder:** + +This hook launches modules when the AdminOrder tab is displayed in the Back Office +{{% /notice %}} + +Hook locations: + - backoffice + +Hook types: + - twig + +Located in: + - src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/view.html.twig + +## Hook call with parameters + +```php +{{ renderhook('displayAdminOrder', {'id_order': orderForViewing.id}) }} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayAdminOrderCreateExtraButtons.md b/modules/concepts/hooks/list-of-hooks/displayAdminOrderCreateExtraButtons.md similarity index 53% rename from modules/concepts/hooks/list-hooks/displayAdminOrderCreateExtraButtons.md rename to modules/concepts/hooks/list-of-hooks/displayAdminOrderCreateExtraButtons.md index 0ca935d458..1948df4f57 100644 --- a/modules/concepts/hooks/list-hooks/displayAdminOrderCreateExtraButtons.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminOrderCreateExtraButtons.md @@ -1,22 +1,36 @@ --- menuTitle: displayAdminOrderCreateExtraButtons -title: displayAdminOrderCreateExtraButtons +Title: displayAdminOrderCreateExtraButtons hidden: true +hookTitle: Add buttons on the create order page dropdown files: - src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/Create/summary.html.twig -types: +locations: - backoffice -hookTypes: +types: - twig --- # Hook : displayAdminOrderCreateExtraButtons -Located in : +## Informations + +{{% notice tip %}} +**Add buttons on the create order page dropdown:** + +Add buttons on the create order page dropdown +{{% /notice %}} + +Hook locations: + - backoffice + +Hook types: + - twig +Located in: - src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/Create/summary.html.twig -## Parameters +## Hook call with parameters ```php {{ renderhook('displayAdminOrderCreateExtraButtons') }} diff --git a/modules/concepts/hooks/list-hooks/displayAdminOrderMain.md b/modules/concepts/hooks/list-of-hooks/displayAdminOrderMain.md similarity index 51% rename from modules/concepts/hooks/list-hooks/displayAdminOrderMain.md rename to modules/concepts/hooks/list-of-hooks/displayAdminOrderMain.md index 5cfa5e30f2..1dec52a781 100644 --- a/modules/concepts/hooks/list-hooks/displayAdminOrderMain.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminOrderMain.md @@ -1,22 +1,36 @@ --- menuTitle: displayAdminOrderMain -title: displayAdminOrderMain +Title: displayAdminOrderMain hidden: true +hookTitle: Admin Order Main Column files: - src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/view.html.twig -types: +locations: - backoffice -hookTypes: +types: - twig --- # Hook : displayAdminOrderMain -Located in : +## Informations + +{{% notice tip %}} +**Admin Order Main Column:** + +This hook displays content in the order view page in the main column under the details view +{{% /notice %}} + +Hook locations: + - backoffice + +Hook types: + - twig +Located in: - src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/view.html.twig -## Parameters +## Hook call with parameters ```php {{ renderhook('displayAdminOrderMain', {'id_order': orderForViewing.id}) }} diff --git a/modules/concepts/hooks/list-hooks/displayAdminOrderMainBottom.md b/modules/concepts/hooks/list-of-hooks/displayAdminOrderMainBottom.md similarity index 52% rename from modules/concepts/hooks/list-hooks/displayAdminOrderMainBottom.md rename to modules/concepts/hooks/list-of-hooks/displayAdminOrderMainBottom.md index e308987755..151eb1c87b 100644 --- a/modules/concepts/hooks/list-hooks/displayAdminOrderMainBottom.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminOrderMainBottom.md @@ -1,22 +1,36 @@ --- menuTitle: displayAdminOrderMainBottom -title: displayAdminOrderMainBottom +Title: displayAdminOrderMainBottom hidden: true +hookTitle: Admin Order Main Column Bottom files: - src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/view.html.twig -types: +locations: - backoffice -hookTypes: +types: - twig --- # Hook : displayAdminOrderMainBottom -Located in : +## Informations + +{{% notice tip %}} +**Admin Order Main Column Bottom:** + +This hook displays content in the order view page at the bottom of the main column +{{% /notice %}} + +Hook locations: + - backoffice + +Hook types: + - twig +Located in: - src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/view.html.twig -## Parameters +## Hook call with parameters ```php {{ renderhook('displayAdminOrderMainBottom', {'id_order': orderForViewing.id}) }} diff --git a/modules/concepts/hooks/list-hooks/displayAdminOrderSide.md b/modules/concepts/hooks/list-of-hooks/displayAdminOrderSide.md similarity index 51% rename from modules/concepts/hooks/list-hooks/displayAdminOrderSide.md rename to modules/concepts/hooks/list-of-hooks/displayAdminOrderSide.md index 9a80dac84a..7cb3eb2ce7 100644 --- a/modules/concepts/hooks/list-hooks/displayAdminOrderSide.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminOrderSide.md @@ -1,22 +1,36 @@ --- menuTitle: displayAdminOrderSide -title: displayAdminOrderSide +Title: displayAdminOrderSide hidden: true +hookTitle: Admin Order Side Column files: - src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/view.html.twig -types: +locations: - backoffice -hookTypes: +types: - twig --- # Hook : displayAdminOrderSide -Located in : +## Informations + +{{% notice tip %}} +**Admin Order Side Column:** + +This hook displays content in the order view page in the side column under the customer view +{{% /notice %}} + +Hook locations: + - backoffice + +Hook types: + - twig +Located in: - src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/view.html.twig -## Parameters +## Hook call with parameters ```php {{ renderhook('displayAdminOrderSide', {'id_order': orderForViewing.id}) }} diff --git a/modules/concepts/hooks/list-hooks/displayAdminOrderSideBottom.md b/modules/concepts/hooks/list-of-hooks/displayAdminOrderSideBottom.md similarity index 69% rename from modules/concepts/hooks/list-hooks/displayAdminOrderSideBottom.md rename to modules/concepts/hooks/list-of-hooks/displayAdminOrderSideBottom.md index bebb52fc8e..0fe1f2f7fd 100644 --- a/modules/concepts/hooks/list-hooks/displayAdminOrderSideBottom.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminOrderSideBottom.md @@ -1,22 +1,30 @@ --- menuTitle: displayAdminOrderSideBottom -title: displayAdminOrderSideBottom +Title: displayAdminOrderSideBottom hidden: true +hookTitle: files: - src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/view.html.twig -types: +locations: - backoffice -hookTypes: +types: - twig --- # Hook : displayAdminOrderSideBottom -Located in : +## Informations + +Hook locations: + - backoffice + +Hook types: + - twig +Located in: - src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/view.html.twig -## Parameters +## Hook call with parameters ```php {{ renderhook('displayAdminOrderSideBottom', {'id_order': orderForViewing.id}) }} diff --git a/modules/concepts/hooks/list-hooks/displayAdminProductsCombinationBottom.md b/modules/concepts/hooks/list-of-hooks/displayAdminProductsCombinationBottom.md similarity index 55% rename from modules/concepts/hooks/list-hooks/displayAdminProductsCombinationBottom.md rename to modules/concepts/hooks/list-of-hooks/displayAdminProductsCombinationBottom.md index 2dc3a4d5af..56970fc472 100644 --- a/modules/concepts/hooks/list-hooks/displayAdminProductsCombinationBottom.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminProductsCombinationBottom.md @@ -1,22 +1,36 @@ --- menuTitle: displayAdminProductsCombinationBottom -title: displayAdminProductsCombinationBottom +Title: displayAdminProductsCombinationBottom hidden: true +hookTitle: Display new elements in back office product page, Combination tab files: - src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Forms/form_combination.html.twig -types: +locations: - backoffice -hookTypes: +types: - twig --- # Hook : displayAdminProductsCombinationBottom -Located in : +## Informations + +{{% notice tip %}} +**Display new elements in back office product page, Combination tab:** + +This hook launches modules when the back office product page is displayed +{{% /notice %}} + +Hook locations: + - backoffice + +Hook types: + - twig +Located in: - src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Forms/form_combination.html.twig -## Parameters +## Hook call with parameters ```php {{ renderhook('displayAdminProductsCombinationBottom', { 'id_product': form.vars.value.id_product, 'id_product_attribute': form.vars.value.id_product_attribute }) }} diff --git a/modules/concepts/hooks/list-of-hooks/displayAdminProductsMainStepLeftColumnBottom.md b/modules/concepts/hooks/list-of-hooks/displayAdminProductsMainStepLeftColumnBottom.md new file mode 100644 index 0000000000..ef49c5337d --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/displayAdminProductsMainStepLeftColumnBottom.md @@ -0,0 +1,37 @@ +--- +menuTitle: displayAdminProductsMainStepLeftColumnBottom +Title: displayAdminProductsMainStepLeftColumnBottom +hidden: true +hookTitle: Display new elements in back office product page, left column of the Basic settings tab +files: + - src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/essentials.html.twig +locations: + - backoffice +types: + - twig +--- + +# Hook : displayAdminProductsMainStepLeftColumnBottom + +## Informations + +{{% notice tip %}} +**Display new elements in back office product page, left column of the Basic settings tab:** + +This hook launches modules when the back office product page is displayed +{{% /notice %}} + +Hook locations: + - backoffice + +Hook types: + - twig + +Located in: + - src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/essentials.html.twig + +## Hook call with parameters + +```php +{{ renderhook('displayAdminProductsMainStepLeftColumnBottom', { 'id_product': productId }) }} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/displayAdminProductsMainStepLeftColumnMiddle.md b/modules/concepts/hooks/list-of-hooks/displayAdminProductsMainStepLeftColumnMiddle.md new file mode 100644 index 0000000000..830ad3e47c --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/displayAdminProductsMainStepLeftColumnMiddle.md @@ -0,0 +1,37 @@ +--- +menuTitle: displayAdminProductsMainStepLeftColumnMiddle +Title: displayAdminProductsMainStepLeftColumnMiddle +hidden: true +hookTitle: Display new elements in back office product page, left column of the Basic settings tab +files: + - src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/essentials.html.twig +locations: + - backoffice +types: + - twig +--- + +# Hook : displayAdminProductsMainStepLeftColumnMiddle + +## Informations + +{{% notice tip %}} +**Display new elements in back office product page, left column of the Basic settings tab:** + +This hook launches modules when the back office product page is displayed +{{% /notice %}} + +Hook locations: + - backoffice + +Hook types: + - twig + +Located in: + - src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/essentials.html.twig + +## Hook call with parameters + +```php +{{ renderhook('displayAdminProductsMainStepLeftColumnMiddle', { 'id_product': productId }) }} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/displayAdminProductsMainStepRightColumnBottom.md b/modules/concepts/hooks/list-of-hooks/displayAdminProductsMainStepRightColumnBottom.md new file mode 100644 index 0000000000..68a6e9e04d --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/displayAdminProductsMainStepRightColumnBottom.md @@ -0,0 +1,37 @@ +--- +menuTitle: displayAdminProductsMainStepRightColumnBottom +Title: displayAdminProductsMainStepRightColumnBottom +hidden: true +hookTitle: Display new elements in back office product page, right column of the Basic settings tab +files: + - src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/essentials.html.twig +locations: + - backoffice +types: + - twig +--- + +# Hook : displayAdminProductsMainStepRightColumnBottom + +## Informations + +{{% notice tip %}} +**Display new elements in back office product page, right column of the Basic settings tab:** + +This hook launches modules when the back office product page is displayed +{{% /notice %}} + +Hook locations: + - backoffice + +Hook types: + - twig + +Located in: + - src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/essentials.html.twig + +## Hook call with parameters + +```php +{{ renderhook('displayAdminProductsMainStepRightColumnBottom', { 'id_product': productId }) }} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayAdminProductsOptionsStepBottom.md b/modules/concepts/hooks/list-of-hooks/displayAdminProductsOptionsStepBottom.md similarity index 51% rename from modules/concepts/hooks/list-hooks/displayAdminProductsOptionsStepBottom.md rename to modules/concepts/hooks/list-of-hooks/displayAdminProductsOptionsStepBottom.md index 0f0aed60af..19c8749cc6 100644 --- a/modules/concepts/hooks/list-hooks/displayAdminProductsOptionsStepBottom.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminProductsOptionsStepBottom.md @@ -1,22 +1,36 @@ --- menuTitle: displayAdminProductsOptionsStepBottom -title: displayAdminProductsOptionsStepBottom +Title: displayAdminProductsOptionsStepBottom hidden: true +hookTitle: Display new elements in back office product page, Options tab files: - src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/options.html.twig -types: +locations: - backoffice -hookTypes: +types: - twig --- # Hook : displayAdminProductsOptionsStepBottom -Located in : +## Informations + +{{% notice tip %}} +**Display new elements in back office product page, Options tab:** + +This hook launches modules when the back office product page is displayed +{{% /notice %}} + +Hook locations: + - backoffice + +Hook types: + - twig +Located in: - src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/options.html.twig -## Parameters +## Hook call with parameters ```php {{ renderhook('displayAdminProductsOptionsStepBottom', { 'id_product': productId }) }} diff --git a/modules/concepts/hooks/list-hooks/displayAdminProductsOptionsStepTop.md b/modules/concepts/hooks/list-of-hooks/displayAdminProductsOptionsStepTop.md similarity index 50% rename from modules/concepts/hooks/list-hooks/displayAdminProductsOptionsStepTop.md rename to modules/concepts/hooks/list-of-hooks/displayAdminProductsOptionsStepTop.md index ca91b03fff..7a4d1f5d05 100644 --- a/modules/concepts/hooks/list-hooks/displayAdminProductsOptionsStepTop.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminProductsOptionsStepTop.md @@ -1,22 +1,36 @@ --- menuTitle: displayAdminProductsOptionsStepTop -title: displayAdminProductsOptionsStepTop +Title: displayAdminProductsOptionsStepTop hidden: true +hookTitle: Display new elements in back office product page, Options tab files: - src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/options.html.twig -types: +locations: - backoffice -hookTypes: +types: - twig --- # Hook : displayAdminProductsOptionsStepTop -Located in : +## Informations + +{{% notice tip %}} +**Display new elements in back office product page, Options tab:** + +This hook launches modules when the back office product page is displayed +{{% /notice %}} + +Hook locations: + - backoffice + +Hook types: + - twig +Located in: - src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/options.html.twig -## Parameters +## Hook call with parameters ```php {{ renderhook('displayAdminProductsOptionsStepTop', { 'id_product': productId }) }} diff --git a/modules/concepts/hooks/list-hooks/displayAdminProductsPriceStepBottom.md b/modules/concepts/hooks/list-of-hooks/displayAdminProductsPriceStepBottom.md similarity index 51% rename from modules/concepts/hooks/list-hooks/displayAdminProductsPriceStepBottom.md rename to modules/concepts/hooks/list-of-hooks/displayAdminProductsPriceStepBottom.md index 7ec1cc4e57..305abdf46b 100644 --- a/modules/concepts/hooks/list-hooks/displayAdminProductsPriceStepBottom.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminProductsPriceStepBottom.md @@ -1,22 +1,36 @@ --- menuTitle: displayAdminProductsPriceStepBottom -title: displayAdminProductsPriceStepBottom +Title: displayAdminProductsPriceStepBottom hidden: true +hookTitle: Display new elements in back office product page, Price tab files: - src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/pricing.html.twig -types: +locations: - backoffice -hookTypes: +types: - twig --- # Hook : displayAdminProductsPriceStepBottom -Located in : +## Informations + +{{% notice tip %}} +**Display new elements in back office product page, Price tab:** + +This hook launches modules when the back office product page is displayed +{{% /notice %}} + +Hook locations: + - backoffice + +Hook types: + - twig +Located in: - src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/pricing.html.twig -## Parameters +## Hook call with parameters ```php {{ renderhook('displayAdminProductsPriceStepBottom', { 'id_product': productId }) }} diff --git a/modules/concepts/hooks/list-hooks/displayAdminProductsQuantitiesStepBottom.md b/modules/concepts/hooks/list-of-hooks/displayAdminProductsQuantitiesStepBottom.md similarity index 50% rename from modules/concepts/hooks/list-hooks/displayAdminProductsQuantitiesStepBottom.md rename to modules/concepts/hooks/list-of-hooks/displayAdminProductsQuantitiesStepBottom.md index 1aae7bad74..f91227ad20 100644 --- a/modules/concepts/hooks/list-hooks/displayAdminProductsQuantitiesStepBottom.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminProductsQuantitiesStepBottom.md @@ -1,22 +1,36 @@ --- menuTitle: displayAdminProductsQuantitiesStepBottom -title: displayAdminProductsQuantitiesStepBottom +Title: displayAdminProductsQuantitiesStepBottom hidden: true +hookTitle: Display new elements in back office product page, Quantities/Combinations tab files: - src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/combinations.html.twig -types: +locations: - backoffice -hookTypes: +types: - twig --- # Hook : displayAdminProductsQuantitiesStepBottom -Located in : +## Informations + +{{% notice tip %}} +**Display new elements in back office product page, Quantities/Combinations tab:** + +This hook launches modules when the back office product page is displayed +{{% /notice %}} + +Hook locations: + - backoffice + +Hook types: + - twig +Located in: - src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/combinations.html.twig -## Parameters +## Hook call with parameters ```php {{ renderhook('displayAdminProductsQuantitiesStepBottom', { 'id_product': productId }) }} diff --git a/modules/concepts/hooks/list-hooks/displayAdminProductsSeoStepBottom.md b/modules/concepts/hooks/list-of-hooks/displayAdminProductsSeoStepBottom.md similarity index 51% rename from modules/concepts/hooks/list-hooks/displayAdminProductsSeoStepBottom.md rename to modules/concepts/hooks/list-of-hooks/displayAdminProductsSeoStepBottom.md index 606d4297e7..1e02acf9ef 100644 --- a/modules/concepts/hooks/list-hooks/displayAdminProductsSeoStepBottom.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminProductsSeoStepBottom.md @@ -1,22 +1,36 @@ --- menuTitle: displayAdminProductsSeoStepBottom -title: displayAdminProductsSeoStepBottom +Title: displayAdminProductsSeoStepBottom hidden: true +hookTitle: Display new elements in back office product page, SEO tab files: - src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Forms/form_seo.html.twig -types: +locations: - backoffice -hookTypes: +types: - twig --- # Hook : displayAdminProductsSeoStepBottom -Located in : +## Informations + +{{% notice tip %}} +**Display new elements in back office product page, SEO tab:** + +This hook launches modules when the back office product page is displayed +{{% /notice %}} + +Hook locations: + - backoffice + +Hook types: + - twig +Located in: - src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Forms/form_seo.html.twig -## Parameters +## Hook call with parameters ```php {{ renderhook('displayAdminProductsSeoStepBottom', { 'id_product': productId }) }} diff --git a/modules/concepts/hooks/list-hooks/displayAdminProductsShippingStepBottom.md b/modules/concepts/hooks/list-of-hooks/displayAdminProductsShippingStepBottom.md similarity index 51% rename from modules/concepts/hooks/list-hooks/displayAdminProductsShippingStepBottom.md rename to modules/concepts/hooks/list-of-hooks/displayAdminProductsShippingStepBottom.md index 891a6da7fe..183614c9a6 100644 --- a/modules/concepts/hooks/list-hooks/displayAdminProductsShippingStepBottom.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminProductsShippingStepBottom.md @@ -1,22 +1,36 @@ --- menuTitle: displayAdminProductsShippingStepBottom -title: displayAdminProductsShippingStepBottom +Title: displayAdminProductsShippingStepBottom hidden: true +hookTitle: Display new elements in back office product page, Shipping tab files: - src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Forms/form_shipping.html.twig -types: +locations: - backoffice -hookTypes: +types: - twig --- # Hook : displayAdminProductsShippingStepBottom -Located in : +## Informations + +{{% notice tip %}} +**Display new elements in back office product page, Shipping tab:** + +This hook launches modules when the back office product page is displayed +{{% /notice %}} + +Hook locations: + - backoffice + +Hook types: + - twig +Located in: - src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Forms/form_shipping.html.twig -## Parameters +## Hook call with parameters ```php {{ renderhook('displayAdminProductsShippingStepBottom', { 'id_product': id_product }) }} diff --git a/modules/concepts/hooks/list-hooks/displayAdminStatsModules.md b/modules/concepts/hooks/list-of-hooks/displayAdminStatsModules.md similarity index 55% rename from modules/concepts/hooks/list-hooks/displayAdminStatsModules.md rename to modules/concepts/hooks/list-of-hooks/displayAdminStatsModules.md index ec122ef6bd..6c0e0a6a3d 100644 --- a/modules/concepts/hooks/list-hooks/displayAdminStatsModules.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminStatsModules.md @@ -1,22 +1,36 @@ --- menuTitle: displayAdminStatsModules -title: displayAdminStatsModules +Title: displayAdminStatsModules hidden: true +hookTitle: Stats - Modules files: - controllers/admin/AdminStatsTabController.php -types: +locations: - backoffice -hookTypes: +types: - legacy --- # Hook : displayAdminStatsModules -Located in : +## Informations + +{{% notice tip %}} +**Stats - Modules:** + + +{{% /notice %}} + +Hook locations: + - backoffice + +Hook types: + - legacy +Located in: - controllers/admin/AdminStatsTabController.php -## Parameters +## Hook call with parameters ```php Hook::exec('displayAdminStatsModules', [], $module_instance->id); diff --git a/modules/concepts/hooks/list-hooks/displayAdminThemesListAfter.md b/modules/concepts/hooks/list-of-hooks/displayAdminThemesListAfter.md similarity index 55% rename from modules/concepts/hooks/list-hooks/displayAdminThemesListAfter.md rename to modules/concepts/hooks/list-of-hooks/displayAdminThemesListAfter.md index b4228eb354..10b0d7390e 100644 --- a/modules/concepts/hooks/list-hooks/displayAdminThemesListAfter.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminThemesListAfter.md @@ -1,22 +1,36 @@ --- menuTitle: displayAdminThemesListAfter -title: displayAdminThemesListAfter +Title: displayAdminThemesListAfter hidden: true +hookTitle: BO themes list extra content files: - src/PrestaShopBundle/Resources/views/Admin/Improve/Design/Theme/index.html.twig -types: +locations: - backoffice -hookTypes: +types: - twig --- # Hook : displayAdminThemesListAfter -Located in : +## Informations + +{{% notice tip %}} +**BO themes list extra content:** + +This hook displays content after the themes list in the back office +{{% /notice %}} + +Hook locations: + - backoffice + +Hook types: + - twig +Located in: - src/PrestaShopBundle/Resources/views/Admin/Improve/Design/Theme/index.html.twig -## Parameters +## Hook call with parameters ```php {{ renderhook('displayAdminThemesListAfter', { 'current_theme_name': currentlyUsedTheme.get('name') }) }} diff --git a/modules/concepts/hooks/list-hooks/displayAdminView.md b/modules/concepts/hooks/list-of-hooks/displayAdminView.md similarity index 65% rename from modules/concepts/hooks/list-hooks/displayAdminView.md rename to modules/concepts/hooks/list-of-hooks/displayAdminView.md index 6fa0596d61..faad09b54c 100644 --- a/modules/concepts/hooks/list-hooks/displayAdminView.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminView.md @@ -1,22 +1,30 @@ --- menuTitle: displayAdminView -title: displayAdminView +Title: displayAdminView hidden: true +hookTitle: files: - admin784x07v4swfhm9fgvc0/themes/default/template/helpers/view/view.tpl -types: +locations: - backoffice -hookTypes: +types: - smarty --- # Hook : displayAdminView -Located in : +## Informations + +Hook locations: + - backoffice + +Hook types: + - smarty +Located in: - admin784x07v4swfhm9fgvc0/themes/default/template/helpers/view/view.tpl -## Parameters +## Hook call with parameters ```php {hook h='displayAdminView'} diff --git a/modules/concepts/hooks/list-of-hooks/displayAfterBodyOpeningTag.md b/modules/concepts/hooks/list-of-hooks/displayAfterBodyOpeningTag.md new file mode 100644 index 0000000000..4f5cf5f313 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/displayAfterBodyOpeningTag.md @@ -0,0 +1,37 @@ +--- +menuTitle: displayAfterBodyOpeningTag +Title: displayAfterBodyOpeningTag +hidden: true +hookTitle: Very top of pages +files: + - themes/classic/templates/layouts/layout-both-columns.tpl +locations: + - frontoffice +types: + - smarty +--- + +# Hook : displayAfterBodyOpeningTag + +## Informations + +{{% notice tip %}} +**Very top of pages:** + +Use this hook for advertisement or modals you want to load first +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook types: + - smarty + +Located in: + - themes/classic/templates/layouts/layout-both-columns.tpl + +## Hook call with parameters + +```php +{hook h='displayAfterBodyOpeningTag'} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayAfterCarrier.md b/modules/concepts/hooks/list-of-hooks/displayAfterCarrier.md similarity index 50% rename from modules/concepts/hooks/list-hooks/displayAfterCarrier.md rename to modules/concepts/hooks/list-of-hooks/displayAfterCarrier.md index 60ec8e6b8f..ecd3170e22 100644 --- a/modules/concepts/hooks/list-hooks/displayAfterCarrier.md +++ b/modules/concepts/hooks/list-of-hooks/displayAfterCarrier.md @@ -1,22 +1,36 @@ --- menuTitle: displayAfterCarrier -title: displayAfterCarrier +Title: displayAfterCarrier hidden: true +hookTitle: After carriers list files: - classes/checkout/CheckoutDeliveryStep.php -types: +locations: - frontoffice -hookTypes: +types: - legacy --- # Hook : displayAfterCarrier -Located in : +## Informations + +{{% notice tip %}} +**After carriers list:** + +This hook is displayed after the carrier list in Front Office +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook types: + - legacy +Located in: - classes/checkout/CheckoutDeliveryStep.php -## Parameters +## Hook call with parameters ```php Hook::exec('displayAfterCarrier', ['cart' => $this->getCheckoutSession()->getCart()]), diff --git a/modules/concepts/hooks/list-of-hooks/displayAfterProductThumbs.md b/modules/concepts/hooks/list-of-hooks/displayAfterProductThumbs.md new file mode 100644 index 0000000000..616f4ae307 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/displayAfterProductThumbs.md @@ -0,0 +1,37 @@ +--- +menuTitle: displayAfterProductThumbs +Title: displayAfterProductThumbs +hidden: true +hookTitle: Display extra content below product thumbs +files: + - themes/classic/templates/catalog/_partials/product-cover-thumbnails.tpl +locations: + - frontoffice +types: + - smarty +--- + +# Hook : displayAfterProductThumbs + +## Informations + +{{% notice tip %}} +**Display extra content below product thumbs:** + +This hook displays new elements below product images ex. additional media +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook types: + - smarty + +Located in: + - themes/classic/templates/catalog/_partials/product-cover-thumbnails.tpl + +## Hook call with parameters + +```php +{hook h='displayAfterProductThumbs' product=$product} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/displayAfterTitleTag.md b/modules/concepts/hooks/list-of-hooks/displayAfterTitleTag.md new file mode 100644 index 0000000000..dc7d44c577 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/displayAfterTitleTag.md @@ -0,0 +1,37 @@ +--- +menuTitle: displayAfterTitleTag +Title: displayAfterTitleTag +hidden: true +hookTitle: After title tag +files: + - themes/classic/templates/_partials/head.tpl +locations: + - frontoffice +types: + - smarty +--- + +# Hook : displayAfterTitleTag + +## Informations + +{{% notice tip %}} +**After title tag:** + +Use this hook to add content after title tag +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook types: + - smarty + +Located in: + - themes/classic/templates/_partials/head.tpl + +## Hook call with parameters + +```php +{hook h='displayAfterTitleTag'} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/displayBackOfficeCategory.md b/modules/concepts/hooks/list-of-hooks/displayBackOfficeCategory.md new file mode 100644 index 0000000000..cec9f91c70 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/displayBackOfficeCategory.md @@ -0,0 +1,37 @@ +--- +menuTitle: displayBackOfficeCategory +Title: displayBackOfficeCategory +hidden: true +hookTitle: Display new elements in the Back Office, tab AdminCategories +files: + - src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Categories/Blocks/form.html.twig +locations: + - backoffice +types: + - twig +--- + +# Hook : displayBackOfficeCategory + +## Informations + +{{% notice tip %}} +**Display new elements in the Back Office, tab AdminCategories:** + +This hook launches modules when the AdminCategories tab is displayed in the Back Office +{{% /notice %}} + +Hook locations: + - backoffice + +Hook types: + - twig + +Located in: + - src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Categories/Blocks/form.html.twig + +## Hook call with parameters + +```php +{{ renderhook('displayBackOfficeCategory') }} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/displayBackOfficeTop.md b/modules/concepts/hooks/list-of-hooks/displayBackOfficeTop.md new file mode 100644 index 0000000000..2d3a3a9c17 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/displayBackOfficeTop.md @@ -0,0 +1,37 @@ +--- +menuTitle: displayBackOfficeTop +Title: displayBackOfficeTop +hidden: true +hookTitle: Administration panel hover the tabs +files: + - classes/controller/AdminController.php +locations: + - backoffice +types: + - legacy +--- + +# Hook : displayBackOfficeTop + +## Informations + +{{% notice tip %}} +**Administration panel hover the tabs:** + +This hook is displayed on the roll hover of the tabs within the admin panel +{{% /notice %}} + +Hook locations: + - backoffice + +Hook types: + - legacy + +Located in: + - classes/controller/AdminController.php + +## Hook call with parameters + +```php +Hook::exec('displayBackOfficeTop'), +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/displayBanner.md b/modules/concepts/hooks/list-of-hooks/displayBanner.md new file mode 100644 index 0000000000..8f65883839 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/displayBanner.md @@ -0,0 +1,37 @@ +--- +menuTitle: displayBanner +Title: displayBanner +hidden: true +hookTitle: Very top of pages +files: + - themes/classic/templates/_partials/header.tpl +locations: + - frontoffice +types: + - smarty +--- + +# Hook : displayBanner + +## Informations + +{{% notice tip %}} +**Very top of pages:** + +Use this hook for banners on top of every pages +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook types: + - smarty + +Located in: + - themes/classic/templates/_partials/header.tpl + +## Hook call with parameters + +```php +{hook h='displayBanner'} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/displayBeforeBodyClosingTag.md b/modules/concepts/hooks/list-of-hooks/displayBeforeBodyClosingTag.md new file mode 100644 index 0000000000..a95430a5d6 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/displayBeforeBodyClosingTag.md @@ -0,0 +1,37 @@ +--- +menuTitle: displayBeforeBodyClosingTag +Title: displayBeforeBodyClosingTag +hidden: true +hookTitle: Very bottom of pages +files: + - themes/classic/templates/layouts/layout-both-columns.tpl +locations: + - frontoffice +types: + - smarty +--- + +# Hook : displayBeforeBodyClosingTag + +## Informations + +{{% notice tip %}} +**Very bottom of pages:** + +Use this hook for your modals or any content you want to load at the very end +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook types: + - smarty + +Located in: + - themes/classic/templates/layouts/layout-both-columns.tpl + +## Hook call with parameters + +```php +{hook h='displayBeforeBodyClosingTag'} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayBeforeCarrier.md b/modules/concepts/hooks/list-of-hooks/displayBeforeCarrier.md similarity index 50% rename from modules/concepts/hooks/list-hooks/displayBeforeCarrier.md rename to modules/concepts/hooks/list-of-hooks/displayBeforeCarrier.md index 09d0fc5b94..b2be298ffa 100644 --- a/modules/concepts/hooks/list-hooks/displayBeforeCarrier.md +++ b/modules/concepts/hooks/list-of-hooks/displayBeforeCarrier.md @@ -1,22 +1,36 @@ --- menuTitle: displayBeforeCarrier -title: displayBeforeCarrier +Title: displayBeforeCarrier hidden: true +hookTitle: Before carriers list files: - classes/checkout/CheckoutDeliveryStep.php -types: +locations: - frontoffice -hookTypes: +types: - legacy --- # Hook : displayBeforeCarrier -Located in : +## Informations + +{{% notice tip %}} +**Before carriers list:** + +This hook is displayed before the carrier list in Front Office +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook types: + - legacy +Located in: - classes/checkout/CheckoutDeliveryStep.php -## Parameters +## Hook call with parameters ```php Hook::exec('displayBeforeCarrier', ['cart' => $this->getCheckoutSession()->getCart()]), diff --git a/modules/concepts/hooks/list-hooks/displayCMSDisputeInformation.md b/modules/concepts/hooks/list-of-hooks/displayCMSDisputeInformation.md similarity index 61% rename from modules/concepts/hooks/list-hooks/displayCMSDisputeInformation.md rename to modules/concepts/hooks/list-of-hooks/displayCMSDisputeInformation.md index fedfe69510..01150b5323 100644 --- a/modules/concepts/hooks/list-hooks/displayCMSDisputeInformation.md +++ b/modules/concepts/hooks/list-of-hooks/displayCMSDisputeInformation.md @@ -1,22 +1,30 @@ --- menuTitle: displayCMSDisputeInformation -title: displayCMSDisputeInformation +Title: displayCMSDisputeInformation hidden: true +hookTitle: files: - themes/classic/templates/cms/page.tpl -types: +locations: - frontoffice -hookTypes: +types: - smarty --- # Hook : displayCMSDisputeInformation -Located in : +## Informations + +Hook locations: + - frontoffice + +Hook types: + - smarty +Located in: - themes/classic/templates/cms/page.tpl -## Parameters +## Hook call with parameters ```php {hook h='displayCMSDisputeInformation'} diff --git a/modules/concepts/hooks/list-hooks/displayCMSPrintButton.md b/modules/concepts/hooks/list-of-hooks/displayCMSPrintButton.md similarity index 60% rename from modules/concepts/hooks/list-hooks/displayCMSPrintButton.md rename to modules/concepts/hooks/list-of-hooks/displayCMSPrintButton.md index b7e7b82642..8ed6e27cad 100644 --- a/modules/concepts/hooks/list-hooks/displayCMSPrintButton.md +++ b/modules/concepts/hooks/list-of-hooks/displayCMSPrintButton.md @@ -1,22 +1,30 @@ --- menuTitle: displayCMSPrintButton -title: displayCMSPrintButton +Title: displayCMSPrintButton hidden: true +hookTitle: files: - themes/classic/templates/cms/page.tpl -types: +locations: - frontoffice -hookTypes: +types: - smarty --- # Hook : displayCMSPrintButton -Located in : +## Informations + +Hook locations: + - frontoffice + +Hook types: + - smarty +Located in: - themes/classic/templates/cms/page.tpl -## Parameters +## Hook call with parameters ```php {hook h='displayCMSPrintButton'} diff --git a/modules/concepts/hooks/list-of-hooks/displayCarrierExtraContent.md b/modules/concepts/hooks/list-of-hooks/displayCarrierExtraContent.md new file mode 100644 index 0000000000..bb410c4522 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/displayCarrierExtraContent.md @@ -0,0 +1,37 @@ +--- +menuTitle: displayCarrierExtraContent +Title: displayCarrierExtraContent +hidden: true +hookTitle: Display additional content for a carrier (e.g pickup points) +files: + - classes/checkout/DeliveryOptionsFinder.php +locations: + - frontoffice +types: + - legacy +--- + +# Hook : displayCarrierExtraContent + +## Informations + +{{% notice tip %}} +**Display additional content for a carrier (e.g pickup points):** + +This hook calls only the module related to the carrier, in order to add options when needed +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook types: + - legacy + +Located in: + - classes/checkout/DeliveryOptionsFinder.php + +## Hook call with parameters + +```php +Hook::exec('displayCarrierExtraContent', ['carrier' => $carrier], $moduleId); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayCartExtraProductActions.md b/modules/concepts/hooks/list-of-hooks/displayCartExtraProductActions.md similarity index 51% rename from modules/concepts/hooks/list-hooks/displayCartExtraProductActions.md rename to modules/concepts/hooks/list-of-hooks/displayCartExtraProductActions.md index 51a295837d..8118118920 100644 --- a/modules/concepts/hooks/list-hooks/displayCartExtraProductActions.md +++ b/modules/concepts/hooks/list-of-hooks/displayCartExtraProductActions.md @@ -1,22 +1,36 @@ --- menuTitle: displayCartExtraProductActions -title: displayCartExtraProductActions +Title: displayCartExtraProductActions hidden: true +hookTitle: Extra buttons in shopping cart files: - themes/classic/templates/checkout/_partials/cart-detailed-product-line.tpl -types: +locations: - frontoffice -hookTypes: +types: - smarty --- # Hook : displayCartExtraProductActions -Located in : +## Informations + +{{% notice tip %}} +**Extra buttons in shopping cart:** + +This hook adds extra buttons to the product lines, in the shopping cart +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook types: + - smarty +Located in: - themes/classic/templates/checkout/_partials/cart-detailed-product-line.tpl -## Parameters +## Hook call with parameters ```php {hook h='displayCartExtraProductActions' product=$product} diff --git a/modules/concepts/hooks/list-of-hooks/displayCartModalContent.md b/modules/concepts/hooks/list-of-hooks/displayCartModalContent.md new file mode 100644 index 0000000000..7242b0a58d --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/displayCartModalContent.md @@ -0,0 +1,37 @@ +--- +menuTitle: displayCartModalContent +Title: displayCartModalContent +hidden: true +hookTitle: Content of Add-to-cart modal +files: + - themes/classic/modules/ps_shoppingcart/modal.tpl +locations: + - frontoffice +types: + - smarty +--- + +# Hook : displayCartModalContent + +## Informations + +{{% notice tip %}} +**Content of Add-to-cart modal:** + +This hook displays content in the middle of the window that appears after adding product to cart +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook types: + - smarty + +Located in: + - themes/classic/modules/ps_shoppingcart/modal.tpl + +## Hook call with parameters + +```php +{hook h='displayCartModalContent' product=$product} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/displayCartModalFooter.md b/modules/concepts/hooks/list-of-hooks/displayCartModalFooter.md new file mode 100644 index 0000000000..f5621d6c7b --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/displayCartModalFooter.md @@ -0,0 +1,37 @@ +--- +menuTitle: displayCartModalFooter +Title: displayCartModalFooter +hidden: true +hookTitle: Bottom of Add-to-cart modal +files: + - themes/classic/modules/ps_shoppingcart/modal.tpl +locations: + - frontoffice +types: + - smarty +--- + +# Hook : displayCartModalFooter + +## Informations + +{{% notice tip %}} +**Bottom of Add-to-cart modal:** + +This hook displays content in the bottom of window that appears after adding product to cart +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook types: + - smarty + +Located in: + - themes/classic/modules/ps_shoppingcart/modal.tpl + +## Hook call with parameters + +```php +{hook h='displayCartModalFooter' product=$product} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/displayCheckoutBeforeConfirmation.md b/modules/concepts/hooks/list-of-hooks/displayCheckoutBeforeConfirmation.md new file mode 100644 index 0000000000..0f8f0bc084 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/displayCheckoutBeforeConfirmation.md @@ -0,0 +1,37 @@ +--- +menuTitle: displayCheckoutBeforeConfirmation +Title: displayCheckoutBeforeConfirmation +hidden: true +hookTitle: Show custom content before checkout confirmation +files: + - themes/classic/templates/checkout/_partials/steps/payment.tpl +locations: + - frontoffice +types: + - smarty +--- + +# Hook : displayCheckoutBeforeConfirmation + +## Informations + +{{% notice tip %}} +**Show custom content before checkout confirmation:** + +This hook allows you to display custom content at the end of checkout process +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook types: + - smarty + +Located in: + - themes/classic/templates/checkout/_partials/steps/payment.tpl + +## Hook call with parameters + +```php +{hook h='displayCheckoutBeforeConfirmation'} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayCheckoutSubtotalDetails.md b/modules/concepts/hooks/list-of-hooks/displayCheckoutSubtotalDetails.md similarity index 67% rename from modules/concepts/hooks/list-hooks/displayCheckoutSubtotalDetails.md rename to modules/concepts/hooks/list-of-hooks/displayCheckoutSubtotalDetails.md index 7e0dd85e92..fcf838de63 100644 --- a/modules/concepts/hooks/list-hooks/displayCheckoutSubtotalDetails.md +++ b/modules/concepts/hooks/list-of-hooks/displayCheckoutSubtotalDetails.md @@ -1,22 +1,30 @@ --- menuTitle: displayCheckoutSubtotalDetails -title: displayCheckoutSubtotalDetails +Title: displayCheckoutSubtotalDetails hidden: true +hookTitle: files: - themes/classic/templates/checkout/_partials/cart-detailed-totals.tpl -types: +locations: - frontoffice -hookTypes: +types: - smarty --- # Hook : displayCheckoutSubtotalDetails -Located in : +## Informations + +Hook locations: + - frontoffice + +Hook types: + - smarty +Located in: - themes/classic/templates/checkout/_partials/cart-detailed-totals.tpl -## Parameters +## Hook call with parameters ```php {hook h='displayCheckoutSubtotalDetails' subtotal=$subtotal} diff --git a/modules/concepts/hooks/list-hooks/displayCheckoutSummaryTop.md b/modules/concepts/hooks/list-of-hooks/displayCheckoutSummaryTop.md similarity index 50% rename from modules/concepts/hooks/list-hooks/displayCheckoutSummaryTop.md rename to modules/concepts/hooks/list-of-hooks/displayCheckoutSummaryTop.md index f1de9652d5..488d84afaf 100644 --- a/modules/concepts/hooks/list-hooks/displayCheckoutSummaryTop.md +++ b/modules/concepts/hooks/list-of-hooks/displayCheckoutSummaryTop.md @@ -1,22 +1,36 @@ --- menuTitle: displayCheckoutSummaryTop -title: displayCheckoutSummaryTop +Title: displayCheckoutSummaryTop hidden: true +hookTitle: Cart summary top files: - themes/classic/templates/checkout/_partials/cart-summary-top.tpl -types: +locations: - frontoffice -hookTypes: +types: - smarty --- # Hook : displayCheckoutSummaryTop -Located in : +## Informations + +{{% notice tip %}} +**Cart summary top:** + +This hook allows you to display new elements in top of cart summary +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook types: + - smarty +Located in: - themes/classic/templates/checkout/_partials/cart-summary-top.tpl -## Parameters +## Hook call with parameters ```php {hook h='displayCheckoutSummaryTop'} diff --git a/modules/concepts/hooks/list-hooks/displayCrossSellingShoppingCart.md b/modules/concepts/hooks/list-of-hooks/displayCrossSellingShoppingCart.md similarity index 62% rename from modules/concepts/hooks/list-hooks/displayCrossSellingShoppingCart.md rename to modules/concepts/hooks/list-of-hooks/displayCrossSellingShoppingCart.md index 8bf28c3556..341f918c5b 100644 --- a/modules/concepts/hooks/list-hooks/displayCrossSellingShoppingCart.md +++ b/modules/concepts/hooks/list-of-hooks/displayCrossSellingShoppingCart.md @@ -1,22 +1,30 @@ --- menuTitle: displayCrossSellingShoppingCart -title: displayCrossSellingShoppingCart +Title: displayCrossSellingShoppingCart hidden: true +hookTitle: files: - themes/classic/templates/checkout/cart.tpl -types: +locations: - frontoffice -hookTypes: +types: - smarty --- # Hook : displayCrossSellingShoppingCart -Located in : +## Informations + +Hook locations: + - frontoffice + +Hook types: + - smarty +Located in: - themes/classic/templates/checkout/cart.tpl -## Parameters +## Hook call with parameters ```php {hook h='displayCrossSellingShoppingCart'} diff --git a/modules/concepts/hooks/list-of-hooks/displayCustomerAccount.md b/modules/concepts/hooks/list-of-hooks/displayCustomerAccount.md new file mode 100644 index 0000000000..50aeda2c72 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/displayCustomerAccount.md @@ -0,0 +1,37 @@ +--- +menuTitle: displayCustomerAccount +Title: displayCustomerAccount +hidden: true +hookTitle: Customer account displayed in Front Office +files: + - themes/classic/templates/customer/my-account.tpl +locations: + - frontoffice +types: + - smarty +--- + +# Hook : displayCustomerAccount + +## Informations + +{{% notice tip %}} +**Customer account displayed in Front Office:** + +This hook displays new elements on the customer account page +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook types: + - smarty + +Located in: + - themes/classic/templates/customer/my-account.tpl + +## Hook call with parameters + +```php +{hook h='displayCustomerAccount'} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/displayCustomerAccountForm.md b/modules/concepts/hooks/list-of-hooks/displayCustomerAccountForm.md new file mode 100644 index 0000000000..7b1ba8ab8b --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/displayCustomerAccountForm.md @@ -0,0 +1,37 @@ +--- +menuTitle: displayCustomerAccountForm +Title: displayCustomerAccountForm +hidden: true +hookTitle: Customer account creation form +files: + - classes/form/CustomerForm.php +locations: + - frontoffice +types: + - legacy +--- + +# Hook : displayCustomerAccountForm + +## Informations + +{{% notice tip %}} +**Customer account creation form:** + +This hook displays some information on the form to create a customer account +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook types: + - legacy + +Located in: + - classes/form/CustomerForm.php + +## Hook call with parameters + +```php +Hook::exec('displayCustomerAccountForm'), +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/displayCustomerAccountFormTop.md b/modules/concepts/hooks/list-of-hooks/displayCustomerAccountFormTop.md new file mode 100644 index 0000000000..b8adfcd414 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/displayCustomerAccountFormTop.md @@ -0,0 +1,37 @@ +--- +menuTitle: displayCustomerAccountFormTop +Title: displayCustomerAccountFormTop +hidden: true +hookTitle: Block above the form for create an account +files: + - controllers/front/RegistrationController.php +locations: + - frontoffice +types: + - legacy +--- + +# Hook : displayCustomerAccountFormTop + +## Informations + +{{% notice tip %}} +**Block above the form for create an account:** + +This hook is displayed above the customer's account creation form +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook types: + - legacy + +Located in: + - controllers/front/RegistrationController.php + +## Hook call with parameters + +```php +Hook::exec('displayCustomerAccountFormTop'), +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/displayCustomerLoginFormAfter.md b/modules/concepts/hooks/list-of-hooks/displayCustomerLoginFormAfter.md new file mode 100644 index 0000000000..daa0e15964 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/displayCustomerLoginFormAfter.md @@ -0,0 +1,37 @@ +--- +menuTitle: displayCustomerLoginFormAfter +Title: displayCustomerLoginFormAfter +hidden: true +hookTitle: Display elements after login form +files: + - themes/classic/templates/customer/authentication.tpl +locations: + - frontoffice +types: + - smarty +--- + +# Hook : displayCustomerLoginFormAfter + +## Informations + +{{% notice tip %}} +**Display elements after login form:** + +This hook displays new elements after the login form +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook types: + - smarty + +Located in: + - themes/classic/templates/customer/authentication.tpl + +## Hook call with parameters + +```php +{hook h='displayCustomerLoginFormAfter'} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayCustomization.md b/modules/concepts/hooks/list-of-hooks/displayCustomization.md similarity index 62% rename from modules/concepts/hooks/list-hooks/displayCustomization.md rename to modules/concepts/hooks/list-of-hooks/displayCustomization.md index 2138318ee9..9fbd5356c3 100644 --- a/modules/concepts/hooks/list-hooks/displayCustomization.md +++ b/modules/concepts/hooks/list-of-hooks/displayCustomization.md @@ -1,22 +1,30 @@ --- menuTitle: displayCustomization -title: displayCustomization +Title: displayCustomization hidden: true +hookTitle: files: - classes/Product.php -types: +locations: - frontoffice -hookTypes: +types: - legacy --- # Hook : displayCustomization -Located in : +## Informations + +Hook locations: + - frontoffice + +Hook types: + - legacy +Located in: - classes/Product.php -## Parameters +## Hook call with parameters ```php Hook::exec('displayCustomization', ['customization' => $row], (int) $row['id_module']); diff --git a/modules/concepts/hooks/list-of-hooks/displayDashboardToolbarIcons.md b/modules/concepts/hooks/list-of-hooks/displayDashboardToolbarIcons.md new file mode 100644 index 0000000000..5236b1f1ad --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/displayDashboardToolbarIcons.md @@ -0,0 +1,37 @@ +--- +menuTitle: displayDashboardToolbarIcons +Title: displayDashboardToolbarIcons +hidden: true +hookTitle: Display new elements in back office page with dashboard, on icons list +files: + - src/PrestaShopBundle/Resources/views/Admin/Product/CatalogPage/Blocks/tools.html.twig +locations: + - backoffice +types: + - twig +--- + +# Hook : displayDashboardToolbarIcons + +## Informations + +{{% notice tip %}} +**Display new elements in back office page with dashboard, on icons list:** + +This hook launches modules when the back office with dashboard is displayed +{{% /notice %}} + +Hook locations: + - backoffice + +Hook types: + - twig + +Located in: + - src/PrestaShopBundle/Resources/views/Admin/Product/CatalogPage/Blocks/tools.html.twig + +## Hook call with parameters + +```php +{{ renderhook('displayDashboardToolbarIcons', {}) }} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/displayDashboardToolbarTopMenu.md b/modules/concepts/hooks/list-of-hooks/displayDashboardToolbarTopMenu.md new file mode 100644 index 0000000000..51dfc2fda4 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/displayDashboardToolbarTopMenu.md @@ -0,0 +1,37 @@ +--- +menuTitle: displayDashboardToolbarTopMenu +Title: displayDashboardToolbarTopMenu +hidden: true +hookTitle: Display new elements in back office page with a dashboard, on top Menu +files: + - admin784x07v4swfhm9fgvc0/themes/new-theme/template/page_header_toolbar.tpl +locations: + - frontoffice +types: + - smarty +--- + +# Hook : displayDashboardToolbarTopMenu + +## Informations + +{{% notice tip %}} +**Display new elements in back office page with a dashboard, on top Menu:** + +This hook launches modules when a page with a dashboard is displayed +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook types: + - smarty + +Located in: + - admin784x07v4swfhm9fgvc0/themes/new-theme/template/page_header_toolbar.tpl + +## Hook call with parameters + +```php +{hook h='displayDashboardToolbarTopMenu'} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayDashboardTop.md b/modules/concepts/hooks/list-of-hooks/displayDashboardTop.md similarity index 53% rename from modules/concepts/hooks/list-hooks/displayDashboardTop.md rename to modules/concepts/hooks/list-of-hooks/displayDashboardTop.md index 68da7fc7d3..806db695ca 100644 --- a/modules/concepts/hooks/list-hooks/displayDashboardTop.md +++ b/modules/concepts/hooks/list-of-hooks/displayDashboardTop.md @@ -1,22 +1,36 @@ --- menuTitle: displayDashboardTop -title: displayDashboardTop +Title: displayDashboardTop hidden: true +hookTitle: Dashboard Top files: - admin784x07v4swfhm9fgvc0/themes/new-theme/template/page_header_toolbar.tpl -types: +locations: - frontoffice -hookTypes: +types: - smarty --- # Hook : displayDashboardTop -Located in : +## Informations + +{{% notice tip %}} +**Dashboard Top:** + +Displays the content in the dashboard's top area +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook types: + - smarty +Located in: - admin784x07v4swfhm9fgvc0/themes/new-theme/template/page_header_toolbar.tpl -## Parameters +## Hook call with parameters ```php {hook h='displayDashboardTop'} diff --git a/modules/concepts/hooks/list-of-hooks/displayEmptyModuleCategoryExtraMessage.md b/modules/concepts/hooks/list-of-hooks/displayEmptyModuleCategoryExtraMessage.md new file mode 100644 index 0000000000..5f43d50463 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/displayEmptyModuleCategoryExtraMessage.md @@ -0,0 +1,37 @@ +--- +menuTitle: displayEmptyModuleCategoryExtraMessage +Title: displayEmptyModuleCategoryExtraMessage +hidden: true +hookTitle: Extra message to display for an empty modules category +files: + - src/PrestaShopBundle/Resources/views/Admin/Module/Includes/grid_manage_empty.html.twig +locations: + - backoffice +types: + - twig +--- + +# Hook : displayEmptyModuleCategoryExtraMessage + +## Informations + +{{% notice tip %}} +**Extra message to display for an empty modules category:** + +This hook allows to add an extra message to display in the Module manager page when a category doesn't have any module +{{% /notice %}} + +Hook locations: + - backoffice + +Hook types: + - twig + +Located in: + - src/PrestaShopBundle/Resources/views/Admin/Module/Includes/grid_manage_empty.html.twig + +## Hook call with parameters + +```php +{{ renderhook('displayEmptyModuleCategoryExtraMessage', {'category_name': category.name}) }} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayExpressCheckout.md b/modules/concepts/hooks/list-of-hooks/displayExpressCheckout.md similarity index 65% rename from modules/concepts/hooks/list-hooks/displayExpressCheckout.md rename to modules/concepts/hooks/list-of-hooks/displayExpressCheckout.md index 5c760ee734..eb19926e80 100644 --- a/modules/concepts/hooks/list-hooks/displayExpressCheckout.md +++ b/modules/concepts/hooks/list-of-hooks/displayExpressCheckout.md @@ -1,22 +1,30 @@ --- menuTitle: displayExpressCheckout -title: displayExpressCheckout +Title: displayExpressCheckout hidden: true +hookTitle: files: - themes/classic/templates/checkout/_partials/cart-detailed-actions.tpl -types: +locations: - frontoffice -hookTypes: +types: - smarty --- # Hook : displayExpressCheckout -Located in : +## Informations + +Hook locations: + - frontoffice + +Hook types: + - smarty +Located in: - themes/classic/templates/checkout/_partials/cart-detailed-actions.tpl -## Parameters +## Hook call with parameters ```php {hook h='displayExpressCheckout'} diff --git a/modules/concepts/hooks/list-hooks/displayFeatureForm.md b/modules/concepts/hooks/list-of-hooks/displayFeatureForm.md similarity index 54% rename from modules/concepts/hooks/list-hooks/displayFeatureForm.md rename to modules/concepts/hooks/list-of-hooks/displayFeatureForm.md index ce80af5abc..dfe9052609 100644 --- a/modules/concepts/hooks/list-hooks/displayFeatureForm.md +++ b/modules/concepts/hooks/list-of-hooks/displayFeatureForm.md @@ -1,22 +1,36 @@ --- menuTitle: displayFeatureForm -title: displayFeatureForm +Title: displayFeatureForm hidden: true +hookTitle: Add fields to the form 'feature' files: - src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Features/Blocks/form.html.twig -types: +locations: - backoffice -hookTypes: +types: - twig --- # Hook : displayFeatureForm -Located in : +## Informations + +{{% notice tip %}} +**Add fields to the form 'feature':** + +This hook adds fields to the form 'feature' +{{% /notice %}} + +Hook locations: + - backoffice + +Hook types: + - twig +Located in: - src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Features/Blocks/form.html.twig -## Parameters +## Hook call with parameters ```php {{ renderhook('displayFeatureForm', {'id_feature': featureId}) }} diff --git a/modules/concepts/hooks/list-of-hooks/displayFooter.md b/modules/concepts/hooks/list-of-hooks/displayFooter.md new file mode 100644 index 0000000000..2971cc303e --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/displayFooter.md @@ -0,0 +1,37 @@ +--- +menuTitle: displayFooter +Title: displayFooter +hidden: true +hookTitle: Footer +files: + - themes/classic/templates/_partials/footer.tpl +locations: + - frontoffice +types: + - smarty +--- + +# Hook : displayFooter + +## Informations + +{{% notice tip %}} +**Footer:** + +This hook displays new blocks in the footer +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook types: + - smarty + +Located in: + - themes/classic/templates/_partials/footer.tpl + +## Hook call with parameters + +```php +{hook h='displayFooter'} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayFooterAfter.md b/modules/concepts/hooks/list-of-hooks/displayFooterAfter.md similarity index 61% rename from modules/concepts/hooks/list-hooks/displayFooterAfter.md rename to modules/concepts/hooks/list-of-hooks/displayFooterAfter.md index aace9834f8..d2d5a7a1c9 100644 --- a/modules/concepts/hooks/list-hooks/displayFooterAfter.md +++ b/modules/concepts/hooks/list-of-hooks/displayFooterAfter.md @@ -1,22 +1,30 @@ --- menuTitle: displayFooterAfter -title: displayFooterAfter +Title: displayFooterAfter hidden: true +hookTitle: files: - themes/classic/templates/_partials/footer.tpl -types: +locations: - frontoffice -hookTypes: +types: - smarty --- # Hook : displayFooterAfter -Located in : +## Informations + +Hook locations: + - frontoffice + +Hook types: + - smarty +Located in: - themes/classic/templates/_partials/footer.tpl -## Parameters +## Hook call with parameters ```php {hook h='displayFooterAfter'} diff --git a/modules/concepts/hooks/list-hooks/displayFooterBefore.md b/modules/concepts/hooks/list-of-hooks/displayFooterBefore.md similarity index 61% rename from modules/concepts/hooks/list-hooks/displayFooterBefore.md rename to modules/concepts/hooks/list-of-hooks/displayFooterBefore.md index 908d4cc8cd..7c7e38a4c8 100644 --- a/modules/concepts/hooks/list-hooks/displayFooterBefore.md +++ b/modules/concepts/hooks/list-of-hooks/displayFooterBefore.md @@ -1,22 +1,30 @@ --- menuTitle: displayFooterBefore -title: displayFooterBefore +Title: displayFooterBefore hidden: true +hookTitle: files: - themes/classic/templates/_partials/footer.tpl -types: +locations: - frontoffice -hookTypes: +types: - smarty --- # Hook : displayFooterBefore -Located in : +## Informations + +Hook locations: + - frontoffice + +Hook types: + - smarty +Located in: - themes/classic/templates/_partials/footer.tpl -## Parameters +## Hook call with parameters ```php {hook h='displayFooterBefore'} diff --git a/modules/concepts/hooks/list-hooks/displayFooterProduct.md b/modules/concepts/hooks/list-of-hooks/displayFooterProduct.md similarity index 50% rename from modules/concepts/hooks/list-hooks/displayFooterProduct.md rename to modules/concepts/hooks/list-of-hooks/displayFooterProduct.md index 42beb20d96..4b49d61bf6 100644 --- a/modules/concepts/hooks/list-hooks/displayFooterProduct.md +++ b/modules/concepts/hooks/list-of-hooks/displayFooterProduct.md @@ -1,22 +1,36 @@ --- menuTitle: displayFooterProduct -title: displayFooterProduct +Title: displayFooterProduct hidden: true +hookTitle: Product footer files: - themes/classic/templates/catalog/product.tpl -types: +locations: - frontoffice -hookTypes: +types: - smarty --- # Hook : displayFooterProduct -Located in : +## Informations + +{{% notice tip %}} +**Product footer:** + +This hook adds new blocks under the product's description +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook types: + - smarty +Located in: - themes/classic/templates/catalog/product.tpl -## Parameters +## Hook call with parameters ```php {hook h='displayFooterProduct' product=$product category=$category} diff --git a/modules/concepts/hooks/list-hooks/displayGDPRConsent.md b/modules/concepts/hooks/list-of-hooks/displayGDPRConsent.md similarity index 69% rename from modules/concepts/hooks/list-hooks/displayGDPRConsent.md rename to modules/concepts/hooks/list-of-hooks/displayGDPRConsent.md index 3169ffe066..f067f453bf 100644 --- a/modules/concepts/hooks/list-hooks/displayGDPRConsent.md +++ b/modules/concepts/hooks/list-of-hooks/displayGDPRConsent.md @@ -1,22 +1,30 @@ --- menuTitle: displayGDPRConsent -title: displayGDPRConsent +Title: displayGDPRConsent hidden: true +hookTitle: files: - themes/classic/modules/ps_emailsubscription/views/templates/hook/ps_emailsubscription.tpl -types: +locations: - frontoffice -hookTypes: +types: - smarty --- # Hook : displayGDPRConsent -Located in : +## Informations + +Hook locations: + - frontoffice + +Hook types: + - smarty +Located in: - themes/classic/modules/ps_emailsubscription/views/templates/hook/ps_emailsubscription.tpl -## Parameters +## Hook call with parameters ```php {hook h='displayGDPRConsent' id_module=$id_module} diff --git a/modules/concepts/hooks/list-of-hooks/displayHeader.md b/modules/concepts/hooks/list-of-hooks/displayHeader.md new file mode 100644 index 0000000000..b1ff3eb305 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/displayHeader.md @@ -0,0 +1,37 @@ +--- +menuTitle: displayHeader +Title: displayHeader +hidden: true +hookTitle: Pages html head section +files: + - classes/controller/FrontController.php +locations: + - frontoffice +types: + - legacy +--- + +# Hook : displayHeader + +## Informations + +{{% notice tip %}} +**Pages html head section:** + +This hook adds additional elements in the head section of your pages (head section of html) +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook types: + - legacy + +Located in: + - classes/controller/FrontController.php + +## Hook call with parameters + +```php +Hook::exec('displayHeader'), +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/displayHome.md b/modules/concepts/hooks/list-of-hooks/displayHome.md new file mode 100644 index 0000000000..3b3e7ef481 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/displayHome.md @@ -0,0 +1,37 @@ +--- +menuTitle: displayHome +Title: displayHome +hidden: true +hookTitle: Homepage content +files: + - controllers/front/IndexController.php +locations: + - frontoffice +types: + - legacy +--- + +# Hook : displayHome + +## Informations + +{{% notice tip %}} +**Homepage content:** + +This hook displays new elements on the homepage +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook types: + - legacy + +Located in: + - controllers/front/IndexController.php + +## Hook call with parameters + +```php +Hook::exec('displayHome'), +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/displayInvoiceLegalFreeText.md b/modules/concepts/hooks/list-of-hooks/displayInvoiceLegalFreeText.md new file mode 100644 index 0000000000..5ec044a739 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/displayInvoiceLegalFreeText.md @@ -0,0 +1,37 @@ +--- +menuTitle: displayInvoiceLegalFreeText +Title: displayInvoiceLegalFreeText +hidden: true +hookTitle: PDF Invoice - Legal Free Text +files: + - classes/pdf/HTMLTemplateInvoice.php +locations: + - frontoffice +types: + - legacy +--- + +# Hook : displayInvoiceLegalFreeText + +## Informations + +{{% notice tip %}} +**PDF Invoice - Legal Free Text:** + +This hook allows you to modify the legal free text on PDF invoices +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook types: + - legacy + +Located in: + - classes/pdf/HTMLTemplateInvoice.php + +## Hook call with parameters + +```php +Hook::exec('displayInvoiceLegalFreeText', ['order' => $this->order]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/displayLeftColumnProduct.md b/modules/concepts/hooks/list-of-hooks/displayLeftColumnProduct.md new file mode 100644 index 0000000000..f89a8feb60 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/displayLeftColumnProduct.md @@ -0,0 +1,37 @@ +--- +menuTitle: displayLeftColumnProduct +Title: displayLeftColumnProduct +hidden: true +hookTitle: New elements on the product page (left column) +files: + - themes/classic/templates/layouts/layout-both-columns.tpl +locations: + - frontoffice +types: + - smarty +--- + +# Hook : displayLeftColumnProduct + +## Informations + +{{% notice tip %}} +**New elements on the product page (left column):** + +This hook displays new elements in the left-hand column of the product page +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook types: + - smarty + +Located in: + - themes/classic/templates/layouts/layout-both-columns.tpl + +## Hook call with parameters + +```php +{hook h='displayLeftColumnProduct' product=$product category=$category} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/displayMaintenance.md b/modules/concepts/hooks/list-of-hooks/displayMaintenance.md new file mode 100644 index 0000000000..bdcd98a94d --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/displayMaintenance.md @@ -0,0 +1,37 @@ +--- +menuTitle: displayMaintenance +Title: displayMaintenance +hidden: true +hookTitle: Maintenance Page +files: + - classes/controller/FrontController.php +locations: + - frontoffice +types: + - legacy +--- + +# Hook : displayMaintenance + +## Informations + +{{% notice tip %}} +**Maintenance Page:** + +This hook displays new elements on the maintenance page +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook types: + - legacy + +Located in: + - classes/controller/FrontController.php + +## Hook call with parameters + +```php +Hook::exec('displayMaintenance', []), +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayMyAccountBlock.md b/modules/concepts/hooks/list-of-hooks/displayMyAccountBlock.md similarity index 51% rename from modules/concepts/hooks/list-hooks/displayMyAccountBlock.md rename to modules/concepts/hooks/list-of-hooks/displayMyAccountBlock.md index 0494fdd636..be77a98239 100644 --- a/modules/concepts/hooks/list-hooks/displayMyAccountBlock.md +++ b/modules/concepts/hooks/list-of-hooks/displayMyAccountBlock.md @@ -1,22 +1,36 @@ --- menuTitle: displayMyAccountBlock -title: displayMyAccountBlock +Title: displayMyAccountBlock hidden: true +hookTitle: My account block files: - themes/classic/modules/ps_customeraccountlinks/ps_customeraccountlinks.tpl -types: +locations: - frontoffice -hookTypes: +types: - smarty --- # Hook : displayMyAccountBlock -Located in : +## Informations + +{{% notice tip %}} +**My account block:** + +This hook displays extra information within the 'my account' block" +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook types: + - smarty +Located in: - themes/classic/modules/ps_customeraccountlinks/ps_customeraccountlinks.tpl -## Parameters +## Hook call with parameters ```php {hook h='displayMyAccountBlock'} diff --git a/modules/concepts/hooks/list-hooks/displayNav1.md b/modules/concepts/hooks/list-of-hooks/displayNav1.md similarity index 62% rename from modules/concepts/hooks/list-hooks/displayNav1.md rename to modules/concepts/hooks/list-of-hooks/displayNav1.md index f4eae36650..04a2606162 100644 --- a/modules/concepts/hooks/list-hooks/displayNav1.md +++ b/modules/concepts/hooks/list-of-hooks/displayNav1.md @@ -1,22 +1,30 @@ --- menuTitle: displayNav1 -title: displayNav1 +Title: displayNav1 hidden: true +hookTitle: files: - themes/classic/templates/checkout/_partials/header.tpl -types: +locations: - frontoffice -hookTypes: +types: - smarty --- # Hook : displayNav1 -Located in : +## Informations + +Hook locations: + - frontoffice + +Hook types: + - smarty +Located in: - themes/classic/templates/checkout/_partials/header.tpl -## Parameters +## Hook call with parameters ```php {hook h='displayNav1'} diff --git a/modules/concepts/hooks/list-hooks/displayNav2.md b/modules/concepts/hooks/list-of-hooks/displayNav2.md similarity index 62% rename from modules/concepts/hooks/list-hooks/displayNav2.md rename to modules/concepts/hooks/list-of-hooks/displayNav2.md index 7a25c4bbcc..ade34a66db 100644 --- a/modules/concepts/hooks/list-hooks/displayNav2.md +++ b/modules/concepts/hooks/list-of-hooks/displayNav2.md @@ -1,22 +1,30 @@ --- menuTitle: displayNav2 -title: displayNav2 +Title: displayNav2 hidden: true +hookTitle: files: - themes/classic/templates/checkout/_partials/header.tpl -types: +locations: - frontoffice -hookTypes: +types: - smarty --- # Hook : displayNav2 -Located in : +## Informations + +Hook locations: + - frontoffice + +Hook types: + - smarty +Located in: - themes/classic/templates/checkout/_partials/header.tpl -## Parameters +## Hook call with parameters ```php {hook h='displayNav2'} diff --git a/modules/concepts/hooks/list-of-hooks/displayNavFullWidth.md b/modules/concepts/hooks/list-of-hooks/displayNavFullWidth.md new file mode 100644 index 0000000000..0b513cb165 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/displayNavFullWidth.md @@ -0,0 +1,37 @@ +--- +menuTitle: displayNavFullWidth +Title: displayNavFullWidth +hidden: true +hookTitle: Navigation +files: + - themes/classic/templates/checkout/_partials/header.tpl +locations: + - frontoffice +types: + - smarty +--- + +# Hook : displayNavFullWidth + +## Informations + +{{% notice tip %}} +**Navigation:** + +This hook displays full width navigation menu at the top of your pages +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook types: + - smarty + +Located in: + - themes/classic/templates/checkout/_partials/header.tpl + +## Hook call with parameters + +```php +{hook h='displayNavFullWidth'} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayNewsletterRegistration.md b/modules/concepts/hooks/list-of-hooks/displayNewsletterRegistration.md similarity index 68% rename from modules/concepts/hooks/list-hooks/displayNewsletterRegistration.md rename to modules/concepts/hooks/list-of-hooks/displayNewsletterRegistration.md index d9d880d901..dee9c4c657 100644 --- a/modules/concepts/hooks/list-hooks/displayNewsletterRegistration.md +++ b/modules/concepts/hooks/list-of-hooks/displayNewsletterRegistration.md @@ -1,22 +1,30 @@ --- menuTitle: displayNewsletterRegistration -title: displayNewsletterRegistration +Title: displayNewsletterRegistration hidden: true +hookTitle: files: - themes/classic/modules/ps_emailsubscription/views/templates/hook/ps_emailsubscription.tpl -types: +locations: - frontoffice -hookTypes: +types: - smarty --- # Hook : displayNewsletterRegistration -Located in : +## Informations + +Hook locations: + - frontoffice + +Hook types: + - smarty +Located in: - themes/classic/modules/ps_emailsubscription/views/templates/hook/ps_emailsubscription.tpl -## Parameters +## Hook call with parameters ```php {hook h='displayNewsletterRegistration'} diff --git a/modules/concepts/hooks/list-hooks/displayNotFound.md b/modules/concepts/hooks/list-of-hooks/displayNotFound.md similarity index 61% rename from modules/concepts/hooks/list-hooks/displayNotFound.md rename to modules/concepts/hooks/list-of-hooks/displayNotFound.md index 034bb78d76..9806553834 100644 --- a/modules/concepts/hooks/list-hooks/displayNotFound.md +++ b/modules/concepts/hooks/list-of-hooks/displayNotFound.md @@ -1,22 +1,30 @@ --- menuTitle: displayNotFound -title: displayNotFound +Title: displayNotFound hidden: true +hookTitle: files: - themes/classic/templates/errors/not-found.tpl -types: +locations: - frontoffice -hookTypes: +types: - smarty --- # Hook : displayNotFound -Located in : +## Informations + +Hook locations: + - frontoffice + +Hook types: + - smarty +Located in: - themes/classic/templates/errors/not-found.tpl -## Parameters +## Hook call with parameters ```php {hook h='displayNotFound'} diff --git a/modules/concepts/hooks/list-of-hooks/displayOrderConfirmation.md b/modules/concepts/hooks/list-of-hooks/displayOrderConfirmation.md new file mode 100644 index 0000000000..5f1bd5378d --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/displayOrderConfirmation.md @@ -0,0 +1,37 @@ +--- +menuTitle: displayOrderConfirmation +Title: displayOrderConfirmation +hidden: true +hookTitle: Order confirmation page +files: + - controllers/front/OrderConfirmationController.php +locations: + - frontoffice +types: + - legacy +--- + +# Hook : displayOrderConfirmation + +## Informations + +{{% notice tip %}} +**Order confirmation page:** + +This hook is called within an order's confirmation page +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook types: + - legacy + +Located in: + - controllers/front/OrderConfirmationController.php + +## Hook call with parameters + +```php +Hook::exec('displayOrderConfirmation', ['order' => $order]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayOrderConfirmation1.md b/modules/concepts/hooks/list-of-hooks/displayOrderConfirmation1.md similarity index 64% rename from modules/concepts/hooks/list-hooks/displayOrderConfirmation1.md rename to modules/concepts/hooks/list-of-hooks/displayOrderConfirmation1.md index 0037459364..15749829f0 100644 --- a/modules/concepts/hooks/list-hooks/displayOrderConfirmation1.md +++ b/modules/concepts/hooks/list-of-hooks/displayOrderConfirmation1.md @@ -1,22 +1,30 @@ --- menuTitle: displayOrderConfirmation1 -title: displayOrderConfirmation1 +Title: displayOrderConfirmation1 hidden: true +hookTitle: files: - themes/classic/templates/checkout/order-confirmation.tpl -types: +locations: - frontoffice -hookTypes: +types: - smarty --- # Hook : displayOrderConfirmation1 -Located in : +## Informations + +Hook locations: + - frontoffice + +Hook types: + - smarty +Located in: - themes/classic/templates/checkout/order-confirmation.tpl -## Parameters +## Hook call with parameters ```php {hook h='displayOrderConfirmation1'} diff --git a/modules/concepts/hooks/list-hooks/displayOrderConfirmation2.md b/modules/concepts/hooks/list-of-hooks/displayOrderConfirmation2.md similarity index 64% rename from modules/concepts/hooks/list-hooks/displayOrderConfirmation2.md rename to modules/concepts/hooks/list-of-hooks/displayOrderConfirmation2.md index 2c220f4bf7..52c1505195 100644 --- a/modules/concepts/hooks/list-hooks/displayOrderConfirmation2.md +++ b/modules/concepts/hooks/list-of-hooks/displayOrderConfirmation2.md @@ -1,22 +1,30 @@ --- menuTitle: displayOrderConfirmation2 -title: displayOrderConfirmation2 +Title: displayOrderConfirmation2 hidden: true +hookTitle: files: - themes/classic/templates/checkout/order-confirmation.tpl -types: +locations: - frontoffice -hookTypes: +types: - smarty --- # Hook : displayOrderConfirmation2 -Located in : +## Informations + +Hook locations: + - frontoffice + +Hook types: + - smarty +Located in: - themes/classic/templates/checkout/order-confirmation.tpl -## Parameters +## Hook call with parameters ```php {hook h='displayOrderConfirmation2'} diff --git a/modules/concepts/hooks/list-of-hooks/displayOrderDetail.md b/modules/concepts/hooks/list-of-hooks/displayOrderDetail.md new file mode 100644 index 0000000000..04adfd615e --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/displayOrderDetail.md @@ -0,0 +1,37 @@ +--- +menuTitle: displayOrderDetail +Title: displayOrderDetail +hidden: true +hookTitle: Order detail +files: + - controllers/front/OrderDetailController.php +locations: + - frontoffice +types: + - legacy +--- + +# Hook : displayOrderDetail + +## Informations + +{{% notice tip %}} +**Order detail:** + +This hook is displayed within the order's details in Front Office +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook types: + - legacy + +Located in: + - controllers/front/OrderDetailController.php + +## Hook call with parameters + +```php +Hook::exec('displayOrderDetail', ['order' => $order]), +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayOrderPreview.md b/modules/concepts/hooks/list-of-hooks/displayOrderPreview.md similarity index 68% rename from modules/concepts/hooks/list-hooks/displayOrderPreview.md rename to modules/concepts/hooks/list-of-hooks/displayOrderPreview.md index 671696452e..caeb0b7ff4 100644 --- a/modules/concepts/hooks/list-hooks/displayOrderPreview.md +++ b/modules/concepts/hooks/list-of-hooks/displayOrderPreview.md @@ -1,22 +1,30 @@ --- menuTitle: displayOrderPreview -title: displayOrderPreview +Title: displayOrderPreview hidden: true +hookTitle: files: - src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/preview.html.twig -types: +locations: - backoffice -hookTypes: +types: - twig --- # Hook : displayOrderPreview -Located in : +## Informations + +Hook locations: + - backoffice + +Hook types: + - twig +Located in: - src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/preview.html.twig -## Parameters +## Hook call with parameters ```php {{ renderhook('displayOrderPreview', {'order_id': orderId}) }} diff --git a/modules/concepts/hooks/list-of-hooks/displayPaymentByBinaries.md b/modules/concepts/hooks/list-of-hooks/displayPaymentByBinaries.md new file mode 100644 index 0000000000..0a42cd1b6d --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/displayPaymentByBinaries.md @@ -0,0 +1,37 @@ +--- +menuTitle: displayPaymentByBinaries +Title: displayPaymentByBinaries +hidden: true +hookTitle: Payment form generated by binaries +files: + - themes/classic/templates/checkout/_partials/steps/payment.tpl +locations: + - frontoffice +types: + - smarty +--- + +# Hook : displayPaymentByBinaries + +## Informations + +{{% notice tip %}} +**Payment form generated by binaries:** + +This hook displays form generated by binaries during the checkout +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook types: + - smarty + +Located in: + - themes/classic/templates/checkout/_partials/steps/payment.tpl + +## Hook call with parameters + +```php +{hook h='displayPaymentByBinaries'} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayPaymentReturn.md b/modules/concepts/hooks/list-of-hooks/displayPaymentReturn.md similarity index 57% rename from modules/concepts/hooks/list-hooks/displayPaymentReturn.md rename to modules/concepts/hooks/list-of-hooks/displayPaymentReturn.md index bd87f39618..6f2090d3d1 100644 --- a/modules/concepts/hooks/list-hooks/displayPaymentReturn.md +++ b/modules/concepts/hooks/list-of-hooks/displayPaymentReturn.md @@ -1,22 +1,36 @@ --- menuTitle: displayPaymentReturn -title: displayPaymentReturn +Title: displayPaymentReturn hidden: true +hookTitle: Payment return files: - controllers/front/OrderConfirmationController.php -types: +locations: - frontoffice -hookTypes: +types: - legacy --- # Hook : displayPaymentReturn -Located in : +## Informations + +{{% notice tip %}} +**Payment return:** + + +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook types: + - legacy +Located in: - controllers/front/OrderConfirmationController.php -## Parameters +## Hook call with parameters ```php Hook::exec('displayPaymentReturn', ['order' => $order], $this->id_module); diff --git a/modules/concepts/hooks/list-of-hooks/displayPaymentTop.md b/modules/concepts/hooks/list-of-hooks/displayPaymentTop.md new file mode 100644 index 0000000000..6fbf36caf7 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/displayPaymentTop.md @@ -0,0 +1,37 @@ +--- +menuTitle: displayPaymentTop +Title: displayPaymentTop +hidden: true +hookTitle: Top of payment page +files: + - themes/classic/templates/checkout/_partials/steps/payment.tpl +locations: + - frontoffice +types: + - smarty +--- + +# Hook : displayPaymentTop + +## Informations + +{{% notice tip %}} +**Top of payment page:** + +This hook is displayed at the top of the payment page +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook types: + - smarty + +Located in: + - themes/classic/templates/checkout/_partials/steps/payment.tpl + +## Hook call with parameters + +```php +{hook h='displayPaymentTop'} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/displayPersonalInformationTop.md b/modules/concepts/hooks/list-of-hooks/displayPersonalInformationTop.md new file mode 100644 index 0000000000..50fd3391b7 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/displayPersonalInformationTop.md @@ -0,0 +1,37 @@ +--- +menuTitle: displayPersonalInformationTop +Title: displayPersonalInformationTop +hidden: true +hookTitle: Content in the checkout funnel, on top of the personal information panel +files: + - themes/classic/templates/checkout/_partials/steps/personal-information.tpl +locations: + - frontoffice +types: + - smarty +--- + +# Hook : displayPersonalInformationTop + +## Informations + +{{% notice tip %}} +**Content in the checkout funnel, on top of the personal information panel:** + +Display actions or additional content in the personal details tab of the checkout funnel. +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook types: + - smarty + +Located in: + - themes/classic/templates/checkout/_partials/steps/personal-information.tpl + +## Hook call with parameters + +```php +{hook h='displayPersonalInformationTop' customer=$customer} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/displayProductActions.md b/modules/concepts/hooks/list-of-hooks/displayProductActions.md new file mode 100644 index 0000000000..3a487b7bfd --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/displayProductActions.md @@ -0,0 +1,37 @@ +--- +menuTitle: displayProductActions +Title: displayProductActions +hidden: true +hookTitle: Display additional action button on the product page +files: + - themes/classic/templates/catalog/_partials/product-add-to-cart.tpl +locations: + - frontoffice +types: + - smarty +--- + +# Hook : displayProductActions + +## Informations + +{{% notice tip %}} +**Display additional action button on the product page:** + +This hook allow additional actions to be triggered, near the add to cart button. +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook types: + - smarty + +Located in: + - themes/classic/templates/catalog/_partials/product-add-to-cart.tpl + +## Hook call with parameters + +```php +{hook h='displayProductActions' product=$product} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displayProductAdditionalInfo.md b/modules/concepts/hooks/list-of-hooks/displayProductAdditionalInfo.md similarity index 50% rename from modules/concepts/hooks/list-hooks/displayProductAdditionalInfo.md rename to modules/concepts/hooks/list-of-hooks/displayProductAdditionalInfo.md index 12ee0e4ff1..7e9438fb31 100644 --- a/modules/concepts/hooks/list-hooks/displayProductAdditionalInfo.md +++ b/modules/concepts/hooks/list-of-hooks/displayProductAdditionalInfo.md @@ -1,22 +1,36 @@ --- menuTitle: displayProductAdditionalInfo -title: displayProductAdditionalInfo +Title: displayProductAdditionalInfo hidden: true +hookTitle: Product page additional info files: - themes/classic/templates/catalog/_partials/quickview.tpl -types: +locations: - frontoffice -hookTypes: +types: - smarty --- # Hook : displayProductAdditionalInfo -Located in : +## Informations + +{{% notice tip %}} +**Product page additional info:** + +This hook adds additional information on the product page +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook types: + - smarty +Located in: - themes/classic/templates/catalog/_partials/quickview.tpl -## Parameters +## Hook call with parameters ```php {hook h='displayProductAdditionalInfo' product=$product} diff --git a/modules/concepts/hooks/list-hooks/displayProductListReviews.md b/modules/concepts/hooks/list-of-hooks/displayProductListReviews.md similarity index 66% rename from modules/concepts/hooks/list-hooks/displayProductListReviews.md rename to modules/concepts/hooks/list-of-hooks/displayProductListReviews.md index 4f49173e04..fc10875e18 100644 --- a/modules/concepts/hooks/list-hooks/displayProductListReviews.md +++ b/modules/concepts/hooks/list-of-hooks/displayProductListReviews.md @@ -1,22 +1,30 @@ --- menuTitle: displayProductListReviews -title: displayProductListReviews +Title: displayProductListReviews hidden: true +hookTitle: files: - themes/classic/templates/catalog/_partials/miniatures/product.tpl -types: +locations: - frontoffice -hookTypes: +types: - smarty --- # Hook : displayProductListReviews -Located in : +## Informations + +Hook locations: + - frontoffice + +Hook types: + - smarty +Located in: - themes/classic/templates/catalog/_partials/miniatures/product.tpl -## Parameters +## Hook call with parameters ```php {hook h='displayProductListReviews' product=$product} diff --git a/modules/concepts/hooks/list-hooks/displayProductPriceBlock.md b/modules/concepts/hooks/list-of-hooks/displayProductPriceBlock.md similarity index 68% rename from modules/concepts/hooks/list-hooks/displayProductPriceBlock.md rename to modules/concepts/hooks/list-of-hooks/displayProductPriceBlock.md index e7beb5e34b..85b7819732 100644 --- a/modules/concepts/hooks/list-hooks/displayProductPriceBlock.md +++ b/modules/concepts/hooks/list-of-hooks/displayProductPriceBlock.md @@ -1,22 +1,30 @@ --- menuTitle: displayProductPriceBlock -title: displayProductPriceBlock +Title: displayProductPriceBlock hidden: true +hookTitle: files: - themes/classic/templates/checkout/_partials/order-confirmation-table.tpl -types: +locations: - frontoffice -hookTypes: +types: - smarty --- # Hook : displayProductPriceBlock -Located in : +## Informations + +Hook locations: + - frontoffice + +Hook types: + - smarty +Located in: - themes/classic/templates/checkout/_partials/order-confirmation-table.tpl -## Parameters +## Hook call with parameters ```php {hook h='displayProductPriceBlock' product=$product type="unit_price"} diff --git a/modules/concepts/hooks/list-hooks/displayReassurance.md b/modules/concepts/hooks/list-of-hooks/displayReassurance.md similarity index 61% rename from modules/concepts/hooks/list-hooks/displayReassurance.md rename to modules/concepts/hooks/list-of-hooks/displayReassurance.md index 86b2128a87..be2f7cad59 100644 --- a/modules/concepts/hooks/list-hooks/displayReassurance.md +++ b/modules/concepts/hooks/list-of-hooks/displayReassurance.md @@ -1,22 +1,30 @@ --- menuTitle: displayReassurance -title: displayReassurance +Title: displayReassurance hidden: true +hookTitle: files: - themes/classic/templates/checkout/checkout.tpl -types: +locations: - frontoffice -hookTypes: +types: - smarty --- # Hook : displayReassurance -Located in : +## Informations + +Hook locations: + - frontoffice + +Hook types: + - smarty +Located in: - themes/classic/templates/checkout/checkout.tpl -## Parameters +## Hook call with parameters ```php {hook h='displayReassurance'} diff --git a/modules/concepts/hooks/list-of-hooks/displayRightColumnProduct.md b/modules/concepts/hooks/list-of-hooks/displayRightColumnProduct.md new file mode 100644 index 0000000000..e3d557564b --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/displayRightColumnProduct.md @@ -0,0 +1,37 @@ +--- +menuTitle: displayRightColumnProduct +Title: displayRightColumnProduct +hidden: true +hookTitle: New elements on the product page (right column) +files: + - themes/classic/templates/layouts/layout-both-columns.tpl +locations: + - frontoffice +types: + - smarty +--- + +# Hook : displayRightColumnProduct + +## Informations + +{{% notice tip %}} +**New elements on the product page (right column):** + +This hook displays new elements in the right-hand column of the product page +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook types: + - smarty + +Located in: + - themes/classic/templates/layouts/layout-both-columns.tpl + +## Hook call with parameters + +```php +{hook h='displayRightColumnProduct'} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/displaySearch.md b/modules/concepts/hooks/list-of-hooks/displaySearch.md similarity index 60% rename from modules/concepts/hooks/list-hooks/displaySearch.md rename to modules/concepts/hooks/list-of-hooks/displaySearch.md index 26c62254db..423a645be7 100644 --- a/modules/concepts/hooks/list-hooks/displaySearch.md +++ b/modules/concepts/hooks/list-of-hooks/displaySearch.md @@ -1,22 +1,30 @@ --- menuTitle: displaySearch -title: displaySearch +Title: displaySearch hidden: true +hookTitle: files: - themes/classic/templates/errors/not-found.tpl -types: +locations: - frontoffice -hookTypes: +types: - smarty --- # Hook : displaySearch -Located in : +## Informations + +Hook locations: + - frontoffice + +Hook types: + - smarty +Located in: - themes/classic/templates/errors/not-found.tpl -## Parameters +## Hook call with parameters ```php {hook h='displaySearch'} diff --git a/modules/concepts/hooks/list-of-hooks/displayShoppingCart.md b/modules/concepts/hooks/list-of-hooks/displayShoppingCart.md new file mode 100644 index 0000000000..e47f8aebec --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/displayShoppingCart.md @@ -0,0 +1,37 @@ +--- +menuTitle: displayShoppingCart +Title: displayShoppingCart +hidden: true +hookTitle: Shopping cart - Additional button +files: + - themes/classic/templates/checkout/cart.tpl +locations: + - frontoffice +types: + - smarty +--- + +# Hook : displayShoppingCart + +## Informations + +{{% notice tip %}} +**Shopping cart - Additional button:** + +This hook displays new action buttons within the shopping cart +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook types: + - smarty + +Located in: + - themes/classic/templates/checkout/cart.tpl + +## Hook call with parameters + +```php +{hook h='displayShoppingCart'} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/displayShoppingCartFooter.md b/modules/concepts/hooks/list-of-hooks/displayShoppingCartFooter.md new file mode 100644 index 0000000000..367948a5d7 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/displayShoppingCartFooter.md @@ -0,0 +1,37 @@ +--- +menuTitle: displayShoppingCartFooter +Title: displayShoppingCartFooter +hidden: true +hookTitle: Shopping cart footer +files: + - themes/classic/templates/checkout/cart.tpl +locations: + - frontoffice +types: + - smarty +--- + +# Hook : displayShoppingCartFooter + +## Informations + +{{% notice tip %}} +**Shopping cart footer:** + +This hook displays some specific information on the shopping cart's page +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook types: + - smarty + +Located in: + - themes/classic/templates/checkout/cart.tpl + +## Hook call with parameters + +```php +{hook h='displayShoppingCartFooter'} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/displayTop.md b/modules/concepts/hooks/list-of-hooks/displayTop.md new file mode 100644 index 0000000000..938c53f69d --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/displayTop.md @@ -0,0 +1,37 @@ +--- +menuTitle: displayTop +Title: displayTop +hidden: true +hookTitle: Top of pages +files: + - themes/classic/templates/checkout/_partials/header.tpl +locations: + - frontoffice +types: + - smarty +--- + +# Hook : displayTop + +## Informations + +{{% notice tip %}} +**Top of pages:** + +This hook displays additional elements at the top of your pages +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook types: + - smarty + +Located in: + - themes/classic/templates/checkout/_partials/header.tpl + +## Hook call with parameters + +```php +{hook h='displayTop'} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/filterProductSearch.md b/modules/concepts/hooks/list-of-hooks/filterProductSearch.md new file mode 100644 index 0000000000..a836373428 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/filterProductSearch.md @@ -0,0 +1,37 @@ +--- +menuTitle: filterProductSearch +Title: filterProductSearch +hidden: true +hookTitle: Filter search products result +files: + - modules/blockwishlist/controllers/front/view.php +locations: + - frontoffice +types: + - legacy +--- + +# Hook : filterProductSearch + +## Informations + +{{% notice tip %}} +**Filter search products result:** + +This hook is called in order to allow to modify search product result +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook types: + - legacy + +Located in: + - modules/blockwishlist/controllers/front/view.php + +## Hook call with parameters + +```php +Hook::exec('filterProductSearch', ['searchVariables' => &$searchVariables]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-hooks/legacyblockkpi.md b/modules/concepts/hooks/list-of-hooks/legacyblockkpi.md similarity index 70% rename from modules/concepts/hooks/list-hooks/legacyblockkpi.md rename to modules/concepts/hooks/list-of-hooks/legacyblockkpi.md index b95f7a94ad..10056e14c9 100644 --- a/modules/concepts/hooks/list-hooks/legacyblockkpi.md +++ b/modules/concepts/hooks/list-of-hooks/legacyblockkpi.md @@ -1,22 +1,30 @@ --- menuTitle: legacyblockkpi -title: legacyblockkpi +Title: legacyblockkpi hidden: true +hookTitle: files: - src/PrestaShopBundle/Resources/views/Admin/Product/CatalogPage/catalog.html.twig -types: +locations: - backoffice -hookTypes: +types: - twig --- # Hook : legacyblockkpi -Located in : +## Informations + +Hook locations: + - backoffice + +Hook types: + - twig +Located in: - src/PrestaShopBundle/Resources/views/Admin/Product/CatalogPage/catalog.html.twig -## Parameters +## Hook call with parameters ```php {{ renderhook('legacy_block_kpi', {'kpi_controller': 'AdminProductsController'}) }} diff --git a/modules/concepts/hooks/list-hooks/moduleRoutes.md b/modules/concepts/hooks/list-of-hooks/moduleRoutes.md similarity index 60% rename from modules/concepts/hooks/list-hooks/moduleRoutes.md rename to modules/concepts/hooks/list-of-hooks/moduleRoutes.md index 1de89585ba..251b38c292 100644 --- a/modules/concepts/hooks/list-hooks/moduleRoutes.md +++ b/modules/concepts/hooks/list-of-hooks/moduleRoutes.md @@ -1,22 +1,30 @@ --- menuTitle: moduleRoutes -title: moduleRoutes +Title: moduleRoutes hidden: true +hookTitle: files: - classes/Dispatcher.php -types: +locations: - frontoffice -hookTypes: +types: - legacy --- # Hook : moduleRoutes -Located in : +## Informations + +Hook locations: + - frontoffice + +Hook types: + - legacy +Located in: - classes/Dispatcher.php -## Parameters +## Hook call with parameters ```php Hook::exec('moduleRoutes', ['id_shop' => $id_shop], null, true, false); diff --git a/modules/concepts/hooks/list-hooks/overrideMinimalPurchasePrice.md b/modules/concepts/hooks/list-of-hooks/overrideMinimalPurchasePrice.md similarity index 67% rename from modules/concepts/hooks/list-hooks/overrideMinimalPurchasePrice.md rename to modules/concepts/hooks/list-of-hooks/overrideMinimalPurchasePrice.md index 3cee9feeea..20cc378339 100644 --- a/modules/concepts/hooks/list-hooks/overrideMinimalPurchasePrice.md +++ b/modules/concepts/hooks/list-of-hooks/overrideMinimalPurchasePrice.md @@ -1,22 +1,30 @@ --- menuTitle: overrideMinimalPurchasePrice -title: overrideMinimalPurchasePrice +Title: overrideMinimalPurchasePrice hidden: true +hookTitle: files: - src/Adapter/Presenter/Cart/CartPresenter.php -types: +locations: - frontoffice -hookTypes: +types: - legacy --- # Hook : overrideMinimalPurchasePrice -Located in : +## Informations + +Hook locations: + - frontoffice + +Hook types: + - legacy +Located in: - src/Adapter/Presenter/Cart/CartPresenter.php -## Parameters +## Hook call with parameters ```php Hook::exec('overrideMinimalPurchasePrice', [ diff --git a/modules/concepts/hooks/list-hooks/termsAndConditions.md b/modules/concepts/hooks/list-of-hooks/termsAndConditions.md similarity index 63% rename from modules/concepts/hooks/list-hooks/termsAndConditions.md rename to modules/concepts/hooks/list-of-hooks/termsAndConditions.md index 024d58ab53..1fac178aaf 100644 --- a/modules/concepts/hooks/list-hooks/termsAndConditions.md +++ b/modules/concepts/hooks/list-of-hooks/termsAndConditions.md @@ -1,22 +1,30 @@ --- menuTitle: termsAndConditions -title: termsAndConditions +Title: termsAndConditions hidden: true +hookTitle: files: - classes/checkout/ConditionsToApproveFinder.php -types: +locations: - frontoffice -hookTypes: +types: - legacy --- # Hook : termsAndConditions -Located in : +## Informations + +Hook locations: + - frontoffice + +Hook types: + - legacy +Located in: - classes/checkout/ConditionsToApproveFinder.php -## Parameters +## Hook call with parameters ```php Hook::exec('termsAndConditions', [], null, true); diff --git a/modules/concepts/hooks/list-of-hooks/validateCustomerFormFields.md b/modules/concepts/hooks/list-of-hooks/validateCustomerFormFields.md new file mode 100644 index 0000000000..e9d0f17069 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/validateCustomerFormFields.md @@ -0,0 +1,37 @@ +--- +menuTitle: validateCustomerFormFields +Title: validateCustomerFormFields +hidden: true +hookTitle: Customer registration form validation +files: + - classes/form/CustomerForm.php +locations: + - frontoffice +types: + - legacy +--- + +# Hook : validateCustomerFormFields + +## Informations + +{{% notice tip %}} +**Customer registration form validation:** + +This hook is called to a module when it has sent additional fields with additionalCustomerFormFields +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook types: + - legacy + +Located in: + - classes/form/CustomerForm.php + +## Hook call with parameters + +```php +Hook::exec('validateCustomerFormFields', ['fields' => $formFields], $moduleId, true); +``` \ No newline at end of file From 7b9ae12c3389d6cb1eb17c1bb3b3b0b16bcba218 Mon Sep 17 00:00:00 2001 From: Thomas Nares Date: Wed, 7 Dec 2022 10:27:47 +0100 Subject: [PATCH 155/310] updates all hooks, extract array_returns, check_exceptions, chains --- modules/concepts/hooks/_index.md | 2 +- .../actionAfter.md | 17 +- .../actionBefore.md | 17 +- .../actionFormModifier.md | 37 +++ ...actionListingFieldsModifier.md | 19 +- ...ctionListingResultsModifier.md | 35 ++ .../actionOptionsModifier.md | 35 ++ .../actionGridDataModifier.md | 33 -- ...ionGridDefinitionModifier.md | 33 -- ...ionGridFilterFormModifier.md | 33 -- ...tionGridPresenterModifier.md | 19 +- .../actionFormBuilderModifier.md | 36 --- ...onFormDataProviderDefaultData.md | 38 +++ .../actionGridQueryBuilderModifier.md | 35 -- ...acyControllerName>ListingFieldsModifier.md | 19 +- ...cyControllerName>ListingResultsModifier.md | 19 +- .../hooks/list-of-hooks/actionAdmin.md | 31 -- .../list-of-hooks/actionAdminAfter.md | 17 +- .../actionAdminBefore.md | 17 +- .../list-of-hooks/actionAdminActivateAfter.md | 35 ++ .../actionAdminActivateBefore.md | 35 ++ ...rametersMetaControllerPostProcessBefore.md | 19 +- ...inWebserviceControllerPostProcessBefore.md | 19 +- ...onControllerPostProcessBefore.md | 35 ++ ...ministrationControllerPostProcessBefore.md | 19 +- ...ceControllerPostProcessBefore.md | 35 ++ ...sPerformanceControllerPostProcessBefore.md | 19 +- .../actionAdminControllerInitAfter.md | 43 +++ .../actionAdminControllerInitBefore.md | 43 +++ .../actionAdminControllerSetMedia.md | 26 +- .../actionAdminDeactivateAfter.md | 35 ++ .../actionAdminDeactivateBefore.md | 35 ++ .../list-of-hooks/actionAdminDeleteAfter.md | 35 ++ .../list-of-hooks/actionAdminDeleteBefore.md | 35 ++ .../actionAdminDuplicateAfter.md | 35 ++ .../actionAdminDuplicateBefore.md | 35 ++ ...onControllerPostProcessBefore.md | 35 ++ ...lGeolocationControllerPostProcessBefore.md | 19 +- ...onControllerPostProcessBefore.md | 35 ++ ...LocalizationControllerPostProcessBefore.md | 19 +- .../actionAdminLoginControllerBefore.md | 43 +++ .../actionAdminLoginControllerForgotAfter.md | 44 +++ .../actionAdminLoginControllerForgotBefore.md | 44 +++ .../actionAdminLoginControllerLoginAfter.md | 45 +++ .../actionAdminLoginControllerLoginBefore.md | 45 +++ .../actionAdminLoginControllerResetAfter.md | 44 +++ .../actionAdminLoginControllerResetBefore.md | 48 +++ .../actionAdminLoginControllerSetMedia.md | 43 +++ ...ionAdminLogsControllerPostProcessBefore.md | 19 +- ...nMaintenanceControllerPostProcessBefore.md | 19 +- .../actionAdminMetaAfterWriteRobotsFile.md | 29 +- .../actionAdminMetaBeforeWriteRobotsFile.md | 43 +++ .../list-of-hooks/actionAdminMetaSave.md | 44 +++ .../actionAdminOrdersTrackingNumberUpdate.md | 33 +- ...nPreferencesControllerPostProcessBefore.md | 19 +- ...ionAdminProductsControllerActivateAfter.md | 35 ++ ...onAdminProductsControllerActivateBefore.md | 35 ++ ...nAdminProductsControllerDeactivateAfter.md | 35 ++ ...AdminProductsControllerDeactivateBefore.md | 35 ++ ...ctionAdminProductsControllerDeleteAfter.md | 35 ++ ...tionAdminProductsControllerDeleteBefore.md | 35 ++ ...onAdminProductsControllerDuplicateAfter.md | 35 ++ ...nAdminProductsControllerDuplicateBefore.md | 35 ++ .../actionAdminProductsControllerSortAfter.md | 35 ++ ...actionAdminProductsControllerSortBefore.md | 35 ++ ...ctionAdminProductsListingFieldsModifier.md | 33 +- ...tionAdminProductsListingResultsModifier.md | 30 +- ...dminSecurityControllerPostProcessBefore.md | 19 +- ...gPreferencesControllerPostProcessBefore.md | 19 +- ...ntrollerPostProcessCarrierOptionsBefore.md | 41 +++ ...ncesControllerPostProcessHandlingBefore.md | 41 +++ ...taControllerPostProcessBefore.md | 35 ++ ...esControllerPostProcessBefore.md | 35 ++ ...rPreferencesControllerPostProcessBefore.md | 19 +- ...esControllerPostProcessBefore.md | 35 ++ ...tPreferencesControllerPostProcessBefore.md | 19 +- .../list-of-hooks/actionAdminSortAfter.md | 35 ++ .../list-of-hooks/actionAdminSortBefore.md | 35 ++ ...AdminThemesControllerUpdateoptionsAfter.md | 32 ++ .../actionAfterCreateFormHandler.md | 19 +- .../actionAfterUpdateFormHandler.md | 19 +- .../hooks/list-of-hooks/actionAjaxDie.md | 31 -- ...actionAjaxDieBefore.md | 32 ++ .../list-of-hooks/actionAjaxDieBefore.md | 29 +- .../actionAttributeCombinationDelete.md | 19 +- .../actionAttributeCombinationSave.md | 19 +- .../list-of-hooks/actionAttributeDelete.md | 25 +- .../actionAttributeGroupDelete.md | 25 +- .../list-of-hooks/actionAttributeGroupSave.md | 25 +- .../list-of-hooks/actionAttributeSave.md | 25 +- .../list-of-hooks/actionAuthentication.md | 25 +- .../actionAuthenticationBefore.md | 25 +- .../list-of-hooks/actionBeforeAjaxDie.md | 31 -- ...actionBeforeAjaxDie.md | 32 ++ ...actionBeforeCreateFormHandler.md | 36 +++ ...actionBeforeUpdateFormHandler.md | 19 +- .../actionBuildFrontEndObject.md | 19 +- .../actionBuildMailLayoutVariables.md | 44 +++ .../list-of-hooks/actionCarrierProcess.md | 25 +- .../list-of-hooks/actionCarrierUpdate.md | 25 +- .../hooks/list-of-hooks/actionCartSave.md | 25 +- .../hooks/list-of-hooks/actionCartSummary.md | 19 +- .../actionCartUpdateQuantityBefore.md | 25 +- .../hooks/list-of-hooks/actionCategoryAdd.md | 25 +- .../list-of-hooks/actionCategoryDelete.md | 25 +- .../list-of-hooks/actionCategoryUpdate.md | 25 +- .../list-of-hooks/actionCheckoutRender.md | 19 +- .../hooks/list-of-hooks/actionClearCache.md | 19 +- .../list-of-hooks/actionClearCompileCache.md | 19 +- .../list-of-hooks/actionClearSf2Cache.md | 19 +- .../actionControllerInitAfter.md | 43 +++ .../actionControllerInitBefore.md | 43 +++ .../list-of-hooks/actionCustomerAccountAdd.md | 34 +- .../actionCustomerAccountUpdate.md | 19 +- .../list-of-hooks/actionCustomerAddGroups.md | 19 +- .../actionCustomerBeforeUpdateGroup.md | 19 +- .../actionCustomerLogoutAfter.md | 19 +- .../actionCustomerLogoutBefore.md | 19 +- .../list-of-hooks/actionDeleteGDPRCustomer.md | 19 +- .../actionDeliveryPriceByPrice.md | 19 +- .../actionDeliveryPriceByWeight.md | 19 +- .../hooks/list-of-hooks/actionDispatcher.md | 19 +- .../list-of-hooks/actionDispatcherAfter.md | 25 +- .../list-of-hooks/actionDispatcherBefore.md | 23 +- .../list-of-hooks/actionDownloadAttachment.md | 19 +- .../actionEmailAddAfterContent.md | 50 +++ .../actionEmailAddBeforeContent.md | 50 +++ .../list-of-hooks/actionEmailSendBefore.md | 61 ++++ .../list-of-hooks/actionExportGDPRData.md | 19 +- .../list-of-hooks/actionFeatureDelete.md | 25 +- .../hooks/list-of-hooks/actionFeatureSave.md | 25 +- .../list-of-hooks/actionFeatureValueDelete.md | 25 +- .../list-of-hooks/actionFeatureValueSave.md | 25 +- .../actionFilterDeliveryOptionList.md | 52 +++ .../actionFrontControllerInitAfter.md | 49 +++ .../actionFrontControllerInitBefore.md | 43 +++ .../actionFrontControllerSetMedia.md | 19 +- .../actionFrontControllerSetVariables.md | 64 ++++ .../actionGetAdminOrderButtons.md | 56 ++++ .../actionGetAdminToolbarButtons.md | 51 +++ .../actionGetAlternativeSearchPanels.md | 58 ++++ .../actionGetExtraMailTemplateVars.md | 44 +++ .../actionGetIDZoneByAddressID.md | 19 +- .../actionGetMailLayoutTransformations.md | 45 +++ .../actionGetProductPropertiesAfter.md | 23 +- ...ctionGetProductPropertiesAfterUnitPrice.md | 19 +- .../actionGetProductPropertiesBefore.md | 19 +- .../list-of-hooks/actionHtaccessCreate.md | 25 +- .../actionInvoiceNumberFormatted.md | 19 +- .../list-of-hooks/actionListMailThemes.md | 41 +++ .../actionMailAlterMessageBeforeSend.md | 19 +- .../list-of-hooks/actionModuleInstallAfter.md | 19 +- .../actionModuleInstallBefore.md | 19 +- .../actionModuleMailAlertSendCustomer.md | 40 +++ .../actionModuleRegisterHookAfter.md | 38 +++ .../actionModuleRegisterHookBefore.md | 38 +++ .../actionModuleUnRegisterHookAfter.md | 38 +++ .../actionModuleUnRegisterHookBefore.md | 19 +- .../actionModuleUninstallAfter.md | 19 +- .../actionModuleUninstallBefore.md | 19 +- .../actionNewsletterRegistrationAfter.md | 40 +++ .../actionNewsletterRegistrationBefore.md | 40 +++ .../actionObjectAddAfter.md | 17 +- .../actionObjectAddBefore.md | 17 +- .../actionObjectDeleteAfter.md | 17 +- .../actionObjectDeleteBefore.md | 17 +- .../actionObjectUpdateAfter.md | 17 +- .../actionObjectUpdateBefore.md | 17 +- .../list-of-hooks/actionObjectAddAfter.md | 19 +- .../list-of-hooks/actionObjectAddBefore.md | 19 +- .../actionObjectAttributeAddBefore.md | 19 +- .../actionObjectAttributeGroupAddBefore.md | 19 +- .../list-of-hooks/actionObjectDeleteAfter.md | 19 +- .../list-of-hooks/actionObjectDeleteBefore.md | 19 +- ...actionObjectProductCommentValidateAfter.md | 19 +- .../actionObjectProductInCartDeleteAfter.md | 19 +- .../actionObjectProductInCartDeleteBefore.md | 21 +- .../list-of-hooks/actionObjectUpdateAfter.md | 19 +- .../list-of-hooks/actionObjectUpdateBefore.md | 19 +- .../list-of-hooks/actionOnImageCutAfter.md | 19 +- .../list-of-hooks/actionOnImageResizeAfter.md | 19 +- .../hooks/list-of-hooks/actionOrderEdited.md | 27 +- .../actionOrderHistoryAddAfter.md | 19 +- .../hooks/list-of-hooks/actionOrderReturn.md | 34 +- .../hooks/list-of-hooks/actionOrderSlipAdd.md | 300 +++--------------- .../actionOrderStatusPostUpdate.md | 59 ++++ .../list-of-hooks/actionOrderStatusUpdate.md | 59 ++++ .../list-of-hooks/actionOutputHTMLBefore.md | 19 +- .../actionOverrideEmployeeImage.md | 44 +++ .../list-of-hooks/actionPDFInvoiceRender.md | 19 +- .../list-of-hooks/actionPasswordRenew.md | 19 +- .../hooks/list-of-hooks/actionPaymentCCAdd.md | 34 +- .../actionPaymentConfirmation.md | 34 +- .../hooks/list-of-hooks/actionPresentCart.md | 40 +++ .../list-of-hooks/actionPresentModule.md | 34 ++ .../hooks/list-of-hooks/actionPresentOrder.md | 40 +++ .../list-of-hooks/actionPresentOrderReturn.md | 40 +++ .../actionPresentPaymentOptions.md | 49 +++ .../list-of-hooks/actionPresentProduct.md | 40 +++ .../actionPresentProductListing.md | 40 +++ .../list-of-hooks/actionProductActivation.md | 19 +- .../hooks/list-of-hooks/actionProductAdd.md | 34 +- .../actionProductAttributeDelete.md | 25 +- .../actionProductAttributeUpdate.md | 25 +- .../list-of-hooks/actionProductCancel.md | 25 +- .../list-of-hooks/actionProductCoverage.md | 39 +++ .../list-of-hooks/actionProductDelete.md | 25 +- .../list-of-hooks/actionProductOutOfStock.md | 23 +- .../hooks/list-of-hooks/actionProductSave.md | 25 +- .../list-of-hooks/actionProductSearchAfter.md | 19 +- ...ctionProductSearchProviderRunQueryAfter.md | 19 +- ...tionProductSearchProviderRunQueryBefore.md | 19 +- .../list-of-hooks/actionProductUpdate.md | 25 +- .../hooks/list-of-hooks/actionSearch.md | 29 +- .../hooks/list-of-hooks/actionSetInvoice.md | 30 +- .../actionShopDataDuplication.md | 107 ++----- .../actionSubmitAccountBefore.md | 25 +- .../actionSubmitCustomerAddressForm.md | 19 +- .../list-of-hooks/actionUpdateLangAfter.md | 19 +- .../list-of-hooks/actionUpdateQuantity.md | 63 ++++ .../actionValidateCustomerAddressForm.md | 117 +------ .../list-of-hooks/actionValidateOrder.md | 38 ++- .../list-of-hooks/actionValidateOrderAfter.md | 62 ++++ .../actionValidateStepComplete.md | 51 +++ .../hooks/list-of-hooks/actionWatermark.md | 44 ++- .../list-of-hooks/actionWishlistAddProduct.md | 19 +- .../list-of-hooks/addWebserviceResources.md | 23 +- .../additionalCustomerAddressFields.md | 21 +- .../additionalCustomerFormFields.md | 21 +- .../hooks/list-of-hooks/dashboardData.md | 21 +- .../hooks/list-of-hooks/dashboardZoneOne.md | 19 +- .../hooks/list-of-hooks/dashboardZoneThree.md | 29 +- .../hooks/list-of-hooks/dashboardZoneTwo.md | 19 +- .../list-of-hooks/deleteProductAttribute.md | 39 +++ .../displayAdditionalCustomerAddressFields.md | 17 +- .../list-of-hooks/displayAdminAfterHeader.md | 17 +- .../list-of-hooks/displayAdminCustomers.md | 32 +- .../list-of-hooks/displayAdminEndContent.md | 17 +- .../hooks/list-of-hooks/displayAdminForm.md | 17 +- .../displayAdminGridTableAfter.md | 34 +- .../displayAdminGridTableBefore.md | 34 +- .../list-of-hooks/displayAdminListAfter.md | 17 +- .../list-of-hooks/displayAdminListBefore.md | 17 +- .../displayAdminNavBarBeforeEnd.md | 17 +- .../list-of-hooks/displayAdminOptions.md | 17 +- .../hooks/list-of-hooks/displayAdminOrder.md | 32 +- .../displayAdminOrderCreateExtraButtons.md | 17 +- .../list-of-hooks/displayAdminOrderMain.md | 26 +- .../displayAdminOrderMainBottom.md | 26 +- .../list-of-hooks/displayAdminOrderSide.md | 32 +- .../displayAdminOrderSideBottom.md | 26 +- .../displayAdminProductsCombinationBottom.md | 17 +- ...ayAdminProductsMainStepLeftColumnBottom.md | 17 +- ...ayAdminProductsMainStepLeftColumnMiddle.md | 17 +- ...yAdminProductsMainStepRightColumnBottom.md | 17 +- .../displayAdminProductsOptionsStepBottom.md | 17 +- .../displayAdminProductsOptionsStepTop.md | 17 +- .../displayAdminProductsPriceStepBottom.md | 17 +- ...isplayAdminProductsQuantitiesStepBottom.md | 17 +- .../displayAdminProductsSeoStepBottom.md | 17 +- .../displayAdminProductsShippingStepBottom.md | 17 +- .../list-of-hooks/displayAdminStatsModules.md | 25 +- .../displayAdminThemesListAfter.md | 26 +- .../hooks/list-of-hooks/displayAdminView.md | 17 +- .../displayAfterBodyOpeningTag.md | 17 +- .../list-of-hooks/displayAfterCarrier.md | 19 +- .../displayAfterProductThumbs.md | 17 +- .../list-of-hooks/displayAfterTitleTag.md | 17 +- .../displayBackOfficeCategory.md | 17 +- .../displayBackOfficeEmployeeMenu.md | 52 +++ .../list-of-hooks/displayBackOfficeHeader.md | 44 +++ .../list-of-hooks/displayBackOfficeTop.md | 25 +- .../hooks/list-of-hooks/displayBanner.md | 17 +- .../displayBeforeBodyClosingTag.md | 17 +- .../list-of-hooks/displayBeforeCarrier.md | 72 ++++- .../displayCMSDisputeInformation.md | 17 +- .../list-of-hooks/displayCMSPrintButton.md | 17 +- .../displayCarrierExtraContent.md | 19 +- .../displayCartExtraProductActions.md | 17 +- .../list-of-hooks/displayCartModalContent.md | 17 +- .../list-of-hooks/displayCartModalFooter.md | 17 +- .../displayCheckoutBeforeConfirmation.md | 17 +- .../displayCheckoutSubtotalDetails.md | 17 +- .../displayCheckoutSummaryTop.md | 17 +- .../displayCrossSellingShoppingCart.md | 17 +- .../list-of-hooks/displayCustomerAccount.md | 23 +- .../displayCustomerAccountForm.md | 25 +- .../displayCustomerAccountFormTop.md | 25 +- .../displayCustomerLoginFormAfter.md | 17 +- .../list-of-hooks/displayCustomization.md | 19 +- .../displayDashboardToolbarIcons.md | 17 +- .../displayDashboardToolbarTopMenu.md | 17 +- .../list-of-hooks/displayDashboardTop.md | 17 +- .../displayEmptyModuleCategoryExtraMessage.md | 25 +- .../list-of-hooks/displayExpressCheckout.md | 17 +- .../hooks/list-of-hooks/displayFeatureForm.md | 23 +- .../displayFeaturePostProcess.md | 47 +++ .../displayFeatureValuePostProcess.md | 47 +++ .../hooks/list-of-hooks/displayFooter.md | 23 +- .../hooks/list-of-hooks/displayFooterAfter.md | 17 +- .../list-of-hooks/displayFooterBefore.md | 17 +- .../list-of-hooks/displayFooterProduct.md | 23 +- .../hooks/list-of-hooks/displayGDPRConsent.md | 17 +- .../hooks/list-of-hooks/displayHeader.md | 25 +- .../hooks/list-of-hooks/displayHome.md | 25 +- .../displayInvoiceLegalFreeText.md | 19 +- .../list-of-hooks/displayLeftColumnProduct.md | 23 +- .../hooks/list-of-hooks/displayMaintenance.md | 19 +- .../list-of-hooks/displayMyAccountBlock.md | 23 +- .../hooks/list-of-hooks/displayNav1.md | 17 +- .../hooks/list-of-hooks/displayNav2.md | 17 +- .../list-of-hooks/displayNavFullWidth.md | 17 +- .../displayNewsletterRegistration.md | 17 +- .../hooks/list-of-hooks/displayNotFound.md | 17 +- .../list-of-hooks/displayOrderConfirmation.md | 34 +- .../displayOrderConfirmation1.md | 17 +- .../displayOrderConfirmation2.md | 17 +- .../hooks/list-of-hooks/displayOrderDetail.md | 34 +- .../list-of-hooks/displayOrderPreview.md | 26 +- .../list-of-hooks/displayOverrideTemplate.md | 46 +++ .../list-of-hooks/displayPaymentByBinaries.md | 17 +- .../list-of-hooks/displayPaymentReturn.md | 25 +- .../hooks/list-of-hooks/displayPaymentTop.md | 23 +- .../displayPersonalInformationTop.md | 17 +- .../list-of-hooks/displayProductActions.md | 17 +- .../displayProductAdditionalInfo.md | 25 +- .../displayProductListReviews.md | 17 +- .../list-of-hooks/displayProductPriceBlock.md | 17 +- .../hooks/list-of-hooks/displayReassurance.md | 17 +- .../displayRightColumnProduct.md | 23 +- .../hooks/list-of-hooks/displaySearch.md | 17 +- .../list-of-hooks/displayShoppingCart.md | 23 +- .../displayShoppingCartFooter.md | 23 +- .../hooks/list-of-hooks/displayTop.md | 23 +- .../list-of-hooks/filterCategoryContent.md | 58 ++++ .../list-of-hooks/filterCmsCategoryContent.md | 49 +++ .../hooks/list-of-hooks/filterCmsContent.md | 49 +++ .../hooks/list-of-hooks/filterHtmlContent.md | 53 ++++ .../filterManufacturerContent.md | 49 +++ .../list-of-hooks/filterProductContent.md | 49 +++ .../list-of-hooks/filterProductSearch.md | 19 +- .../list-of-hooks/filterSupplierContent.md | 49 +++ .../hooks/list-of-hooks/gSitemapAppendUrls.md | 36 +++ .../hooks/list-of-hooks/legacyblockkpi.md | 17 +- .../hooks/list-of-hooks/moduleRoutes.md | 23 +- .../list-of-hooks/overrideLayoutTemplate.md | 41 +++ .../overrideMinimalPurchasePrice.md | 19 +- .../list-of-hooks/productSearchProvider.md | 39 +++ .../sendMailAlterTemplateVars.md | 44 +++ .../hooks/list-of-hooks/termsAndConditions.md | 21 +- .../validateCustomerFormFields.md | 21 +- 351 files changed, 7393 insertions(+), 2772 deletions(-) create mode 100644 modules/concepts/hooks/list-of-hooks/actionFormModifier.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionListingResultsModifier.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionOptionsModifier.md delete mode 100644 modules/concepts/hooks/list-of-hooks/actionGridDataModifier.md delete mode 100644 modules/concepts/hooks/list-of-hooks/actionGridDefinitionModifier.md delete mode 100644 modules/concepts/hooks/list-of-hooks/actionGridFilterFormModifier.md delete mode 100644 modules/concepts/hooks/list-of-hooks/actionFormBuilderModifier.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionFormDataProviderDefaultData.md delete mode 100644 modules/concepts/hooks/list-of-hooks/actionGridQueryBuilderModifier.md delete mode 100644 modules/concepts/hooks/list-of-hooks/actionAdmin.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionAdminActivateAfter.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionAdminActivateBefore.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionAdminAdministrationControllerPostProcessBefore.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionAdminAdvancedParametersPerformanceControllerPostProcessBefore.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionAdminControllerInitAfter.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionAdminControllerInitBefore.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionAdminDeactivateAfter.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionAdminDeactivateBefore.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionAdminDeleteAfter.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionAdminDeleteBefore.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionAdminDuplicateAfter.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionAdminDuplicateBefore.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionAdminInternationalGeolocationControllerPostProcessBefore.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionAdminInternationalLocalizationControllerPostProcessBefore.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionAdminLoginControllerBefore.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionAdminLoginControllerForgotAfter.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionAdminLoginControllerForgotBefore.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionAdminLoginControllerLoginAfter.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionAdminLoginControllerLoginBefore.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionAdminLoginControllerResetAfter.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionAdminLoginControllerResetBefore.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionAdminLoginControllerSetMedia.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionAdminMetaBeforeWriteRobotsFile.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionAdminMetaSave.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerActivateAfter.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerActivateBefore.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerDeactivateAfter.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerDeactivateBefore.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerDeleteAfter.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerDeleteBefore.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerDuplicateAfter.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerDuplicateBefore.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerSortAfter.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerSortBefore.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionAdminShippingPreferencesControllerPostProcessCarrierOptionsBefore.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionAdminShippingPreferencesControllerPostProcessHandlingBefore.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionAdminShopParametersMetaControllerPostProcessBefore.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionAdminShopParametersOrderPreferencesControllerPostProcessBefore.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionAdminShopParametersProductPreferencesControllerPostProcessBefore.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionAdminSortAfter.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionAdminSortBefore.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionAdminThemesControllerUpdateoptionsAfter.md delete mode 100644 modules/concepts/hooks/list-of-hooks/actionAjaxDie.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionAjaxDieBefore.md delete mode 100644 modules/concepts/hooks/list-of-hooks/actionBeforeAjaxDie.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionBeforeAjaxDie.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionBeforeCreateFormHandler.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionBuildMailLayoutVariables.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionControllerInitAfter.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionControllerInitBefore.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionEmailAddAfterContent.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionEmailAddBeforeContent.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionEmailSendBefore.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionFilterDeliveryOptionList.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionFrontControllerInitAfter.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionFrontControllerInitBefore.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionFrontControllerSetVariables.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionGetAdminOrderButtons.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionGetAdminToolbarButtons.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionGetAlternativeSearchPanels.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionGetExtraMailTemplateVars.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionGetMailLayoutTransformations.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionListMailThemes.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionModuleMailAlertSendCustomer.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionModuleRegisterHookAfter.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionModuleRegisterHookBefore.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionModuleUnRegisterHookAfter.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionNewsletterRegistrationAfter.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionNewsletterRegistrationBefore.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionOrderStatusPostUpdate.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionOrderStatusUpdate.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionOverrideEmployeeImage.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionPresentCart.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionPresentModule.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionPresentOrder.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionPresentOrderReturn.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionPresentPaymentOptions.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionPresentProduct.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionPresentProductListing.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionProductCoverage.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionUpdateQuantity.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionValidateOrderAfter.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionValidateStepComplete.md create mode 100644 modules/concepts/hooks/list-of-hooks/deleteProductAttribute.md create mode 100644 modules/concepts/hooks/list-of-hooks/displayBackOfficeEmployeeMenu.md create mode 100644 modules/concepts/hooks/list-of-hooks/displayBackOfficeHeader.md create mode 100644 modules/concepts/hooks/list-of-hooks/displayFeaturePostProcess.md create mode 100644 modules/concepts/hooks/list-of-hooks/displayFeatureValuePostProcess.md create mode 100644 modules/concepts/hooks/list-of-hooks/displayOverrideTemplate.md create mode 100644 modules/concepts/hooks/list-of-hooks/filterCategoryContent.md create mode 100644 modules/concepts/hooks/list-of-hooks/filterCmsCategoryContent.md create mode 100644 modules/concepts/hooks/list-of-hooks/filterCmsContent.md create mode 100644 modules/concepts/hooks/list-of-hooks/filterHtmlContent.md create mode 100644 modules/concepts/hooks/list-of-hooks/filterManufacturerContent.md create mode 100644 modules/concepts/hooks/list-of-hooks/filterProductContent.md create mode 100644 modules/concepts/hooks/list-of-hooks/filterSupplierContent.md create mode 100644 modules/concepts/hooks/list-of-hooks/gSitemapAppendUrls.md create mode 100644 modules/concepts/hooks/list-of-hooks/overrideLayoutTemplate.md create mode 100644 modules/concepts/hooks/list-of-hooks/productSearchProvider.md create mode 100644 modules/concepts/hooks/list-of-hooks/sendMailAlterTemplateVars.md diff --git a/modules/concepts/hooks/_index.md b/modules/concepts/hooks/_index.md index 4867172ce2..943964fe7c 100644 --- a/modules/concepts/hooks/_index.md +++ b/modules/concepts/hooks/_index.md @@ -139,4 +139,4 @@ $this->registerHook('displayAtSpecificPlace'); If the hook "displayAtSpecificPlace" doesn't exist, PrestaShop will create it for you but be careful: this will also plug the current module to the hook. -[hooks-component]: {{< ref "/8/development/components/hook/" >}} +[hooks-component]: {{< ref "/8/development/components/hook/" >}} \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionAfter.md b/modules/concepts/hooks/list-of-hooks/actionAfter.md index 5efa96b3f3..2a324055db 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionAfter.md @@ -7,24 +7,25 @@ files: - classes/controller/AdminController.php locations: - backoffice -types: - - legacy +type: + - action +hookAliases: --- -# Hook : actionAfter +# Hook actionAfter -## Informations +## Information Hook locations: - backoffice -Hook types: - - legacy +Hook type: + - action Located in: - - classes/controller/AdminController.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/AdminController.php](classes/controller/AdminController.php) -## Hook call with parameters +## Hook call in codebase ```php Hook::exec('action' . get_class($this) . ucfirst($this->action) . 'After', ['controller' => $this, 'return' => $return]); diff --git a/modules/concepts/hooks/list-of-hooks/actionBefore.md b/modules/concepts/hooks/list-of-hooks/actionBefore.md index aa409a0838..41afa16be0 100644 --- a/modules/concepts/hooks/list-of-hooks/actionBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionBefore.md @@ -7,24 +7,25 @@ files: - classes/controller/AdminController.php locations: - backoffice -types: - - legacy +type: + - action +hookAliases: --- -# Hook : actionBefore +# Hook actionBefore -## Informations +## Information Hook locations: - backoffice -Hook types: - - legacy +Hook type: + - action Located in: - - classes/controller/AdminController.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/AdminController.php](classes/controller/AdminController.php) -## Hook call with parameters +## Hook call in codebase ```php Hook::exec('action' . get_class($this) . ucfirst($this->action) . 'Before', ['controller' => $this]); diff --git a/modules/concepts/hooks/list-of-hooks/actionFormModifier.md b/modules/concepts/hooks/list-of-hooks/actionFormModifier.md new file mode 100644 index 0000000000..6d44cce03d --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionFormModifier.md @@ -0,0 +1,37 @@ +--- +menuTitle: actionFormModifier +Title: actionFormModifier +hidden: true +hookTitle: +files: + - classes/controller/AdminController.php +locations: + - backoffice +type: + - action +hookAliases: +--- + +# Hook actionFormModifier + +## Information + +Hook locations: + - backoffice + +Hook type: + - action + +Located in: + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/AdminController.php](classes/controller/AdminController.php) + +## Hook call in codebase + +```php +Hook::exec('action' . $this->controller_name . 'FormModifier', [ + 'object' => &$this->object, + 'fields' => &$this->fields_form, + 'fields_value' => &$fields_value, + 'form_vars' => &$this->tpl_form_vars, + ]) +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionListingFieldsModifier.md b/modules/concepts/hooks/list-of-hooks/actionListingFieldsModifier.md index 073c5cc454..8d36bacd55 100644 --- a/modules/concepts/hooks/list-of-hooks/actionListingFieldsModifier.md +++ b/modules/concepts/hooks/list-of-hooks/actionListingFieldsModifier.md @@ -7,27 +7,28 @@ files: - classes/controller/AdminController.php locations: - backoffice -types: - - legacy +type: + - action +hookAliases: --- -# Hook : actionListingFieldsModifier +# Hook actionListingFieldsModifier -## Informations +## Information Hook locations: - backoffice -Hook types: - - legacy +Hook type: + - action Located in: - - classes/controller/AdminController.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/AdminController.php](classes/controller/AdminController.php) -## Hook call with parameters +## Hook call in codebase ```php Hook::exec('action' . $this->controller_name . 'ListingFieldsModifier', [ 'fields' => &$this->fields_list, - ]); + ]) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionListingResultsModifier.md b/modules/concepts/hooks/list-of-hooks/actionListingResultsModifier.md new file mode 100644 index 0000000000..c375446ec8 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionListingResultsModifier.md @@ -0,0 +1,35 @@ +--- +menuTitle: actionListingResultsModifier +Title: actionListingResultsModifier +hidden: true +hookTitle: +files: + - classes/controller/AdminController.php +locations: + - backoffice +type: + - action +hookAliases: +--- + +# Hook actionListingResultsModifier + +## Information + +Hook locations: + - backoffice + +Hook type: + - action + +Located in: + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/AdminController.php](classes/controller/AdminController.php) + +## Hook call in codebase + +```php +Hook::exec('action' . $this->controller_name . 'ListingResultsModifier', [ + 'list' => &$this->_list, + 'list_total' => &$this->_listTotal, + ]) +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionOptionsModifier.md b/modules/concepts/hooks/list-of-hooks/actionOptionsModifier.md new file mode 100644 index 0000000000..6c6d41ead1 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionOptionsModifier.md @@ -0,0 +1,35 @@ +--- +menuTitle: actionOptionsModifier +Title: actionOptionsModifier +hidden: true +hookTitle: +files: + - classes/controller/AdminController.php +locations: + - backoffice +type: + - action +hookAliases: +--- + +# Hook actionOptionsModifier + +## Information + +Hook locations: + - backoffice + +Hook type: + - action + +Located in: + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/AdminController.php](classes/controller/AdminController.php) + +## Hook call in codebase + +```php +Hook::exec('action' . $this->controller_name . 'OptionsModifier', [ + 'options' => &$this->fields_options, + 'option_vars' => &$this->tpl_option_vars, + ]) +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionGridDataModifier.md b/modules/concepts/hooks/list-of-hooks/actionGridDataModifier.md deleted file mode 100644 index c1783c8244..0000000000 --- a/modules/concepts/hooks/list-of-hooks/actionGridDataModifier.md +++ /dev/null @@ -1,33 +0,0 @@ ---- -menuTitle: actionGridDataModifier -Title: actionGridDataModifier -hidden: true -hookTitle: -files: - - src/Core/Grid/GridFactory.php -locations: - - frontoffice -types: - - symfony ---- - -# Hook : actionGridDataModifier - -## Informations - -Hook locations: - - frontoffice - -Hook types: - - symfony - -Located in: - - src/Core/Grid/GridFactory.php - -## Hook call with parameters - -```php -dispatchWithParameters('action' . Container::camelize($definition->getId()) . 'GridDataModifier', [ - 'data' => &$data, - ]); -``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionGridDefinitionModifier.md b/modules/concepts/hooks/list-of-hooks/actionGridDefinitionModifier.md deleted file mode 100644 index 79cda00b85..0000000000 --- a/modules/concepts/hooks/list-of-hooks/actionGridDefinitionModifier.md +++ /dev/null @@ -1,33 +0,0 @@ ---- -menuTitle: actionGridDefinitionModifier -Title: actionGridDefinitionModifier -hidden: true -hookTitle: -files: - - src/Core/Grid/Definition/Factory/AbstractGridDefinitionFactory.php -locations: - - frontoffice -types: - - symfony ---- - -# Hook : actionGridDefinitionModifier - -## Informations - -Hook locations: - - frontoffice - -Hook types: - - symfony - -Located in: - - src/Core/Grid/Definition/Factory/AbstractGridDefinitionFactory.php - -## Hook call with parameters - -```php -dispatchWithParameters('action' . Container::camelize($definition->getId()) . 'GridDefinitionModifier', [ - 'definition' => $definition, - ]); -``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionGridFilterFormModifier.md b/modules/concepts/hooks/list-of-hooks/actionGridFilterFormModifier.md deleted file mode 100644 index 7f740d5e31..0000000000 --- a/modules/concepts/hooks/list-of-hooks/actionGridFilterFormModifier.md +++ /dev/null @@ -1,33 +0,0 @@ ---- -menuTitle: actionGridFilterFormModifier -Title: actionGridFilterFormModifier -hidden: true -hookTitle: -files: - - src/Core/Grid/Filter/GridFilterFormFactory.php -locations: - - frontoffice -types: - - symfony ---- - -# Hook : actionGridFilterFormModifier - -## Informations - -Hook locations: - - frontoffice - -Hook types: - - symfony - -Located in: - - src/Core/Grid/Filter/GridFilterFormFactory.php - -## Hook call with parameters - -```php -dispatchWithParameters('action' . Container::camelize($definition->getId()) . 'GridFilterFormModifier', [ - 'filter_form_builder' => $formBuilder, - ]); -``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionGridPresenterModifier.md b/modules/concepts/hooks/list-of-hooks/actionGridPresenterModifier.md index e8311b37a4..8cb2514919 100644 --- a/modules/concepts/hooks/list-of-hooks/actionGridPresenterModifier.md +++ b/modules/concepts/hooks/list-of-hooks/actionGridPresenterModifier.md @@ -7,27 +7,28 @@ files: - src/Core/Grid/Presenter/GridPresenter.php locations: - frontoffice -types: - - symfony +type: + - action +hookAliases: --- -# Hook : actionGridPresenterModifier +# Hook actionGridPresenterModifier -## Informations +## Information Hook locations: - frontoffice -Hook types: - - symfony +Hook type: + - action Located in: - - src/Core/Grid/Presenter/GridPresenter.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Core/Grid/Presenter/GridPresenter.php](src/Core/Grid/Presenter/GridPresenter.php) -## Hook call with parameters +## Hook call in codebase ```php dispatchWithParameters('action' . Container::camelize($definition->getId()) . 'GridPresenterModifier', [ 'presented_grid' => &$presentedGrid, - ]); + ]) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionFormBuilderModifier.md b/modules/concepts/hooks/list-of-hooks/actionFormBuilderModifier.md deleted file mode 100644 index 390b52c5dd..0000000000 --- a/modules/concepts/hooks/list-of-hooks/actionFormBuilderModifier.md +++ /dev/null @@ -1,36 +0,0 @@ ---- -menuTitle: actionFormBuilderModifier -Title: actionFormBuilderModifier -hidden: true -hookTitle: -files: - - src/Core/Form/IdentifiableObject/Builder/FormBuilder.php -locations: - - frontoffice -types: - - symfony ---- - -# Hook : actionFormBuilderModifier - -## Informations - -Hook locations: - - frontoffice - -Hook types: - - symfony - -Located in: - - src/Core/Form/IdentifiableObject/Builder/FormBuilder.php - -## Hook call with parameters - -```php -dispatchWithParameters('action' . $this->camelize($formBuilder->getName()) . 'FormBuilderModifier', [ - 'form_builder' => $formBuilder, - 'data' => &$data, - 'options' => &$options, - 'id' => $id, - ]); -``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionFormDataProviderDefaultData.md b/modules/concepts/hooks/list-of-hooks/actionFormDataProviderDefaultData.md new file mode 100644 index 0000000000..a9a77fe613 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionFormDataProviderDefaultData.md @@ -0,0 +1,38 @@ +--- +menuTitle: actionFormDataProviderDefaultData +Title: actionFormDataProviderDefaultData +hidden: true +hookTitle: +files: + - src/Core/Form/IdentifiableObject/Builder/FormBuilder.php +locations: + - frontoffice +type: + - action +hookAliases: +--- + +# Hook actionFormDataProviderDefaultData + +## Information + +Hook locations: + - frontoffice + +Hook type: + - action + +Located in: + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Core/Form/IdentifiableObject/Builder/FormBuilder.php](src/Core/Form/IdentifiableObject/Builder/FormBuilder.php) + +## Hook call in codebase + +```php +dispatchWithParameters( + 'action' . $this->camelize($this->getFormName()) . 'FormDataProviderDefaultData', + [ + 'data' => &$data, + 'options' => &$options, + ] + ) +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionGridQueryBuilderModifier.md b/modules/concepts/hooks/list-of-hooks/actionGridQueryBuilderModifier.md deleted file mode 100644 index aaeb056126..0000000000 --- a/modules/concepts/hooks/list-of-hooks/actionGridQueryBuilderModifier.md +++ /dev/null @@ -1,35 +0,0 @@ ---- -menuTitle: actionGridQueryBuilderModifier -Title: actionGridQueryBuilderModifier -hidden: true -hookTitle: -files: - - src/Core/Grid/Data/Factory/DoctrineGridDataFactory.php -locations: - - frontoffice -types: - - symfony ---- - -# Hook : actionGridQueryBuilderModifier - -## Informations - -Hook locations: - - frontoffice - -Hook types: - - symfony - -Located in: - - src/Core/Grid/Data/Factory/DoctrineGridDataFactory.php - -## Hook call with parameters - -```php -dispatchWithParameters('action' . Container::camelize($this->gridId) . 'GridQueryBuilderModifier', [ - 'search_query_builder' => $searchQueryBuilder, - 'count_query_builder' => $countQueryBuilder, - 'search_criteria' => $searchCriteria, - ]); -``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionListingFieldsModifier.md b/modules/concepts/hooks/list-of-hooks/actionListingFieldsModifier.md index 0d2ec90af0..09d6318cc9 100644 --- a/modules/concepts/hooks/list-of-hooks/actionListingFieldsModifier.md +++ b/modules/concepts/hooks/list-of-hooks/actionListingFieldsModifier.md @@ -7,24 +7,25 @@ files: - src/PrestaShopBundle/Bridge/Helper/Listing/HelperBridge/HelperListBridge.php locations: - frontoffice -types: - - symfony +type: + - action +hookAliases: --- -# Hook : actionListingFieldsModifier +# Hook actionListingFieldsModifier -## Informations +## Information Hook locations: - frontoffice -Hook types: - - symfony +Hook type: + - action Located in: - - src/PrestaShopBundle/Bridge/Helper/Listing/HelperBridge/HelperListBridge.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Bridge/Helper/Listing/HelperBridge/HelperListBridge.php](src/PrestaShopBundle/Bridge/Helper/Listing/HelperBridge/HelperListBridge.php) -## Hook call with parameters +## Hook call in codebase ```php dispatchWithParameters('action' . $helperListConfiguration->legacyControllerName . 'ListingFieldsModifier', [ @@ -35,5 +36,5 @@ dispatchWithParameters('action' . $helperListConfiguration->legacyControllerName 'order_by' => &$helperListConfiguration->orderBy, 'order_way' => &$helperListConfiguration->orderWay, 'fields' => &$helperListConfiguration->fieldsList, - ]); + ]) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionListingResultsModifier.md b/modules/concepts/hooks/list-of-hooks/actionListingResultsModifier.md index 6e8b1659bc..625c64bbb7 100644 --- a/modules/concepts/hooks/list-of-hooks/actionListingResultsModifier.md +++ b/modules/concepts/hooks/list-of-hooks/actionListingResultsModifier.md @@ -7,28 +7,29 @@ files: - src/PrestaShopBundle/Bridge/Helper/Listing/HelperBridge/HelperListBridge.php locations: - frontoffice -types: - - symfony +type: + - action +hookAliases: --- -# Hook : actionListingResultsModifier +# Hook actionListingResultsModifier -## Informations +## Information Hook locations: - frontoffice -Hook types: - - symfony +Hook type: + - action Located in: - - src/PrestaShopBundle/Bridge/Helper/Listing/HelperBridge/HelperListBridge.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Bridge/Helper/Listing/HelperBridge/HelperListBridge.php](src/PrestaShopBundle/Bridge/Helper/Listing/HelperBridge/HelperListBridge.php) -## Hook call with parameters +## Hook call in codebase ```php dispatchWithParameters('action' . $helperListConfiguration->legacyControllerName . 'ListingResultsModifier', [ 'list' => &$helperListConfiguration->list, 'list_total' => &$helperListConfiguration->listTotal, - ]); + ]) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdmin.md b/modules/concepts/hooks/list-of-hooks/actionAdmin.md deleted file mode 100644 index ce9ea38f5c..0000000000 --- a/modules/concepts/hooks/list-of-hooks/actionAdmin.md +++ /dev/null @@ -1,31 +0,0 @@ ---- -menuTitle: actionAdmin -Title: actionAdmin -hidden: true -hookTitle: -files: - - classes/controller/AdminController.php -locations: - - backoffice -types: - - legacy ---- - -# Hook : actionAdmin - -## Informations - -Hook locations: - - backoffice - -Hook types: - - legacy - -Located in: - - classes/controller/AdminController.php - -## Hook call with parameters - -```php -Hook::exec('actionAdmin' . ucfirst($this->action) . 'Before', ['controller' => $this]); -``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminAfter.md b/modules/concepts/hooks/list-of-hooks/actionAdminAfter.md index bca9f07b95..92367d9ab8 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminAfter.md @@ -7,24 +7,25 @@ files: - classes/controller/AdminController.php locations: - backoffice -types: - - legacy +type: + - action +hookAliases: --- -# Hook : actionAdminAfter +# Hook actionAdminAfter -## Informations +## Information Hook locations: - backoffice -Hook types: - - legacy +Hook type: + - action Located in: - - classes/controller/AdminController.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/AdminController.php](classes/controller/AdminController.php) -## Hook call with parameters +## Hook call in codebase ```php Hook::exec('actionAdmin' . ucfirst($this->action) . 'After', ['controller' => $this, 'return' => $return]); diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminBefore.md index e35f9d8266..f7fb9f65f8 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminBefore.md @@ -7,24 +7,25 @@ files: - classes/controller/AdminController.php locations: - backoffice -types: - - legacy +type: + - action +hookAliases: --- -# Hook : actionAdminBefore +# Hook actionAdminBefore -## Informations +## Information Hook locations: - backoffice -Hook types: - - legacy +Hook type: + - action Located in: - - classes/controller/AdminController.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/AdminController.php](classes/controller/AdminController.php) -## Hook call with parameters +## Hook call in codebase ```php Hook::exec('actionAdmin' . ucfirst($this->action) . 'Before', ['controller' => $this]); diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminActivateAfter.md b/modules/concepts/hooks/list-of-hooks/actionAdminActivateAfter.md new file mode 100644 index 0000000000..1868463212 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionAdminActivateAfter.md @@ -0,0 +1,35 @@ +--- +menuTitle: actionAdminActivateAfter +Title: actionAdminActivateAfter +hidden: true +hookTitle: +files: + - src/PrestaShopBundle/Controller/Admin/ProductController.php +locations: + - backoffice +type: + - action +hookAliases: +--- + +# Hook actionAdminActivateAfter + +## Information + +Hook locations: + - backoffice + +Hook type: + - action + +Located in: + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/ProductController.php](src/PrestaShopBundle/Controller/Admin/ProductController.php) + +## Hook call in codebase + +```php +dispatchWithParameters( + 'actionAdminActivateAfter', + $hookEventParameters + ) +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminActivateBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminActivateBefore.md new file mode 100644 index 0000000000..a22a3e24a6 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionAdminActivateBefore.md @@ -0,0 +1,35 @@ +--- +menuTitle: actionAdminActivateBefore +Title: actionAdminActivateBefore +hidden: true +hookTitle: +files: + - src/PrestaShopBundle/Controller/Admin/ProductController.php +locations: + - backoffice +type: + - action +hookAliases: +--- + +# Hook actionAdminActivateBefore + +## Information + +Hook locations: + - backoffice + +Hook type: + - action + +Located in: + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/ProductController.php](src/PrestaShopBundle/Controller/Admin/ProductController.php) + +## Hook call in codebase + +```php +dispatchWithParameters( + 'actionAdminActivateBefore', + $hookEventParameters + ) +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminAdminShopParametersMetaControllerPostProcessBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminAdminShopParametersMetaControllerPostProcessBefore.md index 60bbc359c4..ce0b74aba7 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminAdminShopParametersMetaControllerPostProcessBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminAdminShopParametersMetaControllerPostProcessBefore.md @@ -7,13 +7,14 @@ files: - src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/MetaController.php locations: - backoffice -types: - - symfony +type: + - action +hookAliases: --- -# Hook : actionAdminAdminShopParametersMetaControllerPostProcessBefore +# Hook actionAdminAdminShopParametersMetaControllerPostProcessBefore -## Informations +## Information {{% notice tip %}} **On post-process in Admin Configure Shop Parameters Meta Controller:** @@ -24,14 +25,14 @@ This hook is called on Admin Configure Shop Parameters Meta post-process before Hook locations: - backoffice -Hook types: - - symfony +Hook type: + - action Located in: - - src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/MetaController.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/MetaController.php](src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/MetaController.php) -## Hook call with parameters +## Hook call in codebase ```php -dispatchHook('actionAdminAdminShopParametersMetaControllerPostProcessBefore', ['controller' => $this]); +dispatchHook('actionAdminAdminShopParametersMetaControllerPostProcessBefore', ['controller' => $this]) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminAdminWebserviceControllerPostProcessBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminAdminWebserviceControllerPostProcessBefore.md index 45b98dc7a9..61dbe7839f 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminAdminWebserviceControllerPostProcessBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminAdminWebserviceControllerPostProcessBefore.md @@ -7,25 +7,26 @@ files: - src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/WebserviceController.php locations: - backoffice -types: - - symfony +type: + - action +hookAliases: --- -# Hook : actionAdminAdminWebserviceControllerPostProcessBefore +# Hook actionAdminAdminWebserviceControllerPostProcessBefore -## Informations +## Information Hook locations: - backoffice -Hook types: - - symfony +Hook type: + - action Located in: - - src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/WebserviceController.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/WebserviceController.php](src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/WebserviceController.php) -## Hook call with parameters +## Hook call in codebase ```php -dispatchHook('actionAdminAdminWebserviceControllerPostProcessBefore', ['controller' => $this]); +dispatchHook('actionAdminAdminWebserviceControllerPostProcessBefore', ['controller' => $this]) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminAdministrationControllerPostProcessBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminAdministrationControllerPostProcessBefore.md new file mode 100644 index 0000000000..7d343d1ee2 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionAdminAdministrationControllerPostProcessBefore.md @@ -0,0 +1,35 @@ +--- +menuTitle: actionAdminAdministrationControllerPostProcessBefore +Title: actionAdminAdministrationControllerPostProcessBefore +hidden: true +hookTitle: +files: + - src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/AdministrationController.php +locations: + - backoffice +type: + - action +hookAliases: +--- + +# Hook actionAdminAdministrationControllerPostProcessBefore + +## Information + +Hook locations: + - backoffice + +Hook type: + - action + +Located in: + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/AdministrationController.php](src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/AdministrationController.php) + +## Hook call in codebase + +```php +dispatchHook( + 'actionAdminAdministrationControllerPostProcess' . $hookName . 'Before', + ['controller' => $this] + ) +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminAdministrationControllerPostProcessBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminAdministrationControllerPostProcessBefore.md index 4483c5875f..b293ef1a51 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminAdministrationControllerPostProcessBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminAdministrationControllerPostProcessBefore.md @@ -7,13 +7,14 @@ files: - src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/AdministrationController.php locations: - backoffice -types: - - symfony +type: + - action +hookAliases: --- -# Hook : actionAdminAdministrationControllerPostProcessBefore +# Hook actionAdminAdministrationControllerPostProcessBefore -## Informations +## Information {{% notice tip %}} **On post-process in Admin Configure Advanced Parameters Administration Controller:** @@ -24,14 +25,14 @@ This hook is called on Admin Configure Advanced Parameters Administration post-p Hook locations: - backoffice -Hook types: - - symfony +Hook type: + - action Located in: - - src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/AdministrationController.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/AdministrationController.php](src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/AdministrationController.php) -## Hook call with parameters +## Hook call in codebase ```php -dispatchHook('actionAdminAdministrationControllerPostProcessBefore', ['controller' => $this]); +dispatchHook('actionAdminAdministrationControllerPostProcessBefore', ['controller' => $this]) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminAdvancedParametersPerformanceControllerPostProcessBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminAdvancedParametersPerformanceControllerPostProcessBefore.md new file mode 100644 index 0000000000..a038a1eff8 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionAdminAdvancedParametersPerformanceControllerPostProcessBefore.md @@ -0,0 +1,35 @@ +--- +menuTitle: actionAdminAdvancedParametersPerformanceControllerPostProcessBefore +Title: actionAdminAdvancedParametersPerformanceControllerPostProcessBefore +hidden: true +hookTitle: +files: + - src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/PerformanceController.php +locations: + - backoffice +type: + - action +hookAliases: +--- + +# Hook actionAdminAdvancedParametersPerformanceControllerPostProcessBefore + +## Information + +Hook locations: + - backoffice + +Hook type: + - action + +Located in: + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/PerformanceController.php](src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/PerformanceController.php) + +## Hook call in codebase + +```php +dispatchHook( + 'actionAdminAdvancedParametersPerformanceControllerPostProcess' . $hookName . 'Before', + ['controller' => $this] + ) +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminAdvancedParametersPerformanceControllerPostProcessBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminAdvancedParametersPerformanceControllerPostProcessBefore.md index e330d1a0d9..d377783f4b 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminAdvancedParametersPerformanceControllerPostProcessBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminAdvancedParametersPerformanceControllerPostProcessBefore.md @@ -7,13 +7,14 @@ files: - src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/PerformanceController.php locations: - backoffice -types: - - symfony +type: + - action +hookAliases: --- -# Hook : actionAdminAdvancedParametersPerformanceControllerPostProcessBefore +# Hook actionAdminAdvancedParametersPerformanceControllerPostProcessBefore -## Informations +## Information {{% notice tip %}} **On post-process in Admin Configure Advanced Parameters Performance Controller:** @@ -24,14 +25,14 @@ This hook is called on Admin Configure Advanced Parameters Performance post-proc Hook locations: - backoffice -Hook types: - - symfony +Hook type: + - action Located in: - - src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/PerformanceController.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/PerformanceController.php](src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/PerformanceController.php) -## Hook call with parameters +## Hook call in codebase ```php -dispatchHook('actionAdminAdvancedParametersPerformanceControllerPostProcessBefore', ['controller' => $this]); +dispatchHook('actionAdminAdvancedParametersPerformanceControllerPostProcessBefore', ['controller' => $this]) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminControllerInitAfter.md b/modules/concepts/hooks/list-of-hooks/actionAdminControllerInitAfter.md new file mode 100644 index 0000000000..5801329545 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionAdminControllerInitAfter.md @@ -0,0 +1,43 @@ +--- +menuTitle: actionAdminControllerInitAfter +Title: actionAdminControllerInitAfter +hidden: true +hookTitle: Perform actions after admin controller initialization +files: + - classes/controller/AdminController.php +locations: + - backoffice +type: + - action +hookAliases: +--- + +# Hook actionAdminControllerInitAfter + +## Information + +{{% notice tip %}} +**Perform actions after admin controller initialization:** + +This hook is launched after the initialization of all admin controllers +{{% /notice %}} + +Hook locations: + - backoffice + +Hook type: + - action + +Located in: + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/AdminController.php](classes/controller/AdminController.php) + +## Hook call in codebase + +```php +Hook::exec( + 'actionAdminControllerInitAfter', + [ + 'controller' => $this, + ] + ) +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminControllerInitBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminControllerInitBefore.md new file mode 100644 index 0000000000..05a508545f --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionAdminControllerInitBefore.md @@ -0,0 +1,43 @@ +--- +menuTitle: actionAdminControllerInitBefore +Title: actionAdminControllerInitBefore +hidden: true +hookTitle: Perform actions before admin controller initialization +files: + - classes/controller/AdminController.php +locations: + - backoffice +type: + - action +hookAliases: +--- + +# Hook actionAdminControllerInitBefore + +## Information + +{{% notice tip %}} +**Perform actions before admin controller initialization:** + +This hook is launched before the initialization of all admin controllers +{{% /notice %}} + +Hook locations: + - backoffice + +Hook type: + - action + +Located in: + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/AdminController.php](classes/controller/AdminController.php) + +## Hook call in codebase + +```php +Hook::exec( + 'actionAdminControllerInitBefore', + [ + 'controller' => $this, + ] + ) +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminControllerSetMedia.md b/modules/concepts/hooks/list-of-hooks/actionAdminControllerSetMedia.md index 57892032a1..af33868fd9 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminControllerSetMedia.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminControllerSetMedia.md @@ -4,35 +4,29 @@ Title: actionAdminControllerSetMedia hidden: true hookTitle: files: - - classes/controller/AdminController.php - src/PrestaShopBundle/Bridge/AdminController/LegacyControllerBridge.php locations: - backoffice -types: - - legacy - - symfony +type: + - action +hookAliases: --- -# Hook : actionAdminControllerSetMedia +# Hook actionAdminControllerSetMedia -## Informations +## Information Hook locations: - backoffice -Hook types: - - legacy +Hook type: + - action Located in: - - classes/controller/AdminController.php - - src/PrestaShopBundle/Bridge/AdminController/LegacyControllerBridge.php - -## Hook call with parameters + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Bridge/AdminController/LegacyControllerBridge.php](src/PrestaShopBundle/Bridge/AdminController/LegacyControllerBridge.php) -```php -Hook::exec('actionAdminControllerSetMedia'); -``` +## Hook call in codebase ```php -dispatchWithParameters('actionAdminControllerSetMedia'); +dispatchWithParameters('actionAdminControllerSetMedia') ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminDeactivateAfter.md b/modules/concepts/hooks/list-of-hooks/actionAdminDeactivateAfter.md new file mode 100644 index 0000000000..2af7850c2b --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionAdminDeactivateAfter.md @@ -0,0 +1,35 @@ +--- +menuTitle: actionAdminDeactivateAfter +Title: actionAdminDeactivateAfter +hidden: true +hookTitle: +files: + - src/PrestaShopBundle/Controller/Admin/ProductController.php +locations: + - backoffice +type: + - action +hookAliases: +--- + +# Hook actionAdminDeactivateAfter + +## Information + +Hook locations: + - backoffice + +Hook type: + - action + +Located in: + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/ProductController.php](src/PrestaShopBundle/Controller/Admin/ProductController.php) + +## Hook call in codebase + +```php +dispatchWithParameters( + 'actionAdminDeactivateAfter', + $hookEventParameters + ) +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminDeactivateBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminDeactivateBefore.md new file mode 100644 index 0000000000..cfac876f4a --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionAdminDeactivateBefore.md @@ -0,0 +1,35 @@ +--- +menuTitle: actionAdminDeactivateBefore +Title: actionAdminDeactivateBefore +hidden: true +hookTitle: +files: + - src/PrestaShopBundle/Controller/Admin/ProductController.php +locations: + - backoffice +type: + - action +hookAliases: +--- + +# Hook actionAdminDeactivateBefore + +## Information + +Hook locations: + - backoffice + +Hook type: + - action + +Located in: + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/ProductController.php](src/PrestaShopBundle/Controller/Admin/ProductController.php) + +## Hook call in codebase + +```php +dispatchWithParameters( + 'actionAdminDeactivateBefore', + $hookEventParameters + ) +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminDeleteAfter.md b/modules/concepts/hooks/list-of-hooks/actionAdminDeleteAfter.md new file mode 100644 index 0000000000..d613777993 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionAdminDeleteAfter.md @@ -0,0 +1,35 @@ +--- +menuTitle: actionAdminDeleteAfter +Title: actionAdminDeleteAfter +hidden: true +hookTitle: +files: + - src/PrestaShopBundle/Controller/Admin/ProductController.php +locations: + - backoffice +type: + - action +hookAliases: +--- + +# Hook actionAdminDeleteAfter + +## Information + +Hook locations: + - backoffice + +Hook type: + - action + +Located in: + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/ProductController.php](src/PrestaShopBundle/Controller/Admin/ProductController.php) + +## Hook call in codebase + +```php +dispatchWithParameters( + 'actionAdminDeleteAfter', + $hookEventParameters + ) +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminDeleteBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminDeleteBefore.md new file mode 100644 index 0000000000..9f1de835a9 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionAdminDeleteBefore.md @@ -0,0 +1,35 @@ +--- +menuTitle: actionAdminDeleteBefore +Title: actionAdminDeleteBefore +hidden: true +hookTitle: +files: + - src/PrestaShopBundle/Controller/Admin/ProductController.php +locations: + - backoffice +type: + - action +hookAliases: +--- + +# Hook actionAdminDeleteBefore + +## Information + +Hook locations: + - backoffice + +Hook type: + - action + +Located in: + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/ProductController.php](src/PrestaShopBundle/Controller/Admin/ProductController.php) + +## Hook call in codebase + +```php +dispatchWithParameters( + 'actionAdminDeleteBefore', + $hookEventParameters + ) +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminDuplicateAfter.md b/modules/concepts/hooks/list-of-hooks/actionAdminDuplicateAfter.md new file mode 100644 index 0000000000..99a7f0c5d1 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionAdminDuplicateAfter.md @@ -0,0 +1,35 @@ +--- +menuTitle: actionAdminDuplicateAfter +Title: actionAdminDuplicateAfter +hidden: true +hookTitle: +files: + - src/PrestaShopBundle/Controller/Admin/ProductController.php +locations: + - backoffice +type: + - action +hookAliases: +--- + +# Hook actionAdminDuplicateAfter + +## Information + +Hook locations: + - backoffice + +Hook type: + - action + +Located in: + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/ProductController.php](src/PrestaShopBundle/Controller/Admin/ProductController.php) + +## Hook call in codebase + +```php +dispatchWithParameters( + 'actionAdminDuplicateAfter', + $hookEventParameters + ) +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminDuplicateBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminDuplicateBefore.md new file mode 100644 index 0000000000..6bdc0c679c --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionAdminDuplicateBefore.md @@ -0,0 +1,35 @@ +--- +menuTitle: actionAdminDuplicateBefore +Title: actionAdminDuplicateBefore +hidden: true +hookTitle: +files: + - src/PrestaShopBundle/Controller/Admin/ProductController.php +locations: + - backoffice +type: + - action +hookAliases: +--- + +# Hook actionAdminDuplicateBefore + +## Information + +Hook locations: + - backoffice + +Hook type: + - action + +Located in: + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/ProductController.php](src/PrestaShopBundle/Controller/Admin/ProductController.php) + +## Hook call in codebase + +```php +dispatchWithParameters( + 'actionAdminDuplicateBefore', + $hookEventParameters + ) +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminInternationalGeolocationControllerPostProcessBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminInternationalGeolocationControllerPostProcessBefore.md new file mode 100644 index 0000000000..eccdf51f27 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionAdminInternationalGeolocationControllerPostProcessBefore.md @@ -0,0 +1,35 @@ +--- +menuTitle: actionAdminInternationalGeolocationControllerPostProcessBefore +Title: actionAdminInternationalGeolocationControllerPostProcessBefore +hidden: true +hookTitle: +files: + - src/PrestaShopBundle/Controller/Admin/Improve/International/GeolocationController.php +locations: + - backoffice +type: + - action +hookAliases: +--- + +# Hook actionAdminInternationalGeolocationControllerPostProcessBefore + +## Information + +Hook locations: + - backoffice + +Hook type: + - action + +Located in: + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/Improve/International/GeolocationController.php](src/PrestaShopBundle/Controller/Admin/Improve/International/GeolocationController.php) + +## Hook call in codebase + +```php +dispatchHook( + 'actionAdminInternationalGeolocationControllerPostProcess' . $hookName . 'Before', + ['controller' => $this] + ) +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminInternationalGeolocationControllerPostProcessBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminInternationalGeolocationControllerPostProcessBefore.md index dc9dba396b..6b3b767747 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminInternationalGeolocationControllerPostProcessBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminInternationalGeolocationControllerPostProcessBefore.md @@ -7,13 +7,14 @@ files: - src/PrestaShopBundle/Controller/Admin/Improve/International/GeolocationController.php locations: - backoffice -types: - - symfony +type: + - action +hookAliases: --- -# Hook : actionAdminInternationalGeolocationControllerPostProcessBefore +# Hook actionAdminInternationalGeolocationControllerPostProcessBefore -## Informations +## Information {{% notice tip %}} **On post-process in Admin Improve International Geolocation Controller:** @@ -24,14 +25,14 @@ This hook is called on Admin Improve International Geolocation post-process befo Hook locations: - backoffice -Hook types: - - symfony +Hook type: + - action Located in: - - src/PrestaShopBundle/Controller/Admin/Improve/International/GeolocationController.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/Improve/International/GeolocationController.php](src/PrestaShopBundle/Controller/Admin/Improve/International/GeolocationController.php) -## Hook call with parameters +## Hook call in codebase ```php -dispatchHook('actionAdminInternationalGeolocationControllerPostProcessBefore', ['controller' => $this]); +dispatchHook('actionAdminInternationalGeolocationControllerPostProcessBefore', ['controller' => $this]) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminInternationalLocalizationControllerPostProcessBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminInternationalLocalizationControllerPostProcessBefore.md new file mode 100644 index 0000000000..8728ee5192 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionAdminInternationalLocalizationControllerPostProcessBefore.md @@ -0,0 +1,35 @@ +--- +menuTitle: actionAdminInternationalLocalizationControllerPostProcessBefore +Title: actionAdminInternationalLocalizationControllerPostProcessBefore +hidden: true +hookTitle: +files: + - src/PrestaShopBundle/Controller/Admin/Improve/International/LocalizationController.php +locations: + - backoffice +type: + - action +hookAliases: +--- + +# Hook actionAdminInternationalLocalizationControllerPostProcessBefore + +## Information + +Hook locations: + - backoffice + +Hook type: + - action + +Located in: + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/Improve/International/LocalizationController.php](src/PrestaShopBundle/Controller/Admin/Improve/International/LocalizationController.php) + +## Hook call in codebase + +```php +dispatchHook( + 'actionAdminInternationalLocalizationControllerPostProcess' . $hookName . 'Before', + ['controller' => $this] + ) +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminInternationalLocalizationControllerPostProcessBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminInternationalLocalizationControllerPostProcessBefore.md index 557c4eae13..31d5dc3acd 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminInternationalLocalizationControllerPostProcessBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminInternationalLocalizationControllerPostProcessBefore.md @@ -7,13 +7,14 @@ files: - src/PrestaShopBundle/Controller/Admin/Improve/International/LocalizationController.php locations: - backoffice -types: - - symfony +type: + - action +hookAliases: --- -# Hook : actionAdminInternationalLocalizationControllerPostProcessBefore +# Hook actionAdminInternationalLocalizationControllerPostProcessBefore -## Informations +## Information {{% notice tip %}} **On post-process in Admin Improve International Localization Controller:** @@ -24,14 +25,14 @@ This hook is called on Admin Improve International Localization post-process bef Hook locations: - backoffice -Hook types: - - symfony +Hook type: + - action Located in: - - src/PrestaShopBundle/Controller/Admin/Improve/International/LocalizationController.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/Improve/International/LocalizationController.php](src/PrestaShopBundle/Controller/Admin/Improve/International/LocalizationController.php) -## Hook call with parameters +## Hook call in codebase ```php -dispatchHook('actionAdminInternationalLocalizationControllerPostProcessBefore', ['controller' => $this]); +dispatchHook('actionAdminInternationalLocalizationControllerPostProcessBefore', ['controller' => $this]) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminLoginControllerBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminLoginControllerBefore.md new file mode 100644 index 0000000000..e2cff566c8 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionAdminLoginControllerBefore.md @@ -0,0 +1,43 @@ +--- +menuTitle: actionAdminLoginControllerBefore +Title: actionAdminLoginControllerBefore +hidden: true +hookTitle: Perform actions before admin login controller initialization +files: + - controllers/admin/AdminLoginController.php +locations: + - backoffice +type: + - action +hookAliases: +--- + +# Hook actionAdminLoginControllerBefore + +## Information + +{{% notice tip %}} +**Perform actions before admin login controller initialization:** + +This hook is launched before the initialization of the login controller +{{% /notice %}} + +Hook locations: + - backoffice + +Hook type: + - action + +Located in: + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/admin/AdminLoginController.php](controllers/admin/AdminLoginController.php) + +## Hook call in codebase + +```php +Hook::exec( + 'actionAdminLoginControllerBefore', + [ + 'controller' => $this, + ] + ) +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminLoginControllerForgotAfter.md b/modules/concepts/hooks/list-of-hooks/actionAdminLoginControllerForgotAfter.md new file mode 100644 index 0000000000..f70f9f7df0 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionAdminLoginControllerForgotAfter.md @@ -0,0 +1,44 @@ +--- +menuTitle: actionAdminLoginControllerForgotAfter +Title: actionAdminLoginControllerForgotAfter +hidden: true +hookTitle: Perform actions after admin login controller forgot action initialization +files: + - controllers/admin/AdminLoginController.php +locations: + - backoffice +type: + - action +hookAliases: +--- + +# Hook actionAdminLoginControllerForgotAfter + +## Information + +{{% notice tip %}} +**Perform actions after admin login controller forgot action initialization:** + +This hook is launched after the initialization of the forgot action in login controller +{{% /notice %}} + +Hook locations: + - backoffice + +Hook type: + - action + +Located in: + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/admin/AdminLoginController.php](controllers/admin/AdminLoginController.php) + +## Hook call in codebase + +```php +Hook::exec( + 'actionAdminLoginControllerForgotAfter', + [ + 'controller' => $this, + 'employee' => $employee, + ] + ) +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminLoginControllerForgotBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminLoginControllerForgotBefore.md new file mode 100644 index 0000000000..36377c79c5 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionAdminLoginControllerForgotBefore.md @@ -0,0 +1,44 @@ +--- +menuTitle: actionAdminLoginControllerForgotBefore +Title: actionAdminLoginControllerForgotBefore +hidden: true +hookTitle: Perform actions before admin login controller forgot action initialization +files: + - controllers/admin/AdminLoginController.php +locations: + - backoffice +type: + - action +hookAliases: +--- + +# Hook actionAdminLoginControllerForgotBefore + +## Information + +{{% notice tip %}} +**Perform actions before admin login controller forgot action initialization:** + +This hook is launched before the initialization of the forgot action in login controller +{{% /notice %}} + +Hook locations: + - backoffice + +Hook type: + - action + +Located in: + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/admin/AdminLoginController.php](controllers/admin/AdminLoginController.php) + +## Hook call in codebase + +```php +Hook::exec( + 'actionAdminLoginControllerForgotBefore', + [ + 'controller' => $this, + 'email' => $email, + ] + ) +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminLoginControllerLoginAfter.md b/modules/concepts/hooks/list-of-hooks/actionAdminLoginControllerLoginAfter.md new file mode 100644 index 0000000000..48afd13e0d --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionAdminLoginControllerLoginAfter.md @@ -0,0 +1,45 @@ +--- +menuTitle: actionAdminLoginControllerLoginAfter +Title: actionAdminLoginControllerLoginAfter +hidden: true +hookTitle: Perform actions after admin login controller login action initialization +files: + - controllers/admin/AdminLoginController.php +locations: + - backoffice +type: + - action +hookAliases: +--- + +# Hook actionAdminLoginControllerLoginAfter + +## Information + +{{% notice tip %}} +**Perform actions after admin login controller login action initialization:** + +This hook is launched after the initialization of the login action in login controller +{{% /notice %}} + +Hook locations: + - backoffice + +Hook type: + - action + +Located in: + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/admin/AdminLoginController.php](controllers/admin/AdminLoginController.php) + +## Hook call in codebase + +```php +Hook::exec( + 'actionAdminLoginControllerLoginAfter', + [ + 'controller' => $this, + 'employee' => $this->context->employee, + 'redirect' => $url, + ] + ) +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminLoginControllerLoginBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminLoginControllerLoginBefore.md new file mode 100644 index 0000000000..a61bcb6b73 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionAdminLoginControllerLoginBefore.md @@ -0,0 +1,45 @@ +--- +menuTitle: actionAdminLoginControllerLoginBefore +Title: actionAdminLoginControllerLoginBefore +hidden: true +hookTitle: Perform actions before admin login controller login action initialization +files: + - controllers/admin/AdminLoginController.php +locations: + - backoffice +type: + - action +hookAliases: +--- + +# Hook actionAdminLoginControllerLoginBefore + +## Information + +{{% notice tip %}} +**Perform actions before admin login controller login action initialization:** + +This hook is launched before the initialization of the login action in login controller +{{% /notice %}} + +Hook locations: + - backoffice + +Hook type: + - action + +Located in: + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/admin/AdminLoginController.php](controllers/admin/AdminLoginController.php) + +## Hook call in codebase + +```php +Hook::exec( + 'actionAdminLoginControllerLoginBefore', + [ + 'controller' => $this, + 'password' => $passwd, + 'email' => $email, + ] + ) +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminLoginControllerResetAfter.md b/modules/concepts/hooks/list-of-hooks/actionAdminLoginControllerResetAfter.md new file mode 100644 index 0000000000..f66403b57e --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionAdminLoginControllerResetAfter.md @@ -0,0 +1,44 @@ +--- +menuTitle: actionAdminLoginControllerResetAfter +Title: actionAdminLoginControllerResetAfter +hidden: true +hookTitle: Perform actions after admin login controller reset action initialization +files: + - controllers/admin/AdminLoginController.php +locations: + - backoffice +type: + - action +hookAliases: +--- + +# Hook actionAdminLoginControllerResetAfter + +## Information + +{{% notice tip %}} +**Perform actions after admin login controller reset action initialization:** + +This hook is launched after the initialization of the reset action in login controller +{{% /notice %}} + +Hook locations: + - backoffice + +Hook type: + - action + +Located in: + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/admin/AdminLoginController.php](controllers/admin/AdminLoginController.php) + +## Hook call in codebase + +```php +Hook::exec( + 'actionAdminLoginControllerResetAfter', + [ + 'controller' => $this, + 'employee' => $employee, + ] + ) +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminLoginControllerResetBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminLoginControllerResetBefore.md new file mode 100644 index 0000000000..c9aa011ce0 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionAdminLoginControllerResetBefore.md @@ -0,0 +1,48 @@ +--- +menuTitle: actionAdminLoginControllerResetBefore +Title: actionAdminLoginControllerResetBefore +hidden: true +hookTitle: Perform actions before admin login controller reset action initialization +files: + - controllers/admin/AdminLoginController.php +locations: + - backoffice +type: + - action +hookAliases: +--- + +# Hook actionAdminLoginControllerResetBefore + +## Information + +{{% notice tip %}} +**Perform actions before admin login controller reset action initialization:** + +This hook is launched before the initialization of the reset action in login controller +{{% /notice %}} + +Hook locations: + - backoffice + +Hook type: + - action + +Located in: + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/admin/AdminLoginController.php](controllers/admin/AdminLoginController.php) + +## Hook call in codebase + +```php +Hook::exec( + 'actionAdminLoginControllerResetBefore', + [ + 'controller' => $this, + 'reset_token_value' => $reset_token_value, + 'id_employee' => $id_employee, + 'reset_email' => $reset_email, + 'reset_password' => $reset_password, + 'reset_confirm' => $reset_confirm, + ] + ) +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminLoginControllerSetMedia.md b/modules/concepts/hooks/list-of-hooks/actionAdminLoginControllerSetMedia.md new file mode 100644 index 0000000000..80dde89d66 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionAdminLoginControllerSetMedia.md @@ -0,0 +1,43 @@ +--- +menuTitle: actionAdminLoginControllerSetMedia +Title: actionAdminLoginControllerSetMedia +hidden: true +hookTitle: Set media on admin login page header +files: + - controllers/admin/AdminLoginController.php +locations: + - backoffice +type: + - action +hookAliases: +--- + +# Hook actionAdminLoginControllerSetMedia + +## Information + +{{% notice tip %}} +**Set media on admin login page header:** + +This hook is called after adding media to admin login page header +{{% /notice %}} + +Hook locations: + - backoffice + +Hook type: + - action + +Located in: + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/admin/AdminLoginController.php](controllers/admin/AdminLoginController.php) + +## Hook call in codebase + +```php +Hook::exec( + 'actionAdminLoginControllerSetMedia', + [ + 'controller' => $this, + ] + ) +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminLogsControllerPostProcessBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminLogsControllerPostProcessBefore.md index 19f192d4f1..be6babbc28 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminLogsControllerPostProcessBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminLogsControllerPostProcessBefore.md @@ -7,25 +7,26 @@ files: - src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/LogsController.php locations: - backoffice -types: - - symfony +type: + - action +hookAliases: --- -# Hook : actionAdminLogsControllerPostProcessBefore +# Hook actionAdminLogsControllerPostProcessBefore -## Informations +## Information Hook locations: - backoffice -Hook types: - - symfony +Hook type: + - action Located in: - - src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/LogsController.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/LogsController.php](src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/LogsController.php) -## Hook call with parameters +## Hook call in codebase ```php -dispatchHook('actionAdminLogsControllerPostProcessBefore', ['controller' => $this]); +dispatchHook('actionAdminLogsControllerPostProcessBefore', ['controller' => $this]) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminMaintenanceControllerPostProcessBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminMaintenanceControllerPostProcessBefore.md index b307903ed7..2713cd053d 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminMaintenanceControllerPostProcessBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminMaintenanceControllerPostProcessBefore.md @@ -7,25 +7,26 @@ files: - src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/MaintenanceController.php locations: - backoffice -types: - - symfony +type: + - action +hookAliases: --- -# Hook : actionAdminMaintenanceControllerPostProcessBefore +# Hook actionAdminMaintenanceControllerPostProcessBefore -## Informations +## Information Hook locations: - backoffice -Hook types: - - symfony +Hook type: + - action Located in: - - src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/MaintenanceController.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/MaintenanceController.php](src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/MaintenanceController.php) -## Hook call with parameters +## Hook call in codebase ```php -dispatchHook('actionAdminMaintenanceControllerPostProcessBefore', ['controller' => $this]); +dispatchHook('actionAdminMaintenanceControllerPostProcessBefore', ['controller' => $this]) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminMetaAfterWriteRobotsFile.md b/modules/concepts/hooks/list-of-hooks/actionAdminMetaAfterWriteRobotsFile.md index 3b80bc0d98..c4af6fe1c7 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminMetaAfterWriteRobotsFile.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminMetaAfterWriteRobotsFile.md @@ -7,28 +7,39 @@ files: - classes/Tools.php locations: - backoffice -types: - - legacy +type: + - action +hookAliases: --- -# Hook : actionAdminMetaAfterWriteRobotsFile +# Hook actionAdminMetaAfterWriteRobotsFile -## Informations +## Information Hook locations: - backoffice -Hook types: - - legacy +Hook type: + - action Located in: - - classes/Tools.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Tools.php](classes/Tools.php) + +## Parameters details + +```php + (array) File data, + 'write_fd' => &(resource) File handle + ); +``` -## Hook call with parameters +## Hook call in codebase ```php Hook::exec('actionAdminMetaAfterWriteRobotsFile', [ 'rb_data' => $robots_content, 'write_fd' => &$write_fd, - ]); + ]) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminMetaBeforeWriteRobotsFile.md b/modules/concepts/hooks/list-of-hooks/actionAdminMetaBeforeWriteRobotsFile.md new file mode 100644 index 0000000000..c48bc4b6fa --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionAdminMetaBeforeWriteRobotsFile.md @@ -0,0 +1,43 @@ +--- +menuTitle: actionAdminMetaBeforeWriteRobotsFile +Title: actionAdminMetaBeforeWriteRobotsFile +hidden: true +hookTitle: +files: + - classes/Tools.php +locations: + - backoffice +type: + - action +hookAliases: +--- + +# Hook actionAdminMetaBeforeWriteRobotsFile + +## Information + +Hook locations: + - backoffice + +Hook type: + - action + +Located in: + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Tools.php](classes/Tools.php) + +## Parameters details + +```php + &(array) File data + ); +``` + +## Hook call in codebase + +```php +Hook::exec('actionAdminMetaBeforeWriteRobotsFile', [ + 'rb_data' => &$robots_content, + ]) +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminMetaSave.md b/modules/concepts/hooks/list-of-hooks/actionAdminMetaSave.md new file mode 100644 index 0000000000..372366e848 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionAdminMetaSave.md @@ -0,0 +1,44 @@ +--- +menuTitle: actionAdminMetaSave +Title: actionAdminMetaSave +hidden: true +hookTitle: After saving the configuration in AdminMeta +files: + - src/Adapter/Meta/CommandHandler/AddMetaHandler.php +locations: + - backoffice +type: + - action +hookAliases: + - afterSaveAdminMeta +--- + +# Hook actionAdminMetaSave + +Aliases: + - afterSaveAdminMeta + + + +## Information + +{{% notice tip %}} +**After saving the configuration in AdminMeta:** + +This hook is displayed after saving the configuration in AdminMeta +{{% /notice %}} + +Hook locations: + - backoffice + +Hook type: + - action + +Located in: + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Meta/CommandHandler/AddMetaHandler.php](src/Adapter/Meta/CommandHandler/AddMetaHandler.php) + +## Hook call in codebase + +```php +dispatchWithParameters('actionAdminMetaSave') +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminOrdersTrackingNumberUpdate.md b/modules/concepts/hooks/list-of-hooks/actionAdminOrdersTrackingNumberUpdate.md index 3e4d313a6b..b92f0e0ecd 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminOrdersTrackingNumberUpdate.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminOrdersTrackingNumberUpdate.md @@ -7,13 +7,14 @@ files: - src/Adapter/Order/CommandHandler/UpdateOrderShippingDetailsHandler.php locations: - backoffice -types: - - legacy +type: + - action +hookAliases: --- -# Hook : actionAdminOrdersTrackingNumberUpdate +# Hook actionAdminOrdersTrackingNumberUpdate -## Informations +## Information {{% notice tip %}} **After setting the tracking number for the order:** @@ -24,21 +25,29 @@ This hook allows you to execute code after the unique tracking number for the or Hook locations: - backoffice -Hook types: - - legacy +Hook type: + - action Located in: - - src/Adapter/Order/CommandHandler/UpdateOrderShippingDetailsHandler.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Order/CommandHandler/UpdateOrderShippingDetailsHandler.php](src/Adapter/Order/CommandHandler/UpdateOrderShippingDetailsHandler.php) + +## Parameters details + +```php + (Order), + 'customer' => (Customer), + 'carrier' => (Carrier) + ); +``` -## Hook call with parameters +## Hook call in codebase ```php Hook::exec('actionAdminOrdersTrackingNumberUpdate', [ 'order' => $order, 'customer' => $customer, 'carrier' => $carrier, - ], null, false, true, false, $order->id_shop); - } - } finally { - $this->contextStateManager->restorePreviousContext(); + ], null, false, true, false, $order->id_shop) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminPreferencesControllerPostProcessBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminPreferencesControllerPostProcessBefore.md index e856c80699..6b8bcbaaa3 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminPreferencesControllerPostProcessBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminPreferencesControllerPostProcessBefore.md @@ -7,25 +7,26 @@ files: - src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/PreferencesController.php locations: - backoffice -types: - - symfony +type: + - action +hookAliases: --- -# Hook : actionAdminPreferencesControllerPostProcessBefore +# Hook actionAdminPreferencesControllerPostProcessBefore -## Informations +## Information Hook locations: - backoffice -Hook types: - - symfony +Hook type: + - action Located in: - - src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/PreferencesController.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/PreferencesController.php](src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/PreferencesController.php) -## Hook call with parameters +## Hook call in codebase ```php -dispatchHook('actionAdminPreferencesControllerPostProcessBefore', ['controller' => $this]); +dispatchHook('actionAdminPreferencesControllerPostProcessBefore', ['controller' => $this]) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerActivateAfter.md b/modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerActivateAfter.md new file mode 100644 index 0000000000..7c7a4d289b --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerActivateAfter.md @@ -0,0 +1,35 @@ +--- +menuTitle: actionAdminProductsControllerActivateAfter +Title: actionAdminProductsControllerActivateAfter +hidden: true +hookTitle: +files: + - src/PrestaShopBundle/Controller/Admin/ProductController.php +locations: + - backoffice +type: + - action +hookAliases: +--- + +# Hook actionAdminProductsControllerActivateAfter + +## Information + +Hook locations: + - backoffice + +Hook type: + - action + +Located in: + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/ProductController.php](src/PrestaShopBundle/Controller/Admin/ProductController.php) + +## Hook call in codebase + +```php +dispatchWithParameters( + 'actionAdminProductsControllerActivateAfter', + $hookEventParameters + ) +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerActivateBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerActivateBefore.md new file mode 100644 index 0000000000..f6668e3c2f --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerActivateBefore.md @@ -0,0 +1,35 @@ +--- +menuTitle: actionAdminProductsControllerActivateBefore +Title: actionAdminProductsControllerActivateBefore +hidden: true +hookTitle: +files: + - src/PrestaShopBundle/Controller/Admin/ProductController.php +locations: + - backoffice +type: + - action +hookAliases: +--- + +# Hook actionAdminProductsControllerActivateBefore + +## Information + +Hook locations: + - backoffice + +Hook type: + - action + +Located in: + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/ProductController.php](src/PrestaShopBundle/Controller/Admin/ProductController.php) + +## Hook call in codebase + +```php +dispatchWithParameters( + 'actionAdminProductsControllerActivateBefore', + $hookEventParameters + ) +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerDeactivateAfter.md b/modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerDeactivateAfter.md new file mode 100644 index 0000000000..3aa2c6e088 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerDeactivateAfter.md @@ -0,0 +1,35 @@ +--- +menuTitle: actionAdminProductsControllerDeactivateAfter +Title: actionAdminProductsControllerDeactivateAfter +hidden: true +hookTitle: +files: + - src/PrestaShopBundle/Controller/Admin/ProductController.php +locations: + - backoffice +type: + - action +hookAliases: +--- + +# Hook actionAdminProductsControllerDeactivateAfter + +## Information + +Hook locations: + - backoffice + +Hook type: + - action + +Located in: + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/ProductController.php](src/PrestaShopBundle/Controller/Admin/ProductController.php) + +## Hook call in codebase + +```php +dispatchWithParameters( + 'actionAdminProductsControllerDeactivateAfter', + $hookEventParameters + ) +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerDeactivateBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerDeactivateBefore.md new file mode 100644 index 0000000000..51d0db3667 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerDeactivateBefore.md @@ -0,0 +1,35 @@ +--- +menuTitle: actionAdminProductsControllerDeactivateBefore +Title: actionAdminProductsControllerDeactivateBefore +hidden: true +hookTitle: +files: + - src/PrestaShopBundle/Controller/Admin/ProductController.php +locations: + - backoffice +type: + - action +hookAliases: +--- + +# Hook actionAdminProductsControllerDeactivateBefore + +## Information + +Hook locations: + - backoffice + +Hook type: + - action + +Located in: + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/ProductController.php](src/PrestaShopBundle/Controller/Admin/ProductController.php) + +## Hook call in codebase + +```php +dispatchWithParameters( + 'actionAdminProductsControllerDeactivateBefore', + $hookEventParameters + ) +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerDeleteAfter.md b/modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerDeleteAfter.md new file mode 100644 index 0000000000..9031d2731f --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerDeleteAfter.md @@ -0,0 +1,35 @@ +--- +menuTitle: actionAdminProductsControllerDeleteAfter +Title: actionAdminProductsControllerDeleteAfter +hidden: true +hookTitle: +files: + - src/PrestaShopBundle/Controller/Admin/ProductController.php +locations: + - backoffice +type: + - action +hookAliases: +--- + +# Hook actionAdminProductsControllerDeleteAfter + +## Information + +Hook locations: + - backoffice + +Hook type: + - action + +Located in: + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/ProductController.php](src/PrestaShopBundle/Controller/Admin/ProductController.php) + +## Hook call in codebase + +```php +dispatchWithParameters( + 'actionAdminProductsControllerDeleteAfter', + $hookEventParameters + ) +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerDeleteBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerDeleteBefore.md new file mode 100644 index 0000000000..ddd62aaaef --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerDeleteBefore.md @@ -0,0 +1,35 @@ +--- +menuTitle: actionAdminProductsControllerDeleteBefore +Title: actionAdminProductsControllerDeleteBefore +hidden: true +hookTitle: +files: + - src/PrestaShopBundle/Controller/Admin/ProductController.php +locations: + - backoffice +type: + - action +hookAliases: +--- + +# Hook actionAdminProductsControllerDeleteBefore + +## Information + +Hook locations: + - backoffice + +Hook type: + - action + +Located in: + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/ProductController.php](src/PrestaShopBundle/Controller/Admin/ProductController.php) + +## Hook call in codebase + +```php +dispatchWithParameters( + 'actionAdminProductsControllerDeleteBefore', + $hookEventParameters + ) +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerDuplicateAfter.md b/modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerDuplicateAfter.md new file mode 100644 index 0000000000..97ee5e51ec --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerDuplicateAfter.md @@ -0,0 +1,35 @@ +--- +menuTitle: actionAdminProductsControllerDuplicateAfter +Title: actionAdminProductsControllerDuplicateAfter +hidden: true +hookTitle: +files: + - src/PrestaShopBundle/Controller/Admin/ProductController.php +locations: + - backoffice +type: + - action +hookAliases: +--- + +# Hook actionAdminProductsControllerDuplicateAfter + +## Information + +Hook locations: + - backoffice + +Hook type: + - action + +Located in: + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/ProductController.php](src/PrestaShopBundle/Controller/Admin/ProductController.php) + +## Hook call in codebase + +```php +dispatchWithParameters( + 'actionAdminProductsControllerDuplicateAfter', + $hookEventParameters + ) +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerDuplicateBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerDuplicateBefore.md new file mode 100644 index 0000000000..40285f8c2f --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerDuplicateBefore.md @@ -0,0 +1,35 @@ +--- +menuTitle: actionAdminProductsControllerDuplicateBefore +Title: actionAdminProductsControllerDuplicateBefore +hidden: true +hookTitle: +files: + - src/PrestaShopBundle/Controller/Admin/ProductController.php +locations: + - backoffice +type: + - action +hookAliases: +--- + +# Hook actionAdminProductsControllerDuplicateBefore + +## Information + +Hook locations: + - backoffice + +Hook type: + - action + +Located in: + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/ProductController.php](src/PrestaShopBundle/Controller/Admin/ProductController.php) + +## Hook call in codebase + +```php +dispatchWithParameters( + 'actionAdminProductsControllerDuplicateBefore', + $hookEventParameters + ) +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerSortAfter.md b/modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerSortAfter.md new file mode 100644 index 0000000000..2b2f436853 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerSortAfter.md @@ -0,0 +1,35 @@ +--- +menuTitle: actionAdminProductsControllerSortAfter +Title: actionAdminProductsControllerSortAfter +hidden: true +hookTitle: +files: + - src/PrestaShopBundle/Controller/Admin/ProductController.php +locations: + - backoffice +type: + - action +hookAliases: +--- + +# Hook actionAdminProductsControllerSortAfter + +## Information + +Hook locations: + - backoffice + +Hook type: + - action + +Located in: + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/ProductController.php](src/PrestaShopBundle/Controller/Admin/ProductController.php) + +## Hook call in codebase + +```php +dispatchWithParameters( + 'actionAdminProductsControllerSortAfter', + $hookEventParameters + ) +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerSortBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerSortBefore.md new file mode 100644 index 0000000000..b86dfffb18 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerSortBefore.md @@ -0,0 +1,35 @@ +--- +menuTitle: actionAdminProductsControllerSortBefore +Title: actionAdminProductsControllerSortBefore +hidden: true +hookTitle: +files: + - src/PrestaShopBundle/Controller/Admin/ProductController.php +locations: + - backoffice +type: + - action +hookAliases: +--- + +# Hook actionAdminProductsControllerSortBefore + +## Information + +Hook locations: + - backoffice + +Hook type: + - action + +Located in: + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/ProductController.php](src/PrestaShopBundle/Controller/Admin/ProductController.php) + +## Hook call in codebase + +```php +dispatchWithParameters( + 'actionAdminProductsControllerSortBefore', + $hookEventParameters + ) +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminProductsListingFieldsModifier.md b/modules/concepts/hooks/list-of-hooks/actionAdminProductsListingFieldsModifier.md index b91b69ba94..8f61e71ca5 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminProductsListingFieldsModifier.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminProductsListingFieldsModifier.md @@ -7,24 +7,39 @@ files: - src/Adapter/Product/AdminProductDataProvider.php locations: - backoffice -types: - - legacy +type: + - action +hookAliases: --- -# Hook : actionAdminProductsListingFieldsModifier +# Hook actionAdminProductsListingFieldsModifier -## Informations +## Information Hook locations: - backoffice -Hook types: - - legacy +Hook type: + - action Located in: - - src/Adapter/Product/AdminProductDataProvider.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Product/AdminProductDataProvider.php](src/Adapter/Product/AdminProductDataProvider.php) + +## Parameters details + +```php + (string) PrestaShop version, + 'sql_select' => &(array), + 'sql_table' => &(array), + 'sql_where' => &(array), + 'sql_order' => &(array), + 'sql_limit' => &(string), + ); +``` -## Hook call with parameters +## Hook call in codebase ```php Hook::exec('actionAdminProductsListingFieldsModifier', [ @@ -35,5 +50,5 @@ Hook::exec('actionAdminProductsListingFieldsModifier', [ 'sql_group_by' => &$sqlGroupBy, 'sql_order' => &$sqlOrder, 'sql_limit' => &$sqlLimit, - ]); + ]) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminProductsListingResultsModifier.md b/modules/concepts/hooks/list-of-hooks/actionAdminProductsListingResultsModifier.md index 965e519e53..196478a15e 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminProductsListingResultsModifier.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminProductsListingResultsModifier.md @@ -7,29 +7,41 @@ files: - src/Adapter/Product/AdminProductDataProvider.php locations: - backoffice -types: - - legacy +type: + - action +hookAliases: --- -# Hook : actionAdminProductsListingResultsModifier +# Hook actionAdminProductsListingResultsModifier -## Informations +## Information Hook locations: - backoffice -Hook types: - - legacy +Hook type: + - action Located in: - - src/Adapter/Product/AdminProductDataProvider.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Product/AdminProductDataProvider.php](src/Adapter/Product/AdminProductDataProvider.php) + +## Parameters details + +```php + (string) PrestaShop version, + 'products' => &(PDOStatement), + 'total' => (int), + ); +``` -## Hook call with parameters +## Hook call in codebase ```php Hook::exec('actionAdminProductsListingResultsModifier', [ '_ps_version' => AppKernel::VERSION, 'products' => &$products, 'total' => $total, - ]); + ]) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminSecurityControllerPostProcessBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminSecurityControllerPostProcessBefore.md index 3d066b5d4a..e396fae58f 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminSecurityControllerPostProcessBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminSecurityControllerPostProcessBefore.md @@ -7,13 +7,14 @@ files: - src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/SecurityController.php locations: - backoffice -types: - - symfony +type: + - action +hookAliases: --- -# Hook : actionAdminSecurityControllerPostProcessBefore +# Hook actionAdminSecurityControllerPostProcessBefore -## Informations +## Information {{% notice tip %}} **On post-process in Admin Security Controller:** @@ -24,14 +25,14 @@ This hook is called on Admin Security Controller post-process before processing Hook locations: - backoffice -Hook types: - - symfony +Hook type: + - action Located in: - - src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/SecurityController.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/SecurityController.php](src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/SecurityController.php) -## Hook call with parameters +## Hook call in codebase ```php -dispatchHook('actionAdminSecurityControllerPostProcessBefore', ['controller' => $this]); +dispatchHook('actionAdminSecurityControllerPostProcessBefore', ['controller' => $this]) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminShippingPreferencesControllerPostProcessBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminShippingPreferencesControllerPostProcessBefore.md index 3ee6cae526..14424e4eed 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminShippingPreferencesControllerPostProcessBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminShippingPreferencesControllerPostProcessBefore.md @@ -7,13 +7,14 @@ files: - src/PrestaShopBundle/Controller/Admin/Improve/Shipping/PreferencesController.php locations: - backoffice -types: - - symfony +type: + - action +hookAliases: --- -# Hook : actionAdminShippingPreferencesControllerPostProcessBefore +# Hook actionAdminShippingPreferencesControllerPostProcessBefore -## Informations +## Information {{% notice tip %}} **On post-process in Admin Improve Shipping Preferences Controller:** @@ -24,14 +25,14 @@ This hook is called on Admin Improve Shipping Preferences post-process before pr Hook locations: - backoffice -Hook types: - - symfony +Hook type: + - action Located in: - - src/PrestaShopBundle/Controller/Admin/Improve/Shipping/PreferencesController.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/Improve/Shipping/PreferencesController.php](src/PrestaShopBundle/Controller/Admin/Improve/Shipping/PreferencesController.php) -## Hook call with parameters +## Hook call in codebase ```php -dispatchHook('actionAdminShippingPreferencesControllerPostProcessBefore', ['controller' => $this]); +dispatchHook('actionAdminShippingPreferencesControllerPostProcessBefore', ['controller' => $this]) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminShippingPreferencesControllerPostProcessCarrierOptionsBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminShippingPreferencesControllerPostProcessCarrierOptionsBefore.md new file mode 100644 index 0000000000..144b633925 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionAdminShippingPreferencesControllerPostProcessCarrierOptionsBefore.md @@ -0,0 +1,41 @@ +--- +menuTitle: actionAdminShippingPreferencesControllerPostProcessCarrierOptionsBefore +Title: actionAdminShippingPreferencesControllerPostProcessCarrierOptionsBefore +hidden: true +hookTitle: On post-process in Admin Improve Shipping Preferences Controller +files: + - src/PrestaShopBundle/Controller/Admin/Improve/Shipping/PreferencesController.php +locations: + - backoffice +type: + - action +hookAliases: +--- + +# Hook actionAdminShippingPreferencesControllerPostProcessCarrierOptionsBefore + +## Information + +{{% notice tip %}} +**On post-process in Admin Improve Shipping Preferences Controller:** + +This hook is called on Admin Improve Shipping Preferences post-process before processing the Carrier Options form +{{% /notice %}} + +Hook locations: + - backoffice + +Hook type: + - action + +Located in: + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/Improve/Shipping/PreferencesController.php](src/PrestaShopBundle/Controller/Admin/Improve/Shipping/PreferencesController.php) + +## Hook call in codebase + +```php +dispatchHook( + 'actionAdminShippingPreferencesControllerPostProcessCarrierOptionsBefore', + ['controller' => $this] + ) +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminShippingPreferencesControllerPostProcessHandlingBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminShippingPreferencesControllerPostProcessHandlingBefore.md new file mode 100644 index 0000000000..60ebd330d1 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionAdminShippingPreferencesControllerPostProcessHandlingBefore.md @@ -0,0 +1,41 @@ +--- +menuTitle: actionAdminShippingPreferencesControllerPostProcessHandlingBefore +Title: actionAdminShippingPreferencesControllerPostProcessHandlingBefore +hidden: true +hookTitle: On post-process in Admin Improve Shipping Preferences Controller +files: + - src/PrestaShopBundle/Controller/Admin/Improve/Shipping/PreferencesController.php +locations: + - backoffice +type: + - action +hookAliases: +--- + +# Hook actionAdminShippingPreferencesControllerPostProcessHandlingBefore + +## Information + +{{% notice tip %}} +**On post-process in Admin Improve Shipping Preferences Controller:** + +This hook is called on Admin Improve Shipping Preferences post-process before processing the Handling form +{{% /notice %}} + +Hook locations: + - backoffice + +Hook type: + - action + +Located in: + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/Improve/Shipping/PreferencesController.php](src/PrestaShopBundle/Controller/Admin/Improve/Shipping/PreferencesController.php) + +## Hook call in codebase + +```php +dispatchHook( + 'actionAdminShippingPreferencesControllerPostProcessHandlingBefore', + ['controller' => $this] + ) +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminShopParametersMetaControllerPostProcessBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminShopParametersMetaControllerPostProcessBefore.md new file mode 100644 index 0000000000..1b4cdc1836 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionAdminShopParametersMetaControllerPostProcessBefore.md @@ -0,0 +1,35 @@ +--- +menuTitle: actionAdminShopParametersMetaControllerPostProcessBefore +Title: actionAdminShopParametersMetaControllerPostProcessBefore +hidden: true +hookTitle: +files: + - src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/MetaController.php +locations: + - backoffice +type: + - action +hookAliases: +--- + +# Hook actionAdminShopParametersMetaControllerPostProcessBefore + +## Information + +Hook locations: + - backoffice + +Hook type: + - action + +Located in: + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/MetaController.php](src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/MetaController.php) + +## Hook call in codebase + +```php +dispatchHook( + 'actionAdminShopParametersMetaControllerPostProcess' . $hookName . 'Before', + ['controller' => $this] + ) +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminShopParametersOrderPreferencesControllerPostProcessBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminShopParametersOrderPreferencesControllerPostProcessBefore.md new file mode 100644 index 0000000000..91190276a7 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionAdminShopParametersOrderPreferencesControllerPostProcessBefore.md @@ -0,0 +1,35 @@ +--- +menuTitle: actionAdminShopParametersOrderPreferencesControllerPostProcessBefore +Title: actionAdminShopParametersOrderPreferencesControllerPostProcessBefore +hidden: true +hookTitle: +files: + - src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/OrderPreferencesController.php +locations: + - backoffice +type: + - action +hookAliases: +--- + +# Hook actionAdminShopParametersOrderPreferencesControllerPostProcessBefore + +## Information + +Hook locations: + - backoffice + +Hook type: + - action + +Located in: + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/OrderPreferencesController.php](src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/OrderPreferencesController.php) + +## Hook call in codebase + +```php +dispatchHook( + 'actionAdminShopParametersOrderPreferencesControllerPostProcess' . $hookName . 'Before', + ['controller' => $this] + ) +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminShopParametersOrderPreferencesControllerPostProcessBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminShopParametersOrderPreferencesControllerPostProcessBefore.md index 77194098c6..a49b58965f 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminShopParametersOrderPreferencesControllerPostProcessBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminShopParametersOrderPreferencesControllerPostProcessBefore.md @@ -7,13 +7,14 @@ files: - src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/OrderPreferencesController.php locations: - backoffice -types: - - symfony +type: + - action +hookAliases: --- -# Hook : actionAdminShopParametersOrderPreferencesControllerPostProcessBefore +# Hook actionAdminShopParametersOrderPreferencesControllerPostProcessBefore -## Informations +## Information {{% notice tip %}} **On post-process in Admin Configure Shop Parameters Order Preferences Controller:** @@ -24,14 +25,14 @@ This hook is called on Admin Configure Shop Parameters Order Preferences post-pr Hook locations: - backoffice -Hook types: - - symfony +Hook type: + - action Located in: - - src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/OrderPreferencesController.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/OrderPreferencesController.php](src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/OrderPreferencesController.php) -## Hook call with parameters +## Hook call in codebase ```php -dispatchHook('actionAdminShopParametersOrderPreferencesControllerPostProcessBefore', ['controller' => $this]); +dispatchHook('actionAdminShopParametersOrderPreferencesControllerPostProcessBefore', ['controller' => $this]) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminShopParametersProductPreferencesControllerPostProcessBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminShopParametersProductPreferencesControllerPostProcessBefore.md new file mode 100644 index 0000000000..68bf687c3b --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionAdminShopParametersProductPreferencesControllerPostProcessBefore.md @@ -0,0 +1,35 @@ +--- +menuTitle: actionAdminShopParametersProductPreferencesControllerPostProcessBefore +Title: actionAdminShopParametersProductPreferencesControllerPostProcessBefore +hidden: true +hookTitle: +files: + - src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/ProductPreferencesController.php +locations: + - backoffice +type: + - action +hookAliases: +--- + +# Hook actionAdminShopParametersProductPreferencesControllerPostProcessBefore + +## Information + +Hook locations: + - backoffice + +Hook type: + - action + +Located in: + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/ProductPreferencesController.php](src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/ProductPreferencesController.php) + +## Hook call in codebase + +```php +dispatchHook( + 'actionAdminShopParametersProductPreferencesControllerPostProcess' . $hookName . 'Before', + ['controller' => $this] + ) +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminShopParametersProductPreferencesControllerPostProcessBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminShopParametersProductPreferencesControllerPostProcessBefore.md index 06d1ffcc47..d6538737be 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminShopParametersProductPreferencesControllerPostProcessBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminShopParametersProductPreferencesControllerPostProcessBefore.md @@ -7,25 +7,26 @@ files: - src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/ProductPreferencesController.php locations: - backoffice -types: - - symfony +type: + - action +hookAliases: --- -# Hook : actionAdminShopParametersProductPreferencesControllerPostProcessBefore +# Hook actionAdminShopParametersProductPreferencesControllerPostProcessBefore -## Informations +## Information Hook locations: - backoffice -Hook types: - - symfony +Hook type: + - action Located in: - - src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/ProductPreferencesController.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/ProductPreferencesController.php](src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/ProductPreferencesController.php) -## Hook call with parameters +## Hook call in codebase ```php -dispatchHook('actionAdminShopParametersProductPreferencesControllerPostProcessBefore', ['controller' => $this]); +dispatchHook('actionAdminShopParametersProductPreferencesControllerPostProcessBefore', ['controller' => $this]) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminSortAfter.md b/modules/concepts/hooks/list-of-hooks/actionAdminSortAfter.md new file mode 100644 index 0000000000..c47644653f --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionAdminSortAfter.md @@ -0,0 +1,35 @@ +--- +menuTitle: actionAdminSortAfter +Title: actionAdminSortAfter +hidden: true +hookTitle: +files: + - src/PrestaShopBundle/Controller/Admin/ProductController.php +locations: + - backoffice +type: + - action +hookAliases: +--- + +# Hook actionAdminSortAfter + +## Information + +Hook locations: + - backoffice + +Hook type: + - action + +Located in: + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/ProductController.php](src/PrestaShopBundle/Controller/Admin/ProductController.php) + +## Hook call in codebase + +```php +dispatchWithParameters( + 'actionAdminSortAfter', + $hookEventParameters + ) +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminSortBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminSortBefore.md new file mode 100644 index 0000000000..5385915bad --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionAdminSortBefore.md @@ -0,0 +1,35 @@ +--- +menuTitle: actionAdminSortBefore +Title: actionAdminSortBefore +hidden: true +hookTitle: +files: + - src/PrestaShopBundle/Controller/Admin/ProductController.php +locations: + - backoffice +type: + - action +hookAliases: +--- + +# Hook actionAdminSortBefore + +## Information + +Hook locations: + - backoffice + +Hook type: + - action + +Located in: + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/ProductController.php](src/PrestaShopBundle/Controller/Admin/ProductController.php) + +## Hook call in codebase + +```php +dispatchWithParameters( + 'actionAdminSortBefore', + $hookEventParameters + ) +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminThemesControllerUpdateoptionsAfter.md b/modules/concepts/hooks/list-of-hooks/actionAdminThemesControllerUpdateoptionsAfter.md new file mode 100644 index 0000000000..d501822f8f --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionAdminThemesControllerUpdateoptionsAfter.md @@ -0,0 +1,32 @@ +--- +menuTitle: actionAdminThemesControllerUpdateoptionsAfter +Title: actionAdminThemesControllerUpdateoptionsAfter +hidden: true +hookTitle: +files: + - src/Adapter/Shop/CommandHandler/UploadLogosHandler.php +locations: + - backoffice +type: + - action +hookAliases: +--- + +# Hook actionAdminThemesControllerUpdateoptionsAfter + +## Information + +Hook locations: + - backoffice + +Hook type: + - action + +Located in: + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Shop/CommandHandler/UploadLogosHandler.php](src/Adapter/Shop/CommandHandler/UploadLogosHandler.php) + +## Hook call in codebase + +```php +dispatchWithParameters('actionAdminThemesControllerUpdate_optionsAfter') +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionAfterCreateFormHandler.md b/modules/concepts/hooks/list-of-hooks/actionAfterCreateFormHandler.md index bc4877679f..4e60529b15 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAfterCreateFormHandler.md +++ b/modules/concepts/hooks/list-of-hooks/actionAfterCreateFormHandler.md @@ -7,28 +7,29 @@ files: - src/Core/Form/IdentifiableObject/Handler/FormHandler.php locations: - frontoffice -types: - - symfony +type: + - action +hookAliases: --- -# Hook : actionAfterCreateFormHandler +# Hook actionAfterCreateFormHandler -## Informations +## Information Hook locations: - frontoffice -Hook types: - - symfony +Hook type: + - action Located in: - - src/Core/Form/IdentifiableObject/Handler/FormHandler.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Core/Form/IdentifiableObject/Handler/FormHandler.php](src/Core/Form/IdentifiableObject/Handler/FormHandler.php) -## Hook call with parameters +## Hook call in codebase ```php dispatchWithParameters('actionAfterCreate' . Container::camelize($form->getName()) . 'FormHandler', [ 'id' => $id, 'form_data' => &$data, - ]); + ]) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionAfterUpdateFormHandler.md b/modules/concepts/hooks/list-of-hooks/actionAfterUpdateFormHandler.md index 31bbd1acc3..a9b0455cf1 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAfterUpdateFormHandler.md +++ b/modules/concepts/hooks/list-of-hooks/actionAfterUpdateFormHandler.md @@ -7,28 +7,29 @@ files: - src/Core/Form/IdentifiableObject/Handler/FormHandler.php locations: - frontoffice -types: - - symfony +type: + - action +hookAliases: --- -# Hook : actionAfterUpdateFormHandler +# Hook actionAfterUpdateFormHandler -## Informations +## Information Hook locations: - frontoffice -Hook types: - - symfony +Hook type: + - action Located in: - - src/Core/Form/IdentifiableObject/Handler/FormHandler.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Core/Form/IdentifiableObject/Handler/FormHandler.php](src/Core/Form/IdentifiableObject/Handler/FormHandler.php) -## Hook call with parameters +## Hook call in codebase ```php dispatchWithParameters('actionAfterUpdate' . Container::camelize($form->getName()) . 'FormHandler', [ 'id' => $id, 'form_data' => &$data, - ]); + ]) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionAjaxDie.md b/modules/concepts/hooks/list-of-hooks/actionAjaxDie.md deleted file mode 100644 index 1ba7f44f58..0000000000 --- a/modules/concepts/hooks/list-of-hooks/actionAjaxDie.md +++ /dev/null @@ -1,31 +0,0 @@ ---- -menuTitle: actionAjaxDie -Title: actionAjaxDie -hidden: true -hookTitle: -files: - - classes/controller/Controller.php -locations: - - frontoffice -types: - - legacy ---- - -# Hook : actionAjaxDie - -## Informations - -Hook locations: - - frontoffice - -Hook types: - - legacy - -Located in: - - classes/controller/Controller.php - -## Hook call with parameters - -```php -Hook::exec('actionAjaxDie' . $controller . $method . 'Before', ['value' => $value]); -``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionAjaxDieBefore.md b/modules/concepts/hooks/list-of-hooks/actionAjaxDieBefore.md new file mode 100644 index 0000000000..44468ef07c --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionAjaxDieBefore.md @@ -0,0 +1,32 @@ +--- +menuTitle: actionAjaxDieBefore +Title: actionAjaxDieBefore +hidden: true +hookTitle: +files: + - classes/controller/Controller.php +locations: + - frontoffice +type: + - action +hookAliases: +--- + +# Hook actionAjaxDieBefore + +## Information + +Hook locations: + - frontoffice + +Hook type: + - action + +Located in: + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/Controller.php](classes/controller/Controller.php) + +## Hook call in codebase + +```php +Hook::exec('actionAjaxDie' . $controller . $method . 'Before', ['value' => $value]) +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionAjaxDieBefore.md b/modules/concepts/hooks/list-of-hooks/actionAjaxDieBefore.md index 823dfe191c..ecc2eee018 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAjaxDieBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAjaxDieBefore.md @@ -7,25 +7,36 @@ files: - classes/controller/Controller.php locations: - frontoffice -types: - - legacy +type: + - action +hookAliases: + - actionBeforeAjaxDie --- -# Hook : actionAjaxDieBefore +# Hook actionAjaxDieBefore -## Informations +Aliases: + - actionBeforeAjaxDie + + + +## Information + +{{% notice warning %}} +**Deprecated:** Since 1.6.1.1 +{{% /notice %}} Hook locations: - frontoffice -Hook types: - - legacy +Hook type: + - action Located in: - - classes/controller/Controller.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/Controller.php](classes/controller/Controller.php) -## Hook call with parameters +## Hook call in codebase ```php -Hook::exec('actionAjaxDieBefore', ['controller' => $controller, 'method' => $method, 'value' => $value]); +Hook::exec('actionAjaxDieBefore', ['controller' => $controller, 'method' => $method, 'value' => $value]) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionAttributeCombinationDelete.md b/modules/concepts/hooks/list-of-hooks/actionAttributeCombinationDelete.md index 03beda0743..0ac5983b33 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAttributeCombinationDelete.md +++ b/modules/concepts/hooks/list-of-hooks/actionAttributeCombinationDelete.md @@ -7,25 +7,26 @@ files: - classes/Combination.php locations: - frontoffice -types: - - legacy +type: + - action +hookAliases: --- -# Hook : actionAttributeCombinationDelete +# Hook actionAttributeCombinationDelete -## Informations +## Information Hook locations: - frontoffice -Hook types: - - legacy +Hook type: + - action Located in: - - classes/Combination.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Combination.php](classes/Combination.php) -## Hook call with parameters +## Hook call in codebase ```php -Hook::exec('actionAttributeCombinationDelete', ['id_product_attribute' => (int) $this->id]); +Hook::exec('actionAttributeCombinationDelete', ['id_product_attribute' => (int) $this->id]) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionAttributeCombinationSave.md b/modules/concepts/hooks/list-of-hooks/actionAttributeCombinationSave.md index ec7dbb1345..1b4ef85ec0 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAttributeCombinationSave.md +++ b/modules/concepts/hooks/list-of-hooks/actionAttributeCombinationSave.md @@ -7,25 +7,26 @@ files: - classes/Combination.php locations: - frontoffice -types: - - legacy +type: + - action +hookAliases: --- -# Hook : actionAttributeCombinationSave +# Hook actionAttributeCombinationSave -## Informations +## Information Hook locations: - frontoffice -Hook types: - - legacy +Hook type: + - action Located in: - - classes/Combination.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Combination.php](classes/Combination.php) -## Hook call with parameters +## Hook call in codebase ```php -Hook::exec('actionAttributeCombinationSave', ['id_product_attribute' => (int) $this->id, 'id_attributes' => $idsAttribute]); +Hook::exec('actionAttributeCombinationSave', ['id_product_attribute' => (int) $this->id, 'id_attributes' => $idsAttribute]) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionAttributeDelete.md b/modules/concepts/hooks/list-of-hooks/actionAttributeDelete.md index 04272d02cf..47cd8ecdc6 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAttributeDelete.md +++ b/modules/concepts/hooks/list-of-hooks/actionAttributeDelete.md @@ -7,13 +7,20 @@ files: - classes/ProductAttribute.php locations: - frontoffice -types: - - legacy +type: + - action +hookAliases: + - afterDeleteAttribute --- -# Hook : actionAttributeDelete +# Hook actionAttributeDelete -## Informations +Aliases: + - afterDeleteAttribute + + + +## Information {{% notice tip %}} **Deleting an attributes features value:** @@ -24,14 +31,14 @@ This hook is called while deleting an attributes features value Hook locations: - frontoffice -Hook types: - - legacy +Hook type: + - action Located in: - - classes/ProductAttribute.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/ProductAttribute.php](classes/ProductAttribute.php) -## Hook call with parameters +## Hook call in codebase ```php -Hook::exec('actionAttributeDelete', ['id_attribute' => $this->id]); +Hook::exec('actionAttributeDelete', ['id_attribute' => $this->id]) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionAttributeGroupDelete.md b/modules/concepts/hooks/list-of-hooks/actionAttributeGroupDelete.md index b13bb0e5d3..d9fe8fb563 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAttributeGroupDelete.md +++ b/modules/concepts/hooks/list-of-hooks/actionAttributeGroupDelete.md @@ -7,13 +7,20 @@ files: - classes/AttributeGroup.php locations: - frontoffice -types: - - legacy +type: + - action +hookAliases: + - afterDeleteAttributeGroup --- -# Hook : actionAttributeGroupDelete +# Hook actionAttributeGroupDelete -## Informations +Aliases: + - afterDeleteAttributeGroup + + + +## Information {{% notice tip %}} **Deleting attribute group:** @@ -24,14 +31,14 @@ This hook is called while deleting an attributes group Hook locations: - frontoffice -Hook types: - - legacy +Hook type: + - action Located in: - - classes/AttributeGroup.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/AttributeGroup.php](classes/AttributeGroup.php) -## Hook call with parameters +## Hook call in codebase ```php -Hook::exec('actionAttributeGroupDelete', ['id_attribute_group' => $this->id]); +Hook::exec('actionAttributeGroupDelete', ['id_attribute_group' => $this->id]) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionAttributeGroupSave.md b/modules/concepts/hooks/list-of-hooks/actionAttributeGroupSave.md index 38d693a23d..28efed0187 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAttributeGroupSave.md +++ b/modules/concepts/hooks/list-of-hooks/actionAttributeGroupSave.md @@ -7,13 +7,20 @@ files: - classes/AttributeGroup.php locations: - frontoffice -types: - - legacy +type: + - action +hookAliases: + - afterSaveAttributeGroup --- -# Hook : actionAttributeGroupSave +# Hook actionAttributeGroupSave -## Informations +Aliases: + - afterSaveAttributeGroup + + + +## Information {{% notice tip %}} **Saving an attribute group:** @@ -24,14 +31,14 @@ This hook is called while saving an attributes group Hook locations: - frontoffice -Hook types: - - legacy +Hook type: + - action Located in: - - classes/AttributeGroup.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/AttributeGroup.php](classes/AttributeGroup.php) -## Hook call with parameters +## Hook call in codebase ```php -Hook::exec('actionAttributeGroupSave', ['id_attribute_group' => $this->id]); +Hook::exec('actionAttributeGroupSave', ['id_attribute_group' => $this->id]) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionAttributeSave.md b/modules/concepts/hooks/list-of-hooks/actionAttributeSave.md index c3c1204aef..e74e86d31f 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAttributeSave.md +++ b/modules/concepts/hooks/list-of-hooks/actionAttributeSave.md @@ -7,13 +7,20 @@ files: - classes/ProductAttribute.php locations: - frontoffice -types: - - legacy +type: + - action +hookAliases: + - afterSaveAttribute --- -# Hook : actionAttributeSave +# Hook actionAttributeSave -## Informations +Aliases: + - afterSaveAttribute + + + +## Information {{% notice tip %}} **Saving an attributes features value:** @@ -24,14 +31,14 @@ This hook is called while saving an attributes features value Hook locations: - frontoffice -Hook types: - - legacy +Hook type: + - action Located in: - - classes/ProductAttribute.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/ProductAttribute.php](classes/ProductAttribute.php) -## Hook call with parameters +## Hook call in codebase ```php -Hook::exec('actionAttributeSave', ['id_attribute' => $this->id]); +Hook::exec('actionAttributeSave', ['id_attribute' => $this->id]) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionAuthentication.md b/modules/concepts/hooks/list-of-hooks/actionAuthentication.md index 845335e947..f7367f05f9 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAuthentication.md +++ b/modules/concepts/hooks/list-of-hooks/actionAuthentication.md @@ -7,13 +7,20 @@ files: - classes/form/CustomerLoginForm.php locations: - frontoffice -types: - - legacy +type: + - action +hookAliases: + - authentication --- -# Hook : actionAuthentication +# Hook actionAuthentication -## Informations +Aliases: + - authentication + + + +## Information {{% notice tip %}} **Successful customer authentication:** @@ -24,14 +31,14 @@ This hook is displayed after a customer successfully signs in Hook locations: - frontoffice -Hook types: - - legacy +Hook type: + - action Located in: - - classes/form/CustomerLoginForm.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/form/CustomerLoginForm.php](classes/form/CustomerLoginForm.php) -## Hook call with parameters +## Hook call in codebase ```php -Hook::exec('actionAuthentication', ['customer' => $this->context->customer]); +Hook::exec('actionAuthentication', ['customer' => $this->context->customer]) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionAuthenticationBefore.md b/modules/concepts/hooks/list-of-hooks/actionAuthenticationBefore.md index 68a82e8a97..94e95ec9ee 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAuthenticationBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAuthenticationBefore.md @@ -7,25 +7,32 @@ files: - classes/form/CustomerLoginForm.php locations: - frontoffice -types: - - legacy +type: + - action +hookAliases: + - actionBeforeAuthentication --- -# Hook : actionAuthenticationBefore +# Hook actionAuthenticationBefore -## Informations +Aliases: + - actionBeforeAuthentication + + + +## Information Hook locations: - frontoffice -Hook types: - - legacy +Hook type: + - action Located in: - - classes/form/CustomerLoginForm.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/form/CustomerLoginForm.php](classes/form/CustomerLoginForm.php) -## Hook call with parameters +## Hook call in codebase ```php -Hook::exec('actionAuthenticationBefore'); +Hook::exec('actionAuthenticationBefore') ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionBeforeAjaxDie.md b/modules/concepts/hooks/list-of-hooks/actionBeforeAjaxDie.md deleted file mode 100644 index 8ec3745c85..0000000000 --- a/modules/concepts/hooks/list-of-hooks/actionBeforeAjaxDie.md +++ /dev/null @@ -1,31 +0,0 @@ ---- -menuTitle: actionBeforeAjaxDie -Title: actionBeforeAjaxDie -hidden: true -hookTitle: -files: - - classes/controller/Controller.php -locations: - - frontoffice -types: - - legacy ---- - -# Hook : actionBeforeAjaxDie - -## Informations - -Hook locations: - - frontoffice - -Hook types: - - legacy - -Located in: - - classes/controller/Controller.php - -## Hook call with parameters - -```php -Hook::exec('actionBeforeAjaxDie' . $controller . $method, ['value' => $value]); -``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionBeforeAjaxDie.md b/modules/concepts/hooks/list-of-hooks/actionBeforeAjaxDie.md new file mode 100644 index 0000000000..ccbd90b9c9 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionBeforeAjaxDie.md @@ -0,0 +1,32 @@ +--- +menuTitle: actionBeforeAjaxDie +Title: actionBeforeAjaxDie +hidden: true +hookTitle: +files: + - classes/controller/Controller.php +locations: + - frontoffice +type: + - action +hookAliases: +--- + +# Hook actionBeforeAjaxDie + +## Information + +Hook locations: + - frontoffice + +Hook type: + - action + +Located in: + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/Controller.php](classes/controller/Controller.php) + +## Hook call in codebase + +```php +Hook::exec('actionBeforeAjaxDie' . $controller . $method, ['value' => $value]) +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionBeforeCreateFormHandler.md b/modules/concepts/hooks/list-of-hooks/actionBeforeCreateFormHandler.md new file mode 100644 index 0000000000..8e1eb39edd --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionBeforeCreateFormHandler.md @@ -0,0 +1,36 @@ +--- +menuTitle: actionBeforeCreateFormHandler +Title: actionBeforeCreateFormHandler +hidden: true +hookTitle: +files: + - src/Core/Form/IdentifiableObject/Handler/FormHandler.php +locations: + - frontoffice +type: + - action +hookAliases: +--- + +# Hook actionBeforeCreateFormHandler + +## Information + +Hook locations: + - frontoffice + +Hook type: + - action + +Located in: + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Core/Form/IdentifiableObject/Handler/FormHandler.php](src/Core/Form/IdentifiableObject/Handler/FormHandler.php) + +## Hook call in codebase + +```php +dispatchWithParameters( + 'actionBeforeCreate' . Container::camelize($form->getName()) . 'FormHandler', [ + 'form_data' => &$data, + ] + ) +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionBeforeUpdateFormHandler.md b/modules/concepts/hooks/list-of-hooks/actionBeforeUpdateFormHandler.md index 73976ccd58..ceee6f9425 100644 --- a/modules/concepts/hooks/list-of-hooks/actionBeforeUpdateFormHandler.md +++ b/modules/concepts/hooks/list-of-hooks/actionBeforeUpdateFormHandler.md @@ -7,28 +7,29 @@ files: - src/Core/Form/IdentifiableObject/Handler/FormHandler.php locations: - frontoffice -types: - - symfony +type: + - action +hookAliases: --- -# Hook : actionBeforeUpdateFormHandler +# Hook actionBeforeUpdateFormHandler -## Informations +## Information Hook locations: - frontoffice -Hook types: - - symfony +Hook type: + - action Located in: - - src/Core/Form/IdentifiableObject/Handler/FormHandler.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Core/Form/IdentifiableObject/Handler/FormHandler.php](src/Core/Form/IdentifiableObject/Handler/FormHandler.php) -## Hook call with parameters +## Hook call in codebase ```php dispatchWithParameters('actionBeforeUpdate' . Container::camelize($form->getName()) . 'FormHandler', [ 'form_data' => &$data, 'id' => $id, - ]); + ]) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionBuildFrontEndObject.md b/modules/concepts/hooks/list-of-hooks/actionBuildFrontEndObject.md index 6cba9dc923..a3beb0ab9f 100644 --- a/modules/concepts/hooks/list-of-hooks/actionBuildFrontEndObject.md +++ b/modules/concepts/hooks/list-of-hooks/actionBuildFrontEndObject.md @@ -7,13 +7,14 @@ files: - classes/controller/FrontController.php locations: - frontoffice -types: - - legacy +type: + - action +hookAliases: --- -# Hook : actionBuildFrontEndObject +# Hook actionBuildFrontEndObject -## Informations +## Information {{% notice tip %}} **Manage elements added to the "prestashop" javascript object:** @@ -24,16 +25,16 @@ This hook allows you to customize the "prestashop" javascript object that is inc Hook locations: - frontoffice -Hook types: - - legacy +Hook type: + - action Located in: - - classes/controller/FrontController.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/FrontController.php](classes/controller/FrontController.php) -## Hook call with parameters +## Hook call in codebase ```php Hook::exec('actionBuildFrontEndObject', [ 'obj' => &$object, - ]); + ]) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionBuildMailLayoutVariables.md b/modules/concepts/hooks/list-of-hooks/actionBuildMailLayoutVariables.md new file mode 100644 index 0000000000..19d47edf25 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionBuildMailLayoutVariables.md @@ -0,0 +1,44 @@ +--- +menuTitle: actionBuildMailLayoutVariables +Title: actionBuildMailLayoutVariables +hidden: true +hookTitle: Build the variables used in email layout rendering +files: + - src/Core/MailTemplate/Layout/LayoutVariablesBuilder.php +locations: + - frontoffice +type: + - action +hookAliases: +--- + +# Hook actionBuildMailLayoutVariables + +## Information + +{{% notice tip %}} +**Build the variables used in email layout rendering:** + +This hook allows to change the variables used when an email layout is rendered +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook type: + - action + +Located in: + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Core/MailTemplate/Layout/LayoutVariablesBuilder.php](src/Core/MailTemplate/Layout/LayoutVariablesBuilder.php) + +## Hook call in codebase + +```php +dispatchWithParameters( + LayoutVariablesBuilderInterface::BUILD_MAIL_LAYOUT_VARIABLES_HOOK, + [ + 'mailLayout' => $mailLayout, + 'mailLayoutVariables' => &$mailLayoutVariables, + ] + ) +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionCarrierProcess.md b/modules/concepts/hooks/list-of-hooks/actionCarrierProcess.md index ba41e22b20..80e945118e 100644 --- a/modules/concepts/hooks/list-of-hooks/actionCarrierProcess.md +++ b/modules/concepts/hooks/list-of-hooks/actionCarrierProcess.md @@ -7,13 +7,20 @@ files: - classes/checkout/CheckoutDeliveryStep.php locations: - frontoffice -types: - - legacy +type: + - action +hookAliases: + - processCarrier --- -# Hook : actionCarrierProcess +# Hook actionCarrierProcess -## Informations +Aliases: + - processCarrier + + + +## Information {{% notice tip %}} **Carrier process:** @@ -24,14 +31,14 @@ types: Hook locations: - frontoffice -Hook types: - - legacy +Hook type: + - action Located in: - - classes/checkout/CheckoutDeliveryStep.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/checkout/CheckoutDeliveryStep.php](classes/checkout/CheckoutDeliveryStep.php) -## Hook call with parameters +## Hook call in codebase ```php -Hook::exec('actionCarrierProcess', ['cart' => $this->getCheckoutSession()->getCart()]); +Hook::exec('actionCarrierProcess', ['cart' => $this->getCheckoutSession()->getCart()]) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionCarrierUpdate.md b/modules/concepts/hooks/list-of-hooks/actionCarrierUpdate.md index fe51964663..362b766671 100644 --- a/modules/concepts/hooks/list-of-hooks/actionCarrierUpdate.md +++ b/modules/concepts/hooks/list-of-hooks/actionCarrierUpdate.md @@ -7,13 +7,20 @@ files: - controllers/admin/AdminCarriersController.php locations: - backoffice -types: - - legacy +type: + - action +hookAliases: + - updateCarrier --- -# Hook : actionCarrierUpdate +# Hook actionCarrierUpdate -## Informations +Aliases: + - updateCarrier + + + +## Information {{% notice tip %}} **Carrier Update:** @@ -24,17 +31,17 @@ This hook is called when a carrier is updated Hook locations: - backoffice -Hook types: - - legacy +Hook type: + - action Located in: - - controllers/admin/AdminCarriersController.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/admin/AdminCarriersController.php](controllers/admin/AdminCarriersController.php) -## Hook call with parameters +## Hook call in codebase ```php Hook::exec('actionCarrierUpdate', [ 'id_carrier' => (int) $current_carrier->id, 'carrier' => $new_carrier, - ]); + ]) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionCartSave.md b/modules/concepts/hooks/list-of-hooks/actionCartSave.md index 06bb1038b7..6e2eb74e64 100644 --- a/modules/concepts/hooks/list-of-hooks/actionCartSave.md +++ b/modules/concepts/hooks/list-of-hooks/actionCartSave.md @@ -7,13 +7,20 @@ files: - classes/Cart.php locations: - frontoffice -types: - - legacy +type: + - action +hookAliases: + - cart --- -# Hook : actionCartSave +# Hook actionCartSave -## Informations +Aliases: + - cart + + + +## Information {{% notice tip %}} **Cart creation and update:** @@ -24,14 +31,14 @@ This hook is displayed when a product is added to the cart or if the cart's cont Hook locations: - frontoffice -Hook types: - - legacy +Hook type: + - action Located in: - - classes/Cart.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Cart.php](classes/Cart.php) -## Hook call with parameters +## Hook call in codebase ```php -Hook::exec('actionCartSave', ['cart' => $this]); +Hook::exec('actionCartSave', ['cart' => $this]) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionCartSummary.md b/modules/concepts/hooks/list-of-hooks/actionCartSummary.md index 97cab9e26b..2d6e6d4ebe 100644 --- a/modules/concepts/hooks/list-of-hooks/actionCartSummary.md +++ b/modules/concepts/hooks/list-of-hooks/actionCartSummary.md @@ -7,25 +7,26 @@ files: - classes/Cart.php locations: - frontoffice -types: - - legacy +type: + - action +hookAliases: --- -# Hook : actionCartSummary +# Hook actionCartSummary -## Informations +## Information Hook locations: - frontoffice -Hook types: - - legacy +Hook type: + - action Located in: - - classes/Cart.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Cart.php](classes/Cart.php) -## Hook call with parameters +## Hook call in codebase ```php -Hook::exec('actionCartSummary', $summary, null, true); +Hook::exec('actionCartSummary', $summary, null, true) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionCartUpdateQuantityBefore.md b/modules/concepts/hooks/list-of-hooks/actionCartUpdateQuantityBefore.md index ee0e241fd3..71ab241e93 100644 --- a/modules/concepts/hooks/list-of-hooks/actionCartUpdateQuantityBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionCartUpdateQuantityBefore.md @@ -7,25 +7,32 @@ files: - classes/Cart.php locations: - frontoffice -types: - - legacy +type: + - action +hookAliases: + - actionBeforeCartUpdateQty --- -# Hook : actionCartUpdateQuantityBefore +# Hook actionCartUpdateQuantityBefore -## Informations +Aliases: + - actionBeforeCartUpdateQty + + + +## Information Hook locations: - frontoffice -Hook types: - - legacy +Hook type: + - action Located in: - - classes/Cart.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Cart.php](classes/Cart.php) -## Hook call with parameters +## Hook call in codebase ```php -Hook::exec('actionCartUpdateQuantityBefore', $data); +Hook::exec('actionCartUpdateQuantityBefore', $data) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionCategoryAdd.md b/modules/concepts/hooks/list-of-hooks/actionCategoryAdd.md index c099f6a309..be5728c79a 100644 --- a/modules/concepts/hooks/list-of-hooks/actionCategoryAdd.md +++ b/modules/concepts/hooks/list-of-hooks/actionCategoryAdd.md @@ -7,13 +7,20 @@ files: - classes/Category.php locations: - frontoffice -types: - - legacy +type: + - action +hookAliases: + - categoryAddition --- -# Hook : actionCategoryAdd +# Hook actionCategoryAdd -## Informations +Aliases: + - categoryAddition + + + +## Information {{% notice tip %}} **Category creation:** @@ -24,14 +31,14 @@ This hook is displayed when a category is created Hook locations: - frontoffice -Hook types: - - legacy +Hook type: + - action Located in: - - classes/Category.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Category.php](classes/Category.php) -## Hook call with parameters +## Hook call in codebase ```php -Hook::exec('actionCategoryAdd', ['category' => $this]); +Hook::exec('actionCategoryAdd', ['category' => $this]) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionCategoryDelete.md b/modules/concepts/hooks/list-of-hooks/actionCategoryDelete.md index 2bb9d1abe3..55e94633b5 100644 --- a/modules/concepts/hooks/list-of-hooks/actionCategoryDelete.md +++ b/modules/concepts/hooks/list-of-hooks/actionCategoryDelete.md @@ -7,13 +7,20 @@ files: - classes/Category.php locations: - frontoffice -types: - - legacy +type: + - action +hookAliases: + - categoryDeletion --- -# Hook : actionCategoryDelete +# Hook actionCategoryDelete -## Informations +Aliases: + - categoryDeletion + + + +## Information {{% notice tip %}} **Category deletion:** @@ -24,14 +31,14 @@ This hook is displayed when a category is deleted Hook locations: - frontoffice -Hook types: - - legacy +Hook type: + - action Located in: - - classes/Category.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Category.php](classes/Category.php) -## Hook call with parameters +## Hook call in codebase ```php -Hook::exec('actionCategoryDelete', ['category' => $this, 'deleted_children' => $deletedChildren]); +Hook::exec('actionCategoryDelete', ['category' => $this, 'deleted_children' => $deletedChildren]) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionCategoryUpdate.md b/modules/concepts/hooks/list-of-hooks/actionCategoryUpdate.md index 23a6411bf2..950406c01a 100644 --- a/modules/concepts/hooks/list-of-hooks/actionCategoryUpdate.md +++ b/modules/concepts/hooks/list-of-hooks/actionCategoryUpdate.md @@ -7,13 +7,20 @@ files: - controllers/admin/AdminProductsController.php locations: - backoffice -types: - - legacy +type: + - action +hookAliases: + - categoryUpdate --- -# Hook : actionCategoryUpdate +# Hook actionCategoryUpdate -## Informations +Aliases: + - categoryUpdate + + + +## Information {{% notice tip %}} **Category modification:** @@ -24,14 +31,14 @@ This hook is displayed when a category is modified Hook locations: - backoffice -Hook types: - - legacy +Hook type: + - action Located in: - - controllers/admin/AdminProductsController.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/admin/AdminProductsController.php](controllers/admin/AdminProductsController.php) -## Hook call with parameters +## Hook call in codebase ```php -Hook::exec('actionCategoryUpdate', ['category' => $category]); +Hook::exec('actionCategoryUpdate', ['category' => $category]) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionCheckoutRender.md b/modules/concepts/hooks/list-of-hooks/actionCheckoutRender.md index 37abf965be..20123c9b1c 100644 --- a/modules/concepts/hooks/list-of-hooks/actionCheckoutRender.md +++ b/modules/concepts/hooks/list-of-hooks/actionCheckoutRender.md @@ -7,13 +7,14 @@ files: - controllers/front/OrderController.php locations: - frontoffice -types: - - legacy +type: + - action +hookAliases: --- -# Hook : actionCheckoutRender +# Hook actionCheckoutRender -## Informations +## Information {{% notice tip %}} **Modify checkout process:** @@ -24,14 +25,14 @@ This hook is called when constructing the checkout process Hook locations: - frontoffice -Hook types: - - legacy +Hook type: + - action Located in: - - controllers/front/OrderController.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/front/OrderController.php](controllers/front/OrderController.php) -## Hook call with parameters +## Hook call in codebase ```php -Hook::exec('actionCheckoutRender', ['checkoutProcess' => &$this->checkoutProcess]); +Hook::exec('actionCheckoutRender', ['checkoutProcess' => &$this->checkoutProcess]) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionClearCache.md b/modules/concepts/hooks/list-of-hooks/actionClearCache.md index 7deb463d51..219401f5a4 100644 --- a/modules/concepts/hooks/list-of-hooks/actionClearCache.md +++ b/modules/concepts/hooks/list-of-hooks/actionClearCache.md @@ -7,13 +7,14 @@ files: - classes/Tools.php locations: - frontoffice -types: - - legacy +type: + - action +hookAliases: --- -# Hook : actionClearCache +# Hook actionClearCache -## Informations +## Information {{% notice tip %}} **Clear smarty cache:** @@ -24,14 +25,14 @@ This hook is called when smarty's cache is cleared Hook locations: - frontoffice -Hook types: - - legacy +Hook type: + - action Located in: - - classes/Tools.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Tools.php](classes/Tools.php) -## Hook call with parameters +## Hook call in codebase ```php -Hook::exec('actionClearCache'); +Hook::exec('actionClearCache') ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionClearCompileCache.md b/modules/concepts/hooks/list-of-hooks/actionClearCompileCache.md index c81bfd2f1f..dd4ceedcb0 100644 --- a/modules/concepts/hooks/list-of-hooks/actionClearCompileCache.md +++ b/modules/concepts/hooks/list-of-hooks/actionClearCompileCache.md @@ -7,13 +7,14 @@ files: - classes/Tools.php locations: - frontoffice -types: - - legacy +type: + - action +hookAliases: --- -# Hook : actionClearCompileCache +# Hook actionClearCompileCache -## Informations +## Information {{% notice tip %}} **Clear smarty compile cache:** @@ -24,14 +25,14 @@ This hook is called when smarty's compile cache is cleared Hook locations: - frontoffice -Hook types: - - legacy +Hook type: + - action Located in: - - classes/Tools.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Tools.php](classes/Tools.php) -## Hook call with parameters +## Hook call in codebase ```php -Hook::exec('actionClearCompileCache'); +Hook::exec('actionClearCompileCache') ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionClearSf2Cache.md b/modules/concepts/hooks/list-of-hooks/actionClearSf2Cache.md index fb7e991be7..a7a44afadf 100644 --- a/modules/concepts/hooks/list-of-hooks/actionClearSf2Cache.md +++ b/modules/concepts/hooks/list-of-hooks/actionClearSf2Cache.md @@ -7,13 +7,14 @@ files: - src/Adapter/Cache/Clearer/SymfonyCacheClearer.php locations: - frontoffice -types: - - legacy +type: + - action +hookAliases: --- -# Hook : actionClearSf2Cache +# Hook actionClearSf2Cache -## Informations +## Information {{% notice tip %}} **Clear Sf2 cache:** @@ -24,14 +25,14 @@ This hook is called when the Symfony cache is cleared Hook locations: - frontoffice -Hook types: - - legacy +Hook type: + - action Located in: - - src/Adapter/Cache/Clearer/SymfonyCacheClearer.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Cache/Clearer/SymfonyCacheClearer.php](src/Adapter/Cache/Clearer/SymfonyCacheClearer.php) -## Hook call with parameters +## Hook call in codebase ```php -Hook::exec('actionClearSf2Cache'); +Hook::exec('actionClearSf2Cache') ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionControllerInitAfter.md b/modules/concepts/hooks/list-of-hooks/actionControllerInitAfter.md new file mode 100644 index 0000000000..280ff72615 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionControllerInitAfter.md @@ -0,0 +1,43 @@ +--- +menuTitle: actionControllerInitAfter +Title: actionControllerInitAfter +hidden: true +hookTitle: Perform actions after controller initialization +files: + - classes/controller/Controller.php +locations: + - frontoffice +type: + - action +hookAliases: +--- + +# Hook actionControllerInitAfter + +## Information + +{{% notice tip %}} +**Perform actions after controller initialization:** + +This hook is launched after the initialization of all controllers +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook type: + - action + +Located in: + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/Controller.php](classes/controller/Controller.php) + +## Hook call in codebase + +```php +Hook::exec( + 'actionControllerInitAfter', + [ + 'controller' => $this, + ] + ) +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionControllerInitBefore.md b/modules/concepts/hooks/list-of-hooks/actionControllerInitBefore.md new file mode 100644 index 0000000000..f13ac20ea3 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionControllerInitBefore.md @@ -0,0 +1,43 @@ +--- +menuTitle: actionControllerInitBefore +Title: actionControllerInitBefore +hidden: true +hookTitle: Perform actions before controller initialization +files: + - classes/controller/Controller.php +locations: + - frontoffice +type: + - action +hookAliases: +--- + +# Hook actionControllerInitBefore + +## Information + +{{% notice tip %}} +**Perform actions before controller initialization:** + +This hook is launched before the initialization of all controllers +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook type: + - action + +Located in: + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/Controller.php](classes/controller/Controller.php) + +## Hook call in codebase + +```php +Hook::exec( + 'actionControllerInitBefore', + [ + 'controller' => $this, + ] + ) +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionCustomerAccountAdd.md b/modules/concepts/hooks/list-of-hooks/actionCustomerAccountAdd.md index 77cb3df4d6..fac955781c 100644 --- a/modules/concepts/hooks/list-of-hooks/actionCustomerAccountAdd.md +++ b/modules/concepts/hooks/list-of-hooks/actionCustomerAccountAdd.md @@ -7,13 +7,20 @@ files: - classes/form/CustomerPersister.php locations: - frontoffice -types: - - legacy +type: + - action +hookAliases: + - createAccount --- -# Hook : actionCustomerAccountAdd +# Hook actionCustomerAccountAdd -## Informations +Aliases: + - createAccount + + + +## Information {{% notice tip %}} **Successful customer account creation:** @@ -24,16 +31,25 @@ This hook is called when a new customer creates an account successfully Hook locations: - frontoffice -Hook types: - - legacy +Hook type: + - action Located in: - - classes/form/CustomerPersister.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/form/CustomerPersister.php](classes/form/CustomerPersister.php) + +## Parameters details + +```php + (object) Customer object + ); +``` -## Hook call with parameters +## Hook call in codebase ```php Hook::exec('actionCustomerAccountAdd', [ 'newCustomer' => $customer, - ]); + ]) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionCustomerAccountUpdate.md b/modules/concepts/hooks/list-of-hooks/actionCustomerAccountUpdate.md index cdeb43ead1..b93d33dcdd 100644 --- a/modules/concepts/hooks/list-of-hooks/actionCustomerAccountUpdate.md +++ b/modules/concepts/hooks/list-of-hooks/actionCustomerAccountUpdate.md @@ -7,13 +7,14 @@ files: - classes/form/CustomerPersister.php locations: - frontoffice -types: - - legacy +type: + - action +hookAliases: --- -# Hook : actionCustomerAccountUpdate +# Hook actionCustomerAccountUpdate -## Informations +## Information {{% notice tip %}} **Successful customer account update:** @@ -24,16 +25,16 @@ This hook is called when a customer updates its account successfully Hook locations: - frontoffice -Hook types: - - legacy +Hook type: + - action Located in: - - classes/form/CustomerPersister.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/form/CustomerPersister.php](classes/form/CustomerPersister.php) -## Hook call with parameters +## Hook call in codebase ```php Hook::exec('actionCustomerAccountUpdate', [ 'customer' => $customer, - ]); + ]) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionCustomerAddGroups.md b/modules/concepts/hooks/list-of-hooks/actionCustomerAddGroups.md index 3678e0336d..4435d602c6 100644 --- a/modules/concepts/hooks/list-of-hooks/actionCustomerAddGroups.md +++ b/modules/concepts/hooks/list-of-hooks/actionCustomerAddGroups.md @@ -7,25 +7,26 @@ files: - classes/Customer.php locations: - frontoffice -types: - - legacy +type: + - action +hookAliases: --- -# Hook : actionCustomerAddGroups +# Hook actionCustomerAddGroups -## Informations +## Information Hook locations: - frontoffice -Hook types: - - legacy +Hook type: + - action Located in: - - classes/Customer.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Customer.php](classes/Customer.php) -## Hook call with parameters +## Hook call in codebase ```php -Hook::exec('actionCustomerAddGroups', ['id_customer' => $this->id, 'groups' => $groups]); +Hook::exec('actionCustomerAddGroups', ['id_customer' => $this->id, 'groups' => $groups]) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionCustomerBeforeUpdateGroup.md b/modules/concepts/hooks/list-of-hooks/actionCustomerBeforeUpdateGroup.md index 8dd140208e..8629109e4b 100644 --- a/modules/concepts/hooks/list-of-hooks/actionCustomerBeforeUpdateGroup.md +++ b/modules/concepts/hooks/list-of-hooks/actionCustomerBeforeUpdateGroup.md @@ -7,25 +7,26 @@ files: - classes/Customer.php locations: - frontoffice -types: - - legacy +type: + - action +hookAliases: --- -# Hook : actionCustomerBeforeUpdateGroup +# Hook actionCustomerBeforeUpdateGroup -## Informations +## Information Hook locations: - frontoffice -Hook types: - - legacy +Hook type: + - action Located in: - - classes/Customer.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Customer.php](classes/Customer.php) -## Hook call with parameters +## Hook call in codebase ```php -Hook::exec('actionCustomerBeforeUpdateGroup', ['id_customer' => $this->id, 'groups' => $list]); +Hook::exec('actionCustomerBeforeUpdateGroup', ['id_customer' => $this->id, 'groups' => $list]) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionCustomerLogoutAfter.md b/modules/concepts/hooks/list-of-hooks/actionCustomerLogoutAfter.md index d0d2372d70..caa5a4462d 100644 --- a/modules/concepts/hooks/list-of-hooks/actionCustomerLogoutAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionCustomerLogoutAfter.md @@ -7,13 +7,14 @@ files: - classes/Customer.php locations: - frontoffice -types: - - legacy +type: + - action +hookAliases: --- -# Hook : actionCustomerLogoutAfter +# Hook actionCustomerLogoutAfter -## Informations +## Information {{% notice tip %}} **After customer logout:** @@ -24,14 +25,14 @@ This hook allows you to execute code after customer logout Hook locations: - frontoffice -Hook types: - - legacy +Hook type: + - action Located in: - - classes/Customer.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Customer.php](classes/Customer.php) -## Hook call with parameters +## Hook call in codebase ```php -Hook::exec('actionCustomerLogoutAfter', ['customer' => $this]); +Hook::exec('actionCustomerLogoutAfter', ['customer' => $this]) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionCustomerLogoutBefore.md b/modules/concepts/hooks/list-of-hooks/actionCustomerLogoutBefore.md index f50e03a6ea..1826a3256d 100644 --- a/modules/concepts/hooks/list-of-hooks/actionCustomerLogoutBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionCustomerLogoutBefore.md @@ -7,13 +7,14 @@ files: - classes/Customer.php locations: - frontoffice -types: - - legacy +type: + - action +hookAliases: --- -# Hook : actionCustomerLogoutBefore +# Hook actionCustomerLogoutBefore -## Informations +## Information {{% notice tip %}} **Before customer logout:** @@ -24,14 +25,14 @@ This hook allows you to execute code before customer logout Hook locations: - frontoffice -Hook types: - - legacy +Hook type: + - action Located in: - - classes/Customer.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Customer.php](classes/Customer.php) -## Hook call with parameters +## Hook call in codebase ```php -Hook::exec('actionCustomerLogoutBefore', ['customer' => $this]); +Hook::exec('actionCustomerLogoutBefore', ['customer' => $this]) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionDeleteGDPRCustomer.md b/modules/concepts/hooks/list-of-hooks/actionDeleteGDPRCustomer.md index dafbf606c1..ee45aa8a80 100644 --- a/modules/concepts/hooks/list-of-hooks/actionDeleteGDPRCustomer.md +++ b/modules/concepts/hooks/list-of-hooks/actionDeleteGDPRCustomer.md @@ -7,25 +7,26 @@ files: - modules/psgdpr/psgdpr.php locations: - frontoffice -types: - - legacy +type: + - action +hookAliases: --- -# Hook : actionDeleteGDPRCustomer +# Hook actionDeleteGDPRCustomer -## Informations +## Information Hook locations: - frontoffice -Hook types: - - legacy +Hook type: + - action Located in: - - modules/psgdpr/psgdpr.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/modules/psgdpr/psgdpr.php](modules/psgdpr/psgdpr.php) -## Hook call with parameters +## Hook call in codebase ```php -Hook::exec('actionDeleteGDPRCustomer', $customer, $module['id_module']); +Hook::exec('actionDeleteGDPRCustomer', $customer, $module['id_module']) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionDeliveryPriceByPrice.md b/modules/concepts/hooks/list-of-hooks/actionDeliveryPriceByPrice.md index 93702e04fb..5c2a486987 100644 --- a/modules/concepts/hooks/list-of-hooks/actionDeliveryPriceByPrice.md +++ b/modules/concepts/hooks/list-of-hooks/actionDeliveryPriceByPrice.md @@ -7,25 +7,26 @@ files: - classes/Carrier.php locations: - frontoffice -types: - - legacy +type: + - action +hookAliases: --- -# Hook : actionDeliveryPriceByPrice +# Hook actionDeliveryPriceByPrice -## Informations +## Information Hook locations: - frontoffice -Hook types: - - legacy +Hook type: + - action Located in: - - classes/Carrier.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Carrier.php](classes/Carrier.php) -## Hook call with parameters +## Hook call in codebase ```php -Hook::exec('actionDeliveryPriceByPrice', ['id_carrier' => $id_carrier, 'order_total' => $order_total, 'id_zone' => $id_zone]); +Hook::exec('actionDeliveryPriceByPrice', ['id_carrier' => $id_carrier, 'order_total' => $order_total, 'id_zone' => $id_zone]) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionDeliveryPriceByWeight.md b/modules/concepts/hooks/list-of-hooks/actionDeliveryPriceByWeight.md index 2020a57583..7e53103af4 100644 --- a/modules/concepts/hooks/list-of-hooks/actionDeliveryPriceByWeight.md +++ b/modules/concepts/hooks/list-of-hooks/actionDeliveryPriceByWeight.md @@ -7,25 +7,26 @@ files: - classes/Carrier.php locations: - frontoffice -types: - - legacy +type: + - action +hookAliases: --- -# Hook : actionDeliveryPriceByWeight +# Hook actionDeliveryPriceByWeight -## Informations +## Information Hook locations: - frontoffice -Hook types: - - legacy +Hook type: + - action Located in: - - classes/Carrier.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Carrier.php](classes/Carrier.php) -## Hook call with parameters +## Hook call in codebase ```php -Hook::exec('actionDeliveryPriceByWeight', ['id_carrier' => $id_carrier, 'total_weight' => $total_weight, 'id_zone' => $id_zone]); +Hook::exec('actionDeliveryPriceByWeight', ['id_carrier' => $id_carrier, 'total_weight' => $total_weight, 'id_zone' => $id_zone]) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionDispatcher.md b/modules/concepts/hooks/list-of-hooks/actionDispatcher.md index 539b8f2ef0..a2c07d3de6 100644 --- a/modules/concepts/hooks/list-of-hooks/actionDispatcher.md +++ b/modules/concepts/hooks/list-of-hooks/actionDispatcher.md @@ -7,25 +7,26 @@ files: - classes/Dispatcher.php locations: - frontoffice -types: - - legacy +type: + - action +hookAliases: --- -# Hook : actionDispatcher +# Hook actionDispatcher -## Informations +## Information Hook locations: - frontoffice -Hook types: - - legacy +Hook type: + - action Located in: - - classes/Dispatcher.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Dispatcher.php](classes/Dispatcher.php) -## Hook call with parameters +## Hook call in codebase ```php -Hook::exec('actionDispatcher', $params_hook_action_dispatcher); +Hook::exec('actionDispatcher', $params_hook_action_dispatcher) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionDispatcherAfter.md b/modules/concepts/hooks/list-of-hooks/actionDispatcherAfter.md index 58f932d9c5..8c9b7718fa 100644 --- a/modules/concepts/hooks/list-of-hooks/actionDispatcherAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionDispatcherAfter.md @@ -4,16 +4,17 @@ Title: actionDispatcherAfter hidden: true hookTitle: After dispatch files: - - classes/Dispatcher.php + - src/PrestaShopBundle/EventListener/ActionDispatcherLegacyHooksSubscriber.php locations: - frontoffice -types: - - legacy +type: + - action +hookAliases: --- -# Hook : actionDispatcherAfter +# Hook actionDispatcherAfter -## Informations +## Information {{% notice tip %}} **After dispatch:** @@ -24,14 +25,18 @@ This hook is called at the end of the dispatch method of the Dispatcher Hook locations: - frontoffice -Hook types: - - legacy +Hook type: + - action Located in: - - classes/Dispatcher.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/EventListener/ActionDispatcherLegacyHooksSubscriber.php](src/PrestaShopBundle/EventListener/ActionDispatcherLegacyHooksSubscriber.php) -## Hook call with parameters +## Hook call in codebase ```php -Hook::exec('actionDispatcherAfter', $params_hook_action_dispatcher); +dispatchWithParameters(self::DISPATCHER_AFTER_ACTION, [ + 'controller_type' => $requestAttributes->get('controller_type'), + 'controller_class' => $requestAttributes->get('controller_name'), + 'is_module' => 0, + ]) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionDispatcherBefore.md b/modules/concepts/hooks/list-of-hooks/actionDispatcherBefore.md index 8d11b65a5c..538378fcb0 100644 --- a/modules/concepts/hooks/list-of-hooks/actionDispatcherBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionDispatcherBefore.md @@ -4,16 +4,17 @@ Title: actionDispatcherBefore hidden: true hookTitle: Before dispatch files: - - classes/Dispatcher.php + - src/PrestaShopBundle/EventListener/ActionDispatcherLegacyHooksSubscriber.php locations: - frontoffice -types: - - legacy +type: + - action +hookAliases: --- -# Hook : actionDispatcherBefore +# Hook actionDispatcherBefore -## Informations +## Information {{% notice tip %}} **Before dispatch:** @@ -24,14 +25,16 @@ This hook is called at the beginning of the dispatch method of the Dispatcher Hook locations: - frontoffice -Hook types: - - legacy +Hook type: + - action Located in: - - classes/Dispatcher.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/EventListener/ActionDispatcherLegacyHooksSubscriber.php](src/PrestaShopBundle/EventListener/ActionDispatcherLegacyHooksSubscriber.php) -## Hook call with parameters +## Hook call in codebase ```php -Hook::exec('actionDispatcherBefore', ['controller_type' => $this->front_controller]); +dispatchWithParameters(self::DISPATCHER_BEFORE_ACTION, [ + 'controller_type' => $controllerType, + ]) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionDownloadAttachment.md b/modules/concepts/hooks/list-of-hooks/actionDownloadAttachment.md index 7152d40ff7..f3e91e16b8 100644 --- a/modules/concepts/hooks/list-of-hooks/actionDownloadAttachment.md +++ b/modules/concepts/hooks/list-of-hooks/actionDownloadAttachment.md @@ -7,25 +7,26 @@ files: - controllers/front/AttachmentController.php locations: - frontoffice -types: - - legacy +type: + - action +hookAliases: --- -# Hook : actionDownloadAttachment +# Hook actionDownloadAttachment -## Informations +## Information Hook locations: - frontoffice -Hook types: - - legacy +Hook type: + - action Located in: - - controllers/front/AttachmentController.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/front/AttachmentController.php](controllers/front/AttachmentController.php) -## Hook call with parameters +## Hook call in codebase ```php -Hook::exec('actionDownloadAttachment', ['attachment' => &$attachment]); +Hook::exec('actionDownloadAttachment', ['attachment' => &$attachment]) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionEmailAddAfterContent.md b/modules/concepts/hooks/list-of-hooks/actionEmailAddAfterContent.md new file mode 100644 index 0000000000..43e8101490 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionEmailAddAfterContent.md @@ -0,0 +1,50 @@ +--- +menuTitle: actionEmailAddAfterContent +Title: actionEmailAddAfterContent +hidden: true +hookTitle: Add extra content after mail content +files: + - classes/Mail.php +locations: + - frontoffice +type: + - action +hookAliases: +--- + +# Hook actionEmailAddAfterContent + +## Information + +{{% notice tip %}} +**Add extra content after mail content:** + +This hook is called just after fetching mail template +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook type: + - action + +Located in: + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Mail.php](classes/Mail.php) + +This hook has an `$array_return` parameter set to `true` (module output will be set by name in an array, [see explaination here]({{< relref "/8/modules/concepts/hooks">}})). + +## Hook call in codebase + +```php +Hook::exec( + 'actionEmailAddAfterContent', + [ + 'template' => $template, + 'template_html' => &$templateHtml, + 'template_txt' => &$templateTxt, + 'id_lang' => (int) $idLang, + ], + null, + true + ) +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionEmailAddBeforeContent.md b/modules/concepts/hooks/list-of-hooks/actionEmailAddBeforeContent.md new file mode 100644 index 0000000000..7035c27e9e --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionEmailAddBeforeContent.md @@ -0,0 +1,50 @@ +--- +menuTitle: actionEmailAddBeforeContent +Title: actionEmailAddBeforeContent +hidden: true +hookTitle: Add extra content before mail content +files: + - classes/Mail.php +locations: + - frontoffice +type: + - action +hookAliases: +--- + +# Hook actionEmailAddBeforeContent + +## Information + +{{% notice tip %}} +**Add extra content before mail content:** + +This hook is called just before fetching mail template +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook type: + - action + +Located in: + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Mail.php](classes/Mail.php) + +This hook has an `$array_return` parameter set to `true` (module output will be set by name in an array, [see explaination here]({{< relref "/8/modules/concepts/hooks">}})). + +## Hook call in codebase + +```php +Hook::exec( + 'actionEmailAddBeforeContent', + [ + 'template' => $template, + 'template_html' => &$templateHtml, + 'template_txt' => &$templateTxt, + 'id_lang' => (int) $idLang, + ], + null, + true + ) +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionEmailSendBefore.md b/modules/concepts/hooks/list-of-hooks/actionEmailSendBefore.md new file mode 100644 index 0000000000..51a6bf8582 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionEmailSendBefore.md @@ -0,0 +1,61 @@ +--- +menuTitle: actionEmailSendBefore +Title: actionEmailSendBefore +hidden: true +hookTitle: Before sending an email +files: + - classes/Mail.php +locations: + - frontoffice +type: + - action +hookAliases: +--- + +# Hook actionEmailSendBefore + +## Information + +{{% notice tip %}} +**Before sending an email:** + +This hook is used to filter the content or the metadata of an email before sending it or even prevent its sending +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook type: + - action + +Located in: + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Mail.php](classes/Mail.php) + +This hook has an `$array_return` parameter set to `true` (module output will be set by name in an array, [see explaination here]({{< relref "/8/modules/concepts/hooks">}})). + +## Hook call in codebase + +```php +Hook::exec( + 'actionEmailSendBefore', + [ + 'idLang' => &$idLang, + 'template' => &$template, + 'subject' => &$subject, + 'templateVars' => &$templateVars, + 'to' => &$to, + 'toName' => &$toName, + 'from' => &$from, + 'fromName' => &$fromName, + 'fileAttachment' => &$fileAttachment, + 'mode_smtp' => &$mode_smtp, + 'templatePath' => &$templatePath, + 'die' => &$die, + 'idShop' => &$idShop, + 'bcc' => &$bcc, + 'replyTo' => &$replyTo, + ], + null, + true + ) +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionExportGDPRData.md b/modules/concepts/hooks/list-of-hooks/actionExportGDPRData.md index fe2b4d14d5..eb7168f336 100644 --- a/modules/concepts/hooks/list-of-hooks/actionExportGDPRData.md +++ b/modules/concepts/hooks/list-of-hooks/actionExportGDPRData.md @@ -7,25 +7,26 @@ files: - modules/psgdpr/psgdpr.php locations: - frontoffice -types: - - legacy +type: + - action +hookAliases: --- -# Hook : actionExportGDPRData +# Hook actionExportGDPRData -## Informations +## Information Hook locations: - frontoffice -Hook types: - - legacy +Hook type: + - action Located in: - - modules/psgdpr/psgdpr.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/modules/psgdpr/psgdpr.php](modules/psgdpr/psgdpr.php) -## Hook call with parameters +## Hook call in codebase ```php -Hook::exec('actionExportGDPRData', $customer, $module['id_module']); +Hook::exec('actionExportGDPRData', $customer, $module['id_module']) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionFeatureDelete.md b/modules/concepts/hooks/list-of-hooks/actionFeatureDelete.md index c1e7147d5c..f2b2d3fbb3 100644 --- a/modules/concepts/hooks/list-of-hooks/actionFeatureDelete.md +++ b/modules/concepts/hooks/list-of-hooks/actionFeatureDelete.md @@ -7,13 +7,20 @@ files: - classes/Feature.php locations: - frontoffice -types: - - legacy +type: + - action +hookAliases: + - afterDeleteFeature --- -# Hook : actionFeatureDelete +# Hook actionFeatureDelete -## Informations +Aliases: + - afterDeleteFeature + + + +## Information {{% notice tip %}} **Deleting attributes' features:** @@ -24,14 +31,14 @@ This hook is called while deleting an attributes features Hook locations: - frontoffice -Hook types: - - legacy +Hook type: + - action Located in: - - classes/Feature.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Feature.php](classes/Feature.php) -## Hook call with parameters +## Hook call in codebase ```php -Hook::exec('actionFeatureDelete', ['id_feature' => $this->id]); +Hook::exec('actionFeatureDelete', ['id_feature' => $this->id]) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionFeatureSave.md b/modules/concepts/hooks/list-of-hooks/actionFeatureSave.md index 2393401a5e..89e0ccc532 100644 --- a/modules/concepts/hooks/list-of-hooks/actionFeatureSave.md +++ b/modules/concepts/hooks/list-of-hooks/actionFeatureSave.md @@ -7,13 +7,20 @@ files: - classes/Feature.php locations: - frontoffice -types: - - legacy +type: + - action +hookAliases: + - afterSaveFeature --- -# Hook : actionFeatureSave +# Hook actionFeatureSave -## Informations +Aliases: + - afterSaveFeature + + + +## Information {{% notice tip %}} **Saving attributes' features:** @@ -24,14 +31,14 @@ This hook is called while saving an attributes features Hook locations: - frontoffice -Hook types: - - legacy +Hook type: + - action Located in: - - classes/Feature.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Feature.php](classes/Feature.php) -## Hook call with parameters +## Hook call in codebase ```php -Hook::exec('actionFeatureSave', ['id_feature' => $this->id]); +Hook::exec('actionFeatureSave', ['id_feature' => $this->id]) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionFeatureValueDelete.md b/modules/concepts/hooks/list-of-hooks/actionFeatureValueDelete.md index 5d1af182f7..29bf6f8bdf 100644 --- a/modules/concepts/hooks/list-of-hooks/actionFeatureValueDelete.md +++ b/modules/concepts/hooks/list-of-hooks/actionFeatureValueDelete.md @@ -7,13 +7,20 @@ files: - classes/FeatureValue.php locations: - frontoffice -types: - - legacy +type: + - action +hookAliases: + - afterDeleteFeatureValue --- -# Hook : actionFeatureValueDelete +# Hook actionFeatureValueDelete -## Informations +Aliases: + - afterDeleteFeatureValue + + + +## Information {{% notice tip %}} **Deleting attributes' features' values:** @@ -24,14 +31,14 @@ This hook is called while deleting an attributes features value Hook locations: - frontoffice -Hook types: - - legacy +Hook type: + - action Located in: - - classes/FeatureValue.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/FeatureValue.php](classes/FeatureValue.php) -## Hook call with parameters +## Hook call in codebase ```php -Hook::exec('actionFeatureValueDelete', ['id_feature_value' => $this->id]); +Hook::exec('actionFeatureValueDelete', ['id_feature_value' => $this->id]) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionFeatureValueSave.md b/modules/concepts/hooks/list-of-hooks/actionFeatureValueSave.md index 664c4716b9..3b242cb269 100644 --- a/modules/concepts/hooks/list-of-hooks/actionFeatureValueSave.md +++ b/modules/concepts/hooks/list-of-hooks/actionFeatureValueSave.md @@ -7,13 +7,20 @@ files: - classes/FeatureValue.php locations: - frontoffice -types: - - legacy +type: + - action +hookAliases: + - afterSaveFeatureValue --- -# Hook : actionFeatureValueSave +# Hook actionFeatureValueSave -## Informations +Aliases: + - afterSaveFeatureValue + + + +## Information {{% notice tip %}} **Saving an attributes features value:** @@ -24,14 +31,14 @@ This hook is called while saving an attributes features value Hook locations: - frontoffice -Hook types: - - legacy +Hook type: + - action Located in: - - classes/FeatureValue.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/FeatureValue.php](classes/FeatureValue.php) -## Hook call with parameters +## Hook call in codebase ```php -Hook::exec('actionFeatureValueSave', ['id_feature_value' => $this->id]); +Hook::exec('actionFeatureValueSave', ['id_feature_value' => $this->id]) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionFilterDeliveryOptionList.md b/modules/concepts/hooks/list-of-hooks/actionFilterDeliveryOptionList.md new file mode 100644 index 0000000000..a8bbfffe9f --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionFilterDeliveryOptionList.md @@ -0,0 +1,52 @@ +--- +menuTitle: actionFilterDeliveryOptionList +Title: actionFilterDeliveryOptionList +hidden: true +hookTitle: Modify delivery option list result +files: + - classes/Cart.php +locations: + - frontoffice +type: + - action +hookAliases: +--- + +# Hook actionFilterDeliveryOptionList + +## Information + +{{% notice tip %}} +**Modify delivery option list result:** + +This hook allows you to modify delivery option list +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook type: + - action + +Located in: + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Cart.php](classes/Cart.php) + +## Parameters details + +```php + (array) &$delivery_option_list, + ] +``` + +## Hook call in codebase + +```php +Hook::exec( + 'actionFilterDeliveryOptionList', + [ + 'delivery_option_list' => &$delivery_option_list, + ] + ) +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionFrontControllerInitAfter.md b/modules/concepts/hooks/list-of-hooks/actionFrontControllerInitAfter.md new file mode 100644 index 0000000000..2501e66c09 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionFrontControllerInitAfter.md @@ -0,0 +1,49 @@ +--- +menuTitle: actionFrontControllerInitAfter +Title: actionFrontControllerInitAfter +hidden: true +hookTitle: Perform actions after front office controller initialization +files: + - classes/controller/FrontController.php +locations: + - frontoffice +type: + - action +hookAliases: + - actionFrontControllerAfterInit +--- + +# Hook actionFrontControllerInitAfter + +Aliases: + - actionFrontControllerAfterInit + + + +## Information + +{{% notice tip %}} +**Perform actions after front office controller initialization:** + +This hook is launched after the initialization of all front office controllers +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook type: + - action + +Located in: + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/FrontController.php](classes/controller/FrontController.php) + +## Hook call in codebase + +```php +Hook::exec( + 'actionFrontControllerInitAfter', + [ + 'controller' => $this, + ] + ) +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionFrontControllerInitBefore.md b/modules/concepts/hooks/list-of-hooks/actionFrontControllerInitBefore.md new file mode 100644 index 0000000000..da0abaa845 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionFrontControllerInitBefore.md @@ -0,0 +1,43 @@ +--- +menuTitle: actionFrontControllerInitBefore +Title: actionFrontControllerInitBefore +hidden: true +hookTitle: Perform actions before front office controller initialization +files: + - classes/controller/FrontController.php +locations: + - frontoffice +type: + - action +hookAliases: +--- + +# Hook actionFrontControllerInitBefore + +## Information + +{{% notice tip %}} +**Perform actions before front office controller initialization:** + +This hook is launched before the initialization of all front office controllers +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook type: + - action + +Located in: + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/FrontController.php](classes/controller/FrontController.php) + +## Hook call in codebase + +```php +Hook::exec( + 'actionFrontControllerInitBefore', + [ + 'controller' => $this, + ] + ) +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionFrontControllerSetMedia.md b/modules/concepts/hooks/list-of-hooks/actionFrontControllerSetMedia.md index acc4c5272f..d748364286 100644 --- a/modules/concepts/hooks/list-of-hooks/actionFrontControllerSetMedia.md +++ b/modules/concepts/hooks/list-of-hooks/actionFrontControllerSetMedia.md @@ -7,25 +7,26 @@ files: - classes/controller/FrontController.php locations: - frontoffice -types: - - legacy +type: + - action +hookAliases: --- -# Hook : actionFrontControllerSetMedia +# Hook actionFrontControllerSetMedia -## Informations +## Information Hook locations: - frontoffice -Hook types: - - legacy +Hook type: + - action Located in: - - classes/controller/FrontController.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/FrontController.php](classes/controller/FrontController.php) -## Hook call with parameters +## Hook call in codebase ```php -Hook::exec('actionFrontControllerSetMedia', []); +Hook::exec('actionFrontControllerSetMedia', []) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionFrontControllerSetVariables.md b/modules/concepts/hooks/list-of-hooks/actionFrontControllerSetVariables.md new file mode 100644 index 0000000000..96e198c356 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionFrontControllerSetVariables.md @@ -0,0 +1,64 @@ +--- +menuTitle: actionFrontControllerSetVariables +Title: actionFrontControllerSetVariables +hidden: true +hookTitle: Add variables in JavaScript object and Smarty templates +files: + - classes/controller/FrontController.php +locations: + - frontoffice +type: + - action +hookAliases: +--- + +# Hook actionFrontControllerSetVariables + +## Information + +{{% notice tip %}} +**Add variables in JavaScript object and Smarty templates:** + +Add variables to javascript object that is available in Front Office. These are also available in smarty templates in modules.your_module_name. +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook type: + - action + +Located in: + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/FrontController.php](classes/controller/FrontController.php) + +This hook has an `$array_return` parameter set to `true` (module output will be set by name in an array, [see explaination here]({{< relref "/8/modules/concepts/hooks">}})). + +## Parameters details + +```php + &(array) + ); +```php + 'Your variable value', + ]; + } +``` + +## Hook call in codebase + +```php +Hook::exec( + 'actionFrontControllerSetVariables', + [ + 'templateVars' => &$templateVars, + ], + null, + true + ) +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionGetAdminOrderButtons.md b/modules/concepts/hooks/list-of-hooks/actionGetAdminOrderButtons.md new file mode 100644 index 0000000000..270440cd57 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionGetAdminOrderButtons.md @@ -0,0 +1,56 @@ +--- +menuTitle: actionGetAdminOrderButtons +Title: actionGetAdminOrderButtons +hidden: true +hookTitle: Admin Order Buttons +files: + - src/PrestaShopBundle/Controller/Admin/Sell/Order/OrderController.php +locations: + - backoffice +type: + - action +hookAliases: +--- + +# Hook actionGetAdminOrderButtons + +## Information + +{{% notice tip %}} +**Admin Order Buttons:** + +This hook is used to generate the buttons collection on the order view page (see ActionsBarButtonsCollection) +{{% /notice %}} + +Hook locations: + - backoffice + +Hook type: + - action + +Located in: + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/Sell/Order/OrderController.php](src/PrestaShopBundle/Controller/Admin/Sell/Order/OrderController.php) + +## Parameters details + +```php + (OrderController) Symfony controller, + 'id_order' => (int) Order ID, + 'actions_bar_buttons_collection' => (ActionsBarButtonsCollection) Collection of ActionsBarButtonInterface + ); +``` + +## Hook call in codebase + +```php +dispatchHook( + 'actionGetAdminOrderButtons', + [ + 'controller' => $this, + 'id_order' => $orderId, + 'actions_bar_buttons_collection' => $backOfficeOrderButtons, + ] + ) +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionGetAdminToolbarButtons.md b/modules/concepts/hooks/list-of-hooks/actionGetAdminToolbarButtons.md new file mode 100644 index 0000000000..50c6f47461 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionGetAdminToolbarButtons.md @@ -0,0 +1,51 @@ +--- +menuTitle: actionGetAdminToolbarButtons +Title: actionGetAdminToolbarButtons +hidden: true +hookTitle: Allows to add buttons in any toolbar in the back office +files: + - classes/controller/AdminController.php +locations: + - backoffice +type: + - action +hookAliases: +--- + +# Hook actionGetAdminToolbarButtons + +## Information + +{{% notice tip %}} +**Allows to add buttons in any toolbar in the back office:** + +This hook allows you to define descriptions of buttons to add in any toolbar of the back office +{{% /notice %}} + +Hook locations: + - backoffice + +Hook type: + - action + +Located in: + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/AdminController.php](classes/controller/AdminController.php) + +## Parameters details + +```php + (AdminController) $currentController, + 'toolbar_extra_buttons_collection' => (ActionsBarButtonsCollection) $toolbarButtonsCollection, + ] +``` + +## Hook call in codebase + +```php +Hook::exec('actionGetAdminToolbarButtons', [ + 'controller' => $this, + 'toolbar_extra_buttons_collection' => &$toolbarButtonsCollection, + ]) +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionGetAlternativeSearchPanels.md b/modules/concepts/hooks/list-of-hooks/actionGetAlternativeSearchPanels.md new file mode 100644 index 0000000000..5193a01911 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionGetAlternativeSearchPanels.md @@ -0,0 +1,58 @@ +--- +menuTitle: actionGetAlternativeSearchPanels +Title: actionGetAlternativeSearchPanels +hidden: true +hookTitle: Additional search panel +files: + - controllers/admin/AdminSearchController.php +locations: + - backoffice +type: + - action +hookAliases: +--- + +# Hook actionGetAlternativeSearchPanels + +## Information + +{{% notice tip %}} +**Additional search panel:** + +This hook allows to add an additional search panel for external providers in PrestaShop back office +{{% /notice %}} + +Hook locations: + - backoffice + +Hook type: + - action + +Located in: + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/admin/AdminSearchController.php](controllers/admin/AdminSearchController.php) + +This hook has an `$array_return` parameter set to `true` (module output will be set by name in an array, [see explaination here]({{< relref "/8/modules/concepts/hooks">}})). + +## Parameters details + +```php + (array) $searchPanels, + 'bo_query' => (string) $searchedExpression, + ] +``` + +## Hook call in codebase + +```php +Hook::exec( + 'actionGetAlternativeSearchPanels', + [ + 'previous_search_panels' => $searchPanels, + 'bo_query' => $searchedExpression, + ], + null, + true + ) +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionGetExtraMailTemplateVars.md b/modules/concepts/hooks/list-of-hooks/actionGetExtraMailTemplateVars.md new file mode 100644 index 0000000000..deccc635b7 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionGetExtraMailTemplateVars.md @@ -0,0 +1,44 @@ +--- +menuTitle: actionGetExtraMailTemplateVars +Title: actionGetExtraMailTemplateVars +hidden: true +hookTitle: +files: + - classes/Mail.php +locations: + - frontoffice +type: + - action +hookAliases: +--- + +# Hook actionGetExtraMailTemplateVars + +## Information + +Hook locations: + - frontoffice + +Hook type: + - action + +Located in: + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Mail.php](classes/Mail.php) + +This hook has an `$array_return` parameter set to `true` (module output will be set by name in an array, [see explaination here]({{< relref "/8/modules/concepts/hooks">}})). + +## Hook call in codebase + +```php +Hook::exec( + 'actionGetExtraMailTemplateVars', + [ + 'template' => $template, + 'template_vars' => $templateVars, + 'extra_template_vars' => &$extraTemplateVars, + 'id_lang' => (int) $idLang, + ], + null, + true + ) +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionGetIDZoneByAddressID.md b/modules/concepts/hooks/list-of-hooks/actionGetIDZoneByAddressID.md index a426052d9b..f3c31935f2 100644 --- a/modules/concepts/hooks/list-of-hooks/actionGetIDZoneByAddressID.md +++ b/modules/concepts/hooks/list-of-hooks/actionGetIDZoneByAddressID.md @@ -7,25 +7,26 @@ files: - classes/Address.php locations: - frontoffice -types: - - legacy +type: + - action +hookAliases: --- -# Hook : actionGetIDZoneByAddressID +# Hook actionGetIDZoneByAddressID -## Informations +## Information Hook locations: - frontoffice -Hook types: - - legacy +Hook type: + - action Located in: - - classes/Address.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Address.php](classes/Address.php) -## Hook call with parameters +## Hook call in codebase ```php -Hook::exec('actionGetIDZoneByAddressID', ['id_address' => $id_address]); +Hook::exec('actionGetIDZoneByAddressID', ['id_address' => $id_address]) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionGetMailLayoutTransformations.md b/modules/concepts/hooks/list-of-hooks/actionGetMailLayoutTransformations.md new file mode 100644 index 0000000000..dd25400b4f --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionGetMailLayoutTransformations.md @@ -0,0 +1,45 @@ +--- +menuTitle: actionGetMailLayoutTransformations +Title: actionGetMailLayoutTransformations +hidden: true +hookTitle: Define the transformation to apply on layout +files: + - src/Adapter/MailTemplate/MailTemplateTwigRenderer.php +locations: + - frontoffice +type: + - action +hookAliases: +--- + +# Hook actionGetMailLayoutTransformations + +## Information + +{{% notice tip %}} +**Define the transformation to apply on layout:** + +This hook allows to add/remove TransformationInterface used to generate an email layout +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook type: + - action + +Located in: + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/MailTemplate/MailTemplateTwigRenderer.php](src/Adapter/MailTemplate/MailTemplateTwigRenderer.php) + +## Hook call in codebase + +```php +dispatchWithParameters( + MailTemplateRendererInterface::GET_MAIL_LAYOUT_TRANSFORMATIONS, + [ + 'mailLayout' => $mailLayout, + 'templateType' => $templateType, + 'layoutTransformations' => $templateTransformations, + ] + ) +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionGetProductPropertiesAfter.md b/modules/concepts/hooks/list-of-hooks/actionGetProductPropertiesAfter.md index c183600933..8eb920f493 100644 --- a/modules/concepts/hooks/list-of-hooks/actionGetProductPropertiesAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionGetProductPropertiesAfter.md @@ -7,29 +7,34 @@ files: - classes/Product.php locations: - frontoffice -types: - - legacy +type: + - action +hookAliases: --- -# Hook : actionGetProductPropertiesAfter +# Hook actionGetProductPropertiesAfter -## Informations +## Information + +{{% notice warning %}} +**Deprecated:** Since 1.7.8.0 +{{% /notice %}} Hook locations: - frontoffice -Hook types: - - legacy +Hook type: + - action Located in: - - classes/Product.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Product.php](classes/Product.php) -## Hook call with parameters +## Hook call in codebase ```php Hook::exec('actionGetProductPropertiesAfter', [ 'id_lang' => $id_lang, 'product' => &$row, 'context' => $context, - ]); + ]) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionGetProductPropertiesAfterUnitPrice.md b/modules/concepts/hooks/list-of-hooks/actionGetProductPropertiesAfterUnitPrice.md index 579002c27a..ea554a3de9 100644 --- a/modules/concepts/hooks/list-of-hooks/actionGetProductPropertiesAfterUnitPrice.md +++ b/modules/concepts/hooks/list-of-hooks/actionGetProductPropertiesAfterUnitPrice.md @@ -7,13 +7,14 @@ files: - classes/Product.php locations: - frontoffice -types: - - legacy +type: + - action +hookAliases: --- -# Hook : actionGetProductPropertiesAfterUnitPrice +# Hook actionGetProductPropertiesAfterUnitPrice -## Informations +## Information {{% notice tip %}} **Product Properties:** @@ -24,18 +25,18 @@ This hook is called after defining the properties of a product Hook locations: - frontoffice -Hook types: - - legacy +Hook type: + - action Located in: - - classes/Product.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Product.php](classes/Product.php) -## Hook call with parameters +## Hook call in codebase ```php Hook::exec('actionGetProductPropertiesAfterUnitPrice', [ 'id_lang' => $id_lang, 'product' => &$row, 'context' => $context, - ]); + ]) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionGetProductPropertiesBefore.md b/modules/concepts/hooks/list-of-hooks/actionGetProductPropertiesBefore.md index c9b6b9df69..3b5d1fed6b 100644 --- a/modules/concepts/hooks/list-of-hooks/actionGetProductPropertiesBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionGetProductPropertiesBefore.md @@ -7,29 +7,30 @@ files: - classes/Product.php locations: - frontoffice -types: - - legacy +type: + - action +hookAliases: --- -# Hook : actionGetProductPropertiesBefore +# Hook actionGetProductPropertiesBefore -## Informations +## Information Hook locations: - frontoffice -Hook types: - - legacy +Hook type: + - action Located in: - - classes/Product.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Product.php](classes/Product.php) -## Hook call with parameters +## Hook call in codebase ```php Hook::exec('actionGetProductPropertiesBefore', [ 'id_lang' => $id_lang, 'product' => &$row, 'context' => $context, - ]); + ]) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionHtaccessCreate.md b/modules/concepts/hooks/list-of-hooks/actionHtaccessCreate.md index b07e6fb969..69f1a516d6 100644 --- a/modules/concepts/hooks/list-of-hooks/actionHtaccessCreate.md +++ b/modules/concepts/hooks/list-of-hooks/actionHtaccessCreate.md @@ -7,13 +7,20 @@ files: - classes/Tools.php locations: - frontoffice -types: - - legacy +type: + - action +hookAliases: + - afterCreateHtaccess --- -# Hook : actionHtaccessCreate +# Hook actionHtaccessCreate -## Informations +Aliases: + - afterCreateHtaccess + + + +## Information {{% notice tip %}} **After htaccess creation:** @@ -24,14 +31,14 @@ This hook is displayed after the htaccess creation Hook locations: - frontoffice -Hook types: - - legacy +Hook type: + - action Located in: - - classes/Tools.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Tools.php](classes/Tools.php) -## Hook call with parameters +## Hook call in codebase ```php -Hook::exec('actionHtaccessCreate'); +Hook::exec('actionHtaccessCreate') ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionInvoiceNumberFormatted.md b/modules/concepts/hooks/list-of-hooks/actionInvoiceNumberFormatted.md index a1c273bf2e..8c7bfc8f64 100644 --- a/modules/concepts/hooks/list-of-hooks/actionInvoiceNumberFormatted.md +++ b/modules/concepts/hooks/list-of-hooks/actionInvoiceNumberFormatted.md @@ -7,24 +7,25 @@ files: - classes/order/OrderInvoice.php locations: - frontoffice -types: - - legacy +type: + - action +hookAliases: --- -# Hook : actionInvoiceNumberFormatted +# Hook actionInvoiceNumberFormatted -## Informations +## Information Hook locations: - frontoffice -Hook types: - - legacy +Hook type: + - action Located in: - - classes/order/OrderInvoice.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/order/OrderInvoice.php](classes/order/OrderInvoice.php) -## Hook call with parameters +## Hook call in codebase ```php Hook::exec('actionInvoiceNumberFormatted', [ @@ -32,5 +33,5 @@ Hook::exec('actionInvoiceNumberFormatted', [ 'id_lang' => (int) $id_lang, 'id_shop' => (int) $id_shop, 'number' => (int) $this->number, - ]); + ]) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionListMailThemes.md b/modules/concepts/hooks/list-of-hooks/actionListMailThemes.md new file mode 100644 index 0000000000..71edd31b62 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionListMailThemes.md @@ -0,0 +1,41 @@ +--- +menuTitle: actionListMailThemes +Title: actionListMailThemes +hidden: true +hookTitle: List the available email themes and layouts +files: + - src/Core/MailTemplate/FolderThemeCatalog.php +locations: + - frontoffice +type: + - action +hookAliases: +--- + +# Hook actionListMailThemes + +## Information + +{{% notice tip %}} +**List the available email themes and layouts:** + +This hook allows to add/remove available email themes (ThemeInterface) and/or to add/remove their layouts (LayoutInterface) +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook type: + - action + +Located in: + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Core/MailTemplate/FolderThemeCatalog.php](src/Core/MailTemplate/FolderThemeCatalog.php) + +## Hook call in codebase + +```php +dispatchWithParameters( + ThemeCatalogInterface::LIST_MAIL_THEMES_HOOK, + ['mailThemes' => $mailThemes] + ) +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionMailAlterMessageBeforeSend.md b/modules/concepts/hooks/list-of-hooks/actionMailAlterMessageBeforeSend.md index 06ab8754cc..d366260334 100644 --- a/modules/concepts/hooks/list-of-hooks/actionMailAlterMessageBeforeSend.md +++ b/modules/concepts/hooks/list-of-hooks/actionMailAlterMessageBeforeSend.md @@ -7,27 +7,28 @@ files: - classes/Mail.php locations: - frontoffice -types: - - legacy +type: + - action +hookAliases: --- -# Hook : actionMailAlterMessageBeforeSend +# Hook actionMailAlterMessageBeforeSend -## Informations +## Information Hook locations: - frontoffice -Hook types: - - legacy +Hook type: + - action Located in: - - classes/Mail.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Mail.php](classes/Mail.php) -## Hook call with parameters +## Hook call in codebase ```php Hook::exec('actionMailAlterMessageBeforeSend', [ 'message' => &$message, - ]); + ]) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionModuleInstallAfter.md b/modules/concepts/hooks/list-of-hooks/actionModuleInstallAfter.md index cf1ddde90f..af21871cb8 100644 --- a/modules/concepts/hooks/list-of-hooks/actionModuleInstallAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionModuleInstallAfter.md @@ -7,13 +7,14 @@ files: - classes/module/Module.php locations: - frontoffice -types: - - legacy +type: + - action +hookAliases: --- -# Hook : actionModuleInstallAfter +# Hook actionModuleInstallAfter -## Informations +## Information {{% notice tip %}} **actionModuleInstallAfter:** @@ -24,14 +25,14 @@ types: Hook locations: - frontoffice -Hook types: - - legacy +Hook type: + - action Located in: - - classes/module/Module.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/module/Module.php](classes/module/Module.php) -## Hook call with parameters +## Hook call in codebase ```php -Hook::exec('actionModuleInstallAfter', ['object' => $this]); +Hook::exec('actionModuleInstallAfter', ['object' => $this]) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionModuleInstallBefore.md b/modules/concepts/hooks/list-of-hooks/actionModuleInstallBefore.md index b276268e9c..4bc87c19b2 100644 --- a/modules/concepts/hooks/list-of-hooks/actionModuleInstallBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionModuleInstallBefore.md @@ -7,13 +7,14 @@ files: - classes/module/Module.php locations: - frontoffice -types: - - legacy +type: + - action +hookAliases: --- -# Hook : actionModuleInstallBefore +# Hook actionModuleInstallBefore -## Informations +## Information {{% notice tip %}} **actionModuleInstallBefore:** @@ -24,14 +25,14 @@ types: Hook locations: - frontoffice -Hook types: - - legacy +Hook type: + - action Located in: - - classes/module/Module.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/module/Module.php](classes/module/Module.php) -## Hook call with parameters +## Hook call in codebase ```php -Hook::exec('actionModuleInstallBefore', ['object' => $this]); +Hook::exec('actionModuleInstallBefore', ['object' => $this]) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionModuleMailAlertSendCustomer.md b/modules/concepts/hooks/list-of-hooks/actionModuleMailAlertSendCustomer.md new file mode 100644 index 0000000000..5960e23369 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionModuleMailAlertSendCustomer.md @@ -0,0 +1,40 @@ +--- +menuTitle: actionModuleMailAlertSendCustomer +Title: actionModuleMailAlertSendCustomer +hidden: true +hookTitle: +files: + - modules/ps_emailalerts/MailAlert.php +locations: + - frontoffice +type: + - action +hookAliases: +--- + +# Hook actionModuleMailAlertSendCustomer + +## Information + +Hook locations: + - frontoffice + +Hook type: + - action + +Located in: + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/modules/ps_emailalerts/MailAlert.php](modules/ps_emailalerts/MailAlert.php) + +## Hook call in codebase + +```php +Hook::exec( + 'actionModuleMailAlertSendCustomer', + [ + 'product' => $product_name, + 'link' => $product_link, + 'customer' => $customer, + 'product_obj' => $product, + ] + ) +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionModuleRegisterHookAfter.md b/modules/concepts/hooks/list-of-hooks/actionModuleRegisterHookAfter.md new file mode 100644 index 0000000000..de36fc9a85 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionModuleRegisterHookAfter.md @@ -0,0 +1,38 @@ +--- +menuTitle: actionModuleRegisterHookAfter +Title: actionModuleRegisterHookAfter +hidden: true +hookTitle: +files: + - classes/Hook.php +locations: + - frontoffice +type: + - action +hookAliases: +--- + +# Hook actionModuleRegisterHookAfter + +## Information + +Hook locations: + - frontoffice + +Hook type: + - action + +Located in: + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Hook.php](classes/Hook.php) + +## Hook call in codebase + +```php +Hook::exec( + 'actionModuleRegisterHookAfter', + [ + 'object' => $module_instance, + 'hook_name' => $hook_name, + ] + ) +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionModuleRegisterHookBefore.md b/modules/concepts/hooks/list-of-hooks/actionModuleRegisterHookBefore.md new file mode 100644 index 0000000000..0100221082 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionModuleRegisterHookBefore.md @@ -0,0 +1,38 @@ +--- +menuTitle: actionModuleRegisterHookBefore +Title: actionModuleRegisterHookBefore +hidden: true +hookTitle: +files: + - classes/Hook.php +locations: + - frontoffice +type: + - action +hookAliases: +--- + +# Hook actionModuleRegisterHookBefore + +## Information + +Hook locations: + - frontoffice + +Hook type: + - action + +Located in: + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Hook.php](classes/Hook.php) + +## Hook call in codebase + +```php +Hook::exec( + 'actionModuleRegisterHookBefore', + [ + 'object' => $module_instance, + 'hook_name' => $hook_name, + ] + ) +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionModuleUnRegisterHookAfter.md b/modules/concepts/hooks/list-of-hooks/actionModuleUnRegisterHookAfter.md new file mode 100644 index 0000000000..4fa8c0c20b --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionModuleUnRegisterHookAfter.md @@ -0,0 +1,38 @@ +--- +menuTitle: actionModuleUnRegisterHookAfter +Title: actionModuleUnRegisterHookAfter +hidden: true +hookTitle: +files: + - classes/Hook.php +locations: + - frontoffice +type: + - action +hookAliases: +--- + +# Hook actionModuleUnRegisterHookAfter + +## Information + +Hook locations: + - frontoffice + +Hook type: + - action + +Located in: + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Hook.php](classes/Hook.php) + +## Hook call in codebase + +```php +Hook::exec( + 'actionModuleUnRegisterHookAfter', + [ + 'object' => $module_instance, + 'hook_name' => $hook_name, + ] + ) +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionModuleUnRegisterHookBefore.md b/modules/concepts/hooks/list-of-hooks/actionModuleUnRegisterHookBefore.md index df84a1c572..4c57284514 100644 --- a/modules/concepts/hooks/list-of-hooks/actionModuleUnRegisterHookBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionModuleUnRegisterHookBefore.md @@ -7,25 +7,26 @@ files: - classes/Hook.php locations: - frontoffice -types: - - legacy +type: + - action +hookAliases: --- -# Hook : actionModuleUnRegisterHookBefore +# Hook actionModuleUnRegisterHookBefore -## Informations +## Information Hook locations: - frontoffice -Hook types: - - legacy +Hook type: + - action Located in: - - classes/Hook.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Hook.php](classes/Hook.php) -## Hook call with parameters +## Hook call in codebase ```php -Hook::exec('actionModuleUnRegisterHookBefore', ['object' => $module_instance, 'hook_name' => $hook_name]); +Hook::exec('actionModuleUnRegisterHookBefore', ['object' => $module_instance, 'hook_name' => $hook_name]) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionModuleUninstallAfter.md b/modules/concepts/hooks/list-of-hooks/actionModuleUninstallAfter.md index 9888cfc241..b8a7f4cd7d 100644 --- a/modules/concepts/hooks/list-of-hooks/actionModuleUninstallAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionModuleUninstallAfter.md @@ -7,13 +7,14 @@ files: - classes/module/Module.php locations: - frontoffice -types: - - legacy +type: + - action +hookAliases: --- -# Hook : actionModuleUninstallAfter +# Hook actionModuleUninstallAfter -## Informations +## Information {{% notice tip %}} **actionModuleUninstallAfter:** @@ -24,14 +25,14 @@ types: Hook locations: - frontoffice -Hook types: - - legacy +Hook type: + - action Located in: - - classes/module/Module.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/module/Module.php](classes/module/Module.php) -## Hook call with parameters +## Hook call in codebase ```php -Hook::exec('actionModuleUninstallAfter', ['object' => $this]); +Hook::exec('actionModuleUninstallAfter', ['object' => $this]) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionModuleUninstallBefore.md b/modules/concepts/hooks/list-of-hooks/actionModuleUninstallBefore.md index aa49beea24..0ea1b95ff0 100644 --- a/modules/concepts/hooks/list-of-hooks/actionModuleUninstallBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionModuleUninstallBefore.md @@ -7,13 +7,14 @@ files: - classes/module/Module.php locations: - frontoffice -types: - - legacy +type: + - action +hookAliases: --- -# Hook : actionModuleUninstallBefore +# Hook actionModuleUninstallBefore -## Informations +## Information {{% notice tip %}} **actionModuleUninstallBefore:** @@ -24,14 +25,14 @@ types: Hook locations: - frontoffice -Hook types: - - legacy +Hook type: + - action Located in: - - classes/module/Module.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/module/Module.php](classes/module/Module.php) -## Hook call with parameters +## Hook call in codebase ```php -Hook::exec('actionModuleUninstallBefore', ['object' => $this]); +Hook::exec('actionModuleUninstallBefore', ['object' => $this]) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionNewsletterRegistrationAfter.md b/modules/concepts/hooks/list-of-hooks/actionNewsletterRegistrationAfter.md new file mode 100644 index 0000000000..86c66a5a83 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionNewsletterRegistrationAfter.md @@ -0,0 +1,40 @@ +--- +menuTitle: actionNewsletterRegistrationAfter +Title: actionNewsletterRegistrationAfter +hidden: true +hookTitle: +files: + - modules/ps_emailsubscription/ps_emailsubscription.php +locations: + - frontoffice +type: + - action +hookAliases: +--- + +# Hook actionNewsletterRegistrationAfter + +## Information + +Hook locations: + - frontoffice + +Hook type: + - action + +Located in: + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/modules/ps_emailsubscription/ps_emailsubscription.php](modules/ps_emailsubscription/ps_emailsubscription.php) + +## Hook call in codebase + +```php +Hook::exec( + 'actionNewsletterRegistrationAfter', + [ + 'hookName' => $hookName, + 'email' => $_POST['email'], + 'action' => $_POST['action'], + 'error' => &$this->error, + ] + ) +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionNewsletterRegistrationBefore.md b/modules/concepts/hooks/list-of-hooks/actionNewsletterRegistrationBefore.md new file mode 100644 index 0000000000..a40e607f16 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionNewsletterRegistrationBefore.md @@ -0,0 +1,40 @@ +--- +menuTitle: actionNewsletterRegistrationBefore +Title: actionNewsletterRegistrationBefore +hidden: true +hookTitle: +files: + - modules/ps_emailsubscription/ps_emailsubscription.php +locations: + - frontoffice +type: + - action +hookAliases: +--- + +# Hook actionNewsletterRegistrationBefore + +## Information + +Hook locations: + - frontoffice + +Hook type: + - action + +Located in: + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/modules/ps_emailsubscription/ps_emailsubscription.php](modules/ps_emailsubscription/ps_emailsubscription.php) + +## Hook call in codebase + +```php +Hook::exec( + 'actionNewsletterRegistrationBefore', + [ + 'hookName' => $hookName, + 'email' => $_POST['email'], + 'action' => $_POST['action'], + 'hookError' => &$hookError, + ] + ) +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionObjectAddAfter.md b/modules/concepts/hooks/list-of-hooks/actionObjectAddAfter.md index adb2d70481..0f2300e6c5 100644 --- a/modules/concepts/hooks/list-of-hooks/actionObjectAddAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionObjectAddAfter.md @@ -8,25 +8,26 @@ files: locations: - backoffice - frontoffice -types: - - legacy +type: + - action +hookAliases: --- -# Hook : actionObjectAddAfter +# Hook actionObjectAddAfter -## Informations +## Information Hook locations: - backoffice - frontoffice -Hook types: - - legacy +Hook type: + - action Located in: - - classes/ObjectModel.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/ObjectModel.php](classes/ObjectModel.php) -## Hook call with parameters +## Hook call in codebase ```php Hook::exec('actionObject' . $this->getFullyQualifiedName() . 'AddAfter', ['object' => $this]); diff --git a/modules/concepts/hooks/list-of-hooks/actionObjectAddBefore.md b/modules/concepts/hooks/list-of-hooks/actionObjectAddBefore.md index 2777964319..89384c6ce9 100644 --- a/modules/concepts/hooks/list-of-hooks/actionObjectAddBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionObjectAddBefore.md @@ -8,25 +8,26 @@ files: locations: - backoffice - frontoffice -types: - - legacy +type: + - action +hookAliases: --- -# Hook : actionObjectAddBefore +# Hook actionObjectAddBefore -## Informations +## Information Hook locations: - backoffice - frontoffice -Hook types: - - legacy +Hook type: + - action Located in: - - classes/ObjectModel.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/ObjectModel.php](classes/ObjectModel.php) -## Hook call with parameters +## Hook call in codebase ```php Hook::exec('actionObject' . $this->getFullyQualifiedName() . 'AddBefore', ['object' => $this]); diff --git a/modules/concepts/hooks/list-of-hooks/actionObjectDeleteAfter.md b/modules/concepts/hooks/list-of-hooks/actionObjectDeleteAfter.md index a2a1ed839b..1b2d3d88c2 100644 --- a/modules/concepts/hooks/list-of-hooks/actionObjectDeleteAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionObjectDeleteAfter.md @@ -8,25 +8,26 @@ files: locations: - backoffice - frontoffice -types: - - legacy +type: + - action +hookAliases: --- -# Hook : actionObjectDeleteAfter +# Hook actionObjectDeleteAfter -## Informations +## Information Hook locations: - backoffice - frontoffice -Hook types: - - legacy +Hook type: + - action Located in: - - classes/ObjectModel.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/ObjectModel.php](classes/ObjectModel.php) -## Hook call with parameters +## Hook call in codebase ```php Hook::exec('actionObject' . $this->getFullyQualifiedName() . 'DeleteAfter', ['object' => $this]); diff --git a/modules/concepts/hooks/list-of-hooks/actionObjectDeleteBefore.md b/modules/concepts/hooks/list-of-hooks/actionObjectDeleteBefore.md index 79f1f787e0..21b349478a 100644 --- a/modules/concepts/hooks/list-of-hooks/actionObjectDeleteBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionObjectDeleteBefore.md @@ -8,25 +8,26 @@ files: locations: - backoffice - frontoffice -types: - - legacy +type: + - action +hookAliases: --- -# Hook : actionObjectDeleteBefore +# Hook actionObjectDeleteBefore -## Informations +## Information Hook locations: - backoffice - frontoffice -Hook types: - - legacy +Hook type: + - action Located in: - - classes/ObjectModel.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/ObjectModel.php](classes/ObjectModel.php) -## Hook call with parameters +## Hook call in codebase ```php Hook::exec('actionObject' . $this->getFullyQualifiedName() . 'DeleteBefore', ['object' => $this]); diff --git a/modules/concepts/hooks/list-of-hooks/actionObjectUpdateAfter.md b/modules/concepts/hooks/list-of-hooks/actionObjectUpdateAfter.md index 38c1f65a18..dbe7b50a1e 100644 --- a/modules/concepts/hooks/list-of-hooks/actionObjectUpdateAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionObjectUpdateAfter.md @@ -8,25 +8,26 @@ files: locations: - backoffice - frontoffice -types: - - legacy +type: + - action +hookAliases: --- -# Hook : actionObjectUpdateAfter +# Hook actionObjectUpdateAfter -## Informations +## Information Hook locations: - backoffice - frontoffice -Hook types: - - legacy +Hook type: + - action Located in: - - classes/ObjectModel.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/ObjectModel.php](classes/ObjectModel.php) -## Hook call with parameters +## Hook call in codebase ```php Hook::exec('actionObject' . $this->getFullyQualifiedName() . 'UpdateAfter', ['object' => $this]); diff --git a/modules/concepts/hooks/list-of-hooks/actionObjectUpdateBefore.md b/modules/concepts/hooks/list-of-hooks/actionObjectUpdateBefore.md index 838167d436..a96f6327e1 100644 --- a/modules/concepts/hooks/list-of-hooks/actionObjectUpdateBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionObjectUpdateBefore.md @@ -8,25 +8,26 @@ files: locations: - backoffice - frontoffice -types: - - legacy +type: + - action +hookAliases: --- -# Hook : actionObjectUpdateBefore +# Hook actionObjectUpdateBefore -## Informations +## Information Hook locations: - backoffice - frontoffice -Hook types: - - legacy +Hook type: + - action Located in: - - classes/ObjectModel.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/ObjectModel.php](classes/ObjectModel.php) -## Hook call with parameters +## Hook call in codebase ```php Hook::exec('actionObject' . $this->getFullyQualifiedName() . 'UpdateBefore', ['object' => $this]); diff --git a/modules/concepts/hooks/list-of-hooks/actionObjectAddAfter.md b/modules/concepts/hooks/list-of-hooks/actionObjectAddAfter.md index c2521a32e9..727243f368 100644 --- a/modules/concepts/hooks/list-of-hooks/actionObjectAddAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionObjectAddAfter.md @@ -8,26 +8,27 @@ files: locations: - backoffice - frontoffice -types: - - legacy +type: + - action +hookAliases: --- -# Hook : actionObjectAddAfter +# Hook actionObjectAddAfter -## Informations +## Information Hook locations: - backoffice - frontoffice -Hook types: - - legacy +Hook type: + - action Located in: - - classes/ObjectModel.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/ObjectModel.php](classes/ObjectModel.php) -## Hook call with parameters +## Hook call in codebase ```php -Hook::exec('actionObjectAddAfter', ['object' => $this]); +Hook::exec('actionObjectAddAfter', ['object' => $this]) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionObjectAddBefore.md b/modules/concepts/hooks/list-of-hooks/actionObjectAddBefore.md index a66babd485..b9f56ad129 100644 --- a/modules/concepts/hooks/list-of-hooks/actionObjectAddBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionObjectAddBefore.md @@ -8,26 +8,27 @@ files: locations: - backoffice - frontoffice -types: - - legacy +type: + - action +hookAliases: --- -# Hook : actionObjectAddBefore +# Hook actionObjectAddBefore -## Informations +## Information Hook locations: - backoffice - frontoffice -Hook types: - - legacy +Hook type: + - action Located in: - - classes/ObjectModel.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/ObjectModel.php](classes/ObjectModel.php) -## Hook call with parameters +## Hook call in codebase ```php -Hook::exec('actionObjectAddBefore', ['object' => $this]); +Hook::exec('actionObjectAddBefore', ['object' => $this]) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionObjectAttributeAddBefore.md b/modules/concepts/hooks/list-of-hooks/actionObjectAttributeAddBefore.md index 422966916d..312d06b183 100644 --- a/modules/concepts/hooks/list-of-hooks/actionObjectAttributeAddBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionObjectAttributeAddBefore.md @@ -8,26 +8,27 @@ files: locations: - backoffice - frontoffice -types: - - legacy +type: + - action +hookAliases: --- -# Hook : actionObjectAttributeAddBefore +# Hook actionObjectAttributeAddBefore -## Informations +## Information Hook locations: - backoffice - frontoffice -Hook types: - - legacy +Hook type: + - action Located in: - - controllers/admin/AdminAttributesGroupsController.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/admin/AdminAttributesGroupsController.php](controllers/admin/AdminAttributesGroupsController.php) -## Hook call with parameters +## Hook call in codebase ```php -Hook::exec('actionObjectAttributeAddBefore'); +Hook::exec('actionObjectAttributeAddBefore') ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionObjectAttributeGroupAddBefore.md b/modules/concepts/hooks/list-of-hooks/actionObjectAttributeGroupAddBefore.md index 4498b65252..3cbd22f94f 100644 --- a/modules/concepts/hooks/list-of-hooks/actionObjectAttributeGroupAddBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionObjectAttributeGroupAddBefore.md @@ -8,26 +8,27 @@ files: locations: - backoffice - frontoffice -types: - - legacy +type: + - action +hookAliases: --- -# Hook : actionObjectAttributeGroupAddBefore +# Hook actionObjectAttributeGroupAddBefore -## Informations +## Information Hook locations: - backoffice - frontoffice -Hook types: - - legacy +Hook type: + - action Located in: - - controllers/admin/AdminAttributesGroupsController.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/admin/AdminAttributesGroupsController.php](controllers/admin/AdminAttributesGroupsController.php) -## Hook call with parameters +## Hook call in codebase ```php -Hook::exec('actionObjectAttributeGroupAddBefore'); +Hook::exec('actionObjectAttributeGroupAddBefore') ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionObjectDeleteAfter.md b/modules/concepts/hooks/list-of-hooks/actionObjectDeleteAfter.md index 004762e044..19d409e3c7 100644 --- a/modules/concepts/hooks/list-of-hooks/actionObjectDeleteAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionObjectDeleteAfter.md @@ -8,26 +8,27 @@ files: locations: - backoffice - frontoffice -types: - - legacy +type: + - action +hookAliases: --- -# Hook : actionObjectDeleteAfter +# Hook actionObjectDeleteAfter -## Informations +## Information Hook locations: - backoffice - frontoffice -Hook types: - - legacy +Hook type: + - action Located in: - - classes/ObjectModel.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/ObjectModel.php](classes/ObjectModel.php) -## Hook call with parameters +## Hook call in codebase ```php -Hook::exec('actionObjectDeleteAfter', ['object' => $this]); +Hook::exec('actionObjectDeleteAfter', ['object' => $this]) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionObjectDeleteBefore.md b/modules/concepts/hooks/list-of-hooks/actionObjectDeleteBefore.md index 1d5753c699..8e0ba5963b 100644 --- a/modules/concepts/hooks/list-of-hooks/actionObjectDeleteBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionObjectDeleteBefore.md @@ -8,26 +8,27 @@ files: locations: - backoffice - frontoffice -types: - - legacy +type: + - action +hookAliases: --- -# Hook : actionObjectDeleteBefore +# Hook actionObjectDeleteBefore -## Informations +## Information Hook locations: - backoffice - frontoffice -Hook types: - - legacy +Hook type: + - action Located in: - - classes/ObjectModel.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/ObjectModel.php](classes/ObjectModel.php) -## Hook call with parameters +## Hook call in codebase ```php -Hook::exec('actionObjectDeleteBefore', ['object' => $this]); +Hook::exec('actionObjectDeleteBefore', ['object' => $this]) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionObjectProductCommentValidateAfter.md b/modules/concepts/hooks/list-of-hooks/actionObjectProductCommentValidateAfter.md index 94e9de49d8..1a31ef05a8 100644 --- a/modules/concepts/hooks/list-of-hooks/actionObjectProductCommentValidateAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionObjectProductCommentValidateAfter.md @@ -8,26 +8,27 @@ files: locations: - backoffice - frontoffice -types: - - legacy +type: + - action +hookAliases: --- -# Hook : actionObjectProductCommentValidateAfter +# Hook actionObjectProductCommentValidateAfter -## Informations +## Information Hook locations: - backoffice - frontoffice -Hook types: - - legacy +Hook type: + - action Located in: - - modules/productcomments/ProductComment.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/modules/productcomments/ProductComment.php](modules/productcomments/ProductComment.php) -## Hook call with parameters +## Hook call in codebase ```php -Hook::exec('actionObjectProductCommentValidateAfter', ['object' => $this]); +Hook::exec('actionObjectProductCommentValidateAfter', ['object' => $this]) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionObjectProductInCartDeleteAfter.md b/modules/concepts/hooks/list-of-hooks/actionObjectProductInCartDeleteAfter.md index cb8a104542..85c8f0506c 100644 --- a/modules/concepts/hooks/list-of-hooks/actionObjectProductInCartDeleteAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionObjectProductInCartDeleteAfter.md @@ -8,13 +8,14 @@ files: locations: - backoffice - frontoffice -types: - - legacy +type: + - action +hookAliases: --- -# Hook : actionObjectProductInCartDeleteAfter +# Hook actionObjectProductInCartDeleteAfter -## Informations +## Information {{% notice tip %}} **Cart product removal:** @@ -26,14 +27,14 @@ Hook locations: - backoffice - frontoffice -Hook types: - - legacy +Hook type: + - action Located in: - - controllers/front/CartController.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/front/CartController.php](controllers/front/CartController.php) -## Hook call with parameters +## Hook call in codebase ```php -Hook::exec('actionObjectProductInCartDeleteAfter', $data); +Hook::exec('actionObjectProductInCartDeleteAfter', $data) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionObjectProductInCartDeleteBefore.md b/modules/concepts/hooks/list-of-hooks/actionObjectProductInCartDeleteBefore.md index c88253f405..2726cdbcd2 100644 --- a/modules/concepts/hooks/list-of-hooks/actionObjectProductInCartDeleteBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionObjectProductInCartDeleteBefore.md @@ -8,13 +8,14 @@ files: locations: - backoffice - frontoffice -types: - - legacy +type: + - action +hookAliases: --- -# Hook : actionObjectProductInCartDeleteBefore +# Hook actionObjectProductInCartDeleteBefore -## Informations +## Information {{% notice tip %}} **Cart product removal:** @@ -26,14 +27,16 @@ Hook locations: - backoffice - frontoffice -Hook types: - - legacy +Hook type: + - action Located in: - - controllers/front/CartController.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/front/CartController.php](controllers/front/CartController.php) + +This hook has an `$array_return` parameter set to `true` (module output will be set by name in an array, [see explaination here]({{< relref "/8/modules/concepts/hooks">}})). -## Hook call with parameters +## Hook call in codebase ```php -Hook::exec('actionObjectProductInCartDeleteBefore', $data, null, true); +Hook::exec('actionObjectProductInCartDeleteBefore', $data, null, true) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionObjectUpdateAfter.md b/modules/concepts/hooks/list-of-hooks/actionObjectUpdateAfter.md index cafd8abcb9..aaa29a0c79 100644 --- a/modules/concepts/hooks/list-of-hooks/actionObjectUpdateAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionObjectUpdateAfter.md @@ -8,26 +8,27 @@ files: locations: - backoffice - frontoffice -types: - - legacy +type: + - action +hookAliases: --- -# Hook : actionObjectUpdateAfter +# Hook actionObjectUpdateAfter -## Informations +## Information Hook locations: - backoffice - frontoffice -Hook types: - - legacy +Hook type: + - action Located in: - - classes/ObjectModel.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/ObjectModel.php](classes/ObjectModel.php) -## Hook call with parameters +## Hook call in codebase ```php -Hook::exec('actionObjectUpdateAfter', ['object' => $this]); +Hook::exec('actionObjectUpdateAfter', ['object' => $this]) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionObjectUpdateBefore.md b/modules/concepts/hooks/list-of-hooks/actionObjectUpdateBefore.md index 78b4b17a10..d851986890 100644 --- a/modules/concepts/hooks/list-of-hooks/actionObjectUpdateBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionObjectUpdateBefore.md @@ -8,26 +8,27 @@ files: locations: - backoffice - frontoffice -types: - - legacy +type: + - action +hookAliases: --- -# Hook : actionObjectUpdateBefore +# Hook actionObjectUpdateBefore -## Informations +## Information Hook locations: - backoffice - frontoffice -Hook types: - - legacy +Hook type: + - action Located in: - - classes/ObjectModel.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/ObjectModel.php](classes/ObjectModel.php) -## Hook call with parameters +## Hook call in codebase ```php -Hook::exec('actionObjectUpdateBefore', ['object' => $this]); +Hook::exec('actionObjectUpdateBefore', ['object' => $this]) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionOnImageCutAfter.md b/modules/concepts/hooks/list-of-hooks/actionOnImageCutAfter.md index 5620cf4fcc..830b30c5f2 100644 --- a/modules/concepts/hooks/list-of-hooks/actionOnImageCutAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionOnImageCutAfter.md @@ -7,25 +7,26 @@ files: - classes/ImageManager.php locations: - frontoffice -types: - - legacy +type: + - action +hookAliases: --- -# Hook : actionOnImageCutAfter +# Hook actionOnImageCutAfter -## Informations +## Information Hook locations: - frontoffice -Hook types: - - legacy +Hook type: + - action Located in: - - classes/ImageManager.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/ImageManager.php](classes/ImageManager.php) -## Hook call with parameters +## Hook call in codebase ```php -Hook::exec('actionOnImageCutAfter', ['dst_file' => $dstFile, 'file_type' => $fileType]); +Hook::exec('actionOnImageCutAfter', ['dst_file' => $dstFile, 'file_type' => $fileType]) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionOnImageResizeAfter.md b/modules/concepts/hooks/list-of-hooks/actionOnImageResizeAfter.md index d64c93638b..e9985a88bc 100644 --- a/modules/concepts/hooks/list-of-hooks/actionOnImageResizeAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionOnImageResizeAfter.md @@ -7,25 +7,26 @@ files: - classes/ImageManager.php locations: - frontoffice -types: - - legacy +type: + - action +hookAliases: --- -# Hook : actionOnImageResizeAfter +# Hook actionOnImageResizeAfter -## Informations +## Information Hook locations: - frontoffice -Hook types: - - legacy +Hook type: + - action Located in: - - classes/ImageManager.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/ImageManager.php](classes/ImageManager.php) -## Hook call with parameters +## Hook call in codebase ```php -Hook::exec('actionOnImageResizeAfter', ['dst_file' => $destinationFile, 'file_type' => $fileType]); +Hook::exec('actionOnImageResizeAfter', ['dst_file' => $destinationFile, 'file_type' => $fileType]) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionOrderEdited.md b/modules/concepts/hooks/list-of-hooks/actionOrderEdited.md index 1c1e56f6b5..d01097e399 100644 --- a/modules/concepts/hooks/list-of-hooks/actionOrderEdited.md +++ b/modules/concepts/hooks/list-of-hooks/actionOrderEdited.md @@ -7,13 +7,14 @@ files: - src/Adapter/Order/CommandHandler/UpdateProductInOrderHandler.php locations: - frontoffice -types: - - legacy +type: + - action +hookAliases: --- -# Hook : actionOrderEdited +# Hook actionOrderEdited -## Informations +## Information {{% notice tip %}} **Order edited:** @@ -24,14 +25,22 @@ This hook is called when an order is edited Hook locations: - frontoffice -Hook types: - - legacy +Hook type: + - action Located in: - - src/Adapter/Order/CommandHandler/UpdateProductInOrderHandler.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Order/CommandHandler/UpdateProductInOrderHandler.php](src/Adapter/Order/CommandHandler/UpdateProductInOrderHandler.php) + +## Parameters details + +```php + (object) Order + ); +``` -## Hook call with parameters +## Hook call in codebase ```php -Hook::exec('actionOrderEdited', ['order' => $order]); +Hook::exec('actionOrderEdited', ['order' => $order]) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionOrderHistoryAddAfter.md b/modules/concepts/hooks/list-of-hooks/actionOrderHistoryAddAfter.md index dbdeb52f28..e71c86f640 100644 --- a/modules/concepts/hooks/list-of-hooks/actionOrderHistoryAddAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionOrderHistoryAddAfter.md @@ -7,25 +7,26 @@ files: - classes/order/OrderHistory.php locations: - frontoffice -types: - - legacy +type: + - action +hookAliases: --- -# Hook : actionOrderHistoryAddAfter +# Hook actionOrderHistoryAddAfter -## Informations +## Information Hook locations: - frontoffice -Hook types: - - legacy +Hook type: + - action Located in: - - classes/order/OrderHistory.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/order/OrderHistory.php](classes/order/OrderHistory.php) -## Hook call with parameters +## Hook call in codebase ```php -Hook::exec('actionOrderHistoryAddAfter', ['order_history' => $this], null, false, true, false, $order->id_shop); +Hook::exec('actionOrderHistoryAddAfter', ['order_history' => $this], null, false, true, false, $order->id_shop) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionOrderReturn.md b/modules/concepts/hooks/list-of-hooks/actionOrderReturn.md index e998d13089..7f83fd955e 100644 --- a/modules/concepts/hooks/list-of-hooks/actionOrderReturn.md +++ b/modules/concepts/hooks/list-of-hooks/actionOrderReturn.md @@ -7,13 +7,20 @@ files: - controllers/front/OrderFollowController.php locations: - frontoffice -types: - - legacy +type: + - action +hookAliases: + - orderReturn --- -# Hook : actionOrderReturn +# Hook actionOrderReturn -## Informations +Aliases: + - orderReturn + + + +## Information {{% notice tip %}} **Returned product:** @@ -24,14 +31,23 @@ This hook is displayed when a customer returns a product Hook locations: - frontoffice -Hook types: - - legacy +Hook type: + - action Located in: - - controllers/front/OrderFollowController.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/front/OrderFollowController.php](controllers/front/OrderFollowController.php) + +## Parameters details + +```php + (object) OrderReturn + ); +``` -## Hook call with parameters +## Hook call in codebase ```php -Hook::exec('actionOrderReturn', ['orderReturn' => $orderReturn]); +Hook::exec('actionOrderReturn', ['orderReturn' => $orderReturn]) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionOrderSlipAdd.md b/modules/concepts/hooks/list-of-hooks/actionOrderSlipAdd.md index 9318090da5..e7329ce058 100644 --- a/modules/concepts/hooks/list-of-hooks/actionOrderSlipAdd.md +++ b/modules/concepts/hooks/list-of-hooks/actionOrderSlipAdd.md @@ -7,13 +7,20 @@ files: - src/Adapter/Order/Refund/OrderSlipCreator.php locations: - frontoffice -types: - - legacy +type: + - action +hookAliases: + - orderSlip --- -# Hook : actionOrderSlipAdd +# Hook actionOrderSlipAdd -## Informations +Aliases: + - orderSlip + + + +## Information {{% notice tip %}} **Order slip creation:** @@ -24,271 +31,40 @@ This hook is called when a new credit slip is added regarding client order Hook locations: - frontoffice -Hook types: - - legacy +Hook type: + - action Located in: - - src/Adapter/Order/Refund/OrderSlipCreator.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Order/Refund/OrderSlipCreator.php](src/Adapter/Order/Refund/OrderSlipCreator.php) -## Hook call with parameters +## Parameters details + +```php + Order, + 'productList' => array( + (int) product ID 1, + (int) product ID 2, + ..., + (int) product ID n + ), + 'qtyList' => array( + (int) quantity 1, + (int) quantity 2, + ..., + (int) quantity n + ) + ); + The order of IDs and quantities is important! +``` + +## Hook call in codebase ```php Hook::exec('actionOrderSlipAdd', [ 'order' => $order, 'productList' => $orderRefundSummary->getProductRefunds(), 'qtyList' => $fullQuantityList, - ], null, false, true, false, $order->id_shop); - - $customer = new Customer((int) $order->id_customer); - - // @todo: use private method to send mail - $params = [ - '{lastname}' => $customer->lastname, - '{firstname}' => $customer->firstname, - '{id_order}' => $order->id, - '{order_name}' => $order->getUniqReference(), - ]; - - $orderLanguage = $order->getAssociatedLanguage(); - - // @todo: use a dedicated Mail class (see #13945) - // @todo: remove this @and have a proper error handling - @Mail::Send( - (int) $orderLanguage->getId(), - 'credit_slip', - $this->translator->trans( - 'New credit slip regarding your order', - [], - 'Emails.Subject', - $orderLanguage->locale - ), - $params, - $customer->email, - $customer->firstname . ' ' . $customer->lastname, - null, - null, - null, - null, - _PS_MAIL_DIR_, - true, - (int) $order->id_shop - ); - - /** @var OrderDetail $orderDetail */ - foreach ($orderRefundSummary->getOrderDetails() as $orderDetail) { - if ($this->configuration->get('PS_ADVANCED_STOCK_MANAGEMENT')) { - StockAvailable::synchronize($orderDetail->product_id); - } - } - } else { - throw new InvalidCancelProductException(InvalidCancelProductException::INVALID_AMOUNT); - } - } - - /** - * This is a copy of OrderSlip::create except the OrderDetail modification has been removed - * since it's now managed in the handler, this allows to update order details even without - * generating a credit slip - * - * @todo this copy uses array data but could probably be refactored to use OrderDetailRefund objects - * - * @param Order $order - * @param array $product_list - * @param float $shipping_cost - * @param float $amount - * @param bool $amount_choosen - * @param bool $add_tax - * @param int $precision - * - * @return bool - * - * @throws PrestaShopDatabaseException - * @throws PrestaShopException - */ - private function createOrderSlip( - Order $order, - array $product_list, - float $shipping_cost = 0, - float $amount = 0, - bool $amount_choosen = false, - bool $add_tax = true, - int $precision = 6 - ) { - $currency = new Currency((int) $order->id_currency); - $orderSlip = new OrderSlip(); - $orderSlip->id_customer = (int) $order->id_customer; - $orderSlip->id_order = (int) $order->id; - $orderSlip->conversion_rate = $currency->conversion_rate; - - $orderSlip->total_shipping_tax_excl = 0; - $orderSlip->total_shipping_tax_incl = 0; - $orderSlip->partial = 0; - - if ($shipping_cost > 0) { - $orderSlip->shipping_cost = true; - $carrier = new Carrier((int) $order->id_carrier); - // @todo: define if we use invoice or delivery address, or we use configuration PS_TAX_ADDRESS_TYPE - $address = Address::initialize($order->id_address_delivery, false); - $tax_calculator = $carrier->getTaxCalculator($address); - - if ($add_tax) { - $orderSlip->total_shipping_tax_excl = $shipping_cost; - if ($tax_calculator instanceof TaxCalculator) { - $orderSlip->total_shipping_tax_incl = Tools::ps_round($tax_calculator->addTaxes($orderSlip->total_shipping_tax_excl), $precision); - } else { - $orderSlip->total_shipping_tax_incl = $orderSlip->total_shipping_tax_excl; - } - } else { - $orderSlip->total_shipping_tax_incl = $shipping_cost; - if ($tax_calculator instanceof TaxCalculator) { - $orderSlip->total_shipping_tax_excl = Tools::ps_round($tax_calculator->removeTaxes($orderSlip->total_shipping_tax_incl), $precision); - } else { - $orderSlip->total_shipping_tax_excl = $orderSlip->total_shipping_tax_incl; - } - } - } else { - $orderSlip->shipping_cost = false; - } - - $orderSlip->amount = 0; - $orderSlip->total_products_tax_excl = 0; - $orderSlip->total_products_tax_incl = 0; - $total_products = []; - foreach ($product_list as &$product) { - $order_detail = new OrderDetail((int) $product['id_order_detail']); - $price = (float) $product['unit_price']; - $quantity = (int) $product['quantity']; - - // @todo: define if we use invoice or delivery address, or we use configuration PS_TAX_ADDRESS_TYPE - $address = Address::initialize($order->id_address_invoice, false); - $id_address = (int) $address->id; - $id_tax_rules_group = (int) $order_detail->id_tax_rules_group; - $tax_calculator = $order_detail->getTaxCalculator(); - - if ($add_tax) { - $orderSlip->total_products_tax_excl += $price * $quantity; - } else { - $orderSlip->total_products_tax_incl += $price * $quantity; - } - - if (in_array($this->configuration->get('PS_ROUND_TYPE'), [Order::ROUND_ITEM, Order::ROUND_LINE])) { - if (!isset($total_products[$id_tax_rules_group])) { - $total_products[$id_tax_rules_group] = 0; - } - } else { - if (!isset($total_products[$id_tax_rules_group . '_' . $id_address])) { - $total_products[$id_tax_rules_group . '_' . $id_address] = 0; - } - } - - if ($add_tax) { - $product_tax_incl_line = Tools::ps_round($tax_calculator->addTaxes($price) * $quantity, $precision); - } else { - $product_tax_incl_line = Tools::ps_round($tax_calculator->removeTaxes($price) * $quantity, $precision); - } - switch ($this->configuration->get('PS_ROUND_TYPE')) { - case Order::ROUND_ITEM: - if ($add_tax) { - $product_tax_incl = Tools::ps_round($tax_calculator->addTaxes($price), $precision) * $quantity; - } else { - $product_tax_incl = Tools::ps_round($tax_calculator->removeTaxes($price), $precision) * $quantity; - } - $total_products[$id_tax_rules_group] += $product_tax_incl; - break; - case Order::ROUND_LINE: - $product_tax_incl = $product_tax_incl_line; - $total_products[$id_tax_rules_group] += $product_tax_incl; - break; - case Order::ROUND_TOTAL: - $product_tax_incl = $product_tax_incl_line; - $total_products[$id_tax_rules_group . '_' . $id_address] += $price * $quantity; - break; - default: - $product_tax_incl = 0; - } - - if ($add_tax) { - $product['unit_price_tax_excl'] = $price; - $product['unit_price_tax_incl'] = Tools::ps_round($tax_calculator->addTaxes($price), $precision); - $product['total_price_tax_excl'] = Tools::ps_round($price * $quantity, $precision); - $product['total_price_tax_incl'] = Tools::ps_round($product_tax_incl, $precision); - } else { - $product['unit_price_tax_incl'] = $price; - $product['unit_price_tax_excl'] = Tools::ps_round($tax_calculator->removeTaxes($price), $precision); - $product['total_price_tax_incl'] = Tools::ps_round($price * $quantity, $precision); - $product['total_price_tax_excl'] = Tools::ps_round($product_tax_incl, $precision); - } - } - - unset($product); - - foreach ($total_products as $key => $price) { - if ($this->configuration->get('PS_ROUND_TYPE') == Order::ROUND_TOTAL) { - $tmp = explode('_', $key); - $address = Address::initialize((int) $tmp[1], true); - $tax_calculator = TaxManagerFactory::getManager($address, (int) $tmp[0])->getTaxCalculator(); - - if ($add_tax) { - $orderSlip->total_products_tax_incl += Tools::ps_round($tax_calculator->addTaxes($price), $precision); - } else { - $orderSlip->total_products_tax_excl += Tools::ps_round($tax_calculator->removeTaxes($price), $precision); - } - } else { - if ($add_tax) { - $orderSlip->total_products_tax_incl += $price; - } else { - $orderSlip->total_products_tax_excl += $price; - } - } - } - - if ($add_tax) { - $orderSlip->total_products_tax_incl -= $amount && !$amount_choosen ? $amount : 0; - $orderSlip->amount = $amount_choosen ? $amount : $orderSlip->total_products_tax_excl; - } else { - $orderSlip->total_products_tax_excl -= $amount && !$amount_choosen ? $amount : 0; - $orderSlip->amount = $amount_choosen ? $amount : $orderSlip->total_products_tax_incl; - } - $orderSlip->shipping_cost_amount = $orderSlip->total_shipping_tax_incl; - - if ((float) $amount && !$amount_choosen) { - $orderSlip->order_slip_type = VoucherRefundType::PRODUCT_PRICES_EXCLUDING_VOUCHER_REFUND; - } - if (((float) $amount && $amount_choosen) || $orderSlip->shipping_cost_amount > 0) { - $orderSlip->order_slip_type = VoucherRefundType::SPECIFIC_AMOUNT_REFUND; - } - - if (!$orderSlip->add()) { - return false; - } - - $res = true; - - foreach ($product_list as $product) { - $res &= $this->addProductOrderSlip((int) $orderSlip->id, $product); - } - - return (bool) $res; - } - - /** - * @param array $product - * - * @return bool - * - * @throws PrestaShopDatabaseException - */ - private function addProductOrderSlip(int $orderSlipId, array $product): bool - { - return (bool) Db::getInstance()->insert('order_slip_detail', [ - 'id_order_slip' => $orderSlipId, - 'id_order_detail' => (int) $product['id_order_detail'], - 'product_quantity' => $product['quantity'], - 'unit_price_tax_excl' => $product['unit_price_tax_excl'], - 'unit_price_tax_incl' => $product['unit_price_tax_incl'], - 'total_price_tax_excl' => $product['total_price_tax_excl'], - 'total_price_tax_incl' => $product['total_price_tax_incl'], - 'amount_tax_excl' => $product['total_price_tax_excl'], - 'amount_tax_incl' => $product['total_price_tax_incl'], - ]); + ], null, false, true, false, $order->id_shop) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionOrderStatusPostUpdate.md b/modules/concepts/hooks/list-of-hooks/actionOrderStatusPostUpdate.md new file mode 100644 index 0000000000..bf28f18890 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionOrderStatusPostUpdate.md @@ -0,0 +1,59 @@ +--- +menuTitle: actionOrderStatusPostUpdate +Title: actionOrderStatusPostUpdate +hidden: true +hookTitle: Post update of order status +files: + - classes/order/OrderHistory.php +locations: + - frontoffice +type: + - action +hookAliases: + - postUpdateOrderStatus +--- + +# Hook actionOrderStatusPostUpdate + +Aliases: + - postUpdateOrderStatus + + + +## Information + +{{% notice tip %}} +**Post update of order status:** + + +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook type: + - action + +Located in: + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/order/OrderHistory.php](classes/order/OrderHistory.php) + +## Parameters details + +```php + (object) OrderState, + 'oldOrderStatus' => (object) OrderState, + 'id_order' => (int) Order ID + ); +``` + +## Hook call in codebase + +```php +Hook::exec('actionOrderStatusPostUpdate', [ + 'newOrderStatus' => $new_os, + 'oldOrderStatus' => $old_os, + 'id_order' => (int) $order->id, + ], null, false, true, false, $order->id_shop) +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionOrderStatusUpdate.md b/modules/concepts/hooks/list-of-hooks/actionOrderStatusUpdate.md new file mode 100644 index 0000000000..21ce50b77b --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionOrderStatusUpdate.md @@ -0,0 +1,59 @@ +--- +menuTitle: actionOrderStatusUpdate +Title: actionOrderStatusUpdate +hidden: true +hookTitle: Order status update - Event +files: + - classes/order/OrderHistory.php +locations: + - frontoffice +type: + - action +hookAliases: + - updateOrderStatus +--- + +# Hook actionOrderStatusUpdate + +Aliases: + - updateOrderStatus + + + +## Information + +{{% notice tip %}} +**Order status update - Event:** + +This hook launches modules when the status of an order changes +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook type: + - action + +Located in: + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/order/OrderHistory.php](classes/order/OrderHistory.php) + +## Parameters details + +```php + (object) OrderState, + 'oldOrderStatus' => (object) OrderState, + 'id_order' => (int) Order ID + ); +``` + +## Hook call in codebase + +```php +Hook::exec('actionOrderStatusUpdate', [ + 'newOrderStatus' => $new_os, + 'oldOrderStatus' => $old_os, + 'id_order' => (int) $order->id, + ], null, false, true, false, $order->id_shop) +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionOutputHTMLBefore.md b/modules/concepts/hooks/list-of-hooks/actionOutputHTMLBefore.md index 372ff8bdfd..e904d22b0d 100644 --- a/modules/concepts/hooks/list-of-hooks/actionOutputHTMLBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionOutputHTMLBefore.md @@ -7,13 +7,14 @@ files: - classes/controller/FrontController.php locations: - frontoffice -types: - - legacy +type: + - action +hookAliases: --- -# Hook : actionOutputHTMLBefore +# Hook actionOutputHTMLBefore -## Informations +## Information {{% notice tip %}} **Before HTML output:** @@ -24,14 +25,14 @@ This hook is used to filter the whole HTML page before it is rendered (only fron Hook locations: - frontoffice -Hook types: - - legacy +Hook type: + - action Located in: - - classes/controller/FrontController.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/FrontController.php](classes/controller/FrontController.php) -## Hook call with parameters +## Hook call in codebase ```php -Hook::exec('actionOutputHTMLBefore', ['html' => &$html]); +Hook::exec('actionOutputHTMLBefore', ['html' => &$html]) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionOverrideEmployeeImage.md b/modules/concepts/hooks/list-of-hooks/actionOverrideEmployeeImage.md new file mode 100644 index 0000000000..a4b5177d2c --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionOverrideEmployeeImage.md @@ -0,0 +1,44 @@ +--- +menuTitle: actionOverrideEmployeeImage +Title: actionOverrideEmployeeImage +hidden: true +hookTitle: Get Employee Image +files: + - classes/Employee.php +locations: + - frontoffice +type: + - action +hookAliases: +--- + +# Hook actionOverrideEmployeeImage + +## Information + +{{% notice tip %}} +**Get Employee Image:** + +This hook is used to get the employee image +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook type: + - action + +Located in: + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Employee.php](classes/Employee.php) + +## Hook call in codebase + +```php +Hook::exec( + 'actionOverrideEmployeeImage', + [ + 'employee' => $this, + 'imageUrl' => &$imageUrl, + ] + ) +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionPDFInvoiceRender.md b/modules/concepts/hooks/list-of-hooks/actionPDFInvoiceRender.md index b61a964a4c..4f0c481ae3 100644 --- a/modules/concepts/hooks/list-of-hooks/actionPDFInvoiceRender.md +++ b/modules/concepts/hooks/list-of-hooks/actionPDFInvoiceRender.md @@ -7,25 +7,26 @@ files: - src/Adapter/PDF/OrderInvoicePdfGenerator.php locations: - frontoffice -types: - - legacy +type: + - action +hookAliases: --- -# Hook : actionPDFInvoiceRender +# Hook actionPDFInvoiceRender -## Informations +## Information Hook locations: - frontoffice -Hook types: - - legacy +Hook type: + - action Located in: - - src/Adapter/PDF/OrderInvoicePdfGenerator.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/PDF/OrderInvoicePdfGenerator.php](src/Adapter/PDF/OrderInvoicePdfGenerator.php) -## Hook call with parameters +## Hook call in codebase ```php -Hook::exec('actionPDFInvoiceRender', ['order_invoice_list' => $order_invoice_list]); +Hook::exec('actionPDFInvoiceRender', ['order_invoice_list' => $order_invoice_list]) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionPasswordRenew.md b/modules/concepts/hooks/list-of-hooks/actionPasswordRenew.md index 8e6d363f25..fae16bf676 100644 --- a/modules/concepts/hooks/list-of-hooks/actionPasswordRenew.md +++ b/modules/concepts/hooks/list-of-hooks/actionPasswordRenew.md @@ -7,25 +7,26 @@ files: - controllers/front/PasswordController.php locations: - frontoffice -types: - - legacy +type: + - action +hookAliases: --- -# Hook : actionPasswordRenew +# Hook actionPasswordRenew -## Informations +## Information Hook locations: - frontoffice -Hook types: - - legacy +Hook type: + - action Located in: - - controllers/front/PasswordController.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/front/PasswordController.php](controllers/front/PasswordController.php) -## Hook call with parameters +## Hook call in codebase ```php -Hook::exec('actionPasswordRenew', ['customer' => $customer, 'password' => $password]); +Hook::exec('actionPasswordRenew', ['customer' => $customer, 'password' => $password]) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionPaymentCCAdd.md b/modules/concepts/hooks/list-of-hooks/actionPaymentCCAdd.md index 75f455b860..aba9880cfc 100644 --- a/modules/concepts/hooks/list-of-hooks/actionPaymentCCAdd.md +++ b/modules/concepts/hooks/list-of-hooks/actionPaymentCCAdd.md @@ -7,13 +7,20 @@ files: - classes/order/OrderPayment.php locations: - frontoffice -types: - - legacy +type: + - action +hookAliases: + - paymentCCAdded --- -# Hook : actionPaymentCCAdd +# Hook actionPaymentCCAdd -## Informations +Aliases: + - paymentCCAdded + + + +## Information {{% notice tip %}} **Payment CC added:** @@ -24,14 +31,23 @@ types: Hook locations: - frontoffice -Hook types: - - legacy +Hook type: + - action Located in: - - classes/order/OrderPayment.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/order/OrderPayment.php](classes/order/OrderPayment.php) + +## Parameters details + +```php + (object) OrderPayment object + ); +``` -## Hook call with parameters +## Hook call in codebase ```php -Hook::exec('actionPaymentCCAdd', ['paymentCC' => $this]); +Hook::exec('actionPaymentCCAdd', ['paymentCC' => $this]) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionPaymentConfirmation.md b/modules/concepts/hooks/list-of-hooks/actionPaymentConfirmation.md index a925d25f50..eaa4fbe295 100644 --- a/modules/concepts/hooks/list-of-hooks/actionPaymentConfirmation.md +++ b/modules/concepts/hooks/list-of-hooks/actionPaymentConfirmation.md @@ -7,13 +7,20 @@ files: - classes/order/OrderHistory.php locations: - frontoffice -types: - - legacy +type: + - action +hookAliases: + - paymentConfirm --- -# Hook : actionPaymentConfirmation +# Hook actionPaymentConfirmation -## Informations +Aliases: + - paymentConfirm + + + +## Information {{% notice tip %}} **Payment confirmation:** @@ -24,14 +31,23 @@ This hook displays new elements after the payment is validated Hook locations: - frontoffice -Hook types: - - legacy +Hook type: + - action Located in: - - classes/order/OrderHistory.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/order/OrderHistory.php](classes/order/OrderHistory.php) + +## Parameters details + +```php + (int) Order ID + ); +``` -## Hook call with parameters +## Hook call in codebase ```php -Hook::exec('actionPaymentConfirmation', ['id_order' => (int) $order->id], null, false, true, false, $order->id_shop); +Hook::exec('actionPaymentConfirmation', ['id_order' => (int) $order->id], null, false, true, false, $order->id_shop) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionPresentCart.md b/modules/concepts/hooks/list-of-hooks/actionPresentCart.md new file mode 100644 index 0000000000..82aa396b91 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionPresentCart.md @@ -0,0 +1,40 @@ +--- +menuTitle: actionPresentCart +Title: actionPresentCart +hidden: true +hookTitle: Cart Presenter +files: + - src/Adapter/Presenter/Cart/CartPresenter.php +locations: + - frontoffice +type: + - action +hookAliases: +--- + +# Hook actionPresentCart + +## Information + +{{% notice tip %}} +**Cart Presenter:** + +This hook is called before a cart is presented +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook type: + - action + +Located in: + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Presenter/Cart/CartPresenter.php](src/Adapter/Presenter/Cart/CartPresenter.php) + +## Hook call in codebase + +```php +Hook::exec('actionPresentCart', + ['presentedCart' => &$result] + ) +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionPresentModule.md b/modules/concepts/hooks/list-of-hooks/actionPresentModule.md new file mode 100644 index 0000000000..50189edc66 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionPresentModule.md @@ -0,0 +1,34 @@ +--- +menuTitle: actionPresentModule +Title: actionPresentModule +hidden: true +hookTitle: +files: + - src/Adapter/Presenter/Module/ModulePresenter.php +locations: + - frontoffice +type: + - action +hookAliases: +--- + +# Hook actionPresentModule + +## Information + +Hook locations: + - frontoffice + +Hook type: + - action + +Located in: + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Presenter/Module/ModulePresenter.php](src/Adapter/Presenter/Module/ModulePresenter.php) + +## Hook call in codebase + +```php +Hook::exec('actionPresentModule', + ['presentedModule' => &$result] + ) +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionPresentOrder.md b/modules/concepts/hooks/list-of-hooks/actionPresentOrder.md new file mode 100644 index 0000000000..1759a4f525 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionPresentOrder.md @@ -0,0 +1,40 @@ +--- +menuTitle: actionPresentOrder +Title: actionPresentOrder +hidden: true +hookTitle: Order Presenter +files: + - src/Adapter/Presenter/Order/OrderPresenter.php +locations: + - frontoffice +type: + - action +hookAliases: +--- + +# Hook actionPresentOrder + +## Information + +{{% notice tip %}} +**Order Presenter:** + +This hook is called before an order is presented +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook type: + - action + +Located in: + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Presenter/Order/OrderPresenter.php](src/Adapter/Presenter/Order/OrderPresenter.php) + +## Hook call in codebase + +```php +Hook::exec('actionPresentOrder', + ['presentedOrder' => &$orderLazyArray] + ) +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionPresentOrderReturn.md b/modules/concepts/hooks/list-of-hooks/actionPresentOrderReturn.md new file mode 100644 index 0000000000..daf7d1cd5d --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionPresentOrderReturn.md @@ -0,0 +1,40 @@ +--- +menuTitle: actionPresentOrderReturn +Title: actionPresentOrderReturn +hidden: true +hookTitle: Order Return Presenter +files: + - src/Adapter/Presenter/Order/OrderReturnPresenter.php +locations: + - frontoffice +type: + - action +hookAliases: +--- + +# Hook actionPresentOrderReturn + +## Information + +{{% notice tip %}} +**Order Return Presenter:** + +This hook is called before an order return is presented +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook type: + - action + +Located in: + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Presenter/Order/OrderReturnPresenter.php](src/Adapter/Presenter/Order/OrderReturnPresenter.php) + +## Hook call in codebase + +```php +Hook::exec('actionPresentOrderReturn', + ['presentedOrderReturn' => &$orderReturnLazyArray] + ) +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionPresentPaymentOptions.md b/modules/concepts/hooks/list-of-hooks/actionPresentPaymentOptions.md new file mode 100644 index 0000000000..e431a0772e --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionPresentPaymentOptions.md @@ -0,0 +1,49 @@ +--- +menuTitle: actionPresentPaymentOptions +Title: actionPresentPaymentOptions +hidden: true +hookTitle: Payment options Presenter +files: + - classes/checkout/PaymentOptionsFinder.php +locations: + - frontoffice +type: + - action +hookAliases: +--- + +# Hook actionPresentPaymentOptions + +## Information + +{{% notice tip %}} +**Payment options Presenter:** + +This hook is called before payment options are presented +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook type: + - action + +Located in: + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/checkout/PaymentOptionsFinder.php](classes/checkout/PaymentOptionsFinder.php) + +## Parameters details + +```php + (array) &$paymentOptions, + ] +``` + +## Hook call in codebase + +```php +Hook::exec('actionPresentPaymentOptions', + ['paymentOptions' => &$paymentOptions] + ) +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionPresentProduct.md b/modules/concepts/hooks/list-of-hooks/actionPresentProduct.md new file mode 100644 index 0000000000..0dbf9c19c2 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionPresentProduct.md @@ -0,0 +1,40 @@ +--- +menuTitle: actionPresentProduct +Title: actionPresentProduct +hidden: true +hookTitle: Product Presenter +files: + - src/Adapter/Presenter/Product/ProductPresenter.php +locations: + - frontoffice +type: + - action +hookAliases: +--- + +# Hook actionPresentProduct + +## Information + +{{% notice tip %}} +**Product Presenter:** + +This hook is called before a product is presented +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook type: + - action + +Located in: + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Presenter/Product/ProductPresenter.php](src/Adapter/Presenter/Product/ProductPresenter.php) + +## Hook call in codebase + +```php +Hook::exec('actionPresentProduct', + ['presentedProduct' => &$productLazyArray] + ) +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionPresentProductListing.md b/modules/concepts/hooks/list-of-hooks/actionPresentProductListing.md new file mode 100644 index 0000000000..5018609cc8 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionPresentProductListing.md @@ -0,0 +1,40 @@ +--- +menuTitle: actionPresentProductListing +Title: actionPresentProductListing +hidden: true +hookTitle: Product Listing Presenter +files: + - src/Adapter/Presenter/Product/ProductListingPresenter.php +locations: + - frontoffice +type: + - action +hookAliases: +--- + +# Hook actionPresentProductListing + +## Information + +{{% notice tip %}} +**Product Listing Presenter:** + +This hook is called before a product listing is presented +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook type: + - action + +Located in: + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Presenter/Product/ProductListingPresenter.php](src/Adapter/Presenter/Product/ProductListingPresenter.php) + +## Hook call in codebase + +```php +Hook::exec('actionPresentProductListing', + ['presentedProduct' => &$productListingLazyArray] + ) +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionProductActivation.md b/modules/concepts/hooks/list-of-hooks/actionProductActivation.md index 16d3ef1e7f..2a3c0cc163 100644 --- a/modules/concepts/hooks/list-of-hooks/actionProductActivation.md +++ b/modules/concepts/hooks/list-of-hooks/actionProductActivation.md @@ -7,25 +7,26 @@ files: - src/Adapter/Product/AdminProductDataUpdater.php locations: - backoffice -types: - - symfony +type: + - action +hookAliases: --- -# Hook : actionProductActivation +# Hook actionProductActivation -## Informations +## Information Hook locations: - backoffice -Hook types: - - symfony +Hook type: + - action Located in: - - src/Adapter/Product/AdminProductDataUpdater.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Product/AdminProductDataUpdater.php](src/Adapter/Product/AdminProductDataUpdater.php) -## Hook call with parameters +## Hook call in codebase ```php -dispatchWithParameters('actionProductActivation', ['id_product' => (int) $product->id, 'product' => $product, 'activated' => $activate]); +dispatchWithParameters('actionProductActivation', ['id_product' => (int) $product->id, 'product' => $product, 'activated' => $activate]) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionProductAdd.md b/modules/concepts/hooks/list-of-hooks/actionProductAdd.md index 9408f8e5f6..faa3480bd7 100644 --- a/modules/concepts/hooks/list-of-hooks/actionProductAdd.md +++ b/modules/concepts/hooks/list-of-hooks/actionProductAdd.md @@ -4,16 +4,23 @@ Title: actionProductAdd hidden: true hookTitle: Product creation files: - - src/Adapter/Product/AdminProductDataUpdater.php + - src/Adapter/Product/ProductDuplicator.php locations: - - backoffice -types: - - symfony + - frontoffice +type: + - action +hookAliases: + - addproduct --- -# Hook : actionProductAdd +# Hook actionProductAdd -## Informations +Aliases: + - addproduct + + + +## Information {{% notice tip %}} **Product creation:** @@ -22,16 +29,19 @@ This hook is displayed after a product is created {{% /notice %}} Hook locations: - - backoffice + - frontoffice -Hook types: - - symfony +Hook type: + - action Located in: - - src/Adapter/Product/AdminProductDataUpdater.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Product/ProductDuplicator.php](src/Adapter/Product/ProductDuplicator.php) -## Hook call with parameters +## Hook call in codebase ```php -dispatchWithParameters('actionProductAdd', ['id_product_old' => $id_product_old, 'id_product' => (int) $product->id, 'product' => $product]); +dispatchWithParameters( + 'actionProductAdd', + ['id_product_old' => $oldProductId, 'id_product' => $newProductId, 'product' => $newProduct] + ) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionProductAttributeDelete.md b/modules/concepts/hooks/list-of-hooks/actionProductAttributeDelete.md index 8163bd06e5..9c50f4c7f4 100644 --- a/modules/concepts/hooks/list-of-hooks/actionProductAttributeDelete.md +++ b/modules/concepts/hooks/list-of-hooks/actionProductAttributeDelete.md @@ -7,13 +7,20 @@ files: - classes/Product.php locations: - frontoffice -types: - - legacy +type: + - action +hookAliases: + - deleteProductAttribute --- -# Hook : actionProductAttributeDelete +# Hook actionProductAttributeDelete -## Informations +Aliases: + - deleteProductAttribute + + + +## Information {{% notice tip %}} **Product attribute deletion:** @@ -24,14 +31,14 @@ This hook is displayed when a product's attribute is deleted Hook locations: - frontoffice -Hook types: - - legacy +Hook type: + - action Located in: - - classes/Product.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Product.php](classes/Product.php) -## Hook call with parameters +## Hook call in codebase ```php -Hook::exec('actionProductAttributeDelete', ['id_product_attribute' => 0, 'id_product' => (int) $this->id, 'deleteAllAttributes' => true]); +Hook::exec('actionProductAttributeDelete', ['id_product_attribute' => 0, 'id_product' => (int) $this->id, 'deleteAllAttributes' => true]) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionProductAttributeUpdate.md b/modules/concepts/hooks/list-of-hooks/actionProductAttributeUpdate.md index 382a98c21b..2d699cbc50 100644 --- a/modules/concepts/hooks/list-of-hooks/actionProductAttributeUpdate.md +++ b/modules/concepts/hooks/list-of-hooks/actionProductAttributeUpdate.md @@ -7,13 +7,20 @@ files: - classes/Product.php locations: - frontoffice -types: - - legacy +type: + - action +hookAliases: + - updateProductAttribute --- -# Hook : actionProductAttributeUpdate +# Hook actionProductAttributeUpdate -## Informations +Aliases: + - updateProductAttribute + + + +## Information {{% notice tip %}} **Product attribute update:** @@ -24,14 +31,14 @@ This hook is displayed when a product's attribute is updated Hook locations: - frontoffice -Hook types: - - legacy +Hook type: + - action Located in: - - classes/Product.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Product.php](classes/Product.php) -## Hook call with parameters +## Hook call in codebase ```php -Hook::exec('actionProductAttributeUpdate', ['id_product_attribute' => (int) $id_product_attribute]); +Hook::exec('actionProductAttributeUpdate', ['id_product_attribute' => (int) $id_product_attribute]) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionProductCancel.md b/modules/concepts/hooks/list-of-hooks/actionProductCancel.md index 86066ca4a4..1bdcee8c3d 100644 --- a/modules/concepts/hooks/list-of-hooks/actionProductCancel.md +++ b/modules/concepts/hooks/list-of-hooks/actionProductCancel.md @@ -7,13 +7,20 @@ files: - src/Adapter/Order/CommandHandler/IssueStandardRefundHandler.php locations: - frontoffice -types: - - legacy +type: + - action +hookAliases: + - cancelProduct --- -# Hook : actionProductCancel +# Hook actionProductCancel -## Informations +Aliases: + - cancelProduct + + + +## Information {{% notice tip %}} **Product cancelled:** @@ -24,14 +31,14 @@ This hook is called when you cancel a product in an order Hook locations: - frontoffice -Hook types: - - legacy +Hook type: + - action Located in: - - src/Adapter/Order/CommandHandler/IssueStandardRefundHandler.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Order/CommandHandler/IssueStandardRefundHandler.php](src/Adapter/Order/CommandHandler/IssueStandardRefundHandler.php) -## Hook call with parameters +## Hook call in codebase ```php -Hook::exec('actionProductCancel', ['order' => $order, 'id_order_detail' => (int) $orderDetailId, 'cancel_quantity' => $productRefund['quantity'], 'action' => CancellationActionType::STANDARD_REFUND], null, false, true, false, $order->id_shop); +Hook::exec('actionProductCancel', ['order' => $order, 'id_order_detail' => (int) $orderDetailId, 'cancel_quantity' => $productRefund['quantity'], 'action' => CancellationActionType::STANDARD_REFUND], null, false, true, false, $order->id_shop) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionProductCoverage.md b/modules/concepts/hooks/list-of-hooks/actionProductCoverage.md new file mode 100644 index 0000000000..9720335d37 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionProductCoverage.md @@ -0,0 +1,39 @@ +--- +menuTitle: actionProductCoverage +Title: actionProductCoverage +hidden: true +hookTitle: +files: + - classes/stock/StockManager.php +locations: + - frontoffice +type: + - action +hookAliases: +--- + +# Hook actionProductCoverage + +## Information + +Hook locations: + - frontoffice + +Hook type: + - action + +Located in: + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/stock/StockManager.php](classes/stock/StockManager.php) + +## Hook call in codebase + +```php +Hook::exec( + 'actionProductCoverage', + [ + 'id_product' => $id_product, + 'id_product_attribute' => $id_product_attribute, + 'warehouse' => $warehouse, + ] + ) +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionProductDelete.md b/modules/concepts/hooks/list-of-hooks/actionProductDelete.md index 4976237fbf..924a1899e1 100644 --- a/modules/concepts/hooks/list-of-hooks/actionProductDelete.md +++ b/modules/concepts/hooks/list-of-hooks/actionProductDelete.md @@ -7,13 +7,20 @@ files: - classes/Product.php locations: - frontoffice -types: - - legacy +type: + - action +hookAliases: + - deleteproduct --- -# Hook : actionProductDelete +# Hook actionProductDelete -## Informations +Aliases: + - deleteproduct + + + +## Information {{% notice tip %}} **Product deletion:** @@ -24,14 +31,14 @@ This hook is called when a product is deleted Hook locations: - frontoffice -Hook types: - - legacy +Hook type: + - action Located in: - - classes/Product.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Product.php](classes/Product.php) -## Hook call with parameters +## Hook call in codebase ```php -Hook::exec('actionProductDelete', ['id_product' => (int) $this->id, 'product' => $this]); +Hook::exec('actionProductDelete', ['id_product' => (int) $this->id, 'product' => $this]) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionProductOutOfStock.md b/modules/concepts/hooks/list-of-hooks/actionProductOutOfStock.md index 44ad46e0af..f3c1e543b5 100644 --- a/modules/concepts/hooks/list-of-hooks/actionProductOutOfStock.md +++ b/modules/concepts/hooks/list-of-hooks/actionProductOutOfStock.md @@ -7,13 +7,20 @@ files: - themes/classic/templates/catalog/_partials/product-details.tpl locations: - frontoffice -types: - - smarty +type: + - action +hookAliases: + - productOutOfStock --- -# Hook : actionProductOutOfStock +# Hook actionProductOutOfStock -## Informations +Aliases: + - productOutOfStock + + + +## Information {{% notice tip %}} **Out-of-stock product:** @@ -24,13 +31,13 @@ This hook displays new action buttons if a product is out of stock Hook locations: - frontoffice -Hook types: - - smarty +Hook type: + - action Located in: - - themes/classic/templates/catalog/_partials/product-details.tpl + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/catalog/_partials/product-details.tpl](themes/classic/templates/catalog/_partials/product-details.tpl) -## Hook call with parameters +## Hook call in codebase ```php {hook h='actionProductOutOfStock' product=$product} diff --git a/modules/concepts/hooks/list-of-hooks/actionProductSave.md b/modules/concepts/hooks/list-of-hooks/actionProductSave.md index 6e8d784f1c..baaf627469 100644 --- a/modules/concepts/hooks/list-of-hooks/actionProductSave.md +++ b/modules/concepts/hooks/list-of-hooks/actionProductSave.md @@ -7,13 +7,20 @@ files: - classes/Product.php locations: - frontoffice -types: - - legacy +type: + - action +hookAliases: + - afterSaveProduct --- -# Hook : actionProductSave +# Hook actionProductSave -## Informations +Aliases: + - afterSaveProduct + + + +## Information {{% notice tip %}} **Saving products:** @@ -24,14 +31,14 @@ This hook is called while saving products Hook locations: - frontoffice -Hook types: - - legacy +Hook type: + - action Located in: - - classes/Product.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Product.php](classes/Product.php) -## Hook call with parameters +## Hook call in codebase ```php -Hook::exec('actionProductSave', ['id_product' => (int) $this->id, 'product' => $this]); +Hook::exec('actionProductSave', ['id_product' => (int) $this->id, 'product' => $this]) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionProductSearchAfter.md b/modules/concepts/hooks/list-of-hooks/actionProductSearchAfter.md index 06e7f1602c..0bc686a740 100644 --- a/modules/concepts/hooks/list-of-hooks/actionProductSearchAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionProductSearchAfter.md @@ -7,13 +7,14 @@ files: - modules/blockwishlist/controllers/front/view.php locations: - frontoffice -types: - - legacy +type: + - action +hookAliases: --- -# Hook : actionProductSearchAfter +# Hook actionProductSearchAfter -## Informations +## Information {{% notice tip %}} **Event triggered after search product completed:** @@ -24,14 +25,14 @@ This hook is called after the product search. Parameters are already filter Hook locations: - frontoffice -Hook types: - - legacy +Hook type: + - action Located in: - - modules/blockwishlist/controllers/front/view.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/modules/blockwishlist/controllers/front/view.php](modules/blockwishlist/controllers/front/view.php) -## Hook call with parameters +## Hook call in codebase ```php -Hook::exec('actionProductSearchAfter', $searchVariables); +Hook::exec('actionProductSearchAfter', $searchVariables) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionProductSearchProviderRunQueryAfter.md b/modules/concepts/hooks/list-of-hooks/actionProductSearchProviderRunQueryAfter.md index bd7cffbfb8..cb23d69486 100644 --- a/modules/concepts/hooks/list-of-hooks/actionProductSearchProviderRunQueryAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionProductSearchProviderRunQueryAfter.md @@ -7,13 +7,14 @@ files: - classes/controller/ProductListingFrontController.php locations: - frontoffice -types: - - legacy +type: + - action +hookAliases: --- -# Hook : actionProductSearchProviderRunQueryAfter +# Hook actionProductSearchProviderRunQueryAfter -## Informations +## Information {{% notice tip %}} **Runs an action after ProductSearchProviderInterface::RunQuery():** @@ -24,17 +25,17 @@ Required to return a previous state of an SQL query or/and to change a result of Hook locations: - frontoffice -Hook types: - - legacy +Hook type: + - action Located in: - - classes/controller/ProductListingFrontController.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/ProductListingFrontController.php](classes/controller/ProductListingFrontController.php) -## Hook call with parameters +## Hook call in codebase ```php Hook::exec('actionProductSearchProviderRunQueryAfter', [ 'query' => $query, 'result' => $result, - ]); + ]) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionProductSearchProviderRunQueryBefore.md b/modules/concepts/hooks/list-of-hooks/actionProductSearchProviderRunQueryBefore.md index b89e99e873..2ac5ffd02c 100644 --- a/modules/concepts/hooks/list-of-hooks/actionProductSearchProviderRunQueryBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionProductSearchProviderRunQueryBefore.md @@ -7,13 +7,14 @@ files: - classes/controller/ProductListingFrontController.php locations: - frontoffice -types: - - legacy +type: + - action +hookAliases: --- -# Hook : actionProductSearchProviderRunQueryBefore +# Hook actionProductSearchProviderRunQueryBefore -## Informations +## Information {{% notice tip %}} **Runs an action before ProductSearchProviderInterface::RunQuery():** @@ -24,16 +25,16 @@ Required to modify an SQL query before executing it Hook locations: - frontoffice -Hook types: - - legacy +Hook type: + - action Located in: - - classes/controller/ProductListingFrontController.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/ProductListingFrontController.php](classes/controller/ProductListingFrontController.php) -## Hook call with parameters +## Hook call in codebase ```php Hook::exec('actionProductSearchProviderRunQueryBefore', [ 'query' => $query, - ]); + ]) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionProductUpdate.md b/modules/concepts/hooks/list-of-hooks/actionProductUpdate.md index a686786067..a65d871a98 100644 --- a/modules/concepts/hooks/list-of-hooks/actionProductUpdate.md +++ b/modules/concepts/hooks/list-of-hooks/actionProductUpdate.md @@ -7,13 +7,20 @@ files: - src/Adapter/Product/AdminProductWrapper.php locations: - backoffice -types: - - legacy +type: + - action +hookAliases: + - updateproduct --- -# Hook : actionProductUpdate +# Hook actionProductUpdate -## Informations +Aliases: + - updateproduct + + + +## Information {{% notice tip %}} **Product update:** @@ -24,14 +31,14 @@ This hook is displayed after a product has been updated Hook locations: - backoffice -Hook types: - - legacy +Hook type: + - action Located in: - - src/Adapter/Product/AdminProductWrapper.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Product/AdminProductWrapper.php](src/Adapter/Product/AdminProductWrapper.php) -## Hook call with parameters +## Hook call in codebase ```php -Hook::exec('actionProductUpdate', ['id_product' => (int) $product->id, 'product' => $product]); +Hook::exec('actionProductUpdate', ['id_product' => (int) $product->id, 'product' => $product]) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionSearch.md b/modules/concepts/hooks/list-of-hooks/actionSearch.md index 14eee00d2e..69e313d365 100644 --- a/modules/concepts/hooks/list-of-hooks/actionSearch.md +++ b/modules/concepts/hooks/list-of-hooks/actionSearch.md @@ -7,24 +7,35 @@ files: - src/Adapter/Search/SearchProductSearchProvider.php locations: - frontoffice -types: - - legacy +type: + - action +hookAliases: --- -# Hook : actionSearch +# Hook actionSearch -## Informations +## Information Hook locations: - frontoffice -Hook types: - - legacy +Hook type: + - action Located in: - - src/Adapter/Search/SearchProductSearchProvider.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Search/SearchProductSearchProvider.php](src/Adapter/Search/SearchProductSearchProvider.php) + +## Parameters details + +```php + (string) Search query, + 'total' => (int) Amount of search results + ); +``` -## Hook call with parameters +## Hook call in codebase ```php Hook::exec('actionSearch', [ @@ -33,5 +44,5 @@ Hook::exec('actionSearch', [ // deprecated since 1.7.x 'expr' => $queryString, - ]); + ]) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionSetInvoice.md b/modules/concepts/hooks/list-of-hooks/actionSetInvoice.md index 90630c8062..a526e55897 100644 --- a/modules/concepts/hooks/list-of-hooks/actionSetInvoice.md +++ b/modules/concepts/hooks/list-of-hooks/actionSetInvoice.md @@ -7,29 +7,41 @@ files: - classes/order/Order.php locations: - frontoffice -types: - - legacy +type: + - action +hookAliases: --- -# Hook : actionSetInvoice +# Hook actionSetInvoice -## Informations +## Information Hook locations: - frontoffice -Hook types: - - legacy +Hook type: + - action Located in: - - classes/order/Order.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/order/Order.php](classes/order/Order.php) + +## Parameters details + +```php + order object, + 'OrderInvoice' => order invoice object, + 'use_existing_payment' => (bool) + ); +``` -## Hook call with parameters +## Hook call in codebase ```php Hook::exec('actionSetInvoice', [ get_class($this) => $this, get_class($order_invoice) => $order_invoice, 'use_existing_payment' => (bool) $use_existing_payment, - ]); + ]) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionShopDataDuplication.md b/modules/concepts/hooks/list-of-hooks/actionShopDataDuplication.md index 626885f189..414bdf681e 100644 --- a/modules/concepts/hooks/list-of-hooks/actionShopDataDuplication.md +++ b/modules/concepts/hooks/list-of-hooks/actionShopDataDuplication.md @@ -7,106 +7,39 @@ files: - classes/shop/Shop.php locations: - frontoffice -types: - - legacy +type: + - action +hookAliases: --- -# Hook : actionShopDataDuplication +# Hook actionShopDataDuplication -## Informations +## Information Hook locations: - frontoffice -Hook types: - - legacy +Hook type: + - action Located in: - - classes/shop/Shop.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/shop/Shop.php](classes/shop/Shop.php) + +## Parameters details + +```php + (int) Old shop ID, + 'new_id_shop' => (int) New shop ID + ); +``` -## Hook call with parameters +## Hook call in codebase ```php Hook::exec('actionShopDataDuplication', [ 'old_id_shop' => (int) $old_id, 'new_id_shop' => (int) $this->id, - ], $m['id_module']); - } - } - } - } - - /** - * @param int $id - * - * @return array - */ - public static function getCategories($id = 0, $only_id = true) - { - // build query - $query = new DbQuery(); - if ($only_id) { - $query->select('cs.`id_category`'); - } else { - $query->select('DISTINCT cs.`id_category`, cl.`name`, cl.`link_rewrite`'); - } - $query->from('category_shop', 'cs'); - $query->leftJoin('category_lang', 'cl', 'cl.`id_category` = cs.`id_category` AND cl.`id_lang` = ' . (int) Context::getContext()->language->id); - $query->where('cs.`id_shop` = ' . (int) $id); - $result = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS($query); - - if ($only_id) { - $array = []; - foreach ($result as $row) { - $array[] = $row['id_category']; - } - $array = array_unique($array); - } else { - return $result; - } - - return $array; - } - - /** - * @param string $entity - * @param int $id_shop - * - * @return array|bool - */ - public static function getEntityIds($entity, $id_shop, $active = false, $delete = false) - { - if (!Shop::isTableAssociated($entity)) { - return false; - } - - return Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS( - 'SELECT entity.`id_' . bqSQL($entity) . '` - FROM `' . _DB_PREFIX_ . bqSQL($entity) . '_shop`es - LEFT JOIN ' . _DB_PREFIX_ . bqSQL($entity) . ' entity - ON (entity.`id_' . bqSQL($entity) . '` = es.`id_' . bqSQL($entity) . '`) - WHERE es.`id_shop` = ' . (int) $id_shop . - ($active ? ' AND entity.`active` = 1' : '') . - ($delete ? ' AND entity.deleted = 0' : '') - ); - } - - /** - * @param string $host - * - * @return array - * - * @throws PrestaShopDatabaseException - */ - private static function findShopByHost($host) - { - $sql = 'SELECT s.id_shop, CONCAT(su.physical_uri, su.virtual_uri) AS uri, su.domain, su.main - FROM ' . _DB_PREFIX_ . 'shop_url su - LEFT JOIN ' . _DB_PREFIX_ . 'shop s ON (s.id_shop = su.id_shop) - WHERE (su.domain = \'' . pSQL($host) . '\' OR su.domain_ssl = \'' . pSQL($host) . '\') - AND s.active = 1 - AND s.deleted = 0 - ORDER BY LENGTH(CONCAT(su.physical_uri, su.virtual_uri)) DESC'; - - $result = Db::getInstance()->executeS($sql); + ], $m['id_module']) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionSubmitAccountBefore.md b/modules/concepts/hooks/list-of-hooks/actionSubmitAccountBefore.md index 6499940a68..eba4c1c690 100644 --- a/modules/concepts/hooks/list-of-hooks/actionSubmitAccountBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionSubmitAccountBefore.md @@ -7,25 +7,32 @@ files: - controllers/front/RegistrationController.php locations: - frontoffice -types: - - legacy +type: + - action +hookAliases: + - actionBeforeSubmitAccount --- -# Hook : actionSubmitAccountBefore +# Hook actionSubmitAccountBefore -## Informations +Aliases: + - actionBeforeSubmitAccount + + + +## Information Hook locations: - frontoffice -Hook types: - - legacy +Hook type: + - action Located in: - - controllers/front/RegistrationController.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/front/RegistrationController.php](controllers/front/RegistrationController.php) -## Hook call with parameters +## Hook call in codebase ```php -Hook::exec('actionSubmitAccountBefore', [], null, true), +Hook::exec('actionSubmitAccountBefore', [], null, true) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionSubmitCustomerAddressForm.md b/modules/concepts/hooks/list-of-hooks/actionSubmitCustomerAddressForm.md index 0c5d7452dd..1559606f8e 100644 --- a/modules/concepts/hooks/list-of-hooks/actionSubmitCustomerAddressForm.md +++ b/modules/concepts/hooks/list-of-hooks/actionSubmitCustomerAddressForm.md @@ -7,25 +7,26 @@ files: - classes/form/CustomerAddressForm.php locations: - frontoffice -types: - - legacy +type: + - action +hookAliases: --- -# Hook : actionSubmitCustomerAddressForm +# Hook actionSubmitCustomerAddressForm -## Informations +## Information Hook locations: - frontoffice -Hook types: - - legacy +Hook type: + - action Located in: - - classes/form/CustomerAddressForm.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/form/CustomerAddressForm.php](classes/form/CustomerAddressForm.php) -## Hook call with parameters +## Hook call in codebase ```php -Hook::exec('actionSubmitCustomerAddressForm', ['address' => &$address]); +Hook::exec('actionSubmitCustomerAddressForm', ['address' => &$address]) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionUpdateLangAfter.md b/modules/concepts/hooks/list-of-hooks/actionUpdateLangAfter.md index 3c340de9e3..d8f8b66ab0 100644 --- a/modules/concepts/hooks/list-of-hooks/actionUpdateLangAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionUpdateLangAfter.md @@ -7,13 +7,14 @@ files: - classes/Language.php locations: - frontoffice -types: - - legacy +type: + - action +hookAliases: --- -# Hook : actionUpdateLangAfter +# Hook actionUpdateLangAfter -## Informations +## Information {{% notice tip %}} **Update "lang" tables:** @@ -24,14 +25,14 @@ Update "lang" tables after adding or updating a language Hook locations: - frontoffice -Hook types: - - legacy +Hook type: + - action Located in: - - classes/Language.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Language.php](classes/Language.php) -## Hook call with parameters +## Hook call in codebase ```php -Hook::exec('actionUpdateLangAfter', ['lang' => $language]); +Hook::exec('actionUpdateLangAfter', ['lang' => $language]) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionUpdateQuantity.md b/modules/concepts/hooks/list-of-hooks/actionUpdateQuantity.md new file mode 100644 index 0000000000..3106d63d9b --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionUpdateQuantity.md @@ -0,0 +1,63 @@ +--- +menuTitle: actionUpdateQuantity +Title: actionUpdateQuantity +hidden: true +hookTitle: Quantity update +files: + - classes/stock/StockAvailable.php +locations: + - frontoffice +type: + - action +hookAliases: + - updateQuantity +--- + +# Hook actionUpdateQuantity + +Aliases: + - updateQuantity + + + +## Information + +{{% notice tip %}} +**Quantity update:** + +Quantity is updated only when a customer effectively places their order +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook type: + - action + +Located in: + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/stock/StockAvailable.php](classes/stock/StockAvailable.php) + +## Parameters details + +```php + (int) Product ID, + 'id_product_attribute' => (int) Product attribute ID, + 'quantity' => (int) New product quantity + ); +``` + +## Hook call in codebase + +```php +Hook::exec( + 'actionUpdateQuantity', + [ + 'id_product' => $id_product, + 'id_product_attribute' => 0, + 'quantity' => $product_quantity, + 'id_shop' => $id_shop, + ] + ) +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionValidateCustomerAddressForm.md b/modules/concepts/hooks/list-of-hooks/actionValidateCustomerAddressForm.md index e753be0cab..ca473f2290 100644 --- a/modules/concepts/hooks/list-of-hooks/actionValidateCustomerAddressForm.md +++ b/modules/concepts/hooks/list-of-hooks/actionValidateCustomerAddressForm.md @@ -7,13 +7,14 @@ files: - classes/form/CustomerAddressForm.php locations: - frontoffice -types: - - legacy +type: + - action +hookAliases: --- -# Hook : actionValidateCustomerAddressForm +# Hook actionValidateCustomerAddressForm -## Informations +## Information {{% notice tip %}} **Customer address form validation:** @@ -24,107 +25,23 @@ This hook is called when a customer submit its address form Hook locations: - frontoffice -Hook types: - - legacy +Hook type: + - action Located in: - - classes/form/CustomerAddressForm.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/form/CustomerAddressForm.php](classes/form/CustomerAddressForm.php) -## Hook call with parameters +## Parameters details ```php -Hook::exec('actionValidateCustomerAddressForm', ['form' => $this])) !== '') { - $is_valid &= (bool) $hookReturn; - } - - return $is_valid && parent::validate(); - } - - public function submit() - { - if (!$this->validate()) { - return false; - } - - $address = new Address( - Tools::getValue('id_address'), - $this->language->id - ); - - foreach ($this->formFields as $formField) { - $address->{$formField->getName()} = $formField->getValue(); - } - - if (!isset($this->formFields['id_state'])) { - $address->id_state = 0; - } - - if (empty($address->alias)) { - $address->alias = $this->translator->trans('My Address', [], 'Shop.Theme.Checkout'); - } - - Hook::exec('actionSubmitCustomerAddressForm', ['address' => &$address]); - - $this->setAddress($address); + (object) CustomerAddressForm + ); +``` - return $this->getPersister()->save( - $address, - $this->getValue('token') - ); - } +## Hook call in codebase - /** - * @return Address - */ - public function getAddress() - { - return $this->address; - } - - /** - * @return CustomerAddressPersister - */ - protected function getPersister() - { - return $this->persister; - } - - protected function setAddress(Address $address) - { - $this->address = $address; - } - - public function getTemplateVariables() - { - $context = Context::getContext(); - - if (!$this->formFields) { - // This is usually done by fillWith but the form may be - // rendered before fillWith is called. - // I don't want to assign formFields in the constructor - // because it accesses the DB and a constructor should not - // have side effects. - $this->formFields = $this->formatter->getFormat(); - } - - $this->setValue('token', $this->persister->getToken()); - $formFields = array_map( - function (FormField $item) { - return $item->toArray(); - }, - $this->formFields - ); - - if (empty($formFields['firstname']['value'])) { - $formFields['firstname']['value'] = $context->customer->firstname; - } - - if (empty($formFields['lastname']['value'])) { - $formFields['lastname']['value'] = $context->customer->lastname; - } - - return [ - 'id_address' => (isset($this->address->id)) ? $this->address->id : 0, - 'action' => $this->action, - 'errors' => $this->getErrors(), +```php +Hook::exec('actionValidateCustomerAddressForm', ['form' => $this]) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionValidateOrder.md b/modules/concepts/hooks/list-of-hooks/actionValidateOrder.md index 4d145ccc53..5dcf1982ef 100644 --- a/modules/concepts/hooks/list-of-hooks/actionValidateOrder.md +++ b/modules/concepts/hooks/list-of-hooks/actionValidateOrder.md @@ -7,13 +7,20 @@ files: - classes/PaymentModule.php locations: - frontoffice -types: - - legacy +type: + - action +hookAliases: + - newOrder --- -# Hook : actionValidateOrder +# Hook actionValidateOrder -## Informations +Aliases: + - newOrder + + + +## Information {{% notice tip %}} **New orders:** @@ -24,13 +31,26 @@ types: Hook locations: - frontoffice -Hook types: - - legacy +Hook type: + - action Located in: - - classes/PaymentModule.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/PaymentModule.php](classes/PaymentModule.php) + +## Parameters details -## Hook call with parameters +```php + (object) Cart, + 'order' => (object) Order, + 'customer' => (object) Customer, + 'currency' => (object) Currency, + 'orderStatus' => (object) OrderState + ); +``` + +## Hook call in codebase ```php Hook::exec('actionValidateOrder', [ @@ -39,5 +59,5 @@ Hook::exec('actionValidateOrder', [ 'customer' => $this->context->customer, 'currency' => $this->context->currency, 'orderStatus' => $order_status, - ]); + ]) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionValidateOrderAfter.md b/modules/concepts/hooks/list-of-hooks/actionValidateOrderAfter.md new file mode 100644 index 0000000000..6492a1718d --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionValidateOrderAfter.md @@ -0,0 +1,62 @@ +--- +menuTitle: actionValidateOrderAfter +Title: actionValidateOrderAfter +hidden: true +hookTitle: After validating an order +files: + - classes/PaymentModule.php +locations: + - frontoffice +type: + - action +hookAliases: +--- + +# Hook actionValidateOrderAfter + +## Information + +{{% notice tip %}} +**After validating an order:** + +This hook is called after validating an order by core +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook type: + - action + +Located in: + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/PaymentModule.php](classes/PaymentModule.php) + +## Parameters details + +```php + (Cart|null) $contextCart, + 'order' => (Order|null) $order, + 'orders' => (array) $orderList, + 'customer' => (Customer) $contextCustomer, + 'currency' => (Currency) $contextCurrency, + 'orderStatus' => (OrderState) $orderState, + ] +``` + +## Hook call in codebase + +```php +Hook::exec( + 'actionValidateOrderAfter', + [ + 'cart' => $this->context->cart, + 'order' => $order ?? null, + 'orders' => $order_list, + 'customer' => $this->context->customer, + 'currency' => $this->context->currency, + 'orderStatus' => new OrderState(isset($order) ? $order->current_state : null), + ] + ) +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionValidateStepComplete.md b/modules/concepts/hooks/list-of-hooks/actionValidateStepComplete.md new file mode 100644 index 0000000000..20e4dfa9d6 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionValidateStepComplete.md @@ -0,0 +1,51 @@ +--- +menuTitle: actionValidateStepComplete +Title: actionValidateStepComplete +hidden: true +hookTitle: +files: + - classes/checkout/CheckoutDeliveryStep.php +locations: + - frontoffice +type: + - action +hookAliases: +--- + +# Hook actionValidateStepComplete + +## Information + +Hook locations: + - frontoffice + +Hook type: + - action + +Located in: + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/checkout/CheckoutDeliveryStep.php](classes/checkout/CheckoutDeliveryStep.php) + +## Parameters details + +```php + 'delivery', + 'request_params' => $requestParams, + 'completed' => &$isComplete, + ); +``` + +## Hook call in codebase + +```php +Hook::exec( + 'actionValidateStepComplete', + [ + 'step_name' => 'delivery', + 'request_params' => $requestParams, + 'completed' => &$isComplete, + ], + Module::getModuleIdByName($currentDeliveryOption['external_module_name']) + ) +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionWatermark.md b/modules/concepts/hooks/list-of-hooks/actionWatermark.md index 1ff9192006..56cacef1af 100644 --- a/modules/concepts/hooks/list-of-hooks/actionWatermark.md +++ b/modules/concepts/hooks/list-of-hooks/actionWatermark.md @@ -4,16 +4,23 @@ Title: actionWatermark hidden: true hookTitle: Watermark files: - - controllers/admin/AdminProductsController.php + - src/Adapter/Product/Image/Uploader/ProductImageUploader.php locations: - - backoffice -types: - - legacy + - frontoffice +type: + - action +hookAliases: + - watermark --- -# Hook : actionWatermark +# Hook actionWatermark -## Informations +Aliases: + - watermark + + + +## Information {{% notice tip %}} **Watermark:** @@ -22,16 +29,29 @@ types: {{% /notice %}} Hook locations: - - backoffice + - frontoffice -Hook types: - - legacy +Hook type: + - action Located in: - - controllers/admin/AdminProductsController.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Product/Image/Uploader/ProductImageUploader.php](src/Adapter/Product/Image/Uploader/ProductImageUploader.php) + +## Parameters details + +```php + (int) Image ID, + 'id_product' => (int) Product ID + ); +``` -## Hook call with parameters +## Hook call in codebase ```php -Hook::exec('actionWatermark', ['id_image' => $id_image, 'id_product' => $id_product]); +dispatchWithParameters( + 'actionWatermark', + ['id_image' => $imageId->getValue(), 'id_product' => $productId] + ) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionWishlistAddProduct.md b/modules/concepts/hooks/list-of-hooks/actionWishlistAddProduct.md index 8ed061b46e..8146e9a9be 100644 --- a/modules/concepts/hooks/list-of-hooks/actionWishlistAddProduct.md +++ b/modules/concepts/hooks/list-of-hooks/actionWishlistAddProduct.md @@ -7,24 +7,25 @@ files: - modules/blockwishlist/controllers/front/action.php locations: - frontoffice -types: - - legacy +type: + - action +hookAliases: --- -# Hook : actionWishlistAddProduct +# Hook actionWishlistAddProduct -## Informations +## Information Hook locations: - frontoffice -Hook types: - - legacy +Hook type: + - action Located in: - - modules/blockwishlist/controllers/front/action.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/modules/blockwishlist/controllers/front/action.php](modules/blockwishlist/controllers/front/action.php) -## Hook call with parameters +## Hook call in codebase ```php Hook::exec('actionWishlistAddProduct', [ @@ -32,5 +33,5 @@ Hook::exec('actionWishlistAddProduct', [ 'customerId' => $this->context->customer->id, 'idProduct' => $id_product, 'idProductAttribute' => $id_product_attribute, - ]); + ]) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/addWebserviceResources.md b/modules/concepts/hooks/list-of-hooks/addWebserviceResources.md index 252415eb54..2a4ed1c9e8 100644 --- a/modules/concepts/hooks/list-of-hooks/addWebserviceResources.md +++ b/modules/concepts/hooks/list-of-hooks/addWebserviceResources.md @@ -7,13 +7,14 @@ files: - classes/webservice/WebserviceRequest.php locations: - frontoffice -types: - - legacy +type: + - +hookAliases: --- -# Hook : addWebserviceResources +# Hook addWebserviceResources -## Informations +## Information {{% notice tip %}} **Add extra webservice resource:** @@ -24,14 +25,18 @@ This hook is called when webservice resources list in webservice controller Hook locations: - frontoffice -Hook types: - - legacy +Hook type: + - Located in: - - classes/webservice/WebserviceRequest.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/webservice/WebserviceRequest.php](classes/webservice/WebserviceRequest.php) + +This hook has an `$array_return` parameter set to `true` (module output will be set by name in an array, [see explaination here]({{< relref "/8/modules/concepts/hooks">}})). + +This hook has a `$check_exceptions` parameter set to `false` (check permission exceptions, [see explaination here]({{< relref "/8/modules/concepts/hooks">}})). -## Hook call with parameters +## Hook call in codebase ```php -Hook::exec('addWebserviceResources', ['resources' => $resources], null, true, false); +Hook::exec('addWebserviceResources', ['resources' => $resources], null, true, false) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/additionalCustomerAddressFields.md b/modules/concepts/hooks/list-of-hooks/additionalCustomerAddressFields.md index b867a51240..bfbee46092 100644 --- a/modules/concepts/hooks/list-of-hooks/additionalCustomerAddressFields.md +++ b/modules/concepts/hooks/list-of-hooks/additionalCustomerAddressFields.md @@ -7,13 +7,14 @@ files: - classes/form/CustomerAddressFormatter.php locations: - frontoffice -types: - - legacy +type: + - +hookAliases: --- -# Hook : additionalCustomerAddressFields +# Hook additionalCustomerAddressFields -## Informations +## Information {{% notice tip %}} **Add fields to the Customer address form:** @@ -24,14 +25,16 @@ This hook returns an array of FormFields to add them to the customer address reg Hook locations: - frontoffice -Hook types: - - legacy +Hook type: + - Located in: - - classes/form/CustomerAddressFormatter.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/form/CustomerAddressFormatter.php](classes/form/CustomerAddressFormatter.php) + +This hook has an `$array_return` parameter set to `true` (module output will be set by name in an array, [see explaination here]({{< relref "/8/modules/concepts/hooks">}})). -## Hook call with parameters +## Hook call in codebase ```php -Hook::exec('additionalCustomerAddressFields', ['fields' => &$format], null, true); +Hook::exec('additionalCustomerAddressFields', ['fields' => &$format], null, true) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/additionalCustomerFormFields.md b/modules/concepts/hooks/list-of-hooks/additionalCustomerFormFields.md index 87006c916f..cfc936b65e 100644 --- a/modules/concepts/hooks/list-of-hooks/additionalCustomerFormFields.md +++ b/modules/concepts/hooks/list-of-hooks/additionalCustomerFormFields.md @@ -7,13 +7,14 @@ files: - classes/form/CustomerFormatter.php locations: - frontoffice -types: - - legacy +type: + - +hookAliases: --- -# Hook : additionalCustomerFormFields +# Hook additionalCustomerFormFields -## Informations +## Information {{% notice tip %}} **Add fields to the Customer form:** @@ -24,14 +25,16 @@ This hook returns an array of FormFields to add them to the customer registratio Hook locations: - frontoffice -Hook types: - - legacy +Hook type: + - Located in: - - classes/form/CustomerFormatter.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/form/CustomerFormatter.php](classes/form/CustomerFormatter.php) + +This hook has an `$array_return` parameter set to `true` (module output will be set by name in an array, [see explaination here]({{< relref "/8/modules/concepts/hooks">}})). -## Hook call with parameters +## Hook call in codebase ```php -Hook::exec('additionalCustomerFormFields', ['fields' => &$format], null, true); +Hook::exec('additionalCustomerFormFields', ['fields' => &$format], null, true) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/dashboardData.md b/modules/concepts/hooks/list-of-hooks/dashboardData.md index 573122ebf5..3568ecb47e 100644 --- a/modules/concepts/hooks/list-of-hooks/dashboardData.md +++ b/modules/concepts/hooks/list-of-hooks/dashboardData.md @@ -7,25 +7,28 @@ files: - controllers/admin/AdminDashboardController.php locations: - backoffice -types: - - legacy +type: + - +hookAliases: --- -# Hook : dashboardData +# Hook dashboardData -## Informations +## Information Hook locations: - backoffice -Hook types: - - legacy +Hook type: + - Located in: - - controllers/admin/AdminDashboardController.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/admin/AdminDashboardController.php](controllers/admin/AdminDashboardController.php) + +This hook has an `$array_return` parameter set to `true` (module output will be set by name in an array, [see explaination here]({{< relref "/8/modules/concepts/hooks">}})). -## Hook call with parameters +## Hook call in codebase ```php -Hook::exec('dashboardData', $params, $id_module, true))); +Hook::exec('dashboardData', $params, $id_module, true) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/dashboardZoneOne.md b/modules/concepts/hooks/list-of-hooks/dashboardZoneOne.md index 85bb563359..142ca75d66 100644 --- a/modules/concepts/hooks/list-of-hooks/dashboardZoneOne.md +++ b/modules/concepts/hooks/list-of-hooks/dashboardZoneOne.md @@ -7,25 +7,26 @@ files: - controllers/admin/AdminDashboardController.php locations: - backoffice -types: - - legacy +type: + - +hookAliases: --- -# Hook : dashboardZoneOne +# Hook dashboardZoneOne -## Informations +## Information Hook locations: - backoffice -Hook types: - - legacy +Hook type: + - Located in: - - controllers/admin/AdminDashboardController.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/admin/AdminDashboardController.php](controllers/admin/AdminDashboardController.php) -## Hook call with parameters +## Hook call in codebase ```php -Hook::exec('dashboardZoneOne', $params), +Hook::exec('dashboardZoneOne', $params) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/dashboardZoneThree.md b/modules/concepts/hooks/list-of-hooks/dashboardZoneThree.md index a6db12a018..656694f28a 100644 --- a/modules/concepts/hooks/list-of-hooks/dashboardZoneThree.md +++ b/modules/concepts/hooks/list-of-hooks/dashboardZoneThree.md @@ -7,13 +7,14 @@ files: - controllers/admin/AdminDashboardController.php locations: - backoffice -types: - - legacy +type: + - +hookAliases: --- -# Hook : dashboardZoneThree +# Hook dashboardZoneThree -## Informations +## Information {{% notice tip %}} **Dashboard column three:** @@ -24,14 +25,24 @@ This hook is displayed in the third column of the dashboard Hook locations: - backoffice -Hook types: - - legacy +Hook type: + - Located in: - - controllers/admin/AdminDashboardController.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/admin/AdminDashboardController.php](controllers/admin/AdminDashboardController.php) + +## Parameters details + +```php + (string|null) $statsDateFrom, + 'date_to' => (string|null) $statsDateTo, + ] +``` -## Hook call with parameters +## Hook call in codebase ```php -Hook::exec('dashboardZoneThree', $params), +Hook::exec('dashboardZoneThree', $params) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/dashboardZoneTwo.md b/modules/concepts/hooks/list-of-hooks/dashboardZoneTwo.md index 51e86a11d0..e735753448 100644 --- a/modules/concepts/hooks/list-of-hooks/dashboardZoneTwo.md +++ b/modules/concepts/hooks/list-of-hooks/dashboardZoneTwo.md @@ -7,25 +7,26 @@ files: - controllers/admin/AdminDashboardController.php locations: - backoffice -types: - - legacy +type: + - +hookAliases: --- -# Hook : dashboardZoneTwo +# Hook dashboardZoneTwo -## Informations +## Information Hook locations: - backoffice -Hook types: - - legacy +Hook type: + - Located in: - - controllers/admin/AdminDashboardController.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/admin/AdminDashboardController.php](controllers/admin/AdminDashboardController.php) -## Hook call with parameters +## Hook call in codebase ```php -Hook::exec('dashboardZoneTwo', $params), +Hook::exec('dashboardZoneTwo', $params) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/deleteProductAttribute.md b/modules/concepts/hooks/list-of-hooks/deleteProductAttribute.md new file mode 100644 index 0000000000..ce05cadcea --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/deleteProductAttribute.md @@ -0,0 +1,39 @@ +--- +menuTitle: deleteProductAttribute +Title: deleteProductAttribute +hidden: true +hookTitle: +files: + - classes/Product.php +locations: + - frontoffice +type: + - +hookAliases: +--- + +# Hook deleteProductAttribute + +## Information + +Hook locations: + - frontoffice + +Hook type: + - + +Located in: + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Product.php](classes/Product.php) + +## Hook call in codebase + +```php +Hook::exec( + 'deleteProductAttribute', + [ + 'id_product_attribute' => $id_product_attribute, + 'id_product' => $this->id, + 'deleteAllAttributes' => false, + ] + ) +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/displayAdditionalCustomerAddressFields.md b/modules/concepts/hooks/list-of-hooks/displayAdditionalCustomerAddressFields.md index f85e171835..cb6ce34683 100644 --- a/modules/concepts/hooks/list-of-hooks/displayAdditionalCustomerAddressFields.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdditionalCustomerAddressFields.md @@ -7,13 +7,14 @@ files: - themes/classic/templates/customer/_partials/block-address.tpl locations: - frontoffice -types: - - smarty +type: + - display +hookAliases: --- -# Hook : displayAdditionalCustomerAddressFields +# Hook displayAdditionalCustomerAddressFields -## Informations +## Information {{% notice tip %}} **Display additional customer address fields:** @@ -24,13 +25,13 @@ This hook allows to display extra field values added in an address form using ho Hook locations: - frontoffice -Hook types: - - smarty +Hook type: + - display Located in: - - themes/classic/templates/customer/_partials/block-address.tpl + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/customer/_partials/block-address.tpl](themes/classic/templates/customer/_partials/block-address.tpl) -## Hook call with parameters +## Hook call in codebase ```php {hook h='displayAdditionalCustomerAddressFields' address=$address} diff --git a/modules/concepts/hooks/list-of-hooks/displayAdminAfterHeader.md b/modules/concepts/hooks/list-of-hooks/displayAdminAfterHeader.md index e7b6a00e75..9e7d3aa7ce 100644 --- a/modules/concepts/hooks/list-of-hooks/displayAdminAfterHeader.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminAfterHeader.md @@ -7,24 +7,25 @@ files: - admin784x07v4swfhm9fgvc0/themes/new-theme/template/light_display_layout.tpl locations: - backoffice -types: - - smarty +type: + - display +hookAliases: --- -# Hook : displayAdminAfterHeader +# Hook displayAdminAfterHeader -## Informations +## Information Hook locations: - backoffice -Hook types: - - smarty +Hook type: + - display Located in: - - admin784x07v4swfhm9fgvc0/themes/new-theme/template/light_display_layout.tpl + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/admin784x07v4swfhm9fgvc0/themes/new-theme/template/light_display_layout.tpl](admin784x07v4swfhm9fgvc0/themes/new-theme/template/light_display_layout.tpl) -## Hook call with parameters +## Hook call in codebase ```php {hook h='displayAdminAfterHeader'} diff --git a/modules/concepts/hooks/list-of-hooks/displayAdminCustomers.md b/modules/concepts/hooks/list-of-hooks/displayAdminCustomers.md index 3adb40db8e..f146c19f61 100644 --- a/modules/concepts/hooks/list-of-hooks/displayAdminCustomers.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminCustomers.md @@ -7,13 +7,20 @@ files: - src/PrestaShopBundle/Resources/views/Admin/Sell/Customer/view.html.twig locations: - backoffice -types: - - twig +type: + - display +hookAliases: + - adminCustomers --- -# Hook : displayAdminCustomers +# Hook displayAdminCustomers -## Informations +Aliases: + - adminCustomers + + + +## Information {{% notice tip %}} **Display new elements in the Back Office, tab AdminCustomers:** @@ -24,13 +31,22 @@ This hook launches modules when the AdminCustomers tab is displayed in the Back Hook locations: - backoffice -Hook types: - - twig +Hook type: + - display Located in: - - src/PrestaShopBundle/Resources/views/Admin/Sell/Customer/view.html.twig + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Resources/views/Admin/Sell/Customer/view.html.twig](src/PrestaShopBundle/Resources/views/Admin/Sell/Customer/view.html.twig) + +## Parameters details + +```php + (string) $controller + 'legacy_controller' => (string) $legacyController + ); +``` + +## Hook call in codebase ```php {{ renderhook('displayAdminGridTableAfter', { diff --git a/modules/concepts/hooks/list-of-hooks/displayAdminGridTableBefore.md b/modules/concepts/hooks/list-of-hooks/displayAdminGridTableBefore.md index 3f473c55e7..1dbc183dba 100644 --- a/modules/concepts/hooks/list-of-hooks/displayAdminGridTableBefore.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminGridTableBefore.md @@ -7,13 +7,20 @@ files: - src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Blocks/table.html.twig locations: - backoffice -types: - - twig +type: + - display +hookAliases: + - displayAdminListBefore --- -# Hook : displayAdminGridTableBefore +# Hook displayAdminGridTableBefore -## Informations +Aliases: + - displayAdminListBefore + + + +## Information {{% notice tip %}} **Display before Grid table:** @@ -24,13 +31,24 @@ This hook adds new blocks before Grid component table Hook locations: - backoffice -Hook types: - - twig +Hook type: + - display Located in: - - src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Blocks/table.html.twig + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Blocks/table.html.twig](src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Blocks/table.html.twig) + +## Parameters details -## Hook call with parameters +```php + (string) $controller + 'legacy_controller' => (string) $legacyController + ); +``` + +## Hook call in codebase ```php {{ renderhook('displayAdminGridTableBefore', { diff --git a/modules/concepts/hooks/list-of-hooks/displayAdminListAfter.md b/modules/concepts/hooks/list-of-hooks/displayAdminListAfter.md index adfce7289c..aa088dd34f 100644 --- a/modules/concepts/hooks/list-of-hooks/displayAdminListAfter.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminListAfter.md @@ -7,24 +7,25 @@ files: - admin784x07v4swfhm9fgvc0/themes/default/template/helpers/list/list_footer.tpl locations: - backoffice -types: - - smarty +type: + - display +hookAliases: --- -# Hook : displayAdminListAfter +# Hook displayAdminListAfter -## Informations +## Information Hook locations: - backoffice -Hook types: - - smarty +Hook type: + - display Located in: - - admin784x07v4swfhm9fgvc0/themes/default/template/helpers/list/list_footer.tpl + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/admin784x07v4swfhm9fgvc0/themes/default/template/helpers/list/list_footer.tpl](admin784x07v4swfhm9fgvc0/themes/default/template/helpers/list/list_footer.tpl) -## Hook call with parameters +## Hook call in codebase ```php {hook h='displayAdminListAfter'} diff --git a/modules/concepts/hooks/list-of-hooks/displayAdminListBefore.md b/modules/concepts/hooks/list-of-hooks/displayAdminListBefore.md index e7231df9df..06d2f9ff4e 100644 --- a/modules/concepts/hooks/list-of-hooks/displayAdminListBefore.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminListBefore.md @@ -7,24 +7,25 @@ files: - admin784x07v4swfhm9fgvc0/themes/default/template/helpers/list/list_header.tpl locations: - backoffice -types: - - smarty +type: + - display +hookAliases: --- -# Hook : displayAdminListBefore +# Hook displayAdminListBefore -## Informations +## Information Hook locations: - backoffice -Hook types: - - smarty +Hook type: + - display Located in: - - admin784x07v4swfhm9fgvc0/themes/default/template/helpers/list/list_header.tpl + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/admin784x07v4swfhm9fgvc0/themes/default/template/helpers/list/list_header.tpl](admin784x07v4swfhm9fgvc0/themes/default/template/helpers/list/list_header.tpl) -## Hook call with parameters +## Hook call in codebase ```php {hook h='displayAdminListBefore'} diff --git a/modules/concepts/hooks/list-of-hooks/displayAdminNavBarBeforeEnd.md b/modules/concepts/hooks/list-of-hooks/displayAdminNavBarBeforeEnd.md index 9945d81910..84d0ca775b 100644 --- a/modules/concepts/hooks/list-of-hooks/displayAdminNavBarBeforeEnd.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminNavBarBeforeEnd.md @@ -7,24 +7,25 @@ files: - admin784x07v4swfhm9fgvc0/themes/new-theme/template/components/layout/nav_bar.tpl locations: - backoffice -types: - - smarty +type: + - display +hookAliases: --- -# Hook : displayAdminNavBarBeforeEnd +# Hook displayAdminNavBarBeforeEnd -## Informations +## Information Hook locations: - backoffice -Hook types: - - smarty +Hook type: + - display Located in: - - admin784x07v4swfhm9fgvc0/themes/new-theme/template/components/layout/nav_bar.tpl + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/admin784x07v4swfhm9fgvc0/themes/new-theme/template/components/layout/nav_bar.tpl](admin784x07v4swfhm9fgvc0/themes/new-theme/template/components/layout/nav_bar.tpl) -## Hook call with parameters +## Hook call in codebase ```php {hook h='displayAdminNavBarBeforeEnd'} diff --git a/modules/concepts/hooks/list-of-hooks/displayAdminOptions.md b/modules/concepts/hooks/list-of-hooks/displayAdminOptions.md index d48b00a3ef..ccbcb93147 100644 --- a/modules/concepts/hooks/list-of-hooks/displayAdminOptions.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminOptions.md @@ -7,24 +7,25 @@ files: - admin784x07v4swfhm9fgvc0/themes/default/template/helpers/options/options.tpl locations: - backoffice -types: - - smarty +type: + - display +hookAliases: --- -# Hook : displayAdminOptions +# Hook displayAdminOptions -## Informations +## Information Hook locations: - backoffice -Hook types: - - smarty +Hook type: + - display Located in: - - admin784x07v4swfhm9fgvc0/themes/default/template/helpers/options/options.tpl + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/admin784x07v4swfhm9fgvc0/themes/default/template/helpers/options/options.tpl](admin784x07v4swfhm9fgvc0/themes/default/template/helpers/options/options.tpl) -## Hook call with parameters +## Hook call in codebase ```php {hook h='displayAdminOptions'} diff --git a/modules/concepts/hooks/list-of-hooks/displayAdminOrder.md b/modules/concepts/hooks/list-of-hooks/displayAdminOrder.md index 7cc17cf1cf..e107ce2d67 100644 --- a/modules/concepts/hooks/list-of-hooks/displayAdminOrder.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminOrder.md @@ -7,13 +7,20 @@ files: - src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/view.html.twig locations: - backoffice -types: - - twig +type: + - display +hookAliases: + - adminOrder --- -# Hook : displayAdminOrder +# Hook displayAdminOrder -## Informations +Aliases: + - adminOrder + + + +## Information {{% notice tip %}} **Display new elements in the Back Office, tab AdminOrder:** @@ -24,13 +31,22 @@ This hook launches modules when the AdminOrder tab is displayed in the Back Offi Hook locations: - backoffice -Hook types: - - twig +Hook type: + - display Located in: - - src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/view.html.twig + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/view.html.twig](src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/view.html.twig) + +## Parameters details + +```php + (int) Order ID + ); +``` -## Hook call with parameters +## Hook call in codebase ```php {{ renderhook('displayAdminOrderMain', {'id_order': orderForViewing.id}) }} diff --git a/modules/concepts/hooks/list-of-hooks/displayAdminOrderMainBottom.md b/modules/concepts/hooks/list-of-hooks/displayAdminOrderMainBottom.md index 151eb1c87b..6223cfcd3f 100644 --- a/modules/concepts/hooks/list-of-hooks/displayAdminOrderMainBottom.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminOrderMainBottom.md @@ -7,13 +7,14 @@ files: - src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/view.html.twig locations: - backoffice -types: - - twig +type: + - display +hookAliases: --- -# Hook : displayAdminOrderMainBottom +# Hook displayAdminOrderMainBottom -## Informations +## Information {{% notice tip %}} **Admin Order Main Column Bottom:** @@ -24,13 +25,22 @@ This hook displays content in the order view page at the bottom of the main colu Hook locations: - backoffice -Hook types: - - twig +Hook type: + - display Located in: - - src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/view.html.twig + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/view.html.twig](src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/view.html.twig) + +## Parameters details + +```php + (int) Order ID + ); +``` -## Hook call with parameters +## Hook call in codebase ```php {{ renderhook('displayAdminOrderMainBottom', {'id_order': orderForViewing.id}) }} diff --git a/modules/concepts/hooks/list-of-hooks/displayAdminOrderSide.md b/modules/concepts/hooks/list-of-hooks/displayAdminOrderSide.md index 7cb3eb2ce7..d085368ff4 100644 --- a/modules/concepts/hooks/list-of-hooks/displayAdminOrderSide.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminOrderSide.md @@ -7,13 +7,20 @@ files: - src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/view.html.twig locations: - backoffice -types: - - twig +type: + - display +hookAliases: + - displayBackOfficeOrderActions --- -# Hook : displayAdminOrderSide +# Hook displayAdminOrderSide -## Informations +Aliases: + - displayBackOfficeOrderActions + + + +## Information {{% notice tip %}} **Admin Order Side Column:** @@ -24,13 +31,22 @@ This hook displays content in the order view page in the side column under the c Hook locations: - backoffice -Hook types: - - twig +Hook type: + - display Located in: - - src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/view.html.twig + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/view.html.twig](src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/view.html.twig) + +## Parameters details + +```php + (int) Order ID + ); +``` -## Hook call with parameters +## Hook call in codebase ```php {{ renderhook('displayAdminOrderSide', {'id_order': orderForViewing.id}) }} diff --git a/modules/concepts/hooks/list-of-hooks/displayAdminOrderSideBottom.md b/modules/concepts/hooks/list-of-hooks/displayAdminOrderSideBottom.md index 0fe1f2f7fd..aeb253cc03 100644 --- a/modules/concepts/hooks/list-of-hooks/displayAdminOrderSideBottom.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminOrderSideBottom.md @@ -7,24 +7,34 @@ files: - src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/view.html.twig locations: - backoffice -types: - - twig +type: + - display +hookAliases: --- -# Hook : displayAdminOrderSideBottom +# Hook displayAdminOrderSideBottom -## Informations +## Information Hook locations: - backoffice -Hook types: - - twig +Hook type: + - display Located in: - - src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/view.html.twig + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/view.html.twig](src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/view.html.twig) + +## Parameters details + +```php + (int) Order ID + ); +``` -## Hook call with parameters +## Hook call in codebase ```php {{ renderhook('displayAdminOrderSideBottom', {'id_order': orderForViewing.id}) }} diff --git a/modules/concepts/hooks/list-of-hooks/displayAdminProductsCombinationBottom.md b/modules/concepts/hooks/list-of-hooks/displayAdminProductsCombinationBottom.md index 56970fc472..d40a6de9fd 100644 --- a/modules/concepts/hooks/list-of-hooks/displayAdminProductsCombinationBottom.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminProductsCombinationBottom.md @@ -7,13 +7,14 @@ files: - src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Forms/form_combination.html.twig locations: - backoffice -types: - - twig +type: + - display +hookAliases: --- -# Hook : displayAdminProductsCombinationBottom +# Hook displayAdminProductsCombinationBottom -## Informations +## Information {{% notice tip %}} **Display new elements in back office product page, Combination tab:** @@ -24,13 +25,13 @@ This hook launches modules when the back office product page is displayed Hook locations: - backoffice -Hook types: - - twig +Hook type: + - display Located in: - - src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Forms/form_combination.html.twig + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Forms/form_combination.html.twig](src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Forms/form_combination.html.twig) -## Hook call with parameters +## Hook call in codebase ```php {{ renderhook('displayAdminProductsCombinationBottom', { 'id_product': form.vars.value.id_product, 'id_product_attribute': form.vars.value.id_product_attribute }) }} diff --git a/modules/concepts/hooks/list-of-hooks/displayAdminProductsMainStepLeftColumnBottom.md b/modules/concepts/hooks/list-of-hooks/displayAdminProductsMainStepLeftColumnBottom.md index ef49c5337d..57e4848637 100644 --- a/modules/concepts/hooks/list-of-hooks/displayAdminProductsMainStepLeftColumnBottom.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminProductsMainStepLeftColumnBottom.md @@ -7,13 +7,14 @@ files: - src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/essentials.html.twig locations: - backoffice -types: - - twig +type: + - display +hookAliases: --- -# Hook : displayAdminProductsMainStepLeftColumnBottom +# Hook displayAdminProductsMainStepLeftColumnBottom -## Informations +## Information {{% notice tip %}} **Display new elements in back office product page, left column of the Basic settings tab:** @@ -24,13 +25,13 @@ This hook launches modules when the back office product page is displayed Hook locations: - backoffice -Hook types: - - twig +Hook type: + - display Located in: - - src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/essentials.html.twig + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/essentials.html.twig](src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/essentials.html.twig) -## Hook call with parameters +## Hook call in codebase ```php {{ renderhook('displayAdminProductsMainStepLeftColumnBottom', { 'id_product': productId }) }} diff --git a/modules/concepts/hooks/list-of-hooks/displayAdminProductsMainStepLeftColumnMiddle.md b/modules/concepts/hooks/list-of-hooks/displayAdminProductsMainStepLeftColumnMiddle.md index 830ad3e47c..6e41185b5a 100644 --- a/modules/concepts/hooks/list-of-hooks/displayAdminProductsMainStepLeftColumnMiddle.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminProductsMainStepLeftColumnMiddle.md @@ -7,13 +7,14 @@ files: - src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/essentials.html.twig locations: - backoffice -types: - - twig +type: + - display +hookAliases: --- -# Hook : displayAdminProductsMainStepLeftColumnMiddle +# Hook displayAdminProductsMainStepLeftColumnMiddle -## Informations +## Information {{% notice tip %}} **Display new elements in back office product page, left column of the Basic settings tab:** @@ -24,13 +25,13 @@ This hook launches modules when the back office product page is displayed Hook locations: - backoffice -Hook types: - - twig +Hook type: + - display Located in: - - src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/essentials.html.twig + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/essentials.html.twig](src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/essentials.html.twig) -## Hook call with parameters +## Hook call in codebase ```php {{ renderhook('displayAdminProductsMainStepLeftColumnMiddle', { 'id_product': productId }) }} diff --git a/modules/concepts/hooks/list-of-hooks/displayAdminProductsMainStepRightColumnBottom.md b/modules/concepts/hooks/list-of-hooks/displayAdminProductsMainStepRightColumnBottom.md index 68a6e9e04d..c259b2112e 100644 --- a/modules/concepts/hooks/list-of-hooks/displayAdminProductsMainStepRightColumnBottom.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminProductsMainStepRightColumnBottom.md @@ -7,13 +7,14 @@ files: - src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/essentials.html.twig locations: - backoffice -types: - - twig +type: + - display +hookAliases: --- -# Hook : displayAdminProductsMainStepRightColumnBottom +# Hook displayAdminProductsMainStepRightColumnBottom -## Informations +## Information {{% notice tip %}} **Display new elements in back office product page, right column of the Basic settings tab:** @@ -24,13 +25,13 @@ This hook launches modules when the back office product page is displayed Hook locations: - backoffice -Hook types: - - twig +Hook type: + - display Located in: - - src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/essentials.html.twig + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/essentials.html.twig](src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/essentials.html.twig) -## Hook call with parameters +## Hook call in codebase ```php {{ renderhook('displayAdminProductsMainStepRightColumnBottom', { 'id_product': productId }) }} diff --git a/modules/concepts/hooks/list-of-hooks/displayAdminProductsOptionsStepBottom.md b/modules/concepts/hooks/list-of-hooks/displayAdminProductsOptionsStepBottom.md index 19c8749cc6..2368331880 100644 --- a/modules/concepts/hooks/list-of-hooks/displayAdminProductsOptionsStepBottom.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminProductsOptionsStepBottom.md @@ -7,13 +7,14 @@ files: - src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/options.html.twig locations: - backoffice -types: - - twig +type: + - display +hookAliases: --- -# Hook : displayAdminProductsOptionsStepBottom +# Hook displayAdminProductsOptionsStepBottom -## Informations +## Information {{% notice tip %}} **Display new elements in back office product page, Options tab:** @@ -24,13 +25,13 @@ This hook launches modules when the back office product page is displayed Hook locations: - backoffice -Hook types: - - twig +Hook type: + - display Located in: - - src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/options.html.twig + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/options.html.twig](src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/options.html.twig) -## Hook call with parameters +## Hook call in codebase ```php {{ renderhook('displayAdminProductsOptionsStepBottom', { 'id_product': productId }) }} diff --git a/modules/concepts/hooks/list-of-hooks/displayAdminProductsOptionsStepTop.md b/modules/concepts/hooks/list-of-hooks/displayAdminProductsOptionsStepTop.md index 7a4d1f5d05..900027d07e 100644 --- a/modules/concepts/hooks/list-of-hooks/displayAdminProductsOptionsStepTop.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminProductsOptionsStepTop.md @@ -7,13 +7,14 @@ files: - src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/options.html.twig locations: - backoffice -types: - - twig +type: + - display +hookAliases: --- -# Hook : displayAdminProductsOptionsStepTop +# Hook displayAdminProductsOptionsStepTop -## Informations +## Information {{% notice tip %}} **Display new elements in back office product page, Options tab:** @@ -24,13 +25,13 @@ This hook launches modules when the back office product page is displayed Hook locations: - backoffice -Hook types: - - twig +Hook type: + - display Located in: - - src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/options.html.twig + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/options.html.twig](src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/options.html.twig) -## Hook call with parameters +## Hook call in codebase ```php {{ renderhook('displayAdminProductsOptionsStepTop', { 'id_product': productId }) }} diff --git a/modules/concepts/hooks/list-of-hooks/displayAdminProductsPriceStepBottom.md b/modules/concepts/hooks/list-of-hooks/displayAdminProductsPriceStepBottom.md index 305abdf46b..4ad9a9463a 100644 --- a/modules/concepts/hooks/list-of-hooks/displayAdminProductsPriceStepBottom.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminProductsPriceStepBottom.md @@ -7,13 +7,14 @@ files: - src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/pricing.html.twig locations: - backoffice -types: - - twig +type: + - display +hookAliases: --- -# Hook : displayAdminProductsPriceStepBottom +# Hook displayAdminProductsPriceStepBottom -## Informations +## Information {{% notice tip %}} **Display new elements in back office product page, Price tab:** @@ -24,13 +25,13 @@ This hook launches modules when the back office product page is displayed Hook locations: - backoffice -Hook types: - - twig +Hook type: + - display Located in: - - src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/pricing.html.twig + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/pricing.html.twig](src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/pricing.html.twig) -## Hook call with parameters +## Hook call in codebase ```php {{ renderhook('displayAdminProductsPriceStepBottom', { 'id_product': productId }) }} diff --git a/modules/concepts/hooks/list-of-hooks/displayAdminProductsQuantitiesStepBottom.md b/modules/concepts/hooks/list-of-hooks/displayAdminProductsQuantitiesStepBottom.md index f91227ad20..091b875ef4 100644 --- a/modules/concepts/hooks/list-of-hooks/displayAdminProductsQuantitiesStepBottom.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminProductsQuantitiesStepBottom.md @@ -7,13 +7,14 @@ files: - src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/combinations.html.twig locations: - backoffice -types: - - twig +type: + - display +hookAliases: --- -# Hook : displayAdminProductsQuantitiesStepBottom +# Hook displayAdminProductsQuantitiesStepBottom -## Informations +## Information {{% notice tip %}} **Display new elements in back office product page, Quantities/Combinations tab:** @@ -24,13 +25,13 @@ This hook launches modules when the back office product page is displayed Hook locations: - backoffice -Hook types: - - twig +Hook type: + - display Located in: - - src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/combinations.html.twig + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/combinations.html.twig](src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/combinations.html.twig) -## Hook call with parameters +## Hook call in codebase ```php {{ renderhook('displayAdminProductsQuantitiesStepBottom', { 'id_product': productId }) }} diff --git a/modules/concepts/hooks/list-of-hooks/displayAdminProductsSeoStepBottom.md b/modules/concepts/hooks/list-of-hooks/displayAdminProductsSeoStepBottom.md index 1e02acf9ef..32f2819431 100644 --- a/modules/concepts/hooks/list-of-hooks/displayAdminProductsSeoStepBottom.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminProductsSeoStepBottom.md @@ -7,13 +7,14 @@ files: - src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Forms/form_seo.html.twig locations: - backoffice -types: - - twig +type: + - display +hookAliases: --- -# Hook : displayAdminProductsSeoStepBottom +# Hook displayAdminProductsSeoStepBottom -## Informations +## Information {{% notice tip %}} **Display new elements in back office product page, SEO tab:** @@ -24,13 +25,13 @@ This hook launches modules when the back office product page is displayed Hook locations: - backoffice -Hook types: - - twig +Hook type: + - display Located in: - - src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Forms/form_seo.html.twig + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Forms/form_seo.html.twig](src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Forms/form_seo.html.twig) -## Hook call with parameters +## Hook call in codebase ```php {{ renderhook('displayAdminProductsSeoStepBottom', { 'id_product': productId }) }} diff --git a/modules/concepts/hooks/list-of-hooks/displayAdminProductsShippingStepBottom.md b/modules/concepts/hooks/list-of-hooks/displayAdminProductsShippingStepBottom.md index 183614c9a6..a5e8cc2ec3 100644 --- a/modules/concepts/hooks/list-of-hooks/displayAdminProductsShippingStepBottom.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminProductsShippingStepBottom.md @@ -7,13 +7,14 @@ files: - src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Forms/form_shipping.html.twig locations: - backoffice -types: - - twig +type: + - display +hookAliases: --- -# Hook : displayAdminProductsShippingStepBottom +# Hook displayAdminProductsShippingStepBottom -## Informations +## Information {{% notice tip %}} **Display new elements in back office product page, Shipping tab:** @@ -24,13 +25,13 @@ This hook launches modules when the back office product page is displayed Hook locations: - backoffice -Hook types: - - twig +Hook type: + - display Located in: - - src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Forms/form_shipping.html.twig + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Forms/form_shipping.html.twig](src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Forms/form_shipping.html.twig) -## Hook call with parameters +## Hook call in codebase ```php {{ renderhook('displayAdminProductsShippingStepBottom', { 'id_product': id_product }) }} diff --git a/modules/concepts/hooks/list-of-hooks/displayAdminStatsModules.md b/modules/concepts/hooks/list-of-hooks/displayAdminStatsModules.md index 6c0e0a6a3d..b8f753d333 100644 --- a/modules/concepts/hooks/list-of-hooks/displayAdminStatsModules.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminStatsModules.md @@ -7,13 +7,20 @@ files: - controllers/admin/AdminStatsTabController.php locations: - backoffice -types: - - legacy +type: + - display +hookAliases: + - AdminStatsModules --- -# Hook : displayAdminStatsModules +# Hook displayAdminStatsModules -## Informations +Aliases: + - AdminStatsModules + + + +## Information {{% notice tip %}} **Stats - Modules:** @@ -24,14 +31,14 @@ types: Hook locations: - backoffice -Hook types: - - legacy +Hook type: + - display Located in: - - controllers/admin/AdminStatsTabController.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/admin/AdminStatsTabController.php](controllers/admin/AdminStatsTabController.php) -## Hook call with parameters +## Hook call in codebase ```php -Hook::exec('displayAdminStatsModules', [], $module_instance->id); +Hook::exec('displayAdminStatsModules', [], $module_instance->id) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/displayAdminThemesListAfter.md b/modules/concepts/hooks/list-of-hooks/displayAdminThemesListAfter.md index 10b0d7390e..960a60c715 100644 --- a/modules/concepts/hooks/list-of-hooks/displayAdminThemesListAfter.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminThemesListAfter.md @@ -7,13 +7,14 @@ files: - src/PrestaShopBundle/Resources/views/Admin/Improve/Design/Theme/index.html.twig locations: - backoffice -types: - - twig +type: + - display +hookAliases: --- -# Hook : displayAdminThemesListAfter +# Hook displayAdminThemesListAfter -## Informations +## Information {{% notice tip %}} **BO themes list extra content:** @@ -24,13 +25,22 @@ This hook displays content after the themes list in the back office Hook locations: - backoffice -Hook types: - - twig +Hook type: + - display Located in: - - src/PrestaShopBundle/Resources/views/Admin/Improve/Design/Theme/index.html.twig + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Resources/views/Admin/Improve/Design/Theme/index.html.twig](src/PrestaShopBundle/Resources/views/Admin/Improve/Design/Theme/index.html.twig) + +## Parameters details + +```php + (string) Name of the currently used theme + ); +``` -## Hook call with parameters +## Hook call in codebase ```php {{ renderhook('displayAdminThemesListAfter', { 'current_theme_name': currentlyUsedTheme.get('name') }) }} diff --git a/modules/concepts/hooks/list-of-hooks/displayAdminView.md b/modules/concepts/hooks/list-of-hooks/displayAdminView.md index faad09b54c..7b8a83dcbf 100644 --- a/modules/concepts/hooks/list-of-hooks/displayAdminView.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminView.md @@ -7,24 +7,25 @@ files: - admin784x07v4swfhm9fgvc0/themes/default/template/helpers/view/view.tpl locations: - backoffice -types: - - smarty +type: + - display +hookAliases: --- -# Hook : displayAdminView +# Hook displayAdminView -## Informations +## Information Hook locations: - backoffice -Hook types: - - smarty +Hook type: + - display Located in: - - admin784x07v4swfhm9fgvc0/themes/default/template/helpers/view/view.tpl + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/admin784x07v4swfhm9fgvc0/themes/default/template/helpers/view/view.tpl](admin784x07v4swfhm9fgvc0/themes/default/template/helpers/view/view.tpl) -## Hook call with parameters +## Hook call in codebase ```php {hook h='displayAdminView'} diff --git a/modules/concepts/hooks/list-of-hooks/displayAfterBodyOpeningTag.md b/modules/concepts/hooks/list-of-hooks/displayAfterBodyOpeningTag.md index 4f5cf5f313..367fba9939 100644 --- a/modules/concepts/hooks/list-of-hooks/displayAfterBodyOpeningTag.md +++ b/modules/concepts/hooks/list-of-hooks/displayAfterBodyOpeningTag.md @@ -7,13 +7,14 @@ files: - themes/classic/templates/layouts/layout-both-columns.tpl locations: - frontoffice -types: - - smarty +type: + - display +hookAliases: --- -# Hook : displayAfterBodyOpeningTag +# Hook displayAfterBodyOpeningTag -## Informations +## Information {{% notice tip %}} **Very top of pages:** @@ -24,13 +25,13 @@ Use this hook for advertisement or modals you want to load first Hook locations: - frontoffice -Hook types: - - smarty +Hook type: + - display Located in: - - themes/classic/templates/layouts/layout-both-columns.tpl + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/layouts/layout-both-columns.tpl](themes/classic/templates/layouts/layout-both-columns.tpl) -## Hook call with parameters +## Hook call in codebase ```php {hook h='displayAfterBodyOpeningTag'} diff --git a/modules/concepts/hooks/list-of-hooks/displayAfterCarrier.md b/modules/concepts/hooks/list-of-hooks/displayAfterCarrier.md index ecd3170e22..c14dec1750 100644 --- a/modules/concepts/hooks/list-of-hooks/displayAfterCarrier.md +++ b/modules/concepts/hooks/list-of-hooks/displayAfterCarrier.md @@ -7,13 +7,14 @@ files: - classes/checkout/CheckoutDeliveryStep.php locations: - frontoffice -types: - - legacy +type: + - display +hookAliases: --- -# Hook : displayAfterCarrier +# Hook displayAfterCarrier -## Informations +## Information {{% notice tip %}} **After carriers list:** @@ -24,14 +25,14 @@ This hook is displayed after the carrier list in Front Office Hook locations: - frontoffice -Hook types: - - legacy +Hook type: + - display Located in: - - classes/checkout/CheckoutDeliveryStep.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/checkout/CheckoutDeliveryStep.php](classes/checkout/CheckoutDeliveryStep.php) -## Hook call with parameters +## Hook call in codebase ```php -Hook::exec('displayAfterCarrier', ['cart' => $this->getCheckoutSession()->getCart()]), +Hook::exec('displayAfterCarrier', ['cart' => $this->getCheckoutSession()->getCart()]) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/displayAfterProductThumbs.md b/modules/concepts/hooks/list-of-hooks/displayAfterProductThumbs.md index 616f4ae307..30676d1b25 100644 --- a/modules/concepts/hooks/list-of-hooks/displayAfterProductThumbs.md +++ b/modules/concepts/hooks/list-of-hooks/displayAfterProductThumbs.md @@ -7,13 +7,14 @@ files: - themes/classic/templates/catalog/_partials/product-cover-thumbnails.tpl locations: - frontoffice -types: - - smarty +type: + - display +hookAliases: --- -# Hook : displayAfterProductThumbs +# Hook displayAfterProductThumbs -## Informations +## Information {{% notice tip %}} **Display extra content below product thumbs:** @@ -24,13 +25,13 @@ This hook displays new elements below product images ex. additional media Hook locations: - frontoffice -Hook types: - - smarty +Hook type: + - display Located in: - - themes/classic/templates/catalog/_partials/product-cover-thumbnails.tpl + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/catalog/_partials/product-cover-thumbnails.tpl](themes/classic/templates/catalog/_partials/product-cover-thumbnails.tpl) -## Hook call with parameters +## Hook call in codebase ```php {hook h='displayAfterProductThumbs' product=$product} diff --git a/modules/concepts/hooks/list-of-hooks/displayAfterTitleTag.md b/modules/concepts/hooks/list-of-hooks/displayAfterTitleTag.md index dc7d44c577..f61ae98ac3 100644 --- a/modules/concepts/hooks/list-of-hooks/displayAfterTitleTag.md +++ b/modules/concepts/hooks/list-of-hooks/displayAfterTitleTag.md @@ -7,13 +7,14 @@ files: - themes/classic/templates/_partials/head.tpl locations: - frontoffice -types: - - smarty +type: + - display +hookAliases: --- -# Hook : displayAfterTitleTag +# Hook displayAfterTitleTag -## Informations +## Information {{% notice tip %}} **After title tag:** @@ -24,13 +25,13 @@ Use this hook to add content after title tag Hook locations: - frontoffice -Hook types: - - smarty +Hook type: + - display Located in: - - themes/classic/templates/_partials/head.tpl + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/_partials/head.tpl](themes/classic/templates/_partials/head.tpl) -## Hook call with parameters +## Hook call in codebase ```php {hook h='displayAfterTitleTag'} diff --git a/modules/concepts/hooks/list-of-hooks/displayBackOfficeCategory.md b/modules/concepts/hooks/list-of-hooks/displayBackOfficeCategory.md index cec9f91c70..6f5d90da8f 100644 --- a/modules/concepts/hooks/list-of-hooks/displayBackOfficeCategory.md +++ b/modules/concepts/hooks/list-of-hooks/displayBackOfficeCategory.md @@ -7,13 +7,14 @@ files: - src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Categories/Blocks/form.html.twig locations: - backoffice -types: - - twig +type: + - display +hookAliases: --- -# Hook : displayBackOfficeCategory +# Hook displayBackOfficeCategory -## Informations +## Information {{% notice tip %}} **Display new elements in the Back Office, tab AdminCategories:** @@ -24,13 +25,13 @@ This hook launches modules when the AdminCategories tab is displayed in the Back Hook locations: - backoffice -Hook types: - - twig +Hook type: + - display Located in: - - src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Categories/Blocks/form.html.twig + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Categories/Blocks/form.html.twig](src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Categories/Blocks/form.html.twig) -## Hook call with parameters +## Hook call in codebase ```php {{ renderhook('displayBackOfficeCategory') }} diff --git a/modules/concepts/hooks/list-of-hooks/displayBackOfficeEmployeeMenu.md b/modules/concepts/hooks/list-of-hooks/displayBackOfficeEmployeeMenu.md new file mode 100644 index 0000000000..59170be450 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/displayBackOfficeEmployeeMenu.md @@ -0,0 +1,52 @@ +--- +menuTitle: displayBackOfficeEmployeeMenu +Title: displayBackOfficeEmployeeMenu +hidden: true +hookTitle: Administration Employee menu +files: + - src/PrestaShopBundle/Bridge/Smarty/HeaderConfigurator.php +locations: + - frontoffice +type: + - display +hookAliases: +--- + +# Hook displayBackOfficeEmployeeMenu + +## Information + +{{% notice tip %}} +**Administration Employee menu:** + +This hook is displayed in the employee menu +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook type: + - display + +Located in: + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Bridge/Smarty/HeaderConfigurator.php](src/PrestaShopBundle/Bridge/Smarty/HeaderConfigurator.php) + +## Parameters details + +```php + (ActionsBarButtonsCollection) $menuLinksCollections, + ] +``` + +## Hook call in codebase + +```php +dispatchWithParameters( + 'displayBackOfficeEmployeeMenu', + [ + 'links' => $menuLinksCollections, + ] + ) +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/displayBackOfficeHeader.md b/modules/concepts/hooks/list-of-hooks/displayBackOfficeHeader.md new file mode 100644 index 0000000000..5300626a9e --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/displayBackOfficeHeader.md @@ -0,0 +1,44 @@ +--- +menuTitle: displayBackOfficeHeader +Title: displayBackOfficeHeader +hidden: true +hookTitle: Administration panel header +files: + - classes/controller/AdminController.php +locations: + - backoffice +type: + - display +hookAliases: + - backOfficeHeader +--- + +# Hook displayBackOfficeHeader + +Aliases: + - backOfficeHeader + + + +## Information + +{{% notice tip %}} +**Administration panel header:** + +This hook is displayed in the header of the admin panel +{{% /notice %}} + +Hook locations: + - backoffice + +Hook type: + - display + +Located in: + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/AdminController.php](classes/controller/AdminController.php) + +## Hook call in codebase + +```php +Hook::exec('displayBackOfficeHeader') +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/displayBackOfficeTop.md b/modules/concepts/hooks/list-of-hooks/displayBackOfficeTop.md index 2d3a3a9c17..8166eea5b0 100644 --- a/modules/concepts/hooks/list-of-hooks/displayBackOfficeTop.md +++ b/modules/concepts/hooks/list-of-hooks/displayBackOfficeTop.md @@ -7,13 +7,20 @@ files: - classes/controller/AdminController.php locations: - backoffice -types: - - legacy +type: + - display +hookAliases: + - backOfficeTop --- -# Hook : displayBackOfficeTop +# Hook displayBackOfficeTop -## Informations +Aliases: + - backOfficeTop + + + +## Information {{% notice tip %}} **Administration panel hover the tabs:** @@ -24,14 +31,14 @@ This hook is displayed on the roll hover of the tabs within the admin panel Hook locations: - backoffice -Hook types: - - legacy +Hook type: + - display Located in: - - classes/controller/AdminController.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/AdminController.php](classes/controller/AdminController.php) -## Hook call with parameters +## Hook call in codebase ```php -Hook::exec('displayBackOfficeTop'), +Hook::exec('displayBackOfficeTop') ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/displayBanner.md b/modules/concepts/hooks/list-of-hooks/displayBanner.md index 8f65883839..1fa06eb976 100644 --- a/modules/concepts/hooks/list-of-hooks/displayBanner.md +++ b/modules/concepts/hooks/list-of-hooks/displayBanner.md @@ -7,13 +7,14 @@ files: - themes/classic/templates/_partials/header.tpl locations: - frontoffice -types: - - smarty +type: + - display +hookAliases: --- -# Hook : displayBanner +# Hook displayBanner -## Informations +## Information {{% notice tip %}} **Very top of pages:** @@ -24,13 +25,13 @@ Use this hook for banners on top of every pages Hook locations: - frontoffice -Hook types: - - smarty +Hook type: + - display Located in: - - themes/classic/templates/_partials/header.tpl + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/_partials/header.tpl](themes/classic/templates/_partials/header.tpl) -## Hook call with parameters +## Hook call in codebase ```php {hook h='displayBanner'} diff --git a/modules/concepts/hooks/list-of-hooks/displayBeforeBodyClosingTag.md b/modules/concepts/hooks/list-of-hooks/displayBeforeBodyClosingTag.md index a95430a5d6..fa15efdd0b 100644 --- a/modules/concepts/hooks/list-of-hooks/displayBeforeBodyClosingTag.md +++ b/modules/concepts/hooks/list-of-hooks/displayBeforeBodyClosingTag.md @@ -7,13 +7,14 @@ files: - themes/classic/templates/layouts/layout-both-columns.tpl locations: - frontoffice -types: - - smarty +type: + - display +hookAliases: --- -# Hook : displayBeforeBodyClosingTag +# Hook displayBeforeBodyClosingTag -## Informations +## Information {{% notice tip %}} **Very bottom of pages:** @@ -24,13 +25,13 @@ Use this hook for your modals or any content you want to load at the very end Hook locations: - frontoffice -Hook types: - - smarty +Hook type: + - display Located in: - - themes/classic/templates/layouts/layout-both-columns.tpl + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/layouts/layout-both-columns.tpl](themes/classic/templates/layouts/layout-both-columns.tpl) -## Hook call with parameters +## Hook call in codebase ```php {hook h='displayBeforeBodyClosingTag'} diff --git a/modules/concepts/hooks/list-of-hooks/displayBeforeCarrier.md b/modules/concepts/hooks/list-of-hooks/displayBeforeCarrier.md index b2be298ffa..7ee4bf0597 100644 --- a/modules/concepts/hooks/list-of-hooks/displayBeforeCarrier.md +++ b/modules/concepts/hooks/list-of-hooks/displayBeforeCarrier.md @@ -7,13 +7,20 @@ files: - classes/checkout/CheckoutDeliveryStep.php locations: - frontoffice -types: - - legacy +type: + - display +hookAliases: + - beforeCarrier --- -# Hook : displayBeforeCarrier +# Hook displayBeforeCarrier -## Informations +Aliases: + - beforeCarrier + + + +## Information {{% notice tip %}} **Before carriers list:** @@ -24,14 +31,61 @@ This hook is displayed before the carrier list in Front Office Hook locations: - frontoffice -Hook types: - - legacy +Hook type: + - display Located in: - - classes/checkout/CheckoutDeliveryStep.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/checkout/CheckoutDeliveryStep.php](classes/checkout/CheckoutDeliveryStep.php) + +## Parameters details + +```php + array( + array( + 'name' => (string) Name, + 'img' => (string) Image URL, + 'delay' => (string) Delay text, + 'price' => (float) Total price with tax, + 'price_tax_exc' => (float) Total price without tax, + 'id_carrier' => (int) intified option delivery identifier, + 'id_module' => (int) Module ID + )), + 'checked' => (int) intified selected carriers, + 'delivery_option_list' => array(array( + 0 => array( // First address + '12,' => array( // First delivery option available for this address + carrier_list => array( + 12 => array( // First carrier for this option + 'instance' => Carrier Object, + 'logo' => , + 'price_with_tax' => 12.4, // Example + 'price_without_tax' => 12.4, // Example + 'package_list' => array( + 1, // Example + 3, // Example + ), + ), + ), + is_best_grade => true, // Does this option have the biggest grade (quick shipping) for this shipping address + is_best_price => true, // Does this option have the lower price for this shipping address + unique_carrier => true, // Does this option use a unique carrier + total_price_with_tax => 12.5, + total_price_without_tax => 12.5, + position => 5, // Average of the carrier position + ), + ), + )), + 'delivery_option' => array( + '' => Delivery option, + ... + ) + ); +``` -## Hook call with parameters +## Hook call in codebase ```php -Hook::exec('displayBeforeCarrier', ['cart' => $this->getCheckoutSession()->getCart()]), +Hook::exec('displayBeforeCarrier', ['cart' => $this->getCheckoutSession()->getCart()]) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/displayCMSDisputeInformation.md b/modules/concepts/hooks/list-of-hooks/displayCMSDisputeInformation.md index 01150b5323..4d39d316ad 100644 --- a/modules/concepts/hooks/list-of-hooks/displayCMSDisputeInformation.md +++ b/modules/concepts/hooks/list-of-hooks/displayCMSDisputeInformation.md @@ -7,24 +7,25 @@ files: - themes/classic/templates/cms/page.tpl locations: - frontoffice -types: - - smarty +type: + - display +hookAliases: --- -# Hook : displayCMSDisputeInformation +# Hook displayCMSDisputeInformation -## Informations +## Information Hook locations: - frontoffice -Hook types: - - smarty +Hook type: + - display Located in: - - themes/classic/templates/cms/page.tpl + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/cms/page.tpl](themes/classic/templates/cms/page.tpl) -## Hook call with parameters +## Hook call in codebase ```php {hook h='displayCMSDisputeInformation'} diff --git a/modules/concepts/hooks/list-of-hooks/displayCMSPrintButton.md b/modules/concepts/hooks/list-of-hooks/displayCMSPrintButton.md index 8ed6e27cad..4674911a04 100644 --- a/modules/concepts/hooks/list-of-hooks/displayCMSPrintButton.md +++ b/modules/concepts/hooks/list-of-hooks/displayCMSPrintButton.md @@ -7,24 +7,25 @@ files: - themes/classic/templates/cms/page.tpl locations: - frontoffice -types: - - smarty +type: + - display +hookAliases: --- -# Hook : displayCMSPrintButton +# Hook displayCMSPrintButton -## Informations +## Information Hook locations: - frontoffice -Hook types: - - smarty +Hook type: + - display Located in: - - themes/classic/templates/cms/page.tpl + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/cms/page.tpl](themes/classic/templates/cms/page.tpl) -## Hook call with parameters +## Hook call in codebase ```php {hook h='displayCMSPrintButton'} diff --git a/modules/concepts/hooks/list-of-hooks/displayCarrierExtraContent.md b/modules/concepts/hooks/list-of-hooks/displayCarrierExtraContent.md index bb410c4522..e71f6b0872 100644 --- a/modules/concepts/hooks/list-of-hooks/displayCarrierExtraContent.md +++ b/modules/concepts/hooks/list-of-hooks/displayCarrierExtraContent.md @@ -7,13 +7,14 @@ files: - classes/checkout/DeliveryOptionsFinder.php locations: - frontoffice -types: - - legacy +type: + - display +hookAliases: --- -# Hook : displayCarrierExtraContent +# Hook displayCarrierExtraContent -## Informations +## Information {{% notice tip %}} **Display additional content for a carrier (e.g pickup points):** @@ -24,14 +25,14 @@ This hook calls only the module related to the carrier, in order to add options Hook locations: - frontoffice -Hook types: - - legacy +Hook type: + - display Located in: - - classes/checkout/DeliveryOptionsFinder.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/checkout/DeliveryOptionsFinder.php](classes/checkout/DeliveryOptionsFinder.php) -## Hook call with parameters +## Hook call in codebase ```php -Hook::exec('displayCarrierExtraContent', ['carrier' => $carrier], $moduleId); +Hook::exec('displayCarrierExtraContent', ['carrier' => $carrier], $moduleId) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/displayCartExtraProductActions.md b/modules/concepts/hooks/list-of-hooks/displayCartExtraProductActions.md index 8118118920..9598162603 100644 --- a/modules/concepts/hooks/list-of-hooks/displayCartExtraProductActions.md +++ b/modules/concepts/hooks/list-of-hooks/displayCartExtraProductActions.md @@ -7,13 +7,14 @@ files: - themes/classic/templates/checkout/_partials/cart-detailed-product-line.tpl locations: - frontoffice -types: - - smarty +type: + - action +hookAliases: --- -# Hook : displayCartExtraProductActions +# Hook displayCartExtraProductActions -## Informations +## Information {{% notice tip %}} **Extra buttons in shopping cart:** @@ -24,13 +25,13 @@ This hook adds extra buttons to the product lines, in the shopping cart Hook locations: - frontoffice -Hook types: - - smarty +Hook type: + - action Located in: - - themes/classic/templates/checkout/_partials/cart-detailed-product-line.tpl + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/checkout/_partials/cart-detailed-product-line.tpl](themes/classic/templates/checkout/_partials/cart-detailed-product-line.tpl) -## Hook call with parameters +## Hook call in codebase ```php {hook h='displayCartExtraProductActions' product=$product} diff --git a/modules/concepts/hooks/list-of-hooks/displayCartModalContent.md b/modules/concepts/hooks/list-of-hooks/displayCartModalContent.md index 7242b0a58d..5a67b621a9 100644 --- a/modules/concepts/hooks/list-of-hooks/displayCartModalContent.md +++ b/modules/concepts/hooks/list-of-hooks/displayCartModalContent.md @@ -7,13 +7,14 @@ files: - themes/classic/modules/ps_shoppingcart/modal.tpl locations: - frontoffice -types: - - smarty +type: + - display +hookAliases: --- -# Hook : displayCartModalContent +# Hook displayCartModalContent -## Informations +## Information {{% notice tip %}} **Content of Add-to-cart modal:** @@ -24,13 +25,13 @@ This hook displays content in the middle of the window that appears after adding Hook locations: - frontoffice -Hook types: - - smarty +Hook type: + - display Located in: - - themes/classic/modules/ps_shoppingcart/modal.tpl + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/modules/ps_shoppingcart/modal.tpl](themes/classic/modules/ps_shoppingcart/modal.tpl) -## Hook call with parameters +## Hook call in codebase ```php {hook h='displayCartModalContent' product=$product} diff --git a/modules/concepts/hooks/list-of-hooks/displayCartModalFooter.md b/modules/concepts/hooks/list-of-hooks/displayCartModalFooter.md index f5621d6c7b..a9b360700c 100644 --- a/modules/concepts/hooks/list-of-hooks/displayCartModalFooter.md +++ b/modules/concepts/hooks/list-of-hooks/displayCartModalFooter.md @@ -7,13 +7,14 @@ files: - themes/classic/modules/ps_shoppingcart/modal.tpl locations: - frontoffice -types: - - smarty +type: + - display +hookAliases: --- -# Hook : displayCartModalFooter +# Hook displayCartModalFooter -## Informations +## Information {{% notice tip %}} **Bottom of Add-to-cart modal:** @@ -24,13 +25,13 @@ This hook displays content in the bottom of window that appears after adding pro Hook locations: - frontoffice -Hook types: - - smarty +Hook type: + - display Located in: - - themes/classic/modules/ps_shoppingcart/modal.tpl + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/modules/ps_shoppingcart/modal.tpl](themes/classic/modules/ps_shoppingcart/modal.tpl) -## Hook call with parameters +## Hook call in codebase ```php {hook h='displayCartModalFooter' product=$product} diff --git a/modules/concepts/hooks/list-of-hooks/displayCheckoutBeforeConfirmation.md b/modules/concepts/hooks/list-of-hooks/displayCheckoutBeforeConfirmation.md index 0f8f0bc084..1d69cdc3af 100644 --- a/modules/concepts/hooks/list-of-hooks/displayCheckoutBeforeConfirmation.md +++ b/modules/concepts/hooks/list-of-hooks/displayCheckoutBeforeConfirmation.md @@ -7,13 +7,14 @@ files: - themes/classic/templates/checkout/_partials/steps/payment.tpl locations: - frontoffice -types: - - smarty +type: + - display +hookAliases: --- -# Hook : displayCheckoutBeforeConfirmation +# Hook displayCheckoutBeforeConfirmation -## Informations +## Information {{% notice tip %}} **Show custom content before checkout confirmation:** @@ -24,13 +25,13 @@ This hook allows you to display custom content at the end of checkout process Hook locations: - frontoffice -Hook types: - - smarty +Hook type: + - display Located in: - - themes/classic/templates/checkout/_partials/steps/payment.tpl + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/checkout/_partials/steps/payment.tpl](themes/classic/templates/checkout/_partials/steps/payment.tpl) -## Hook call with parameters +## Hook call in codebase ```php {hook h='displayCheckoutBeforeConfirmation'} diff --git a/modules/concepts/hooks/list-of-hooks/displayCheckoutSubtotalDetails.md b/modules/concepts/hooks/list-of-hooks/displayCheckoutSubtotalDetails.md index fcf838de63..b71af139d9 100644 --- a/modules/concepts/hooks/list-of-hooks/displayCheckoutSubtotalDetails.md +++ b/modules/concepts/hooks/list-of-hooks/displayCheckoutSubtotalDetails.md @@ -7,24 +7,25 @@ files: - themes/classic/templates/checkout/_partials/cart-detailed-totals.tpl locations: - frontoffice -types: - - smarty +type: + - display +hookAliases: --- -# Hook : displayCheckoutSubtotalDetails +# Hook displayCheckoutSubtotalDetails -## Informations +## Information Hook locations: - frontoffice -Hook types: - - smarty +Hook type: + - display Located in: - - themes/classic/templates/checkout/_partials/cart-detailed-totals.tpl + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/checkout/_partials/cart-detailed-totals.tpl](themes/classic/templates/checkout/_partials/cart-detailed-totals.tpl) -## Hook call with parameters +## Hook call in codebase ```php {hook h='displayCheckoutSubtotalDetails' subtotal=$subtotal} diff --git a/modules/concepts/hooks/list-of-hooks/displayCheckoutSummaryTop.md b/modules/concepts/hooks/list-of-hooks/displayCheckoutSummaryTop.md index 488d84afaf..5e808f8233 100644 --- a/modules/concepts/hooks/list-of-hooks/displayCheckoutSummaryTop.md +++ b/modules/concepts/hooks/list-of-hooks/displayCheckoutSummaryTop.md @@ -7,13 +7,14 @@ files: - themes/classic/templates/checkout/_partials/cart-summary-top.tpl locations: - frontoffice -types: - - smarty +type: + - display +hookAliases: --- -# Hook : displayCheckoutSummaryTop +# Hook displayCheckoutSummaryTop -## Informations +## Information {{% notice tip %}} **Cart summary top:** @@ -24,13 +25,13 @@ This hook allows you to display new elements in top of cart summary Hook locations: - frontoffice -Hook types: - - smarty +Hook type: + - display Located in: - - themes/classic/templates/checkout/_partials/cart-summary-top.tpl + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/checkout/_partials/cart-summary-top.tpl](themes/classic/templates/checkout/_partials/cart-summary-top.tpl) -## Hook call with parameters +## Hook call in codebase ```php {hook h='displayCheckoutSummaryTop'} diff --git a/modules/concepts/hooks/list-of-hooks/displayCrossSellingShoppingCart.md b/modules/concepts/hooks/list-of-hooks/displayCrossSellingShoppingCart.md index 341f918c5b..c4b7fd75bc 100644 --- a/modules/concepts/hooks/list-of-hooks/displayCrossSellingShoppingCart.md +++ b/modules/concepts/hooks/list-of-hooks/displayCrossSellingShoppingCart.md @@ -7,24 +7,25 @@ files: - themes/classic/templates/checkout/cart.tpl locations: - frontoffice -types: - - smarty +type: + - display +hookAliases: --- -# Hook : displayCrossSellingShoppingCart +# Hook displayCrossSellingShoppingCart -## Informations +## Information Hook locations: - frontoffice -Hook types: - - smarty +Hook type: + - display Located in: - - themes/classic/templates/checkout/cart.tpl + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/checkout/cart.tpl](themes/classic/templates/checkout/cart.tpl) -## Hook call with parameters +## Hook call in codebase ```php {hook h='displayCrossSellingShoppingCart'} diff --git a/modules/concepts/hooks/list-of-hooks/displayCustomerAccount.md b/modules/concepts/hooks/list-of-hooks/displayCustomerAccount.md index 50aeda2c72..ae1af7e55c 100644 --- a/modules/concepts/hooks/list-of-hooks/displayCustomerAccount.md +++ b/modules/concepts/hooks/list-of-hooks/displayCustomerAccount.md @@ -7,13 +7,20 @@ files: - themes/classic/templates/customer/my-account.tpl locations: - frontoffice -types: - - smarty +type: + - display +hookAliases: + - customerAccount --- -# Hook : displayCustomerAccount +# Hook displayCustomerAccount -## Informations +Aliases: + - customerAccount + + + +## Information {{% notice tip %}} **Customer account displayed in Front Office:** @@ -24,13 +31,13 @@ This hook displays new elements on the customer account page Hook locations: - frontoffice -Hook types: - - smarty +Hook type: + - display Located in: - - themes/classic/templates/customer/my-account.tpl + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/customer/my-account.tpl](themes/classic/templates/customer/my-account.tpl) -## Hook call with parameters +## Hook call in codebase ```php {hook h='displayCustomerAccount'} diff --git a/modules/concepts/hooks/list-of-hooks/displayCustomerAccountForm.md b/modules/concepts/hooks/list-of-hooks/displayCustomerAccountForm.md index 7b1ba8ab8b..beb729dcb6 100644 --- a/modules/concepts/hooks/list-of-hooks/displayCustomerAccountForm.md +++ b/modules/concepts/hooks/list-of-hooks/displayCustomerAccountForm.md @@ -7,13 +7,20 @@ files: - classes/form/CustomerForm.php locations: - frontoffice -types: - - legacy +type: + - display +hookAliases: + - createAccountForm --- -# Hook : displayCustomerAccountForm +# Hook displayCustomerAccountForm -## Informations +Aliases: + - createAccountForm + + + +## Information {{% notice tip %}} **Customer account creation form:** @@ -24,14 +31,14 @@ This hook displays some information on the form to create a customer account Hook locations: - frontoffice -Hook types: - - legacy +Hook type: + - display Located in: - - classes/form/CustomerForm.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/form/CustomerForm.php](classes/form/CustomerForm.php) -## Hook call with parameters +## Hook call in codebase ```php -Hook::exec('displayCustomerAccountForm'), +Hook::exec('displayCustomerAccountForm') ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/displayCustomerAccountFormTop.md b/modules/concepts/hooks/list-of-hooks/displayCustomerAccountFormTop.md index b8adfcd414..78f1c45cc0 100644 --- a/modules/concepts/hooks/list-of-hooks/displayCustomerAccountFormTop.md +++ b/modules/concepts/hooks/list-of-hooks/displayCustomerAccountFormTop.md @@ -7,13 +7,20 @@ files: - controllers/front/RegistrationController.php locations: - frontoffice -types: - - legacy +type: + - display +hookAliases: + - createAccountTop --- -# Hook : displayCustomerAccountFormTop +# Hook displayCustomerAccountFormTop -## Informations +Aliases: + - createAccountTop + + + +## Information {{% notice tip %}} **Block above the form for create an account:** @@ -24,14 +31,14 @@ This hook is displayed above the customer's account creation form Hook locations: - frontoffice -Hook types: - - legacy +Hook type: + - display Located in: - - controllers/front/RegistrationController.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/front/RegistrationController.php](controllers/front/RegistrationController.php) -## Hook call with parameters +## Hook call in codebase ```php -Hook::exec('displayCustomerAccountFormTop'), +Hook::exec('displayCustomerAccountFormTop') ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/displayCustomerLoginFormAfter.md b/modules/concepts/hooks/list-of-hooks/displayCustomerLoginFormAfter.md index daa0e15964..53b213af8f 100644 --- a/modules/concepts/hooks/list-of-hooks/displayCustomerLoginFormAfter.md +++ b/modules/concepts/hooks/list-of-hooks/displayCustomerLoginFormAfter.md @@ -7,13 +7,14 @@ files: - themes/classic/templates/customer/authentication.tpl locations: - frontoffice -types: - - smarty +type: + - display +hookAliases: --- -# Hook : displayCustomerLoginFormAfter +# Hook displayCustomerLoginFormAfter -## Informations +## Information {{% notice tip %}} **Display elements after login form:** @@ -24,13 +25,13 @@ This hook displays new elements after the login form Hook locations: - frontoffice -Hook types: - - smarty +Hook type: + - display Located in: - - themes/classic/templates/customer/authentication.tpl + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/customer/authentication.tpl](themes/classic/templates/customer/authentication.tpl) -## Hook call with parameters +## Hook call in codebase ```php {hook h='displayCustomerLoginFormAfter'} diff --git a/modules/concepts/hooks/list-of-hooks/displayCustomization.md b/modules/concepts/hooks/list-of-hooks/displayCustomization.md index 9fbd5356c3..f78f01d33a 100644 --- a/modules/concepts/hooks/list-of-hooks/displayCustomization.md +++ b/modules/concepts/hooks/list-of-hooks/displayCustomization.md @@ -7,25 +7,26 @@ files: - classes/Product.php locations: - frontoffice -types: - - legacy +type: + - display +hookAliases: --- -# Hook : displayCustomization +# Hook displayCustomization -## Informations +## Information Hook locations: - frontoffice -Hook types: - - legacy +Hook type: + - display Located in: - - classes/Product.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Product.php](classes/Product.php) -## Hook call with parameters +## Hook call in codebase ```php -Hook::exec('displayCustomization', ['customization' => $row], (int) $row['id_module']); +Hook::exec('displayCustomization', ['customization' => $row], (int) $row['id_module']) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/displayDashboardToolbarIcons.md b/modules/concepts/hooks/list-of-hooks/displayDashboardToolbarIcons.md index 5236b1f1ad..2bcba6f8de 100644 --- a/modules/concepts/hooks/list-of-hooks/displayDashboardToolbarIcons.md +++ b/modules/concepts/hooks/list-of-hooks/displayDashboardToolbarIcons.md @@ -7,13 +7,14 @@ files: - src/PrestaShopBundle/Resources/views/Admin/Product/CatalogPage/Blocks/tools.html.twig locations: - backoffice -types: - - twig +type: + - display +hookAliases: --- -# Hook : displayDashboardToolbarIcons +# Hook displayDashboardToolbarIcons -## Informations +## Information {{% notice tip %}} **Display new elements in back office page with dashboard, on icons list:** @@ -24,13 +25,13 @@ This hook launches modules when the back office with dashboard is displayed Hook locations: - backoffice -Hook types: - - twig +Hook type: + - display Located in: - - src/PrestaShopBundle/Resources/views/Admin/Product/CatalogPage/Blocks/tools.html.twig + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Resources/views/Admin/Product/CatalogPage/Blocks/tools.html.twig](src/PrestaShopBundle/Resources/views/Admin/Product/CatalogPage/Blocks/tools.html.twig) -## Hook call with parameters +## Hook call in codebase ```php {{ renderhook('displayDashboardToolbarIcons', {}) }} diff --git a/modules/concepts/hooks/list-of-hooks/displayDashboardToolbarTopMenu.md b/modules/concepts/hooks/list-of-hooks/displayDashboardToolbarTopMenu.md index 51dfc2fda4..7a62d5b970 100644 --- a/modules/concepts/hooks/list-of-hooks/displayDashboardToolbarTopMenu.md +++ b/modules/concepts/hooks/list-of-hooks/displayDashboardToolbarTopMenu.md @@ -7,13 +7,14 @@ files: - admin784x07v4swfhm9fgvc0/themes/new-theme/template/page_header_toolbar.tpl locations: - frontoffice -types: - - smarty +type: + - display +hookAliases: --- -# Hook : displayDashboardToolbarTopMenu +# Hook displayDashboardToolbarTopMenu -## Informations +## Information {{% notice tip %}} **Display new elements in back office page with a dashboard, on top Menu:** @@ -24,13 +25,13 @@ This hook launches modules when a page with a dashboard is displayed Hook locations: - frontoffice -Hook types: - - smarty +Hook type: + - display Located in: - - admin784x07v4swfhm9fgvc0/themes/new-theme/template/page_header_toolbar.tpl + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/admin784x07v4swfhm9fgvc0/themes/new-theme/template/page_header_toolbar.tpl](admin784x07v4swfhm9fgvc0/themes/new-theme/template/page_header_toolbar.tpl) -## Hook call with parameters +## Hook call in codebase ```php {hook h='displayDashboardToolbarTopMenu'} diff --git a/modules/concepts/hooks/list-of-hooks/displayDashboardTop.md b/modules/concepts/hooks/list-of-hooks/displayDashboardTop.md index 806db695ca..3817d98d01 100644 --- a/modules/concepts/hooks/list-of-hooks/displayDashboardTop.md +++ b/modules/concepts/hooks/list-of-hooks/displayDashboardTop.md @@ -7,13 +7,14 @@ files: - admin784x07v4swfhm9fgvc0/themes/new-theme/template/page_header_toolbar.tpl locations: - frontoffice -types: - - smarty +type: + - display +hookAliases: --- -# Hook : displayDashboardTop +# Hook displayDashboardTop -## Informations +## Information {{% notice tip %}} **Dashboard Top:** @@ -24,13 +25,13 @@ Displays the content in the dashboard's top area Hook locations: - frontoffice -Hook types: - - smarty +Hook type: + - display Located in: - - admin784x07v4swfhm9fgvc0/themes/new-theme/template/page_header_toolbar.tpl + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/admin784x07v4swfhm9fgvc0/themes/new-theme/template/page_header_toolbar.tpl](admin784x07v4swfhm9fgvc0/themes/new-theme/template/page_header_toolbar.tpl) -## Hook call with parameters +## Hook call in codebase ```php {hook h='displayDashboardTop'} diff --git a/modules/concepts/hooks/list-of-hooks/displayEmptyModuleCategoryExtraMessage.md b/modules/concepts/hooks/list-of-hooks/displayEmptyModuleCategoryExtraMessage.md index 5f43d50463..e3c46bd8a7 100644 --- a/modules/concepts/hooks/list-of-hooks/displayEmptyModuleCategoryExtraMessage.md +++ b/modules/concepts/hooks/list-of-hooks/displayEmptyModuleCategoryExtraMessage.md @@ -7,13 +7,14 @@ files: - src/PrestaShopBundle/Resources/views/Admin/Module/Includes/grid_manage_empty.html.twig locations: - backoffice -types: - - twig +type: + - display +hookAliases: --- -# Hook : displayEmptyModuleCategoryExtraMessage +# Hook displayEmptyModuleCategoryExtraMessage -## Informations +## Information {{% notice tip %}} **Extra message to display for an empty modules category:** @@ -24,13 +25,21 @@ This hook allows to add an extra message to display in the Module manager page w Hook locations: - backoffice -Hook types: - - twig +Hook type: + - display Located in: - - src/PrestaShopBundle/Resources/views/Admin/Module/Includes/grid_manage_empty.html.twig + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Resources/views/Admin/Module/Includes/grid_manage_empty.html.twig](src/PrestaShopBundle/Resources/views/Admin/Module/Includes/grid_manage_empty.html.twig) + +## Parameters details + +```html.twig + { + 'category_name': (string) categoryName + } +``` -## Hook call with parameters +## Hook call in codebase ```php {{ renderhook('displayEmptyModuleCategoryExtraMessage', {'category_name': category.name}) }} diff --git a/modules/concepts/hooks/list-of-hooks/displayExpressCheckout.md b/modules/concepts/hooks/list-of-hooks/displayExpressCheckout.md index eb19926e80..d811e551ee 100644 --- a/modules/concepts/hooks/list-of-hooks/displayExpressCheckout.md +++ b/modules/concepts/hooks/list-of-hooks/displayExpressCheckout.md @@ -7,24 +7,25 @@ files: - themes/classic/templates/checkout/_partials/cart-detailed-actions.tpl locations: - frontoffice -types: - - smarty +type: + - display +hookAliases: --- -# Hook : displayExpressCheckout +# Hook displayExpressCheckout -## Informations +## Information Hook locations: - frontoffice -Hook types: - - smarty +Hook type: + - display Located in: - - themes/classic/templates/checkout/_partials/cart-detailed-actions.tpl + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/checkout/_partials/cart-detailed-actions.tpl](themes/classic/templates/checkout/_partials/cart-detailed-actions.tpl) -## Hook call with parameters +## Hook call in codebase ```php {hook h='displayExpressCheckout'} diff --git a/modules/concepts/hooks/list-of-hooks/displayFeatureForm.md b/modules/concepts/hooks/list-of-hooks/displayFeatureForm.md index dfe9052609..1899328705 100644 --- a/modules/concepts/hooks/list-of-hooks/displayFeatureForm.md +++ b/modules/concepts/hooks/list-of-hooks/displayFeatureForm.md @@ -7,13 +7,20 @@ files: - src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Features/Blocks/form.html.twig locations: - backoffice -types: - - twig +type: + - display +hookAliases: + - featureForm --- -# Hook : displayFeatureForm +# Hook displayFeatureForm -## Informations +Aliases: + - featureForm + + + +## Information {{% notice tip %}} **Add fields to the form 'feature':** @@ -24,13 +31,13 @@ This hook adds fields to the form 'feature' Hook locations: - backoffice -Hook types: - - twig +Hook type: + - display Located in: - - src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Features/Blocks/form.html.twig + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Features/Blocks/form.html.twig](src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Features/Blocks/form.html.twig) -## Hook call with parameters +## Hook call in codebase ```php {{ renderhook('displayFeatureForm', {'id_feature': featureId}) }} diff --git a/modules/concepts/hooks/list-of-hooks/displayFeaturePostProcess.md b/modules/concepts/hooks/list-of-hooks/displayFeaturePostProcess.md new file mode 100644 index 0000000000..d988fc71d5 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/displayFeaturePostProcess.md @@ -0,0 +1,47 @@ +--- +menuTitle: displayFeaturePostProcess +Title: displayFeaturePostProcess +hidden: true +hookTitle: On post-process in admin feature +files: + - controllers/admin/AdminFeaturesController.php +locations: + - backoffice +type: + - display +hookAliases: + - postProcessFeature +--- + +# Hook displayFeaturePostProcess + +Aliases: + - postProcessFeature + + + +## Information + +{{% notice tip %}} +**On post-process in admin feature:** + +This hook is called on post-process in admin feature +{{% /notice %}} + +Hook locations: + - backoffice + +Hook type: + - display + +Located in: + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/admin/AdminFeaturesController.php](controllers/admin/AdminFeaturesController.php) + +## Hook call in codebase + +```php +Hook::exec( + 'displayFeaturePostProcess', + ['errors' => &$this->errors] + ) +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/displayFeatureValuePostProcess.md b/modules/concepts/hooks/list-of-hooks/displayFeatureValuePostProcess.md new file mode 100644 index 0000000000..3fd3eba1af --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/displayFeatureValuePostProcess.md @@ -0,0 +1,47 @@ +--- +menuTitle: displayFeatureValuePostProcess +Title: displayFeatureValuePostProcess +hidden: true +hookTitle: On post-process in admin feature value +files: + - controllers/admin/AdminFeaturesController.php +locations: + - backoffice +type: + - display +hookAliases: + - postProcessFeatureValue +--- + +# Hook displayFeatureValuePostProcess + +Aliases: + - postProcessFeatureValue + + + +## Information + +{{% notice tip %}} +**On post-process in admin feature value:** + +This hook is called on post-process in admin feature value +{{% /notice %}} + +Hook locations: + - backoffice + +Hook type: + - display + +Located in: + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/admin/AdminFeaturesController.php](controllers/admin/AdminFeaturesController.php) + +## Hook call in codebase + +```php +Hook::exec( + 'displayFeatureValuePostProcess', + ['errors' => &$this->errors] + ) +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/displayFooter.md b/modules/concepts/hooks/list-of-hooks/displayFooter.md index 2971cc303e..69ef8e737a 100644 --- a/modules/concepts/hooks/list-of-hooks/displayFooter.md +++ b/modules/concepts/hooks/list-of-hooks/displayFooter.md @@ -7,13 +7,20 @@ files: - themes/classic/templates/_partials/footer.tpl locations: - frontoffice -types: - - smarty +type: + - display +hookAliases: + - footer --- -# Hook : displayFooter +# Hook displayFooter -## Informations +Aliases: + - footer + + + +## Information {{% notice tip %}} **Footer:** @@ -24,13 +31,13 @@ This hook displays new blocks in the footer Hook locations: - frontoffice -Hook types: - - smarty +Hook type: + - display Located in: - - themes/classic/templates/_partials/footer.tpl + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/_partials/footer.tpl](themes/classic/templates/_partials/footer.tpl) -## Hook call with parameters +## Hook call in codebase ```php {hook h='displayFooter'} diff --git a/modules/concepts/hooks/list-of-hooks/displayFooterAfter.md b/modules/concepts/hooks/list-of-hooks/displayFooterAfter.md index d2d5a7a1c9..5bce1bf4ed 100644 --- a/modules/concepts/hooks/list-of-hooks/displayFooterAfter.md +++ b/modules/concepts/hooks/list-of-hooks/displayFooterAfter.md @@ -7,24 +7,25 @@ files: - themes/classic/templates/_partials/footer.tpl locations: - frontoffice -types: - - smarty +type: + - display +hookAliases: --- -# Hook : displayFooterAfter +# Hook displayFooterAfter -## Informations +## Information Hook locations: - frontoffice -Hook types: - - smarty +Hook type: + - display Located in: - - themes/classic/templates/_partials/footer.tpl + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/_partials/footer.tpl](themes/classic/templates/_partials/footer.tpl) -## Hook call with parameters +## Hook call in codebase ```php {hook h='displayFooterAfter'} diff --git a/modules/concepts/hooks/list-of-hooks/displayFooterBefore.md b/modules/concepts/hooks/list-of-hooks/displayFooterBefore.md index 7c7e38a4c8..cca6a37080 100644 --- a/modules/concepts/hooks/list-of-hooks/displayFooterBefore.md +++ b/modules/concepts/hooks/list-of-hooks/displayFooterBefore.md @@ -7,24 +7,25 @@ files: - themes/classic/templates/_partials/footer.tpl locations: - frontoffice -types: - - smarty +type: + - display +hookAliases: --- -# Hook : displayFooterBefore +# Hook displayFooterBefore -## Informations +## Information Hook locations: - frontoffice -Hook types: - - smarty +Hook type: + - display Located in: - - themes/classic/templates/_partials/footer.tpl + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/_partials/footer.tpl](themes/classic/templates/_partials/footer.tpl) -## Hook call with parameters +## Hook call in codebase ```php {hook h='displayFooterBefore'} diff --git a/modules/concepts/hooks/list-of-hooks/displayFooterProduct.md b/modules/concepts/hooks/list-of-hooks/displayFooterProduct.md index 4b49d61bf6..be4500a23e 100644 --- a/modules/concepts/hooks/list-of-hooks/displayFooterProduct.md +++ b/modules/concepts/hooks/list-of-hooks/displayFooterProduct.md @@ -7,13 +7,20 @@ files: - themes/classic/templates/catalog/product.tpl locations: - frontoffice -types: - - smarty +type: + - display +hookAliases: + - productfooter --- -# Hook : displayFooterProduct +# Hook displayFooterProduct -## Informations +Aliases: + - productfooter + + + +## Information {{% notice tip %}} **Product footer:** @@ -24,13 +31,13 @@ This hook adds new blocks under the product's description Hook locations: - frontoffice -Hook types: - - smarty +Hook type: + - display Located in: - - themes/classic/templates/catalog/product.tpl + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/catalog/product.tpl](themes/classic/templates/catalog/product.tpl) -## Hook call with parameters +## Hook call in codebase ```php {hook h='displayFooterProduct' product=$product category=$category} diff --git a/modules/concepts/hooks/list-of-hooks/displayGDPRConsent.md b/modules/concepts/hooks/list-of-hooks/displayGDPRConsent.md index f067f453bf..1ba7c07d70 100644 --- a/modules/concepts/hooks/list-of-hooks/displayGDPRConsent.md +++ b/modules/concepts/hooks/list-of-hooks/displayGDPRConsent.md @@ -7,24 +7,25 @@ files: - themes/classic/modules/ps_emailsubscription/views/templates/hook/ps_emailsubscription.tpl locations: - frontoffice -types: - - smarty +type: + - display +hookAliases: --- -# Hook : displayGDPRConsent +# Hook displayGDPRConsent -## Informations +## Information Hook locations: - frontoffice -Hook types: - - smarty +Hook type: + - display Located in: - - themes/classic/modules/ps_emailsubscription/views/templates/hook/ps_emailsubscription.tpl + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/modules/ps_emailsubscription/views/templates/hook/ps_emailsubscription.tpl](themes/classic/modules/ps_emailsubscription/views/templates/hook/ps_emailsubscription.tpl) -## Hook call with parameters +## Hook call in codebase ```php {hook h='displayGDPRConsent' id_module=$id_module} diff --git a/modules/concepts/hooks/list-of-hooks/displayHeader.md b/modules/concepts/hooks/list-of-hooks/displayHeader.md index b1ff3eb305..b2abc7f382 100644 --- a/modules/concepts/hooks/list-of-hooks/displayHeader.md +++ b/modules/concepts/hooks/list-of-hooks/displayHeader.md @@ -7,13 +7,20 @@ files: - classes/controller/FrontController.php locations: - frontoffice -types: - - legacy +type: + - display +hookAliases: + - Header --- -# Hook : displayHeader +# Hook displayHeader -## Informations +Aliases: + - Header + + + +## Information {{% notice tip %}} **Pages html head section:** @@ -24,14 +31,14 @@ This hook adds additional elements in the head section of your pages (head secti Hook locations: - frontoffice -Hook types: - - legacy +Hook type: + - display Located in: - - classes/controller/FrontController.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/FrontController.php](classes/controller/FrontController.php) -## Hook call with parameters +## Hook call in codebase ```php -Hook::exec('displayHeader'), +Hook::exec('displayHeader') ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/displayHome.md b/modules/concepts/hooks/list-of-hooks/displayHome.md index 3b3e7ef481..4928640e87 100644 --- a/modules/concepts/hooks/list-of-hooks/displayHome.md +++ b/modules/concepts/hooks/list-of-hooks/displayHome.md @@ -7,13 +7,20 @@ files: - controllers/front/IndexController.php locations: - frontoffice -types: - - legacy +type: + - display +hookAliases: + - home --- -# Hook : displayHome +# Hook displayHome -## Informations +Aliases: + - home + + + +## Information {{% notice tip %}} **Homepage content:** @@ -24,14 +31,14 @@ This hook displays new elements on the homepage Hook locations: - frontoffice -Hook types: - - legacy +Hook type: + - display Located in: - - controllers/front/IndexController.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/front/IndexController.php](controllers/front/IndexController.php) -## Hook call with parameters +## Hook call in codebase ```php -Hook::exec('displayHome'), +Hook::exec('displayHome') ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/displayInvoiceLegalFreeText.md b/modules/concepts/hooks/list-of-hooks/displayInvoiceLegalFreeText.md index 5ec044a739..7046ed177b 100644 --- a/modules/concepts/hooks/list-of-hooks/displayInvoiceLegalFreeText.md +++ b/modules/concepts/hooks/list-of-hooks/displayInvoiceLegalFreeText.md @@ -7,13 +7,14 @@ files: - classes/pdf/HTMLTemplateInvoice.php locations: - frontoffice -types: - - legacy +type: + - display +hookAliases: --- -# Hook : displayInvoiceLegalFreeText +# Hook displayInvoiceLegalFreeText -## Informations +## Information {{% notice tip %}} **PDF Invoice - Legal Free Text:** @@ -24,14 +25,14 @@ This hook allows you to modify the legal free text on PDF invoices Hook locations: - frontoffice -Hook types: - - legacy +Hook type: + - display Located in: - - classes/pdf/HTMLTemplateInvoice.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/pdf/HTMLTemplateInvoice.php](classes/pdf/HTMLTemplateInvoice.php) -## Hook call with parameters +## Hook call in codebase ```php -Hook::exec('displayInvoiceLegalFreeText', ['order' => $this->order]); +Hook::exec('displayInvoiceLegalFreeText', ['order' => $this->order]) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/displayLeftColumnProduct.md b/modules/concepts/hooks/list-of-hooks/displayLeftColumnProduct.md index f89a8feb60..dcb22ffcbe 100644 --- a/modules/concepts/hooks/list-of-hooks/displayLeftColumnProduct.md +++ b/modules/concepts/hooks/list-of-hooks/displayLeftColumnProduct.md @@ -7,13 +7,20 @@ files: - themes/classic/templates/layouts/layout-both-columns.tpl locations: - frontoffice -types: - - smarty +type: + - display +hookAliases: + - extraLeft --- -# Hook : displayLeftColumnProduct +# Hook displayLeftColumnProduct -## Informations +Aliases: + - extraLeft + + + +## Information {{% notice tip %}} **New elements on the product page (left column):** @@ -24,13 +31,13 @@ This hook displays new elements in the left-hand column of the product page Hook locations: - frontoffice -Hook types: - - smarty +Hook type: + - display Located in: - - themes/classic/templates/layouts/layout-both-columns.tpl + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/layouts/layout-both-columns.tpl](themes/classic/templates/layouts/layout-both-columns.tpl) -## Hook call with parameters +## Hook call in codebase ```php {hook h='displayLeftColumnProduct' product=$product category=$category} diff --git a/modules/concepts/hooks/list-of-hooks/displayMaintenance.md b/modules/concepts/hooks/list-of-hooks/displayMaintenance.md index bdcd98a94d..6076cdcf0a 100644 --- a/modules/concepts/hooks/list-of-hooks/displayMaintenance.md +++ b/modules/concepts/hooks/list-of-hooks/displayMaintenance.md @@ -7,13 +7,14 @@ files: - classes/controller/FrontController.php locations: - frontoffice -types: - - legacy +type: + - display +hookAliases: --- -# Hook : displayMaintenance +# Hook displayMaintenance -## Informations +## Information {{% notice tip %}} **Maintenance Page:** @@ -24,14 +25,14 @@ This hook displays new elements on the maintenance page Hook locations: - frontoffice -Hook types: - - legacy +Hook type: + - display Located in: - - classes/controller/FrontController.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/FrontController.php](classes/controller/FrontController.php) -## Hook call with parameters +## Hook call in codebase ```php -Hook::exec('displayMaintenance', []), +Hook::exec('displayMaintenance', []) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/displayMyAccountBlock.md b/modules/concepts/hooks/list-of-hooks/displayMyAccountBlock.md index be77a98239..6811192718 100644 --- a/modules/concepts/hooks/list-of-hooks/displayMyAccountBlock.md +++ b/modules/concepts/hooks/list-of-hooks/displayMyAccountBlock.md @@ -7,13 +7,20 @@ files: - themes/classic/modules/ps_customeraccountlinks/ps_customeraccountlinks.tpl locations: - frontoffice -types: - - smarty +type: + - display +hookAliases: + - myAccountBlock --- -# Hook : displayMyAccountBlock +# Hook displayMyAccountBlock -## Informations +Aliases: + - myAccountBlock + + + +## Information {{% notice tip %}} **My account block:** @@ -24,13 +31,13 @@ This hook displays extra information within the 'my account' block" Hook locations: - frontoffice -Hook types: - - smarty +Hook type: + - display Located in: - - themes/classic/modules/ps_customeraccountlinks/ps_customeraccountlinks.tpl + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/modules/ps_customeraccountlinks/ps_customeraccountlinks.tpl](themes/classic/modules/ps_customeraccountlinks/ps_customeraccountlinks.tpl) -## Hook call with parameters +## Hook call in codebase ```php {hook h='displayMyAccountBlock'} diff --git a/modules/concepts/hooks/list-of-hooks/displayNav1.md b/modules/concepts/hooks/list-of-hooks/displayNav1.md index 04a2606162..ffe3c40c51 100644 --- a/modules/concepts/hooks/list-of-hooks/displayNav1.md +++ b/modules/concepts/hooks/list-of-hooks/displayNav1.md @@ -7,24 +7,25 @@ files: - themes/classic/templates/checkout/_partials/header.tpl locations: - frontoffice -types: - - smarty +type: + - display +hookAliases: --- -# Hook : displayNav1 +# Hook displayNav1 -## Informations +## Information Hook locations: - frontoffice -Hook types: - - smarty +Hook type: + - display Located in: - - themes/classic/templates/checkout/_partials/header.tpl + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/checkout/_partials/header.tpl](themes/classic/templates/checkout/_partials/header.tpl) -## Hook call with parameters +## Hook call in codebase ```php {hook h='displayNav1'} diff --git a/modules/concepts/hooks/list-of-hooks/displayNav2.md b/modules/concepts/hooks/list-of-hooks/displayNav2.md index ade34a66db..7afef6b5db 100644 --- a/modules/concepts/hooks/list-of-hooks/displayNav2.md +++ b/modules/concepts/hooks/list-of-hooks/displayNav2.md @@ -7,24 +7,25 @@ files: - themes/classic/templates/checkout/_partials/header.tpl locations: - frontoffice -types: - - smarty +type: + - display +hookAliases: --- -# Hook : displayNav2 +# Hook displayNav2 -## Informations +## Information Hook locations: - frontoffice -Hook types: - - smarty +Hook type: + - display Located in: - - themes/classic/templates/checkout/_partials/header.tpl + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/checkout/_partials/header.tpl](themes/classic/templates/checkout/_partials/header.tpl) -## Hook call with parameters +## Hook call in codebase ```php {hook h='displayNav2'} diff --git a/modules/concepts/hooks/list-of-hooks/displayNavFullWidth.md b/modules/concepts/hooks/list-of-hooks/displayNavFullWidth.md index 0b513cb165..d3d90ed4c3 100644 --- a/modules/concepts/hooks/list-of-hooks/displayNavFullWidth.md +++ b/modules/concepts/hooks/list-of-hooks/displayNavFullWidth.md @@ -7,13 +7,14 @@ files: - themes/classic/templates/checkout/_partials/header.tpl locations: - frontoffice -types: - - smarty +type: + - display +hookAliases: --- -# Hook : displayNavFullWidth +# Hook displayNavFullWidth -## Informations +## Information {{% notice tip %}} **Navigation:** @@ -24,13 +25,13 @@ This hook displays full width navigation menu at the top of your pages Hook locations: - frontoffice -Hook types: - - smarty +Hook type: + - display Located in: - - themes/classic/templates/checkout/_partials/header.tpl + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/checkout/_partials/header.tpl](themes/classic/templates/checkout/_partials/header.tpl) -## Hook call with parameters +## Hook call in codebase ```php {hook h='displayNavFullWidth'} diff --git a/modules/concepts/hooks/list-of-hooks/displayNewsletterRegistration.md b/modules/concepts/hooks/list-of-hooks/displayNewsletterRegistration.md index dee9c4c657..7eb5252289 100644 --- a/modules/concepts/hooks/list-of-hooks/displayNewsletterRegistration.md +++ b/modules/concepts/hooks/list-of-hooks/displayNewsletterRegistration.md @@ -7,24 +7,25 @@ files: - themes/classic/modules/ps_emailsubscription/views/templates/hook/ps_emailsubscription.tpl locations: - frontoffice -types: - - smarty +type: + - display +hookAliases: --- -# Hook : displayNewsletterRegistration +# Hook displayNewsletterRegistration -## Informations +## Information Hook locations: - frontoffice -Hook types: - - smarty +Hook type: + - display Located in: - - themes/classic/modules/ps_emailsubscription/views/templates/hook/ps_emailsubscription.tpl + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/modules/ps_emailsubscription/views/templates/hook/ps_emailsubscription.tpl](themes/classic/modules/ps_emailsubscription/views/templates/hook/ps_emailsubscription.tpl) -## Hook call with parameters +## Hook call in codebase ```php {hook h='displayNewsletterRegistration'} diff --git a/modules/concepts/hooks/list-of-hooks/displayNotFound.md b/modules/concepts/hooks/list-of-hooks/displayNotFound.md index 9806553834..d32f09cdef 100644 --- a/modules/concepts/hooks/list-of-hooks/displayNotFound.md +++ b/modules/concepts/hooks/list-of-hooks/displayNotFound.md @@ -7,24 +7,25 @@ files: - themes/classic/templates/errors/not-found.tpl locations: - frontoffice -types: - - smarty +type: + - display +hookAliases: --- -# Hook : displayNotFound +# Hook displayNotFound -## Informations +## Information Hook locations: - frontoffice -Hook types: - - smarty +Hook type: + - display Located in: - - themes/classic/templates/errors/not-found.tpl + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/errors/not-found.tpl](themes/classic/templates/errors/not-found.tpl) -## Hook call with parameters +## Hook call in codebase ```php {hook h='displayNotFound'} diff --git a/modules/concepts/hooks/list-of-hooks/displayOrderConfirmation.md b/modules/concepts/hooks/list-of-hooks/displayOrderConfirmation.md index 5f1bd5378d..9aceeabdf3 100644 --- a/modules/concepts/hooks/list-of-hooks/displayOrderConfirmation.md +++ b/modules/concepts/hooks/list-of-hooks/displayOrderConfirmation.md @@ -7,13 +7,20 @@ files: - controllers/front/OrderConfirmationController.php locations: - frontoffice -types: - - legacy +type: + - display +hookAliases: + - orderConfirmation --- -# Hook : displayOrderConfirmation +# Hook displayOrderConfirmation -## Informations +Aliases: + - orderConfirmation + + + +## Information {{% notice tip %}} **Order confirmation page:** @@ -24,14 +31,23 @@ This hook is called within an order's confirmation page Hook locations: - frontoffice -Hook types: - - legacy +Hook type: + - display Located in: - - controllers/front/OrderConfirmationController.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/front/OrderConfirmationController.php](controllers/front/OrderConfirmationController.php) + +## Parameters details + +```php + (object) Order + ); +``` -## Hook call with parameters +## Hook call in codebase ```php -Hook::exec('displayOrderConfirmation', ['order' => $order]); +Hook::exec('displayOrderConfirmation', ['order' => $order]) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/displayOrderConfirmation1.md b/modules/concepts/hooks/list-of-hooks/displayOrderConfirmation1.md index 15749829f0..a1a02c7c3e 100644 --- a/modules/concepts/hooks/list-of-hooks/displayOrderConfirmation1.md +++ b/modules/concepts/hooks/list-of-hooks/displayOrderConfirmation1.md @@ -7,24 +7,25 @@ files: - themes/classic/templates/checkout/order-confirmation.tpl locations: - frontoffice -types: - - smarty +type: + - display +hookAliases: --- -# Hook : displayOrderConfirmation1 +# Hook displayOrderConfirmation1 -## Informations +## Information Hook locations: - frontoffice -Hook types: - - smarty +Hook type: + - display Located in: - - themes/classic/templates/checkout/order-confirmation.tpl + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/checkout/order-confirmation.tpl](themes/classic/templates/checkout/order-confirmation.tpl) -## Hook call with parameters +## Hook call in codebase ```php {hook h='displayOrderConfirmation1'} diff --git a/modules/concepts/hooks/list-of-hooks/displayOrderConfirmation2.md b/modules/concepts/hooks/list-of-hooks/displayOrderConfirmation2.md index 52c1505195..ca122df5f4 100644 --- a/modules/concepts/hooks/list-of-hooks/displayOrderConfirmation2.md +++ b/modules/concepts/hooks/list-of-hooks/displayOrderConfirmation2.md @@ -7,24 +7,25 @@ files: - themes/classic/templates/checkout/order-confirmation.tpl locations: - frontoffice -types: - - smarty +type: + - display +hookAliases: --- -# Hook : displayOrderConfirmation2 +# Hook displayOrderConfirmation2 -## Informations +## Information Hook locations: - frontoffice -Hook types: - - smarty +Hook type: + - display Located in: - - themes/classic/templates/checkout/order-confirmation.tpl + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/checkout/order-confirmation.tpl](themes/classic/templates/checkout/order-confirmation.tpl) -## Hook call with parameters +## Hook call in codebase ```php {hook h='displayOrderConfirmation2'} diff --git a/modules/concepts/hooks/list-of-hooks/displayOrderDetail.md b/modules/concepts/hooks/list-of-hooks/displayOrderDetail.md index 04adfd615e..516ed9d28b 100644 --- a/modules/concepts/hooks/list-of-hooks/displayOrderDetail.md +++ b/modules/concepts/hooks/list-of-hooks/displayOrderDetail.md @@ -7,13 +7,20 @@ files: - controllers/front/OrderDetailController.php locations: - frontoffice -types: - - legacy +type: + - display +hookAliases: + - orderDetailDisplayed --- -# Hook : displayOrderDetail +# Hook displayOrderDetail -## Informations +Aliases: + - orderDetailDisplayed + + + +## Information {{% notice tip %}} **Order detail:** @@ -24,14 +31,23 @@ This hook is displayed within the order's details in Front Office Hook locations: - frontoffice -Hook types: - - legacy +Hook type: + - display Located in: - - controllers/front/OrderDetailController.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/front/OrderDetailController.php](controllers/front/OrderDetailController.php) + +## Parameters details + +```php + (object) Order object + ); +``` -## Hook call with parameters +## Hook call in codebase ```php -Hook::exec('displayOrderDetail', ['order' => $order]), +Hook::exec('displayOrderDetail', ['order' => $order]) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/displayOrderPreview.md b/modules/concepts/hooks/list-of-hooks/displayOrderPreview.md index caeb0b7ff4..10f487f2e9 100644 --- a/modules/concepts/hooks/list-of-hooks/displayOrderPreview.md +++ b/modules/concepts/hooks/list-of-hooks/displayOrderPreview.md @@ -7,24 +7,34 @@ files: - src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/preview.html.twig locations: - backoffice -types: - - twig +type: + - display +hookAliases: --- -# Hook : displayOrderPreview +# Hook displayOrderPreview -## Informations +## Information Hook locations: - backoffice -Hook types: - - twig +Hook type: + - display Located in: - - src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/preview.html.twig + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/preview.html.twig](src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/preview.html.twig) + +## Parameters details + +```php + (integer) Order Id + ); +``` -## Hook call with parameters +## Hook call in codebase ```php {{ renderhook('displayOrderPreview', {'order_id': orderId}) }} diff --git a/modules/concepts/hooks/list-of-hooks/displayOverrideTemplate.md b/modules/concepts/hooks/list-of-hooks/displayOverrideTemplate.md new file mode 100644 index 0000000000..2b898d0405 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/displayOverrideTemplate.md @@ -0,0 +1,46 @@ +--- +menuTitle: displayOverrideTemplate +Title: displayOverrideTemplate +hidden: true +hookTitle: Change the default template of current controller +files: + - classes/controller/FrontController.php +locations: + - frontoffice +type: + - display +hookAliases: +--- + +# Hook displayOverrideTemplate + +## Information + +{{% notice tip %}} +**Change the default template of current controller:** + + +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook type: + - display + +Located in: + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/FrontController.php](classes/controller/FrontController.php) + +## Hook call in codebase + +```php +Hook::exec( + 'displayOverrideTemplate', + [ + 'controller' => $this, + 'template_file' => $template, + 'id' => $params['id'], + 'locale' => $locale, + ] + ) +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/displayPaymentByBinaries.md b/modules/concepts/hooks/list-of-hooks/displayPaymentByBinaries.md index 0a42cd1b6d..b75f6d419a 100644 --- a/modules/concepts/hooks/list-of-hooks/displayPaymentByBinaries.md +++ b/modules/concepts/hooks/list-of-hooks/displayPaymentByBinaries.md @@ -7,13 +7,14 @@ files: - themes/classic/templates/checkout/_partials/steps/payment.tpl locations: - frontoffice -types: - - smarty +type: + - display +hookAliases: --- -# Hook : displayPaymentByBinaries +# Hook displayPaymentByBinaries -## Informations +## Information {{% notice tip %}} **Payment form generated by binaries:** @@ -24,13 +25,13 @@ This hook displays form generated by binaries during the checkout Hook locations: - frontoffice -Hook types: - - smarty +Hook type: + - display Located in: - - themes/classic/templates/checkout/_partials/steps/payment.tpl + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/checkout/_partials/steps/payment.tpl](themes/classic/templates/checkout/_partials/steps/payment.tpl) -## Hook call with parameters +## Hook call in codebase ```php {hook h='displayPaymentByBinaries'} diff --git a/modules/concepts/hooks/list-of-hooks/displayPaymentReturn.md b/modules/concepts/hooks/list-of-hooks/displayPaymentReturn.md index 6f2090d3d1..0b3f3ad41c 100644 --- a/modules/concepts/hooks/list-of-hooks/displayPaymentReturn.md +++ b/modules/concepts/hooks/list-of-hooks/displayPaymentReturn.md @@ -7,13 +7,20 @@ files: - controllers/front/OrderConfirmationController.php locations: - frontoffice -types: - - legacy +type: + - display +hookAliases: + - paymentReturn --- -# Hook : displayPaymentReturn +# Hook displayPaymentReturn -## Informations +Aliases: + - paymentReturn + + + +## Information {{% notice tip %}} **Payment return:** @@ -24,14 +31,14 @@ types: Hook locations: - frontoffice -Hook types: - - legacy +Hook type: + - display Located in: - - controllers/front/OrderConfirmationController.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/front/OrderConfirmationController.php](controllers/front/OrderConfirmationController.php) -## Hook call with parameters +## Hook call in codebase ```php -Hook::exec('displayPaymentReturn', ['order' => $order], $this->id_module); +Hook::exec('displayPaymentReturn', ['order' => $order], $this->id_module) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/displayPaymentTop.md b/modules/concepts/hooks/list-of-hooks/displayPaymentTop.md index 6fbf36caf7..b6f47cbd73 100644 --- a/modules/concepts/hooks/list-of-hooks/displayPaymentTop.md +++ b/modules/concepts/hooks/list-of-hooks/displayPaymentTop.md @@ -7,13 +7,20 @@ files: - themes/classic/templates/checkout/_partials/steps/payment.tpl locations: - frontoffice -types: - - smarty +type: + - display +hookAliases: + - paymentTop --- -# Hook : displayPaymentTop +# Hook displayPaymentTop -## Informations +Aliases: + - paymentTop + + + +## Information {{% notice tip %}} **Top of payment page:** @@ -24,13 +31,13 @@ This hook is displayed at the top of the payment page Hook locations: - frontoffice -Hook types: - - smarty +Hook type: + - display Located in: - - themes/classic/templates/checkout/_partials/steps/payment.tpl + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/checkout/_partials/steps/payment.tpl](themes/classic/templates/checkout/_partials/steps/payment.tpl) -## Hook call with parameters +## Hook call in codebase ```php {hook h='displayPaymentTop'} diff --git a/modules/concepts/hooks/list-of-hooks/displayPersonalInformationTop.md b/modules/concepts/hooks/list-of-hooks/displayPersonalInformationTop.md index 50fd3391b7..03d682b06c 100644 --- a/modules/concepts/hooks/list-of-hooks/displayPersonalInformationTop.md +++ b/modules/concepts/hooks/list-of-hooks/displayPersonalInformationTop.md @@ -7,13 +7,14 @@ files: - themes/classic/templates/checkout/_partials/steps/personal-information.tpl locations: - frontoffice -types: - - smarty +type: + - display +hookAliases: --- -# Hook : displayPersonalInformationTop +# Hook displayPersonalInformationTop -## Informations +## Information {{% notice tip %}} **Content in the checkout funnel, on top of the personal information panel:** @@ -24,13 +25,13 @@ Display actions or additional content in the personal details tab of the checkou Hook locations: - frontoffice -Hook types: - - smarty +Hook type: + - display Located in: - - themes/classic/templates/checkout/_partials/steps/personal-information.tpl + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/checkout/_partials/steps/personal-information.tpl](themes/classic/templates/checkout/_partials/steps/personal-information.tpl) -## Hook call with parameters +## Hook call in codebase ```php {hook h='displayPersonalInformationTop' customer=$customer} diff --git a/modules/concepts/hooks/list-of-hooks/displayProductActions.md b/modules/concepts/hooks/list-of-hooks/displayProductActions.md index 3a487b7bfd..4203f789ca 100644 --- a/modules/concepts/hooks/list-of-hooks/displayProductActions.md +++ b/modules/concepts/hooks/list-of-hooks/displayProductActions.md @@ -7,13 +7,14 @@ files: - themes/classic/templates/catalog/_partials/product-add-to-cart.tpl locations: - frontoffice -types: - - smarty +type: + - action +hookAliases: --- -# Hook : displayProductActions +# Hook displayProductActions -## Informations +## Information {{% notice tip %}} **Display additional action button on the product page:** @@ -24,13 +25,13 @@ This hook allow additional actions to be triggered, near the add to cart button. Hook locations: - frontoffice -Hook types: - - smarty +Hook type: + - action Located in: - - themes/classic/templates/catalog/_partials/product-add-to-cart.tpl + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/catalog/_partials/product-add-to-cart.tpl](themes/classic/templates/catalog/_partials/product-add-to-cart.tpl) -## Hook call with parameters +## Hook call in codebase ```php {hook h='displayProductActions' product=$product} diff --git a/modules/concepts/hooks/list-of-hooks/displayProductAdditionalInfo.md b/modules/concepts/hooks/list-of-hooks/displayProductAdditionalInfo.md index 7e9438fb31..929f07e7b8 100644 --- a/modules/concepts/hooks/list-of-hooks/displayProductAdditionalInfo.md +++ b/modules/concepts/hooks/list-of-hooks/displayProductAdditionalInfo.md @@ -7,13 +7,22 @@ files: - themes/classic/templates/catalog/_partials/quickview.tpl locations: - frontoffice -types: - - smarty +type: + - display +hookAliases: + - productActions + - displayProductButtons --- -# Hook : displayProductAdditionalInfo +# Hook displayProductAdditionalInfo -## Informations +Aliases: + - productActions + - displayProductButtons + + + +## Information {{% notice tip %}} **Product page additional info:** @@ -24,13 +33,13 @@ This hook adds additional information on the product page Hook locations: - frontoffice -Hook types: - - smarty +Hook type: + - display Located in: - - themes/classic/templates/catalog/_partials/quickview.tpl + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/catalog/_partials/quickview.tpl](themes/classic/templates/catalog/_partials/quickview.tpl) -## Hook call with parameters +## Hook call in codebase ```php {hook h='displayProductAdditionalInfo' product=$product} diff --git a/modules/concepts/hooks/list-of-hooks/displayProductListReviews.md b/modules/concepts/hooks/list-of-hooks/displayProductListReviews.md index fc10875e18..f4156799c3 100644 --- a/modules/concepts/hooks/list-of-hooks/displayProductListReviews.md +++ b/modules/concepts/hooks/list-of-hooks/displayProductListReviews.md @@ -7,24 +7,25 @@ files: - themes/classic/templates/catalog/_partials/miniatures/product.tpl locations: - frontoffice -types: - - smarty +type: + - display +hookAliases: --- -# Hook : displayProductListReviews +# Hook displayProductListReviews -## Informations +## Information Hook locations: - frontoffice -Hook types: - - smarty +Hook type: + - display Located in: - - themes/classic/templates/catalog/_partials/miniatures/product.tpl + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/catalog/_partials/miniatures/product.tpl](themes/classic/templates/catalog/_partials/miniatures/product.tpl) -## Hook call with parameters +## Hook call in codebase ```php {hook h='displayProductListReviews' product=$product} diff --git a/modules/concepts/hooks/list-of-hooks/displayProductPriceBlock.md b/modules/concepts/hooks/list-of-hooks/displayProductPriceBlock.md index 85b7819732..d03f20433a 100644 --- a/modules/concepts/hooks/list-of-hooks/displayProductPriceBlock.md +++ b/modules/concepts/hooks/list-of-hooks/displayProductPriceBlock.md @@ -7,24 +7,25 @@ files: - themes/classic/templates/checkout/_partials/order-confirmation-table.tpl locations: - frontoffice -types: - - smarty +type: + - display +hookAliases: --- -# Hook : displayProductPriceBlock +# Hook displayProductPriceBlock -## Informations +## Information Hook locations: - frontoffice -Hook types: - - smarty +Hook type: + - display Located in: - - themes/classic/templates/checkout/_partials/order-confirmation-table.tpl + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/checkout/_partials/order-confirmation-table.tpl](themes/classic/templates/checkout/_partials/order-confirmation-table.tpl) -## Hook call with parameters +## Hook call in codebase ```php {hook h='displayProductPriceBlock' product=$product type="unit_price"} diff --git a/modules/concepts/hooks/list-of-hooks/displayReassurance.md b/modules/concepts/hooks/list-of-hooks/displayReassurance.md index be2f7cad59..95f25be5d6 100644 --- a/modules/concepts/hooks/list-of-hooks/displayReassurance.md +++ b/modules/concepts/hooks/list-of-hooks/displayReassurance.md @@ -7,24 +7,25 @@ files: - themes/classic/templates/checkout/checkout.tpl locations: - frontoffice -types: - - smarty +type: + - display +hookAliases: --- -# Hook : displayReassurance +# Hook displayReassurance -## Informations +## Information Hook locations: - frontoffice -Hook types: - - smarty +Hook type: + - display Located in: - - themes/classic/templates/checkout/checkout.tpl + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/checkout/checkout.tpl](themes/classic/templates/checkout/checkout.tpl) -## Hook call with parameters +## Hook call in codebase ```php {hook h='displayReassurance'} diff --git a/modules/concepts/hooks/list-of-hooks/displayRightColumnProduct.md b/modules/concepts/hooks/list-of-hooks/displayRightColumnProduct.md index e3d557564b..ffd71ae14c 100644 --- a/modules/concepts/hooks/list-of-hooks/displayRightColumnProduct.md +++ b/modules/concepts/hooks/list-of-hooks/displayRightColumnProduct.md @@ -7,13 +7,20 @@ files: - themes/classic/templates/layouts/layout-both-columns.tpl locations: - frontoffice -types: - - smarty +type: + - display +hookAliases: + - extraRight --- -# Hook : displayRightColumnProduct +# Hook displayRightColumnProduct -## Informations +Aliases: + - extraRight + + + +## Information {{% notice tip %}} **New elements on the product page (right column):** @@ -24,13 +31,13 @@ This hook displays new elements in the right-hand column of the product page Hook locations: - frontoffice -Hook types: - - smarty +Hook type: + - display Located in: - - themes/classic/templates/layouts/layout-both-columns.tpl + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/layouts/layout-both-columns.tpl](themes/classic/templates/layouts/layout-both-columns.tpl) -## Hook call with parameters +## Hook call in codebase ```php {hook h='displayRightColumnProduct'} diff --git a/modules/concepts/hooks/list-of-hooks/displaySearch.md b/modules/concepts/hooks/list-of-hooks/displaySearch.md index 423a645be7..2d08cdffc9 100644 --- a/modules/concepts/hooks/list-of-hooks/displaySearch.md +++ b/modules/concepts/hooks/list-of-hooks/displaySearch.md @@ -7,24 +7,25 @@ files: - themes/classic/templates/errors/not-found.tpl locations: - frontoffice -types: - - smarty +type: + - display +hookAliases: --- -# Hook : displaySearch +# Hook displaySearch -## Informations +## Information Hook locations: - frontoffice -Hook types: - - smarty +Hook type: + - display Located in: - - themes/classic/templates/errors/not-found.tpl + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/errors/not-found.tpl](themes/classic/templates/errors/not-found.tpl) -## Hook call with parameters +## Hook call in codebase ```php {hook h='displaySearch'} diff --git a/modules/concepts/hooks/list-of-hooks/displayShoppingCart.md b/modules/concepts/hooks/list-of-hooks/displayShoppingCart.md index e47f8aebec..7dd27d5d24 100644 --- a/modules/concepts/hooks/list-of-hooks/displayShoppingCart.md +++ b/modules/concepts/hooks/list-of-hooks/displayShoppingCart.md @@ -7,13 +7,20 @@ files: - themes/classic/templates/checkout/cart.tpl locations: - frontoffice -types: - - smarty +type: + - display +hookAliases: + - shoppingCartExtra --- -# Hook : displayShoppingCart +# Hook displayShoppingCart -## Informations +Aliases: + - shoppingCartExtra + + + +## Information {{% notice tip %}} **Shopping cart - Additional button:** @@ -24,13 +31,13 @@ This hook displays new action buttons within the shopping cart Hook locations: - frontoffice -Hook types: - - smarty +Hook type: + - display Located in: - - themes/classic/templates/checkout/cart.tpl + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/checkout/cart.tpl](themes/classic/templates/checkout/cart.tpl) -## Hook call with parameters +## Hook call in codebase ```php {hook h='displayShoppingCart'} diff --git a/modules/concepts/hooks/list-of-hooks/displayShoppingCartFooter.md b/modules/concepts/hooks/list-of-hooks/displayShoppingCartFooter.md index 367948a5d7..324d04abc4 100644 --- a/modules/concepts/hooks/list-of-hooks/displayShoppingCartFooter.md +++ b/modules/concepts/hooks/list-of-hooks/displayShoppingCartFooter.md @@ -7,13 +7,20 @@ files: - themes/classic/templates/checkout/cart.tpl locations: - frontoffice -types: - - smarty +type: + - display +hookAliases: + - shoppingCart --- -# Hook : displayShoppingCartFooter +# Hook displayShoppingCartFooter -## Informations +Aliases: + - shoppingCart + + + +## Information {{% notice tip %}} **Shopping cart footer:** @@ -24,13 +31,13 @@ This hook displays some specific information on the shopping cart's page Hook locations: - frontoffice -Hook types: - - smarty +Hook type: + - display Located in: - - themes/classic/templates/checkout/cart.tpl + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/checkout/cart.tpl](themes/classic/templates/checkout/cart.tpl) -## Hook call with parameters +## Hook call in codebase ```php {hook h='displayShoppingCartFooter'} diff --git a/modules/concepts/hooks/list-of-hooks/displayTop.md b/modules/concepts/hooks/list-of-hooks/displayTop.md index 938c53f69d..8c18544b44 100644 --- a/modules/concepts/hooks/list-of-hooks/displayTop.md +++ b/modules/concepts/hooks/list-of-hooks/displayTop.md @@ -7,13 +7,20 @@ files: - themes/classic/templates/checkout/_partials/header.tpl locations: - frontoffice -types: - - smarty +type: + - display +hookAliases: + - top --- -# Hook : displayTop +# Hook displayTop -## Informations +Aliases: + - top + + + +## Information {{% notice tip %}} **Top of pages:** @@ -24,13 +31,13 @@ This hook displays additional elements at the top of your pages Hook locations: - frontoffice -Hook types: - - smarty +Hook type: + - display Located in: - - themes/classic/templates/checkout/_partials/header.tpl + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/checkout/_partials/header.tpl](themes/classic/templates/checkout/_partials/header.tpl) -## Hook call with parameters +## Hook call in codebase ```php {hook h='displayTop'} diff --git a/modules/concepts/hooks/list-of-hooks/filterCategoryContent.md b/modules/concepts/hooks/list-of-hooks/filterCategoryContent.md new file mode 100644 index 0000000000..1862697447 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/filterCategoryContent.md @@ -0,0 +1,58 @@ +--- +menuTitle: filterCategoryContent +Title: filterCategoryContent +hidden: true +hookTitle: Filter the content page category +files: + - controllers/front/listing/CategoryController.php +locations: + - frontoffice +type: + - +hookAliases: +--- + +# Hook filterCategoryContent + +## Information + +{{% notice tip %}} +**Filter the content page category:** + +This hook is called just before fetching content page category +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook type: + - + +Located in: + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/front/listing/CategoryController.php](controllers/front/listing/CategoryController.php) + +This hook has a `$chain` parameter set to `true` (hook will chain the return of hook module, [see explaination here]({{< relref "/8/modules/concepts/hooks">}})). + +## Parameters details + +```php + (object) Category object + ), +``` + +## Hook call in codebase + +```php +Hook::exec( + 'filterCategoryContent', + ['object' => $categoryVar], + $id_module = null, + $array_return = false, + $check_exceptions = true, + $use_push = false, + $id_shop = null, + $chain = true + ) +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/filterCmsCategoryContent.md b/modules/concepts/hooks/list-of-hooks/filterCmsCategoryContent.md new file mode 100644 index 0000000000..652e1ef94a --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/filterCmsCategoryContent.md @@ -0,0 +1,49 @@ +--- +menuTitle: filterCmsCategoryContent +Title: filterCmsCategoryContent +hidden: true +hookTitle: Filter the content page category +files: + - controllers/front/CmsController.php +locations: + - frontoffice +type: + - +hookAliases: +--- + +# Hook filterCmsCategoryContent + +## Information + +{{% notice tip %}} +**Filter the content page category:** + +This hook is called just before fetching content page category +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook type: + - + +Located in: + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/front/CmsController.php](controllers/front/CmsController.php) + +This hook has a `$chain` parameter set to `true` (hook will chain the return of hook module, [see explaination here]({{< relref "/8/modules/concepts/hooks">}})). + +## Hook call in codebase + +```php +Hook::exec( + 'filterCmsCategoryContent', + ['object' => $cmsCategoryVar], + $id_module = null, + $array_return = false, + $check_exceptions = true, + $use_push = false, + $id_shop = null, + $chain = true + ) +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/filterCmsContent.md b/modules/concepts/hooks/list-of-hooks/filterCmsContent.md new file mode 100644 index 0000000000..8ac16a7325 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/filterCmsContent.md @@ -0,0 +1,49 @@ +--- +menuTitle: filterCmsContent +Title: filterCmsContent +hidden: true +hookTitle: Filter the content page +files: + - controllers/front/CmsController.php +locations: + - frontoffice +type: + - +hookAliases: +--- + +# Hook filterCmsContent + +## Information + +{{% notice tip %}} +**Filter the content page:** + +This hook is called just before fetching content page +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook type: + - + +Located in: + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/front/CmsController.php](controllers/front/CmsController.php) + +This hook has a `$chain` parameter set to `true` (hook will chain the return of hook module, [see explaination here]({{< relref "/8/modules/concepts/hooks">}})). + +## Hook call in codebase + +```php +Hook::exec( + 'filterCmsContent', + ['object' => $cmsVar], + $id_module = null, + $array_return = false, + $check_exceptions = true, + $use_push = false, + $id_shop = null, + $chain = true + ) +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/filterHtmlContent.md b/modules/concepts/hooks/list-of-hooks/filterHtmlContent.md new file mode 100644 index 0000000000..237f6b4bc9 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/filterHtmlContent.md @@ -0,0 +1,53 @@ +--- +menuTitle: filterHtmlContent +Title: filterHtmlContent +hidden: true +hookTitle: Filter HTML field before rending a page +files: + - src/Adapter/Presenter/Object/ObjectPresenter.php +locations: + - frontoffice +type: + - +hookAliases: +--- + +# Hook filterHtmlContent + +## Information + +{{% notice tip %}} +**Filter HTML field before rending a page:** + +This hook is called just before fetching a page on HTML field +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook type: + - + +Located in: + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Presenter/Object/ObjectPresenter.php](src/Adapter/Presenter/Object/ObjectPresenter.php) + +This hook has a `$chain` parameter set to `true` (hook will chain the return of hook module, [see explaination here]({{< relref "/8/modules/concepts/hooks">}})). + +## Hook call in codebase + +```php +Hook::exec( + 'filterHtmlContent', + [ + 'type' => $type, + 'htmlFields' => $htmlFields, + 'object' => $presentedObject, + ], + null, + false, + true, + false, + null, + true + ) +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/filterManufacturerContent.md b/modules/concepts/hooks/list-of-hooks/filterManufacturerContent.md new file mode 100644 index 0000000000..bed7758b20 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/filterManufacturerContent.md @@ -0,0 +1,49 @@ +--- +menuTitle: filterManufacturerContent +Title: filterManufacturerContent +hidden: true +hookTitle: Filter the content page manufacturer +files: + - controllers/front/listing/ManufacturerController.php +locations: + - frontoffice +type: + - +hookAliases: +--- + +# Hook filterManufacturerContent + +## Information + +{{% notice tip %}} +**Filter the content page manufacturer:** + +This hook is called just before fetching content page manufacturer +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook type: + - + +Located in: + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/front/listing/ManufacturerController.php](controllers/front/listing/ManufacturerController.php) + +This hook has a `$chain` parameter set to `true` (hook will chain the return of hook module, [see explaination here]({{< relref "/8/modules/concepts/hooks">}})). + +## Hook call in codebase + +```php +Hook::exec( + 'filterManufacturerContent', + ['filtered_content' => $manufacturerVar['description']], + $id_module = null, + $array_return = false, + $check_exceptions = true, + $use_push = false, + $id_shop = null, + $chain = true + ) +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/filterProductContent.md b/modules/concepts/hooks/list-of-hooks/filterProductContent.md new file mode 100644 index 0000000000..655b8ef88f --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/filterProductContent.md @@ -0,0 +1,49 @@ +--- +menuTitle: filterProductContent +Title: filterProductContent +hidden: true +hookTitle: Filter the content page product +files: + - controllers/front/ProductController.php +locations: + - frontoffice +type: + - +hookAliases: +--- + +# Hook filterProductContent + +## Information + +{{% notice tip %}} +**Filter the content page product:** + +This hook is called just before fetching content page product +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook type: + - + +Located in: + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/front/ProductController.php](controllers/front/ProductController.php) + +This hook has a `$chain` parameter set to `true` (hook will chain the return of hook module, [see explaination here]({{< relref "/8/modules/concepts/hooks">}})). + +## Hook call in codebase + +```php +Hook::exec( + 'filterProductContent', + ['object' => $product_for_template], + null, + false, + true, + false, + null, + true + ) +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/filterProductSearch.md b/modules/concepts/hooks/list-of-hooks/filterProductSearch.md index a836373428..8c84607665 100644 --- a/modules/concepts/hooks/list-of-hooks/filterProductSearch.md +++ b/modules/concepts/hooks/list-of-hooks/filterProductSearch.md @@ -7,13 +7,14 @@ files: - modules/blockwishlist/controllers/front/view.php locations: - frontoffice -types: - - legacy +type: + - +hookAliases: --- -# Hook : filterProductSearch +# Hook filterProductSearch -## Informations +## Information {{% notice tip %}} **Filter search products result:** @@ -24,14 +25,14 @@ This hook is called in order to allow to modify search product result Hook locations: - frontoffice -Hook types: - - legacy +Hook type: + - Located in: - - modules/blockwishlist/controllers/front/view.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/modules/blockwishlist/controllers/front/view.php](modules/blockwishlist/controllers/front/view.php) -## Hook call with parameters +## Hook call in codebase ```php -Hook::exec('filterProductSearch', ['searchVariables' => &$searchVariables]); +Hook::exec('filterProductSearch', ['searchVariables' => &$searchVariables]) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/filterSupplierContent.md b/modules/concepts/hooks/list-of-hooks/filterSupplierContent.md new file mode 100644 index 0000000000..ad1470068c --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/filterSupplierContent.md @@ -0,0 +1,49 @@ +--- +menuTitle: filterSupplierContent +Title: filterSupplierContent +hidden: true +hookTitle: Filter the content page supplier +files: + - controllers/front/listing/SupplierController.php +locations: + - frontoffice +type: + - +hookAliases: +--- + +# Hook filterSupplierContent + +## Information + +{{% notice tip %}} +**Filter the content page supplier:** + +This hook is called just before fetching content page supplier +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook type: + - + +Located in: + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/front/listing/SupplierController.php](controllers/front/listing/SupplierController.php) + +This hook has a `$chain` parameter set to `true` (hook will chain the return of hook module, [see explaination here]({{< relref "/8/modules/concepts/hooks">}})). + +## Hook call in codebase + +```php +Hook::exec( + 'filterSupplierContent', + ['object' => $supplierVar], + $id_module = null, + $array_return = false, + $check_exceptions = true, + $use_push = false, + $id_shop = null, + $chain = true + ) +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/gSitemapAppendUrls.md b/modules/concepts/hooks/list-of-hooks/gSitemapAppendUrls.md new file mode 100644 index 0000000000..00acfe6a36 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/gSitemapAppendUrls.md @@ -0,0 +1,36 @@ +--- +menuTitle: gSitemapAppendUrls +Title: gSitemapAppendUrls +hidden: true +hookTitle: +files: + - modules/gsitemap/gsitemap.php +locations: + - frontoffice +type: + - +hookAliases: +--- + +# Hook gSitemapAppendUrls + +## Information + +Hook locations: + - frontoffice + +Hook type: + - + +Located in: + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/modules/gsitemap/gsitemap.php](modules/gsitemap/gsitemap.php) + +This hook has an `$array_return` parameter set to `true` (module output will be set by name in an array, [see explaination here]({{< relref "/8/modules/concepts/hooks">}})). + +## Hook call in codebase + +```php +Hook::exec(self::HOOK_ADD_URLS, array( + 'lang' => $lang, + ), null, true) +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/legacyblockkpi.md b/modules/concepts/hooks/list-of-hooks/legacyblockkpi.md index 10056e14c9..69f3ca9cc1 100644 --- a/modules/concepts/hooks/list-of-hooks/legacyblockkpi.md +++ b/modules/concepts/hooks/list-of-hooks/legacyblockkpi.md @@ -7,24 +7,25 @@ files: - src/PrestaShopBundle/Resources/views/Admin/Product/CatalogPage/catalog.html.twig locations: - backoffice -types: - - twig +type: + - +hookAliases: --- -# Hook : legacyblockkpi +# Hook legacyblockkpi -## Informations +## Information Hook locations: - backoffice -Hook types: - - twig +Hook type: + - Located in: - - src/PrestaShopBundle/Resources/views/Admin/Product/CatalogPage/catalog.html.twig + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Resources/views/Admin/Product/CatalogPage/catalog.html.twig](src/PrestaShopBundle/Resources/views/Admin/Product/CatalogPage/catalog.html.twig) -## Hook call with parameters +## Hook call in codebase ```php {{ renderhook('legacy_block_kpi', {'kpi_controller': 'AdminProductsController'}) }} diff --git a/modules/concepts/hooks/list-of-hooks/moduleRoutes.md b/modules/concepts/hooks/list-of-hooks/moduleRoutes.md index 251b38c292..ad7fb96a0f 100644 --- a/modules/concepts/hooks/list-of-hooks/moduleRoutes.md +++ b/modules/concepts/hooks/list-of-hooks/moduleRoutes.md @@ -7,25 +7,30 @@ files: - classes/Dispatcher.php locations: - frontoffice -types: - - legacy +type: + - +hookAliases: --- -# Hook : moduleRoutes +# Hook moduleRoutes -## Informations +## Information Hook locations: - frontoffice -Hook types: - - legacy +Hook type: + - Located in: - - classes/Dispatcher.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Dispatcher.php](classes/Dispatcher.php) + +This hook has an `$array_return` parameter set to `true` (module output will be set by name in an array, [see explaination here]({{< relref "/8/modules/concepts/hooks">}})). + +This hook has a `$check_exception` parameter set to `false` (check permission exception, [see explaination here]({{< relref "/8/modules/concepts/hooks">}})). -## Hook call with parameters +## Hook call in codebase ```php -Hook::exec('moduleRoutes', ['id_shop' => $id_shop], null, true, false); +Hook::exec('moduleRoutes', ['id_shop' => $id_shop], null, true, false) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/overrideLayoutTemplate.md b/modules/concepts/hooks/list-of-hooks/overrideLayoutTemplate.md new file mode 100644 index 0000000000..13a787e53e --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/overrideLayoutTemplate.md @@ -0,0 +1,41 @@ +--- +menuTitle: overrideLayoutTemplate +Title: overrideLayoutTemplate +hidden: true +hookTitle: +files: + - classes/controller/FrontController.php +locations: + - frontoffice +type: + - +hookAliases: +--- + +# Hook overrideLayoutTemplate + +## Information + +Hook locations: + - frontoffice + +Hook type: + - + +Located in: + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/FrontController.php](classes/controller/FrontController.php) + +## Hook call in codebase + +```php +Hook::exec( + 'overrideLayoutTemplate', + [ + 'default_layout' => $layout, + 'entity' => $entity, + 'locale' => $this->context->language->locale, + 'controller' => $this, + 'content_only' => $content_only, + ] + ) +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/overrideMinimalPurchasePrice.md b/modules/concepts/hooks/list-of-hooks/overrideMinimalPurchasePrice.md index 20cc378339..cebdc9f5d8 100644 --- a/modules/concepts/hooks/list-of-hooks/overrideMinimalPurchasePrice.md +++ b/modules/concepts/hooks/list-of-hooks/overrideMinimalPurchasePrice.md @@ -7,27 +7,28 @@ files: - src/Adapter/Presenter/Cart/CartPresenter.php locations: - frontoffice -types: - - legacy +type: + - +hookAliases: --- -# Hook : overrideMinimalPurchasePrice +# Hook overrideMinimalPurchasePrice -## Informations +## Information Hook locations: - frontoffice -Hook types: - - legacy +Hook type: + - Located in: - - src/Adapter/Presenter/Cart/CartPresenter.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Presenter/Cart/CartPresenter.php](src/Adapter/Presenter/Cart/CartPresenter.php) -## Hook call with parameters +## Hook call in codebase ```php Hook::exec('overrideMinimalPurchasePrice', [ 'minimalPurchase' => &$minimalPurchase, - ]); + ]) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/productSearchProvider.md b/modules/concepts/hooks/list-of-hooks/productSearchProvider.md new file mode 100644 index 0000000000..386e29cbdb --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/productSearchProvider.md @@ -0,0 +1,39 @@ +--- +menuTitle: productSearchProvider +Title: productSearchProvider +hidden: true +hookTitle: +files: + - classes/controller/ProductListingFrontController.php +locations: + - frontoffice +type: + - +hookAliases: +--- + +# Hook productSearchProvider + +## Information + +Hook locations: + - frontoffice + +Hook type: + - + +Located in: + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/ProductListingFrontController.php](classes/controller/ProductListingFrontController.php) + +This hook has an `$array_return` parameter set to `true` (module output will be set by name in an array, [see explaination here]({{< relref "/8/modules/concepts/hooks">}})). + +## Hook call in codebase + +```php +Hook::exec( + 'productSearchProvider', + ['query' => $query], + null, + true + ) +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/sendMailAlterTemplateVars.md b/modules/concepts/hooks/list-of-hooks/sendMailAlterTemplateVars.md new file mode 100644 index 0000000000..553bae6a1b --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/sendMailAlterTemplateVars.md @@ -0,0 +1,44 @@ +--- +menuTitle: sendMailAlterTemplateVars +Title: sendMailAlterTemplateVars +hidden: true +hookTitle: Alter template vars on the fly +files: + - classes/Mail.php +locations: + - frontoffice +type: + - +hookAliases: +--- + +# Hook sendMailAlterTemplateVars + +## Information + +{{% notice tip %}} +**Alter template vars on the fly:** + +This hook is called when Mail::send() is called +{{% /notice %}} + +Hook locations: + - frontoffice + +Hook type: + - + +Located in: + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Mail.php](classes/Mail.php) + +## Hook call in codebase + +```php +Hook::exec( + 'sendMailAlterTemplateVars', + [ + 'template' => $template, + 'template_vars' => &$templateVars, + ] + ) +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/termsAndConditions.md b/modules/concepts/hooks/list-of-hooks/termsAndConditions.md index 1fac178aaf..cbe57a521b 100644 --- a/modules/concepts/hooks/list-of-hooks/termsAndConditions.md +++ b/modules/concepts/hooks/list-of-hooks/termsAndConditions.md @@ -7,25 +7,28 @@ files: - classes/checkout/ConditionsToApproveFinder.php locations: - frontoffice -types: - - legacy +type: + - +hookAliases: --- -# Hook : termsAndConditions +# Hook termsAndConditions -## Informations +## Information Hook locations: - frontoffice -Hook types: - - legacy +Hook type: + - Located in: - - classes/checkout/ConditionsToApproveFinder.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/checkout/ConditionsToApproveFinder.php](classes/checkout/ConditionsToApproveFinder.php) + +This hook has an `$array_return` parameter set to `true` (module output will be set by name in an array, [see explaination here]({{< relref "/8/modules/concepts/hooks">}})). -## Hook call with parameters +## Hook call in codebase ```php -Hook::exec('termsAndConditions', [], null, true); +Hook::exec('termsAndConditions', [], null, true) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/validateCustomerFormFields.md b/modules/concepts/hooks/list-of-hooks/validateCustomerFormFields.md index e9d0f17069..574ebfc317 100644 --- a/modules/concepts/hooks/list-of-hooks/validateCustomerFormFields.md +++ b/modules/concepts/hooks/list-of-hooks/validateCustomerFormFields.md @@ -7,13 +7,14 @@ files: - classes/form/CustomerForm.php locations: - frontoffice -types: - - legacy +type: + - +hookAliases: --- -# Hook : validateCustomerFormFields +# Hook validateCustomerFormFields -## Informations +## Information {{% notice tip %}} **Customer registration form validation:** @@ -24,14 +25,16 @@ This hook is called to a module when it has sent additional fields with addition Hook locations: - frontoffice -Hook types: - - legacy +Hook type: + - Located in: - - classes/form/CustomerForm.php + - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/form/CustomerForm.php](classes/form/CustomerForm.php) + +This hook has an `$array_return` parameter set to `true` (module output will be set by name in an array, [see explaination here]({{< relref "/8/modules/concepts/hooks">}})). -## Hook call with parameters +## Hook call in codebase ```php -Hook::exec('validateCustomerFormFields', ['fields' => $formFields], $moduleId, true); +Hook::exec('validateCustomerFormFields', ['fields' => $formFields], $moduleId, true) ``` \ No newline at end of file From 302118e06c9864730beb5d2fe5b675774d7ad25f Mon Sep 17 00:00:00 2001 From: Thomas Nares Date: Wed, 7 Dec 2022 10:32:43 +0100 Subject: [PATCH 156/310] fix no type hooks --- modules/concepts/hooks/list-of-hooks/filterCategoryContent.md | 3 --- .../concepts/hooks/list-of-hooks/filterCmsCategoryContent.md | 3 --- modules/concepts/hooks/list-of-hooks/filterCmsContent.md | 3 --- modules/concepts/hooks/list-of-hooks/filterHtmlContent.md | 3 --- .../concepts/hooks/list-of-hooks/filterManufacturerContent.md | 3 --- modules/concepts/hooks/list-of-hooks/filterProductContent.md | 3 --- modules/concepts/hooks/list-of-hooks/filterProductSearch.md | 3 --- modules/concepts/hooks/list-of-hooks/filterSupplierContent.md | 3 --- modules/concepts/hooks/list-of-hooks/gSitemapAppendUrls.md | 3 --- modules/concepts/hooks/list-of-hooks/legacyblockkpi.md | 3 --- modules/concepts/hooks/list-of-hooks/moduleRoutes.md | 3 --- modules/concepts/hooks/list-of-hooks/overrideLayoutTemplate.md | 3 --- .../hooks/list-of-hooks/overrideMinimalPurchasePrice.md | 3 --- modules/concepts/hooks/list-of-hooks/productSearchProvider.md | 3 --- .../concepts/hooks/list-of-hooks/sendMailAlterTemplateVars.md | 3 --- modules/concepts/hooks/list-of-hooks/termsAndConditions.md | 3 --- .../concepts/hooks/list-of-hooks/validateCustomerFormFields.md | 3 --- 17 files changed, 51 deletions(-) diff --git a/modules/concepts/hooks/list-of-hooks/filterCategoryContent.md b/modules/concepts/hooks/list-of-hooks/filterCategoryContent.md index 1862697447..2b589745de 100644 --- a/modules/concepts/hooks/list-of-hooks/filterCategoryContent.md +++ b/modules/concepts/hooks/list-of-hooks/filterCategoryContent.md @@ -25,9 +25,6 @@ This hook is called just before fetching content page category Hook locations: - frontoffice -Hook type: - - - Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/front/listing/CategoryController.php](controllers/front/listing/CategoryController.php) diff --git a/modules/concepts/hooks/list-of-hooks/filterCmsCategoryContent.md b/modules/concepts/hooks/list-of-hooks/filterCmsCategoryContent.md index 652e1ef94a..0a5dfe1af5 100644 --- a/modules/concepts/hooks/list-of-hooks/filterCmsCategoryContent.md +++ b/modules/concepts/hooks/list-of-hooks/filterCmsCategoryContent.md @@ -25,9 +25,6 @@ This hook is called just before fetching content page category Hook locations: - frontoffice -Hook type: - - - Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/front/CmsController.php](controllers/front/CmsController.php) diff --git a/modules/concepts/hooks/list-of-hooks/filterCmsContent.md b/modules/concepts/hooks/list-of-hooks/filterCmsContent.md index 8ac16a7325..85fac09030 100644 --- a/modules/concepts/hooks/list-of-hooks/filterCmsContent.md +++ b/modules/concepts/hooks/list-of-hooks/filterCmsContent.md @@ -25,9 +25,6 @@ This hook is called just before fetching content page Hook locations: - frontoffice -Hook type: - - - Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/front/CmsController.php](controllers/front/CmsController.php) diff --git a/modules/concepts/hooks/list-of-hooks/filterHtmlContent.md b/modules/concepts/hooks/list-of-hooks/filterHtmlContent.md index 237f6b4bc9..9517a14291 100644 --- a/modules/concepts/hooks/list-of-hooks/filterHtmlContent.md +++ b/modules/concepts/hooks/list-of-hooks/filterHtmlContent.md @@ -25,9 +25,6 @@ This hook is called just before fetching a page on HTML field Hook locations: - frontoffice -Hook type: - - - Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Presenter/Object/ObjectPresenter.php](src/Adapter/Presenter/Object/ObjectPresenter.php) diff --git a/modules/concepts/hooks/list-of-hooks/filterManufacturerContent.md b/modules/concepts/hooks/list-of-hooks/filterManufacturerContent.md index bed7758b20..67025953f1 100644 --- a/modules/concepts/hooks/list-of-hooks/filterManufacturerContent.md +++ b/modules/concepts/hooks/list-of-hooks/filterManufacturerContent.md @@ -25,9 +25,6 @@ This hook is called just before fetching content page manufacturer Hook locations: - frontoffice -Hook type: - - - Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/front/listing/ManufacturerController.php](controllers/front/listing/ManufacturerController.php) diff --git a/modules/concepts/hooks/list-of-hooks/filterProductContent.md b/modules/concepts/hooks/list-of-hooks/filterProductContent.md index 655b8ef88f..fb245e8fd4 100644 --- a/modules/concepts/hooks/list-of-hooks/filterProductContent.md +++ b/modules/concepts/hooks/list-of-hooks/filterProductContent.md @@ -25,9 +25,6 @@ This hook is called just before fetching content page product Hook locations: - frontoffice -Hook type: - - - Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/front/ProductController.php](controllers/front/ProductController.php) diff --git a/modules/concepts/hooks/list-of-hooks/filterProductSearch.md b/modules/concepts/hooks/list-of-hooks/filterProductSearch.md index 8c84607665..27a0098524 100644 --- a/modules/concepts/hooks/list-of-hooks/filterProductSearch.md +++ b/modules/concepts/hooks/list-of-hooks/filterProductSearch.md @@ -25,9 +25,6 @@ This hook is called in order to allow to modify search product result Hook locations: - frontoffice -Hook type: - - - Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/modules/blockwishlist/controllers/front/view.php](modules/blockwishlist/controllers/front/view.php) diff --git a/modules/concepts/hooks/list-of-hooks/filterSupplierContent.md b/modules/concepts/hooks/list-of-hooks/filterSupplierContent.md index ad1470068c..f5ba6aed60 100644 --- a/modules/concepts/hooks/list-of-hooks/filterSupplierContent.md +++ b/modules/concepts/hooks/list-of-hooks/filterSupplierContent.md @@ -25,9 +25,6 @@ This hook is called just before fetching content page supplier Hook locations: - frontoffice -Hook type: - - - Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/front/listing/SupplierController.php](controllers/front/listing/SupplierController.php) diff --git a/modules/concepts/hooks/list-of-hooks/gSitemapAppendUrls.md b/modules/concepts/hooks/list-of-hooks/gSitemapAppendUrls.md index 00acfe6a36..536ed79593 100644 --- a/modules/concepts/hooks/list-of-hooks/gSitemapAppendUrls.md +++ b/modules/concepts/hooks/list-of-hooks/gSitemapAppendUrls.md @@ -19,9 +19,6 @@ hookAliases: Hook locations: - frontoffice -Hook type: - - - Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/modules/gsitemap/gsitemap.php](modules/gsitemap/gsitemap.php) diff --git a/modules/concepts/hooks/list-of-hooks/legacyblockkpi.md b/modules/concepts/hooks/list-of-hooks/legacyblockkpi.md index 69f3ca9cc1..0be777f6f1 100644 --- a/modules/concepts/hooks/list-of-hooks/legacyblockkpi.md +++ b/modules/concepts/hooks/list-of-hooks/legacyblockkpi.md @@ -19,9 +19,6 @@ hookAliases: Hook locations: - backoffice -Hook type: - - - Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Resources/views/Admin/Product/CatalogPage/catalog.html.twig](src/PrestaShopBundle/Resources/views/Admin/Product/CatalogPage/catalog.html.twig) diff --git a/modules/concepts/hooks/list-of-hooks/moduleRoutes.md b/modules/concepts/hooks/list-of-hooks/moduleRoutes.md index ad7fb96a0f..e12729a7ac 100644 --- a/modules/concepts/hooks/list-of-hooks/moduleRoutes.md +++ b/modules/concepts/hooks/list-of-hooks/moduleRoutes.md @@ -19,9 +19,6 @@ hookAliases: Hook locations: - frontoffice -Hook type: - - - Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Dispatcher.php](classes/Dispatcher.php) diff --git a/modules/concepts/hooks/list-of-hooks/overrideLayoutTemplate.md b/modules/concepts/hooks/list-of-hooks/overrideLayoutTemplate.md index 13a787e53e..f76747f49f 100644 --- a/modules/concepts/hooks/list-of-hooks/overrideLayoutTemplate.md +++ b/modules/concepts/hooks/list-of-hooks/overrideLayoutTemplate.md @@ -19,9 +19,6 @@ hookAliases: Hook locations: - frontoffice -Hook type: - - - Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/FrontController.php](classes/controller/FrontController.php) diff --git a/modules/concepts/hooks/list-of-hooks/overrideMinimalPurchasePrice.md b/modules/concepts/hooks/list-of-hooks/overrideMinimalPurchasePrice.md index cebdc9f5d8..18973d3064 100644 --- a/modules/concepts/hooks/list-of-hooks/overrideMinimalPurchasePrice.md +++ b/modules/concepts/hooks/list-of-hooks/overrideMinimalPurchasePrice.md @@ -19,9 +19,6 @@ hookAliases: Hook locations: - frontoffice -Hook type: - - - Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Presenter/Cart/CartPresenter.php](src/Adapter/Presenter/Cart/CartPresenter.php) diff --git a/modules/concepts/hooks/list-of-hooks/productSearchProvider.md b/modules/concepts/hooks/list-of-hooks/productSearchProvider.md index 386e29cbdb..c4e0781286 100644 --- a/modules/concepts/hooks/list-of-hooks/productSearchProvider.md +++ b/modules/concepts/hooks/list-of-hooks/productSearchProvider.md @@ -19,9 +19,6 @@ hookAliases: Hook locations: - frontoffice -Hook type: - - - Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/ProductListingFrontController.php](classes/controller/ProductListingFrontController.php) diff --git a/modules/concepts/hooks/list-of-hooks/sendMailAlterTemplateVars.md b/modules/concepts/hooks/list-of-hooks/sendMailAlterTemplateVars.md index 553bae6a1b..1b8a332801 100644 --- a/modules/concepts/hooks/list-of-hooks/sendMailAlterTemplateVars.md +++ b/modules/concepts/hooks/list-of-hooks/sendMailAlterTemplateVars.md @@ -25,9 +25,6 @@ This hook is called when Mail::send() is called Hook locations: - frontoffice -Hook type: - - - Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Mail.php](classes/Mail.php) diff --git a/modules/concepts/hooks/list-of-hooks/termsAndConditions.md b/modules/concepts/hooks/list-of-hooks/termsAndConditions.md index cbe57a521b..bbd950e168 100644 --- a/modules/concepts/hooks/list-of-hooks/termsAndConditions.md +++ b/modules/concepts/hooks/list-of-hooks/termsAndConditions.md @@ -19,9 +19,6 @@ hookAliases: Hook locations: - frontoffice -Hook type: - - - Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/checkout/ConditionsToApproveFinder.php](classes/checkout/ConditionsToApproveFinder.php) diff --git a/modules/concepts/hooks/list-of-hooks/validateCustomerFormFields.md b/modules/concepts/hooks/list-of-hooks/validateCustomerFormFields.md index 574ebfc317..74e48429cd 100644 --- a/modules/concepts/hooks/list-of-hooks/validateCustomerFormFields.md +++ b/modules/concepts/hooks/list-of-hooks/validateCustomerFormFields.md @@ -25,9 +25,6 @@ This hook is called to a module when it has sent additional fields with addition Hook locations: - frontoffice -Hook type: - - - Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/form/CustomerForm.php](classes/form/CustomerForm.php) From 9a8b7c587d7ab6439bfe41ad69e52bb3956c1af2 Mon Sep 17 00:00:00 2001 From: Thomas Nares Date: Wed, 7 Dec 2022 10:41:04 +0100 Subject: [PATCH 157/310] change link to hook component --- .../hooks/list-of-hooks/actionEmailAddAfterContent.md | 2 +- .../hooks/list-of-hooks/actionEmailAddBeforeContent.md | 2 +- modules/concepts/hooks/list-of-hooks/actionEmailSendBefore.md | 2 +- .../hooks/list-of-hooks/actionFrontControllerSetVariables.md | 2 +- .../hooks/list-of-hooks/actionGetAlternativeSearchPanels.md | 2 +- .../hooks/list-of-hooks/actionGetExtraMailTemplateVars.md | 2 +- .../list-of-hooks/actionObjectProductInCartDeleteBefore.md | 2 +- .../concepts/hooks/list-of-hooks/addWebserviceResources.md | 4 ++-- .../hooks/list-of-hooks/additionalCustomerAddressFields.md | 2 +- .../hooks/list-of-hooks/additionalCustomerFormFields.md | 2 +- modules/concepts/hooks/list-of-hooks/dashboardData.md | 2 +- modules/concepts/hooks/list-of-hooks/filterCategoryContent.md | 2 +- .../concepts/hooks/list-of-hooks/filterCmsCategoryContent.md | 2 +- modules/concepts/hooks/list-of-hooks/filterCmsContent.md | 2 +- modules/concepts/hooks/list-of-hooks/filterHtmlContent.md | 2 +- .../concepts/hooks/list-of-hooks/filterManufacturerContent.md | 2 +- modules/concepts/hooks/list-of-hooks/filterProductContent.md | 2 +- modules/concepts/hooks/list-of-hooks/filterSupplierContent.md | 2 +- modules/concepts/hooks/list-of-hooks/gSitemapAppendUrls.md | 2 +- modules/concepts/hooks/list-of-hooks/moduleRoutes.md | 4 ++-- modules/concepts/hooks/list-of-hooks/productSearchProvider.md | 2 +- modules/concepts/hooks/list-of-hooks/termsAndConditions.md | 2 +- .../hooks/list-of-hooks/validateCustomerFormFields.md | 2 +- 23 files changed, 25 insertions(+), 25 deletions(-) diff --git a/modules/concepts/hooks/list-of-hooks/actionEmailAddAfterContent.md b/modules/concepts/hooks/list-of-hooks/actionEmailAddAfterContent.md index 43e8101490..8f2ca9ae6e 100644 --- a/modules/concepts/hooks/list-of-hooks/actionEmailAddAfterContent.md +++ b/modules/concepts/hooks/list-of-hooks/actionEmailAddAfterContent.md @@ -31,7 +31,7 @@ Hook type: Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Mail.php](classes/Mail.php) -This hook has an `$array_return` parameter set to `true` (module output will be set by name in an array, [see explaination here]({{< relref "/8/modules/concepts/hooks">}})). +This hook has an `$array_return` parameter set to `true` (module output will be set by name in an array, [see explaination here]({{< relref "/8/development/components/hook/dispatching-hook">}})). ## Hook call in codebase diff --git a/modules/concepts/hooks/list-of-hooks/actionEmailAddBeforeContent.md b/modules/concepts/hooks/list-of-hooks/actionEmailAddBeforeContent.md index 7035c27e9e..88dd347708 100644 --- a/modules/concepts/hooks/list-of-hooks/actionEmailAddBeforeContent.md +++ b/modules/concepts/hooks/list-of-hooks/actionEmailAddBeforeContent.md @@ -31,7 +31,7 @@ Hook type: Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Mail.php](classes/Mail.php) -This hook has an `$array_return` parameter set to `true` (module output will be set by name in an array, [see explaination here]({{< relref "/8/modules/concepts/hooks">}})). +This hook has an `$array_return` parameter set to `true` (module output will be set by name in an array, [see explaination here]({{< relref "/8/development/components/hook/dispatching-hook">}})). ## Hook call in codebase diff --git a/modules/concepts/hooks/list-of-hooks/actionEmailSendBefore.md b/modules/concepts/hooks/list-of-hooks/actionEmailSendBefore.md index 51a6bf8582..e30f7524eb 100644 --- a/modules/concepts/hooks/list-of-hooks/actionEmailSendBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionEmailSendBefore.md @@ -31,7 +31,7 @@ Hook type: Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Mail.php](classes/Mail.php) -This hook has an `$array_return` parameter set to `true` (module output will be set by name in an array, [see explaination here]({{< relref "/8/modules/concepts/hooks">}})). +This hook has an `$array_return` parameter set to `true` (module output will be set by name in an array, [see explaination here]({{< relref "/8/development/components/hook/dispatching-hook">}})). ## Hook call in codebase diff --git a/modules/concepts/hooks/list-of-hooks/actionFrontControllerSetVariables.md b/modules/concepts/hooks/list-of-hooks/actionFrontControllerSetVariables.md index 96e198c356..a05b9d30af 100644 --- a/modules/concepts/hooks/list-of-hooks/actionFrontControllerSetVariables.md +++ b/modules/concepts/hooks/list-of-hooks/actionFrontControllerSetVariables.md @@ -31,7 +31,7 @@ Hook type: Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/FrontController.php](classes/controller/FrontController.php) -This hook has an `$array_return` parameter set to `true` (module output will be set by name in an array, [see explaination here]({{< relref "/8/modules/concepts/hooks">}})). +This hook has an `$array_return` parameter set to `true` (module output will be set by name in an array, [see explaination here]({{< relref "/8/development/components/hook/dispatching-hook">}})). ## Parameters details diff --git a/modules/concepts/hooks/list-of-hooks/actionGetAlternativeSearchPanels.md b/modules/concepts/hooks/list-of-hooks/actionGetAlternativeSearchPanels.md index 5193a01911..4e7160fcf0 100644 --- a/modules/concepts/hooks/list-of-hooks/actionGetAlternativeSearchPanels.md +++ b/modules/concepts/hooks/list-of-hooks/actionGetAlternativeSearchPanels.md @@ -31,7 +31,7 @@ Hook type: Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/admin/AdminSearchController.php](controllers/admin/AdminSearchController.php) -This hook has an `$array_return` parameter set to `true` (module output will be set by name in an array, [see explaination here]({{< relref "/8/modules/concepts/hooks">}})). +This hook has an `$array_return` parameter set to `true` (module output will be set by name in an array, [see explaination here]({{< relref "/8/development/components/hook/dispatching-hook">}})). ## Parameters details diff --git a/modules/concepts/hooks/list-of-hooks/actionGetExtraMailTemplateVars.md b/modules/concepts/hooks/list-of-hooks/actionGetExtraMailTemplateVars.md index deccc635b7..a6046c87b8 100644 --- a/modules/concepts/hooks/list-of-hooks/actionGetExtraMailTemplateVars.md +++ b/modules/concepts/hooks/list-of-hooks/actionGetExtraMailTemplateVars.md @@ -25,7 +25,7 @@ Hook type: Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Mail.php](classes/Mail.php) -This hook has an `$array_return` parameter set to `true` (module output will be set by name in an array, [see explaination here]({{< relref "/8/modules/concepts/hooks">}})). +This hook has an `$array_return` parameter set to `true` (module output will be set by name in an array, [see explaination here]({{< relref "/8/development/components/hook/dispatching-hook">}})). ## Hook call in codebase diff --git a/modules/concepts/hooks/list-of-hooks/actionObjectProductInCartDeleteBefore.md b/modules/concepts/hooks/list-of-hooks/actionObjectProductInCartDeleteBefore.md index 2726cdbcd2..e9bd6e2bd3 100644 --- a/modules/concepts/hooks/list-of-hooks/actionObjectProductInCartDeleteBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionObjectProductInCartDeleteBefore.md @@ -33,7 +33,7 @@ Hook type: Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/front/CartController.php](controllers/front/CartController.php) -This hook has an `$array_return` parameter set to `true` (module output will be set by name in an array, [see explaination here]({{< relref "/8/modules/concepts/hooks">}})). +This hook has an `$array_return` parameter set to `true` (module output will be set by name in an array, [see explaination here]({{< relref "/8/development/components/hook/dispatching-hook">}})). ## Hook call in codebase diff --git a/modules/concepts/hooks/list-of-hooks/addWebserviceResources.md b/modules/concepts/hooks/list-of-hooks/addWebserviceResources.md index 2a4ed1c9e8..709b8d3a3d 100644 --- a/modules/concepts/hooks/list-of-hooks/addWebserviceResources.md +++ b/modules/concepts/hooks/list-of-hooks/addWebserviceResources.md @@ -31,9 +31,9 @@ Hook type: Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/webservice/WebserviceRequest.php](classes/webservice/WebserviceRequest.php) -This hook has an `$array_return` parameter set to `true` (module output will be set by name in an array, [see explaination here]({{< relref "/8/modules/concepts/hooks">}})). +This hook has an `$array_return` parameter set to `true` (module output will be set by name in an array, [see explaination here]({{< relref "/8/development/components/hook/dispatching-hook">}})). -This hook has a `$check_exceptions` parameter set to `false` (check permission exceptions, [see explaination here]({{< relref "/8/modules/concepts/hooks">}})). +This hook has a `$check_exceptions` parameter set to `false` (check permission exceptions, [see explaination here]({{< relref "/8/development/components/hook/dispatching-hook">}})). ## Hook call in codebase diff --git a/modules/concepts/hooks/list-of-hooks/additionalCustomerAddressFields.md b/modules/concepts/hooks/list-of-hooks/additionalCustomerAddressFields.md index bfbee46092..c72394abbb 100644 --- a/modules/concepts/hooks/list-of-hooks/additionalCustomerAddressFields.md +++ b/modules/concepts/hooks/list-of-hooks/additionalCustomerAddressFields.md @@ -31,7 +31,7 @@ Hook type: Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/form/CustomerAddressFormatter.php](classes/form/CustomerAddressFormatter.php) -This hook has an `$array_return` parameter set to `true` (module output will be set by name in an array, [see explaination here]({{< relref "/8/modules/concepts/hooks">}})). +This hook has an `$array_return` parameter set to `true` (module output will be set by name in an array, [see explaination here]({{< relref "/8/development/components/hook/dispatching-hook">}})). ## Hook call in codebase diff --git a/modules/concepts/hooks/list-of-hooks/additionalCustomerFormFields.md b/modules/concepts/hooks/list-of-hooks/additionalCustomerFormFields.md index cfc936b65e..8a2647ad9b 100644 --- a/modules/concepts/hooks/list-of-hooks/additionalCustomerFormFields.md +++ b/modules/concepts/hooks/list-of-hooks/additionalCustomerFormFields.md @@ -31,7 +31,7 @@ Hook type: Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/form/CustomerFormatter.php](classes/form/CustomerFormatter.php) -This hook has an `$array_return` parameter set to `true` (module output will be set by name in an array, [see explaination here]({{< relref "/8/modules/concepts/hooks">}})). +This hook has an `$array_return` parameter set to `true` (module output will be set by name in an array, [see explaination here]({{< relref "/8/development/components/hook/dispatching-hook">}})). ## Hook call in codebase diff --git a/modules/concepts/hooks/list-of-hooks/dashboardData.md b/modules/concepts/hooks/list-of-hooks/dashboardData.md index 3568ecb47e..b8d6af8840 100644 --- a/modules/concepts/hooks/list-of-hooks/dashboardData.md +++ b/modules/concepts/hooks/list-of-hooks/dashboardData.md @@ -25,7 +25,7 @@ Hook type: Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/admin/AdminDashboardController.php](controllers/admin/AdminDashboardController.php) -This hook has an `$array_return` parameter set to `true` (module output will be set by name in an array, [see explaination here]({{< relref "/8/modules/concepts/hooks">}})). +This hook has an `$array_return` parameter set to `true` (module output will be set by name in an array, [see explaination here]({{< relref "/8/development/components/hook/dispatching-hook">}})). ## Hook call in codebase diff --git a/modules/concepts/hooks/list-of-hooks/filterCategoryContent.md b/modules/concepts/hooks/list-of-hooks/filterCategoryContent.md index 2b589745de..c73d835ddf 100644 --- a/modules/concepts/hooks/list-of-hooks/filterCategoryContent.md +++ b/modules/concepts/hooks/list-of-hooks/filterCategoryContent.md @@ -28,7 +28,7 @@ Hook locations: Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/front/listing/CategoryController.php](controllers/front/listing/CategoryController.php) -This hook has a `$chain` parameter set to `true` (hook will chain the return of hook module, [see explaination here]({{< relref "/8/modules/concepts/hooks">}})). +This hook has a `$chain` parameter set to `true` (hook will chain the return of hook module, [see explaination here]({{< relref "/8/development/components/hook/dispatching-hook">}})). ## Parameters details diff --git a/modules/concepts/hooks/list-of-hooks/filterCmsCategoryContent.md b/modules/concepts/hooks/list-of-hooks/filterCmsCategoryContent.md index 0a5dfe1af5..005228a32b 100644 --- a/modules/concepts/hooks/list-of-hooks/filterCmsCategoryContent.md +++ b/modules/concepts/hooks/list-of-hooks/filterCmsCategoryContent.md @@ -28,7 +28,7 @@ Hook locations: Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/front/CmsController.php](controllers/front/CmsController.php) -This hook has a `$chain` parameter set to `true` (hook will chain the return of hook module, [see explaination here]({{< relref "/8/modules/concepts/hooks">}})). +This hook has a `$chain` parameter set to `true` (hook will chain the return of hook module, [see explaination here]({{< relref "/8/development/components/hook/dispatching-hook">}})). ## Hook call in codebase diff --git a/modules/concepts/hooks/list-of-hooks/filterCmsContent.md b/modules/concepts/hooks/list-of-hooks/filterCmsContent.md index 85fac09030..6181122023 100644 --- a/modules/concepts/hooks/list-of-hooks/filterCmsContent.md +++ b/modules/concepts/hooks/list-of-hooks/filterCmsContent.md @@ -28,7 +28,7 @@ Hook locations: Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/front/CmsController.php](controllers/front/CmsController.php) -This hook has a `$chain` parameter set to `true` (hook will chain the return of hook module, [see explaination here]({{< relref "/8/modules/concepts/hooks">}})). +This hook has a `$chain` parameter set to `true` (hook will chain the return of hook module, [see explaination here]({{< relref "/8/development/components/hook/dispatching-hook">}})). ## Hook call in codebase diff --git a/modules/concepts/hooks/list-of-hooks/filterHtmlContent.md b/modules/concepts/hooks/list-of-hooks/filterHtmlContent.md index 9517a14291..3c8373d5b6 100644 --- a/modules/concepts/hooks/list-of-hooks/filterHtmlContent.md +++ b/modules/concepts/hooks/list-of-hooks/filterHtmlContent.md @@ -28,7 +28,7 @@ Hook locations: Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Presenter/Object/ObjectPresenter.php](src/Adapter/Presenter/Object/ObjectPresenter.php) -This hook has a `$chain` parameter set to `true` (hook will chain the return of hook module, [see explaination here]({{< relref "/8/modules/concepts/hooks">}})). +This hook has a `$chain` parameter set to `true` (hook will chain the return of hook module, [see explaination here]({{< relref "/8/development/components/hook/dispatching-hook">}})). ## Hook call in codebase diff --git a/modules/concepts/hooks/list-of-hooks/filterManufacturerContent.md b/modules/concepts/hooks/list-of-hooks/filterManufacturerContent.md index 67025953f1..f324201769 100644 --- a/modules/concepts/hooks/list-of-hooks/filterManufacturerContent.md +++ b/modules/concepts/hooks/list-of-hooks/filterManufacturerContent.md @@ -28,7 +28,7 @@ Hook locations: Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/front/listing/ManufacturerController.php](controllers/front/listing/ManufacturerController.php) -This hook has a `$chain` parameter set to `true` (hook will chain the return of hook module, [see explaination here]({{< relref "/8/modules/concepts/hooks">}})). +This hook has a `$chain` parameter set to `true` (hook will chain the return of hook module, [see explaination here]({{< relref "/8/development/components/hook/dispatching-hook">}})). ## Hook call in codebase diff --git a/modules/concepts/hooks/list-of-hooks/filterProductContent.md b/modules/concepts/hooks/list-of-hooks/filterProductContent.md index fb245e8fd4..c18f8ae439 100644 --- a/modules/concepts/hooks/list-of-hooks/filterProductContent.md +++ b/modules/concepts/hooks/list-of-hooks/filterProductContent.md @@ -28,7 +28,7 @@ Hook locations: Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/front/ProductController.php](controllers/front/ProductController.php) -This hook has a `$chain` parameter set to `true` (hook will chain the return of hook module, [see explaination here]({{< relref "/8/modules/concepts/hooks">}})). +This hook has a `$chain` parameter set to `true` (hook will chain the return of hook module, [see explaination here]({{< relref "/8/development/components/hook/dispatching-hook">}})). ## Hook call in codebase diff --git a/modules/concepts/hooks/list-of-hooks/filterSupplierContent.md b/modules/concepts/hooks/list-of-hooks/filterSupplierContent.md index f5ba6aed60..5a5dac5b6b 100644 --- a/modules/concepts/hooks/list-of-hooks/filterSupplierContent.md +++ b/modules/concepts/hooks/list-of-hooks/filterSupplierContent.md @@ -28,7 +28,7 @@ Hook locations: Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/front/listing/SupplierController.php](controllers/front/listing/SupplierController.php) -This hook has a `$chain` parameter set to `true` (hook will chain the return of hook module, [see explaination here]({{< relref "/8/modules/concepts/hooks">}})). +This hook has a `$chain` parameter set to `true` (hook will chain the return of hook module, [see explaination here]({{< relref "/8/development/components/hook/dispatching-hook">}})). ## Hook call in codebase diff --git a/modules/concepts/hooks/list-of-hooks/gSitemapAppendUrls.md b/modules/concepts/hooks/list-of-hooks/gSitemapAppendUrls.md index 536ed79593..54f8cc1a27 100644 --- a/modules/concepts/hooks/list-of-hooks/gSitemapAppendUrls.md +++ b/modules/concepts/hooks/list-of-hooks/gSitemapAppendUrls.md @@ -22,7 +22,7 @@ Hook locations: Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/modules/gsitemap/gsitemap.php](modules/gsitemap/gsitemap.php) -This hook has an `$array_return` parameter set to `true` (module output will be set by name in an array, [see explaination here]({{< relref "/8/modules/concepts/hooks">}})). +This hook has an `$array_return` parameter set to `true` (module output will be set by name in an array, [see explaination here]({{< relref "/8/development/components/hook/dispatching-hook">}})). ## Hook call in codebase diff --git a/modules/concepts/hooks/list-of-hooks/moduleRoutes.md b/modules/concepts/hooks/list-of-hooks/moduleRoutes.md index e12729a7ac..52e499d0bf 100644 --- a/modules/concepts/hooks/list-of-hooks/moduleRoutes.md +++ b/modules/concepts/hooks/list-of-hooks/moduleRoutes.md @@ -22,9 +22,9 @@ Hook locations: Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Dispatcher.php](classes/Dispatcher.php) -This hook has an `$array_return` parameter set to `true` (module output will be set by name in an array, [see explaination here]({{< relref "/8/modules/concepts/hooks">}})). +This hook has an `$array_return` parameter set to `true` (module output will be set by name in an array, [see explaination here]({{< relref "/8/development/components/hook/dispatching-hook">}})). -This hook has a `$check_exception` parameter set to `false` (check permission exception, [see explaination here]({{< relref "/8/modules/concepts/hooks">}})). +This hook has a `$check_exception` parameter set to `false` (check permission exception, [see explaination here]({{< relref "/8/development/components/hook/dispatching-hook">}})). ## Hook call in codebase diff --git a/modules/concepts/hooks/list-of-hooks/productSearchProvider.md b/modules/concepts/hooks/list-of-hooks/productSearchProvider.md index c4e0781286..8af257ba00 100644 --- a/modules/concepts/hooks/list-of-hooks/productSearchProvider.md +++ b/modules/concepts/hooks/list-of-hooks/productSearchProvider.md @@ -22,7 +22,7 @@ Hook locations: Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/ProductListingFrontController.php](classes/controller/ProductListingFrontController.php) -This hook has an `$array_return` parameter set to `true` (module output will be set by name in an array, [see explaination here]({{< relref "/8/modules/concepts/hooks">}})). +This hook has an `$array_return` parameter set to `true` (module output will be set by name in an array, [see explaination here]({{< relref "/8/development/components/hook/dispatching-hook">}})). ## Hook call in codebase diff --git a/modules/concepts/hooks/list-of-hooks/termsAndConditions.md b/modules/concepts/hooks/list-of-hooks/termsAndConditions.md index bbd950e168..016593458b 100644 --- a/modules/concepts/hooks/list-of-hooks/termsAndConditions.md +++ b/modules/concepts/hooks/list-of-hooks/termsAndConditions.md @@ -22,7 +22,7 @@ Hook locations: Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/checkout/ConditionsToApproveFinder.php](classes/checkout/ConditionsToApproveFinder.php) -This hook has an `$array_return` parameter set to `true` (module output will be set by name in an array, [see explaination here]({{< relref "/8/modules/concepts/hooks">}})). +This hook has an `$array_return` parameter set to `true` (module output will be set by name in an array, [see explaination here]({{< relref "/8/development/components/hook/dispatching-hook">}})). ## Hook call in codebase diff --git a/modules/concepts/hooks/list-of-hooks/validateCustomerFormFields.md b/modules/concepts/hooks/list-of-hooks/validateCustomerFormFields.md index 74e48429cd..5260067620 100644 --- a/modules/concepts/hooks/list-of-hooks/validateCustomerFormFields.md +++ b/modules/concepts/hooks/list-of-hooks/validateCustomerFormFields.md @@ -28,7 +28,7 @@ Hook locations: Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/form/CustomerForm.php](classes/form/CustomerForm.php) -This hook has an `$array_return` parameter set to `true` (module output will be set by name in an array, [see explaination here]({{< relref "/8/modules/concepts/hooks">}})). +This hook has an `$array_return` parameter set to `true` (module output will be set by name in an array, [see explaination here]({{< relref "/8/development/components/hook/dispatching-hook">}})). ## Hook call in codebase From a2f38b8cfaff12d122544351d44b6df14001fef9 Mon Sep 17 00:00:00 2001 From: Thomas NARES Date: Thu, 8 Dec 2022 09:31:28 +0100 Subject: [PATCH 158/310] Apply suggestions from code review Co-authored-by: Krystian Podemski --- development/orders-lifecycle/_index.md | 28 +++++++++++++------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/development/orders-lifecycle/_index.md b/development/orders-lifecycle/_index.md index 92dc7a003c..e9c0134e3c 100644 --- a/development/orders-lifecycle/_index.md +++ b/development/orders-lifecycle/_index.md @@ -7,7 +7,7 @@ useMermaid: true # Order lifecycle: Cart, Checkout, and Order {{% notice note %}} -Orders can be created from a cart either in Front Office (FO) by the customer or in Back Office (BO) `Sell -> Orders -> "Add new order"` by the shop admin. See [Add new order page]({{< relref "../page-reference/back-office/order/add-new-order" >}}). +Orders can be created from a cart, either in Front Office (FO) by the customer or Back Office (BO) `Sell -> Orders -> "Add new order"` by the shop employee. See [Add new order page]({{< relref "../page-reference/back-office/order/add-new-order" >}}). {{% /notice %}} ## Carts @@ -22,7 +22,7 @@ creating a new one.
flowchart LR A(Guest with empty cart)-->|Add item to Cart|B{{Cart creation}}-->C(Cart)-->|Login|D{{Associate cart to customer}}-->F - A-->|Login|G{{Cart creation}}-->E{{Associate cart to customer}}-->F(Associated Cart) + A-->|Login|G{{Cart creation}}-->E{{Associate cart to customer}}-->F(Associated cart)
{{% notice note %}} @@ -33,7 +33,7 @@ can be adjusted in BO `Configure -> Administration -> General "lifetime of front ### Cart in Back Office (BO) -When creating an order in the BO, a new empty cart is created once the customer is selected. An existing cart (already associated to the customer) can also be selected, or an existing order can be used to create a new cart. +When creating an order in the BO, a new empty cart is created once the customer is selected. You can also choose an existing cart (already associated with the customer) or an existing order on which the new cart will base.
flowchart LR @@ -59,18 +59,18 @@ flowchart TB Please note that if a cart contains only Virtual products, there is no `checkout-addresses-step` and `checkout-delivery-step`. It goes directly from `checkout-personal-information-step` to `checkout-payment-step`. {{% /notice %}} -1. **Associate to customer** (checkout-personal-information-step): details like name, email, birthday etc. In FO you can either fill - this information manually as guest (and optionally create new customer account) or login with existing customer. - In BO order creation you will be asked to select an existing customer before you can modify the existing cart or create a new one. +1. **Associate to customer** (checkout-personal-information-step): details like name, email, birthday, etc. In FO you can either fill + this information manually as a guest (and optionally create a new customer account) or log in as an existing customer. + If you create an order from BO, you will be asked to select an existing customer before modifying the existing cart or creating a new one. 2. **Select shipping and invoice addresses** (checkout-addresses-step): provide the shipping and invoice addresses information. - Shipping (a.k.a. delivery) address is where the ordered products should be sent while the invoice address is where the invoice is sent. + The shipping (a.k.a. delivery) address is where the ordered products should be sent, while the invoice address is used as a document billing address. In FO, you can provide one address to be used as both - shipping and invoice. In BO, you must select shipping and invoice addresses (the same address can also be selected for both - shipping and invoices). -3. **Select shipping method and carrier** (checkout-delivery-step): after this step is complete you will need to select available carriers - (carriers are searched by delivery address and can be modified by shop admin in Improve -> Shipping -> Carriers page). - Note - carrier will not be available if selected country or zone is disabled (in BO International -> Locations) or carrier shipping +3. **Select a shipping method** (checkout-delivery-step): after this step is complete, you will need to select one of the available carriers + (carriers are searched by delivery address, sometimes the total weight of the products, their prices, and information about the customer (a group to which the customer belongs) and can be modified by shop employees on Improve -> Shipping -> Carriers page). + Note that the carrier will not be available if a selected country or zone is disabled (in BO International -> Locations) or carrier shipping and locations settings are not configured. -3. **Select payment method** (checkout-payment-step): choose how to pay for the order. Shop admin can configure payment methods in +3. **Select payment method** (checkout-payment-step): choose how to pay for the order. Shop employees can configure payment methods in BO Payment -> Payment methods. All payments are handled by payment modules. Prestashop comes with 2 payment modules by default: @@ -78,9 +78,9 @@ Please note that if a cart contains only Virtual products, there is no `checkout * ps_wirepayment - allows wire payments (bank transfers). {{% notice note %}} - Payment restrictions for currency, country, group and carrier can be configured in BO `Improve -> Payment -> Preferences`. + You can restrict the availability of the payment methods in FO by currencies, countries, and groups and map them to carriers (ship2pay). You can do that in BO `Improve -> Payment -> Preferences`. {{% /notice %}} -4. **Submit Order**: Once the order is submitted, a unique order reference is generated and certain records from a cart and related +4. **Submit Order**: Once the order is submitted, a unique order reference is generated, and certain records from a cart and related entities are added into following database tables: * `orders` * `order_history` @@ -90,7 +90,7 @@ Please note that if a cart contains only Virtual products, there is no `checkout * `order_detail_tax` (if any taxes are applied) {{% notice note %}} -At this step, some important data is duplicated (in `order_detail`) to ensure product data will remain available in the order even if the product is deleted afterwards. Price information is also duplicated, to ensure the order amount will remain immutable. +At this step, some important data is duplicated (in `order_detail`) to ensure product data will remain available in the order even if the product is deleted or modified afterward. Information about the prices is also duplicated to ensure the order amount will remain immutable. {{% /notice %}} 5. After order is successfully created, an email with the order information is sent to the customer. From b99f01f3e61a7dd8ad6c0c42f338117c027f82fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20Fernandez?= <50865159+micka-fdz@users.noreply.github.com> Date: Mon, 12 Dec 2022 15:45:19 +0100 Subject: [PATCH 159/310] Fix typo on install-from-cli.md --- basics/installation/install-from-cli.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/basics/installation/install-from-cli.md b/basics/installation/install-from-cli.md index 48b237182d..268c6669c1 100644 --- a/basics/installation/install-from-cli.md +++ b/basics/installation/install-from-cli.md @@ -78,7 +78,7 @@ To start the installation, we recommend that you provide at least these argument Example: ```shell -php install_cli.php +php index_cli.php --domain=example.com --db_server=sql.example.com --db_name=myshop @@ -108,4 +108,4 @@ If your MySQL server is configured on a different port than `3306`, please speci [iso-639-1]: https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes [tz-database]: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones [activities]: https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Form/Admin/Configure/ShopParameters/General/PreferencesType.php#L211-L230 -[iso-3166]: https://en.wikipedia.org/wiki/List_of_ISO_3166_country_codes \ No newline at end of file +[iso-3166]: https://en.wikipedia.org/wiki/List_of_ISO_3166_country_codes From d402b7a7db9d2332b4805648490dce74535b5bee Mon Sep 17 00:00:00 2001 From: Louis AUTHIE <65625876+LouisAUTHIE@users.noreply.github.com> Date: Mon, 12 Dec 2022 15:54:32 +0100 Subject: [PATCH 160/310] Update _index.md --- modules/concepts/services/_index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/concepts/services/_index.md b/modules/concepts/services/_index.md index 4ebedf5ced..11e3dfa960 100644 --- a/modules/concepts/services/_index.md +++ b/modules/concepts/services/_index.md @@ -317,7 +317,7 @@ class yourmodule { ### Environments Keep in mind that the legacy container is a light version of the full Symfony container so you won't have access to all the -Symfony components. But you will be able to use the **Doctrine** service as well as a few few core services from PrestaShop. +Symfony components. But you will be able to use the **Doctrine** service as well as a few core services from PrestaShop. For more details about available services you can check in `/config/services/` folder which services are available in admin or front. Be careful and always keep in mind in which context/environment you are calling your service. From 99c9bd9b595c3164c2dfc36d9af9821ad6e40005 Mon Sep 17 00:00:00 2001 From: Thomas Nares Date: Tue, 13 Dec 2022 10:13:05 +0400 Subject: [PATCH 161/310] improve order lifecycle --- development/orders-lifecycle/_index.md | 90 +++++++++++++------------- 1 file changed, 45 insertions(+), 45 deletions(-) diff --git a/development/orders-lifecycle/_index.md b/development/orders-lifecycle/_index.md index e9c0134e3c..95b109db76 100644 --- a/development/orders-lifecycle/_index.md +++ b/development/orders-lifecycle/_index.md @@ -7,39 +7,39 @@ useMermaid: true # Order lifecycle: Cart, Checkout, and Order {{% notice note %}} -Orders can be created from a cart, either in Front Office (FO) by the customer or Back Office (BO) `Sell -> Orders -> "Add new order"` by the shop employee. See [Add new order page]({{< relref "../page-reference/back-office/order/add-new-order" >}}). +Orders can be created from a Cart, either in Front Office (FO) by the Customer or Back Office (BO) `Sell -> Orders -> "Add new Order"` by the Shop Employee. See [Add new Order page]({{< relref "../page-reference/back-office/order/add-new-order" >}}). {{% /notice %}} ## Carts ### Cart in Front Office (FO) -In FO by default, a new empty cart is created in database everytime a customer signs in - this behavior can be adjusted in BO -`Configure -> Shop parameters -> Customer settings`. If customer is not signed in (guest) - the cart is created in database once -first product is being added into it. If guest already has a cart and signs in, the cart is assigned to him instead of +In FO by default, a new empty Cart is created in database everytime a Customer signs in - this behavior can be adjusted in BO +`Configure -> Shop parameters -> Customer settings`. If Customer is not signed in (guest) - the Cart is created in database once +first Product is being added into it. If guest already has a Cart and signs in, the Cart is assigned to him instead of creating a new one.
flowchart LR - A(Guest with empty cart)-->|Add item to Cart|B{{Cart creation}}-->C(Cart)-->|Login|D{{Associate cart to customer}}-->F - A-->|Login|G{{Cart creation}}-->E{{Associate cart to customer}}-->F(Associated cart) + A(Guest with empty Cart)-->|Add item to Cart|B{{Cart creation}}-->C(Cart)-->|Login|D{{Associate Cart to Customer}}-->F + A-->|Login|G{{Cart creation}}-->E{{Associate Cart to Customer}}-->F(Associated Cart)
{{% notice note %}} -In FO, browser cookies are used to determine if current guest has a cart. This way guest can still see his previous cart -if he is visiting the shop from the same browser in a short period of time (the time depends on cookie settings, which +In FO, browser cookies are used to determine if current guest has a Cart. This way guest can still see his previous Cart +if he is visiting the Shop from the same browser in a short period of time (the time depends on cookie settings, which can be adjusted in BO `Configure -> Administration -> General "lifetime of front office cookies"`). {{% /notice %}} ### Cart in Back Office (BO) -When creating an order in the BO, a new empty cart is created once the customer is selected. You can also choose an existing cart (already associated with the customer) or an existing order on which the new cart will base. +When creating an Order in the BO, a new empty Cart is created once the Customer is selected. You can also choose an existing Cart (already associated with the Customer) or an existing Order on which the new Cart will base.
flowchart LR - A{{Select Customer}}-->|Create new cart|E{{Cart creation}}-->G - A-->|Use existing cart|B{{Select existing Cart}}-->F - A-->|Create new cart from order|C{{Select existing Order}}-->D{{Cart creation from Order content}}-->G{{Associate cart to customer}}-->F(Associated Cart) + A{{Select Customer}}-->|Create new Cart|E{{Cart creation}}-->G + A-->|Use existing Cart|B{{Select existing Cart}}-->F + A-->|Create new Cart from Order|C{{Select existing Order}}-->D{{Cart creation from Order content}}-->G{{Associate Cart to Customer}}-->F(Associated Cart)
## The Checkout: from Cart to Order @@ -52,56 +52,57 @@ flowchart TB B-->|checkout-addresses-step|C(Cart addressed) C-->|checkout-delivery-step|D(Cart shipping configured) D-->|checkout-payment-step|E(Cart payment configured) - E-->|Submit order|F(Order) + E-->|Submit Order|F(Order)
{{% notice note %}} -Please note that if a cart contains only Virtual products, there is no `checkout-addresses-step` and `checkout-delivery-step`. It goes directly from `checkout-personal-information-step` to `checkout-payment-step`. +Please note that if a Cart contains only Virtual Products, there is no `checkout-addresses-step` and `checkout-delivery-step`. It goes directly from `checkout-personal-information-step` to `checkout-payment-step`. {{% /notice %}} -1. **Associate to customer** (checkout-personal-information-step): details like name, email, birthday, etc. In FO you can either fill - this information manually as a guest (and optionally create a new customer account) or log in as an existing customer. - If you create an order from BO, you will be asked to select an existing customer before modifying the existing cart or creating a new one. +1. **Associate to Customer** (checkout-personal-information-step): details like name, email, birthday, etc. In FO you can either fill + this information manually as a guest (and optionally create a new Customer account) or log in as an existing Customer. + If you create an Order from BO, you will be asked to select an existing Customer before modifying the existing Cart or creating a new one. 2. **Select shipping and invoice addresses** (checkout-addresses-step): provide the shipping and invoice addresses information. - The shipping (a.k.a. delivery) address is where the ordered products should be sent, while the invoice address is used as a document billing address. + The shipping (a.k.a. delivery) address is where the Ordered Products should be sent, while the invoice address is used as a document billing address. In FO, you can provide one address to be used as both - shipping and invoice. In BO, you must select shipping and invoice addresses (the same address can also be selected for both - shipping and invoices). -3. **Select a shipping method** (checkout-delivery-step): after this step is complete, you will need to select one of the available carriers - (carriers are searched by delivery address, sometimes the total weight of the products, their prices, and information about the customer (a group to which the customer belongs) and can be modified by shop employees on Improve -> Shipping -> Carriers page). - Note that the carrier will not be available if a selected country or zone is disabled (in BO International -> Locations) or carrier shipping - and locations settings are not configured. -3. **Select payment method** (checkout-payment-step): choose how to pay for the order. Shop employees can configure payment methods in +3. **Select a shipping method** (checkout-delivery-step): after this step is complete, you will need to select one of the available Carriers + (Carriers are searched by delivery address, sometimes the total weight of the Products, their prices, and information about the Customer (a group to which the Customer belongs) and can be modified by Shop Employees on Improve -> Shipping -> Carriers page). + Note that the Carrier will not be available if a selected country or zone is disabled (in BO International -> Locations) or Carrier shipping and locations settings are not configured. +3. **Select payment method** (checkout-payment-step): choose how to pay for the Order. Shop Employees can configure payment methods in BO Payment -> Payment methods. - All payments are handled by payment modules. Prestashop comes with 2 payment modules by default: + All payments are handled by payment modules. PrestaShop comes with 3 [payment modules]({{< relref "/8/modules/payment" >}}) by default: * ps_checkpayment - allows check payments. * ps_wirepayment - allows wire payments (bank transfers). + * ps_cashondelivery - allows for cash on delivery payments. {{% notice note %}} - You can restrict the availability of the payment methods in FO by currencies, countries, and groups and map them to carriers (ship2pay). You can do that in BO `Improve -> Payment -> Preferences`. +You can restrict the availability of the payment methods in FO by currencies, countries, and groups and map them to Carriers (ship2pay). You can do that in BO `Improve -> Payment -> Preferences`. {{% /notice %}} -4. **Submit Order**: Once the order is submitted, a unique order reference is generated, and certain records from a cart and related + +4. **Submit Order**: Once the Order is submitted, a unique Order reference is generated, and certain records from a Cart and related entities are added into following database tables: - * `orders` - * `order_history` - * `order_detail` - * `order_carrier` - * `order_cart_rule` (if any discounts were applied) - * `order_detail_tax` (if any taxes are applied) + * `Orders` + * `Order_history` + * `Order_detail` + * `Order_carrier` + * `Order_cart_rule` (if any discounts were applied) + * `Order_detail_tax` (if any taxes are applied) {{% notice note %}} -At this step, some important data is duplicated (in `order_detail`) to ensure product data will remain available in the order even if the product is deleted or modified afterward. Information about the prices is also duplicated to ensure the order amount will remain immutable. +At this step, some important data is duplicated (in `Order_detail`) to ensure Product data will remain available in the Order even if the Product is deleted or modified afterward. Information about the prices is also duplicated to ensure the Order amount will remain immutable. {{% /notice %}} -5. After order is successfully created, an email with the order information is sent to the customer. +5. After Order is successfully created, an email with the Order information is sent to the Customer. {{% notice note %}} Email sending settings can be found in BO `Configure -> Advanced parameters -> E-mail`. Email translations and templates in `Improve -> International -> Translations`. -When order is being created in BO, email with the link to a prefilled cart can be sent before creating the order (so the -customer can finish up the checkout process). To do that -click `More actions -> Send pre-filled order to the customer by email` in summary block. +When Order is being created in BO, email with the link to a prefilled Cart can be sent before creating the Order (so the +Customer can finish up the checkout process). To do that +click `More actions -> Send pre-filled Order to the Customer by email` in summary block. {{% /notice %}} {{% notice note %}} @@ -116,20 +117,19 @@ Learn how it works under the hood by looking at: ## Order status -When creating order from the FO, the initial order status will differ depending on selected payment method. For example, -if "Payment by check" is selected, then order will be created with the "Awaiting check payment" status, or if "Bank +When creating Order from the FO, the initial Order status will differ depending on selected payment method. For example, +if "Payment by check" is selected, then Order will be created with the "Awaiting check payment" status, or if "Bank transfer" is selected, the status will be "Awaiting wire payment". Order status changing cycle depends on payment module. Some modules (like the default ones provided above) will require -shop admin to control the order status manually, which can be done in BO `Sell -> Orders -> Orders`. Other more -complicated payment modules, which integrates online payments in checkout process, will control the order status -automatically (e.g. when payment is done, the order status automatically changes to "Payment accepted"). +Shop admin to control the Order status manually, which can be done in BO `Sell -> Orders -> Orders`. Other more +complicated payment modules, which integrates online payments in checkout process, will control the Order status +automatically (e.g. when payment is done, the Order status automatically changes to "Payment accepted"). Order statuses can be configured in BO `Shop parameters -> Order settings -> Statuses`. {{% notice note %}} -When creating order from the BO, the initial order status must be selected manually. - -{{% /notice %}} +When creating Order from the BO, the initial Order status must be selected manually. +{{% /notice %}} \ No newline at end of file From c4507de711c0036ad1fb6649217f8506574cbfac Mon Sep 17 00:00:00 2001 From: Thomas Nares Date: Tue, 13 Dec 2022 17:33:49 +0400 Subject: [PATCH 162/310] Suggestions from review : single type, codebase sentence, < generic name --- .../actionAfter.md | 14 +++++------ .../actionBefore.md | 14 +++++------ .../actionFormModifier.md | 14 +++++------ ...actionListingFieldsModifier.md | 14 +++++------ ...ctionListingResultsModifier.md | 14 +++++------ .../actionOptionsModifier.md | 14 +++++------ ...tionGridPresenterModifier.md | 14 +++++------ ...onFormDataProviderDefaultData.md | 14 +++++------ ...acyControllerName>ListingFieldsModifier.md | 14 +++++------ ...cyControllerName>ListingResultsModifier.md | 14 +++++------ .../list-of-hooks/actionAdminAfter.md | 14 +++++------ .../actionAdminBefore.md | 14 +++++------ .../list-of-hooks/actionAdminActivateAfter.md | 12 ++++------ .../actionAdminActivateBefore.md | 12 ++++------ ...rametersMetaControllerPostProcessBefore.md | 12 ++++------ ...inWebserviceControllerPostProcessBefore.md | 12 ++++------ ...onControllerPostProcessBefore.md | 14 +++++------ ...ministrationControllerPostProcessBefore.md | 12 ++++------ ...ceControllerPostProcessBefore.md | 14 +++++------ ...sPerformanceControllerPostProcessBefore.md | 12 ++++------ .../actionAdminControllerInitAfter.md | 12 ++++------ .../actionAdminControllerInitBefore.md | 12 ++++------ .../actionAdminControllerSetMedia.md | 12 ++++------ .../actionAdminDeactivateAfter.md | 12 ++++------ .../actionAdminDeactivateBefore.md | 12 ++++------ .../list-of-hooks/actionAdminDeleteAfter.md | 12 ++++------ .../list-of-hooks/actionAdminDeleteBefore.md | 12 ++++------ .../actionAdminDuplicateAfter.md | 12 ++++------ .../actionAdminDuplicateBefore.md | 12 ++++------ ...onControllerPostProcessBefore.md | 14 +++++------ ...lGeolocationControllerPostProcessBefore.md | 12 ++++------ ...onControllerPostProcessBefore.md | 14 +++++------ ...LocalizationControllerPostProcessBefore.md | 12 ++++------ .../actionAdminLoginControllerBefore.md | 12 ++++------ .../actionAdminLoginControllerForgotAfter.md | 12 ++++------ .../actionAdminLoginControllerForgotBefore.md | 12 ++++------ .../actionAdminLoginControllerLoginAfter.md | 12 ++++------ .../actionAdminLoginControllerLoginBefore.md | 12 ++++------ .../actionAdminLoginControllerResetAfter.md | 12 ++++------ .../actionAdminLoginControllerResetBefore.md | 12 ++++------ .../actionAdminLoginControllerSetMedia.md | 12 ++++------ ...ionAdminLogsControllerPostProcessBefore.md | 12 ++++------ ...nMaintenanceControllerPostProcessBefore.md | 12 ++++------ .../actionAdminMetaAfterWriteRobotsFile.md | 12 ++++------ .../actionAdminMetaBeforeWriteRobotsFile.md | 12 ++++------ .../list-of-hooks/actionAdminMetaSave.md | 12 ++++------ .../actionAdminOrdersTrackingNumberUpdate.md | 12 ++++------ ...nPreferencesControllerPostProcessBefore.md | 12 ++++------ ...ionAdminProductsControllerActivateAfter.md | 12 ++++------ ...onAdminProductsControllerActivateBefore.md | 12 ++++------ ...nAdminProductsControllerDeactivateAfter.md | 12 ++++------ ...AdminProductsControllerDeactivateBefore.md | 12 ++++------ ...ctionAdminProductsControllerDeleteAfter.md | 12 ++++------ ...tionAdminProductsControllerDeleteBefore.md | 12 ++++------ ...onAdminProductsControllerDuplicateAfter.md | 12 ++++------ ...nAdminProductsControllerDuplicateBefore.md | 12 ++++------ .../actionAdminProductsControllerSortAfter.md | 12 ++++------ ...actionAdminProductsControllerSortBefore.md | 12 ++++------ ...ctionAdminProductsListingFieldsModifier.md | 12 ++++------ ...tionAdminProductsListingResultsModifier.md | 12 ++++------ ...dminSecurityControllerPostProcessBefore.md | 12 ++++------ ...gPreferencesControllerPostProcessBefore.md | 12 ++++------ ...ntrollerPostProcessCarrierOptionsBefore.md | 12 ++++------ ...ncesControllerPostProcessHandlingBefore.md | 12 ++++------ ...taControllerPostProcessBefore.md | 14 +++++------ ...esControllerPostProcessBefore.md | 14 +++++------ ...rPreferencesControllerPostProcessBefore.md | 12 ++++------ ...esControllerPostProcessBefore.md | 14 +++++------ ...tPreferencesControllerPostProcessBefore.md | 12 ++++------ .../list-of-hooks/actionAdminSortAfter.md | 12 ++++------ .../list-of-hooks/actionAdminSortBefore.md | 12 ++++------ ...AdminThemesControllerUpdateoptionsAfter.md | 12 ++++------ .../actionAfterCreateFormHandler.md | 14 +++++------ .../actionAfterUpdateFormHandler.md | 14 +++++------ ...actionAjaxDieBefore.md | 14 +++++------ .../list-of-hooks/actionAjaxDieBefore.md | 12 ++++------ .../actionAttributeCombinationDelete.md | 12 ++++------ .../actionAttributeCombinationSave.md | 12 ++++------ .../list-of-hooks/actionAttributeDelete.md | 12 ++++------ .../actionAttributeGroupDelete.md | 12 ++++------ .../list-of-hooks/actionAttributeGroupSave.md | 12 ++++------ .../list-of-hooks/actionAttributeSave.md | 12 ++++------ .../list-of-hooks/actionAuthentication.md | 12 ++++------ .../actionAuthenticationBefore.md | 12 ++++------ ...actionBeforeAjaxDie.md | 14 +++++------ ...actionBeforeCreateFormHandler.md | 14 +++++------ ...actionBeforeUpdateFormHandler.md | 14 +++++------ .../actionBuildFrontEndObject.md | 12 ++++------ .../actionBuildMailLayoutVariables.md | 12 ++++------ .../list-of-hooks/actionCarrierProcess.md | 12 ++++------ .../list-of-hooks/actionCarrierUpdate.md | 12 ++++------ .../hooks/list-of-hooks/actionCartSave.md | 12 ++++------ .../hooks/list-of-hooks/actionCartSummary.md | 12 ++++------ .../actionCartUpdateQuantityBefore.md | 12 ++++------ .../hooks/list-of-hooks/actionCategoryAdd.md | 12 ++++------ .../list-of-hooks/actionCategoryDelete.md | 12 ++++------ .../list-of-hooks/actionCategoryUpdate.md | 12 ++++------ .../list-of-hooks/actionCheckoutRender.md | 12 ++++------ .../hooks/list-of-hooks/actionClearCache.md | 12 ++++------ .../list-of-hooks/actionClearCompileCache.md | 12 ++++------ .../list-of-hooks/actionClearSf2Cache.md | 12 ++++------ .../actionControllerInitAfter.md | 12 ++++------ .../actionControllerInitBefore.md | 12 ++++------ .../list-of-hooks/actionCustomerAccountAdd.md | 12 ++++------ .../actionCustomerAccountUpdate.md | 12 ++++------ .../list-of-hooks/actionCustomerAddGroups.md | 12 ++++------ .../actionCustomerBeforeUpdateGroup.md | 12 ++++------ .../actionCustomerLogoutAfter.md | 12 ++++------ .../actionCustomerLogoutBefore.md | 12 ++++------ .../list-of-hooks/actionDeleteGDPRCustomer.md | 12 ++++------ .../actionDeliveryPriceByPrice.md | 12 ++++------ .../actionDeliveryPriceByWeight.md | 12 ++++------ .../hooks/list-of-hooks/actionDispatcher.md | 12 ++++------ .../list-of-hooks/actionDispatcherAfter.md | 12 ++++------ .../list-of-hooks/actionDispatcherBefore.md | 12 ++++------ .../list-of-hooks/actionDownloadAttachment.md | 12 ++++------ .../actionEmailAddAfterContent.md | 12 ++++------ .../actionEmailAddBeforeContent.md | 12 ++++------ .../list-of-hooks/actionEmailSendBefore.md | 12 ++++------ .../list-of-hooks/actionExportGDPRData.md | 12 ++++------ .../list-of-hooks/actionFeatureDelete.md | 12 ++++------ .../hooks/list-of-hooks/actionFeatureSave.md | 12 ++++------ .../list-of-hooks/actionFeatureValueDelete.md | 12 ++++------ .../list-of-hooks/actionFeatureValueSave.md | 12 ++++------ .../actionFilterDeliveryOptionList.md | 12 ++++------ .../actionFrontControllerInitAfter.md | 12 ++++------ .../actionFrontControllerInitBefore.md | 12 ++++------ .../actionFrontControllerSetMedia.md | 12 ++++------ .../actionFrontControllerSetVariables.md | 12 ++++------ .../actionGetAdminOrderButtons.md | 14 +++++------ .../actionGetAdminToolbarButtons.md | 12 ++++------ .../actionGetAlternativeSearchPanels.md | 12 ++++------ .../actionGetExtraMailTemplateVars.md | 12 ++++------ .../actionGetIDZoneByAddressID.md | 12 ++++------ .../actionGetMailLayoutTransformations.md | 12 ++++------ .../actionGetProductPropertiesAfter.md | 12 ++++------ ...ctionGetProductPropertiesAfterUnitPrice.md | 12 ++++------ .../actionGetProductPropertiesBefore.md | 12 ++++------ .../list-of-hooks/actionHtaccessCreate.md | 12 ++++------ .../actionInvoiceNumberFormatted.md | 12 ++++------ .../list-of-hooks/actionListMailThemes.md | 12 ++++------ .../actionMailAlterMessageBeforeSend.md | 12 ++++------ .../list-of-hooks/actionModuleInstallAfter.md | 12 ++++------ .../actionModuleInstallBefore.md | 12 ++++------ .../actionModuleMailAlertSendCustomer.md | 12 ++++------ .../actionModuleRegisterHookAfter.md | 12 ++++------ .../actionModuleRegisterHookBefore.md | 12 ++++------ .../actionModuleUnRegisterHookAfter.md | 12 ++++------ .../actionModuleUnRegisterHookBefore.md | 12 ++++------ .../actionModuleUninstallAfter.md | 12 ++++------ .../actionModuleUninstallBefore.md | 12 ++++------ .../actionNewsletterRegistrationAfter.md | 12 ++++------ .../actionNewsletterRegistrationBefore.md | 12 ++++------ .../actionObjectAddAfter.md | 18 +++++++------- .../actionObjectAddBefore.md | 18 +++++++------- .../actionObjectDeleteAfter.md | 18 +++++++------- .../actionObjectDeleteBefore.md | 18 +++++++------- .../actionObjectUpdateAfter.md | 18 +++++++------- .../actionObjectUpdateBefore.md | 18 +++++++------- .../list-of-hooks/actionObjectAddAfter.md | 16 ++++++------- .../list-of-hooks/actionObjectAddBefore.md | 16 ++++++------- .../actionObjectAttributeAddBefore.md | 16 ++++++------- .../actionObjectAttributeGroupAddBefore.md | 16 ++++++------- .../list-of-hooks/actionObjectDeleteAfter.md | 16 ++++++------- .../list-of-hooks/actionObjectDeleteBefore.md | 16 ++++++------- ...actionObjectProductCommentValidateAfter.md | 16 ++++++------- .../actionObjectProductInCartDeleteAfter.md | 16 ++++++------- .../actionObjectProductInCartDeleteBefore.md | 16 ++++++------- .../list-of-hooks/actionObjectUpdateAfter.md | 16 ++++++------- .../list-of-hooks/actionObjectUpdateBefore.md | 16 ++++++------- .../list-of-hooks/actionOnImageCutAfter.md | 12 ++++------ .../list-of-hooks/actionOnImageResizeAfter.md | 12 ++++------ .../hooks/list-of-hooks/actionOrderEdited.md | 12 ++++------ .../actionOrderHistoryAddAfter.md | 12 ++++------ .../hooks/list-of-hooks/actionOrderReturn.md | 12 ++++------ .../hooks/list-of-hooks/actionOrderSlipAdd.md | 12 ++++------ .../actionOrderStatusPostUpdate.md | 12 ++++------ .../list-of-hooks/actionOrderStatusUpdate.md | 12 ++++------ .../list-of-hooks/actionOutputHTMLBefore.md | 12 ++++------ .../actionOverrideEmployeeImage.md | 12 ++++------ .../list-of-hooks/actionPDFInvoiceRender.md | 12 ++++------ .../list-of-hooks/actionPasswordRenew.md | 12 ++++------ .../hooks/list-of-hooks/actionPaymentCCAdd.md | 12 ++++------ .../actionPaymentConfirmation.md | 12 ++++------ .../hooks/list-of-hooks/actionPresentCart.md | 12 ++++------ .../list-of-hooks/actionPresentModule.md | 12 ++++------ .../hooks/list-of-hooks/actionPresentOrder.md | 12 ++++------ .../list-of-hooks/actionPresentOrderReturn.md | 12 ++++------ .../actionPresentPaymentOptions.md | 12 ++++------ .../list-of-hooks/actionPresentProduct.md | 12 ++++------ .../actionPresentProductListing.md | 12 ++++------ .../list-of-hooks/actionProductActivation.md | 12 ++++------ .../hooks/list-of-hooks/actionProductAdd.md | 12 ++++------ .../actionProductAttributeDelete.md | 12 ++++------ .../actionProductAttributeUpdate.md | 12 ++++------ .../list-of-hooks/actionProductCancel.md | 12 ++++------ .../list-of-hooks/actionProductCoverage.md | 12 ++++------ .../list-of-hooks/actionProductDelete.md | 12 ++++------ .../list-of-hooks/actionProductOutOfStock.md | 12 ++++------ .../hooks/list-of-hooks/actionProductSave.md | 12 ++++------ .../list-of-hooks/actionProductSearchAfter.md | 12 ++++------ ...ctionProductSearchProviderRunQueryAfter.md | 12 ++++------ ...tionProductSearchProviderRunQueryBefore.md | 12 ++++------ .../list-of-hooks/actionProductUpdate.md | 12 ++++------ .../hooks/list-of-hooks/actionSearch.md | 12 ++++------ .../hooks/list-of-hooks/actionSetInvoice.md | 12 ++++------ .../actionShopDataDuplication.md | 12 ++++------ .../actionSubmitAccountBefore.md | 12 ++++------ .../actionSubmitCustomerAddressForm.md | 12 ++++------ .../list-of-hooks/actionUpdateLangAfter.md | 12 ++++------ .../list-of-hooks/actionUpdateQuantity.md | 12 ++++------ .../actionValidateCustomerAddressForm.md | 12 ++++------ .../list-of-hooks/actionValidateOrder.md | 12 ++++------ .../list-of-hooks/actionValidateOrderAfter.md | 12 ++++------ .../actionValidateStepComplete.md | 12 ++++------ .../hooks/list-of-hooks/actionWatermark.md | 12 ++++------ .../list-of-hooks/actionWishlistAddProduct.md | 12 ++++------ .../list-of-hooks/addWebserviceResources.md | 10 ++++---- .../additionalCustomerAddressFields.md | 10 ++++---- .../additionalCustomerFormFields.md | 10 ++++---- .../hooks/list-of-hooks/dashboardData.md | 10 ++++---- .../hooks/list-of-hooks/dashboardZoneOne.md | 10 ++++---- .../hooks/list-of-hooks/dashboardZoneThree.md | 10 ++++---- .../hooks/list-of-hooks/dashboardZoneTwo.md | 10 ++++---- .../list-of-hooks/deleteProductAttribute.md | 10 ++++---- .../displayAdditionalCustomerAddressFields.md | 12 ++++------ .../list-of-hooks/displayAdminAfterHeader.md | 12 ++++------ .../list-of-hooks/displayAdminCustomers.md | 12 ++++------ .../list-of-hooks/displayAdminEndContent.md | 12 ++++------ .../hooks/list-of-hooks/displayAdminForm.md | 12 ++++------ .../displayAdminGridTableAfter.md | 12 ++++------ .../displayAdminGridTableBefore.md | 12 ++++------ .../list-of-hooks/displayAdminListAfter.md | 12 ++++------ .../list-of-hooks/displayAdminListBefore.md | 12 ++++------ .../displayAdminNavBarBeforeEnd.md | 12 ++++------ .../list-of-hooks/displayAdminOptions.md | 12 ++++------ .../hooks/list-of-hooks/displayAdminOrder.md | 12 ++++------ .../displayAdminOrderCreateExtraButtons.md | 12 ++++------ .../list-of-hooks/displayAdminOrderMain.md | 12 ++++------ .../displayAdminOrderMainBottom.md | 12 ++++------ .../list-of-hooks/displayAdminOrderSide.md | 16 ++++++------- .../displayAdminOrderSideBottom.md | 12 ++++------ .../displayAdminProductsCombinationBottom.md | 12 ++++------ ...ayAdminProductsMainStepLeftColumnBottom.md | 12 ++++------ ...ayAdminProductsMainStepLeftColumnMiddle.md | 12 ++++------ ...yAdminProductsMainStepRightColumnBottom.md | 12 ++++------ .../displayAdminProductsOptionsStepBottom.md | 12 ++++------ .../displayAdminProductsOptionsStepTop.md | 12 ++++------ .../displayAdminProductsPriceStepBottom.md | 12 ++++------ ...isplayAdminProductsQuantitiesStepBottom.md | 12 ++++------ .../displayAdminProductsSeoStepBottom.md | 12 ++++------ .../displayAdminProductsShippingStepBottom.md | 12 ++++------ .../list-of-hooks/displayAdminStatsModules.md | 12 ++++------ .../displayAdminThemesListAfter.md | 12 ++++------ .../hooks/list-of-hooks/displayAdminView.md | 12 ++++------ .../displayAfterBodyOpeningTag.md | 12 ++++------ .../list-of-hooks/displayAfterCarrier.md | 12 ++++------ .../displayAfterProductThumbs.md | 12 ++++------ .../list-of-hooks/displayAfterTitleTag.md | 12 ++++------ .../displayBackOfficeCategory.md | 20 +++++++--------- .../displayBackOfficeEmployeeMenu.md | 20 +++++++--------- .../list-of-hooks/displayBackOfficeHeader.md | 24 +++++++++---------- .../list-of-hooks/displayBackOfficeTop.md | 24 +++++++++---------- .../hooks/list-of-hooks/displayBanner.md | 12 ++++------ .../displayBeforeBodyClosingTag.md | 12 ++++------ .../list-of-hooks/displayBeforeCarrier.md | 12 ++++------ .../displayCMSDisputeInformation.md | 12 ++++------ .../list-of-hooks/displayCMSPrintButton.md | 12 ++++------ .../displayCarrierExtraContent.md | 12 ++++------ .../displayCartExtraProductActions.md | 12 ++++------ .../list-of-hooks/displayCartModalContent.md | 12 ++++------ .../list-of-hooks/displayCartModalFooter.md | 12 ++++------ .../displayCheckoutBeforeConfirmation.md | 12 ++++------ .../displayCheckoutSubtotalDetails.md | 12 ++++------ .../displayCheckoutSummaryTop.md | 12 ++++------ .../displayCrossSellingShoppingCart.md | 12 ++++------ .../list-of-hooks/displayCustomerAccount.md | 12 ++++------ .../displayCustomerAccountForm.md | 12 ++++------ .../displayCustomerAccountFormTop.md | 12 ++++------ .../displayCustomerLoginFormAfter.md | 12 ++++------ .../list-of-hooks/displayCustomization.md | 12 ++++------ .../displayDashboardToolbarIcons.md | 12 ++++------ .../displayDashboardToolbarTopMenu.md | 12 ++++------ .../list-of-hooks/displayDashboardTop.md | 12 ++++------ .../displayEmptyModuleCategoryExtraMessage.md | 12 ++++------ .../list-of-hooks/displayExpressCheckout.md | 12 ++++------ .../hooks/list-of-hooks/displayFeatureForm.md | 12 ++++------ .../displayFeaturePostProcess.md | 12 ++++------ .../displayFeatureValuePostProcess.md | 12 ++++------ .../hooks/list-of-hooks/displayFooter.md | 12 ++++------ .../hooks/list-of-hooks/displayFooterAfter.md | 12 ++++------ .../list-of-hooks/displayFooterBefore.md | 12 ++++------ .../list-of-hooks/displayFooterProduct.md | 12 ++++------ .../hooks/list-of-hooks/displayGDPRConsent.md | 12 ++++------ .../hooks/list-of-hooks/displayHeader.md | 12 ++++------ .../hooks/list-of-hooks/displayHome.md | 12 ++++------ .../displayInvoiceLegalFreeText.md | 12 ++++------ .../list-of-hooks/displayLeftColumnProduct.md | 12 ++++------ .../hooks/list-of-hooks/displayMaintenance.md | 12 ++++------ .../list-of-hooks/displayMyAccountBlock.md | 12 ++++------ .../hooks/list-of-hooks/displayNav1.md | 12 ++++------ .../hooks/list-of-hooks/displayNav2.md | 12 ++++------ .../list-of-hooks/displayNavFullWidth.md | 12 ++++------ .../displayNewsletterRegistration.md | 12 ++++------ .../hooks/list-of-hooks/displayNotFound.md | 12 ++++------ .../list-of-hooks/displayOrderConfirmation.md | 12 ++++------ .../displayOrderConfirmation1.md | 12 ++++------ .../displayOrderConfirmation2.md | 12 ++++------ .../hooks/list-of-hooks/displayOrderDetail.md | 12 ++++------ .../list-of-hooks/displayOrderPreview.md | 12 ++++------ .../list-of-hooks/displayOverrideTemplate.md | 12 ++++------ .../list-of-hooks/displayPaymentByBinaries.md | 12 ++++------ .../list-of-hooks/displayPaymentReturn.md | 12 ++++------ .../hooks/list-of-hooks/displayPaymentTop.md | 12 ++++------ .../displayPersonalInformationTop.md | 12 ++++------ .../list-of-hooks/displayProductActions.md | 12 ++++------ .../displayProductAdditionalInfo.md | 12 ++++------ .../displayProductListReviews.md | 12 ++++------ .../list-of-hooks/displayProductPriceBlock.md | 12 ++++------ .../hooks/list-of-hooks/displayReassurance.md | 12 ++++------ .../displayRightColumnProduct.md | 12 ++++------ .../hooks/list-of-hooks/displaySearch.md | 12 ++++------ .../list-of-hooks/displayShoppingCart.md | 12 ++++------ .../displayShoppingCartFooter.md | 12 ++++------ .../hooks/list-of-hooks/displayTop.md | 12 ++++------ .../list-of-hooks/filterCategoryContent.md | 9 ++++--- .../list-of-hooks/filterCmsCategoryContent.md | 9 ++++--- .../hooks/list-of-hooks/filterCmsContent.md | 9 ++++--- .../hooks/list-of-hooks/filterHtmlContent.md | 9 ++++--- .../filterManufacturerContent.md | 9 ++++--- .../list-of-hooks/filterProductContent.md | 9 ++++--- .../list-of-hooks/filterProductSearch.md | 9 ++++--- .../list-of-hooks/filterSupplierContent.md | 9 ++++--- .../hooks/list-of-hooks/gSitemapAppendUrls.md | 9 ++++--- .../hooks/list-of-hooks/legacyblockkpi.md | 9 ++++--- .../hooks/list-of-hooks/moduleRoutes.md | 9 ++++--- .../list-of-hooks/overrideLayoutTemplate.md | 9 ++++--- .../overrideMinimalPurchasePrice.md | 9 ++++--- .../list-of-hooks/productSearchProvider.md | 9 ++++--- .../sendMailAlterTemplateVars.md | 9 ++++--- .../hooks/list-of-hooks/termsAndConditions.md | 9 ++++--- .../validateCustomerFormFields.md | 9 ++++--- 342 files changed, 1773 insertions(+), 2440 deletions(-) diff --git a/modules/concepts/hooks/list-of-hooks/actionAfter.md b/modules/concepts/hooks/list-of-hooks/actionAfter.md index 2a324055db..de7c9c8211 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionAfter.md @@ -6,26 +6,24 @@ hookTitle: files: - classes/controller/AdminController.php locations: - - backoffice -type: - - action + - back office +type: action hookAliases: --- -# Hook actionAfter +# Hook action<ClassName><Action>After ## Information Hook locations: - - backoffice + - back office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/AdminController.php](classes/controller/AdminController.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('action' . get_class($this) . ucfirst($this->action) . 'After', ['controller' => $this, 'return' => $return]); diff --git a/modules/concepts/hooks/list-of-hooks/actionBefore.md b/modules/concepts/hooks/list-of-hooks/actionBefore.md index 41afa16be0..71d39c5e73 100644 --- a/modules/concepts/hooks/list-of-hooks/actionBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionBefore.md @@ -6,26 +6,24 @@ hookTitle: files: - classes/controller/AdminController.php locations: - - backoffice -type: - - action + - back office +type: action hookAliases: --- -# Hook actionBefore +# Hook action<ClassName><Action>Before ## Information Hook locations: - - backoffice + - back office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/AdminController.php](classes/controller/AdminController.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('action' . get_class($this) . ucfirst($this->action) . 'Before', ['controller' => $this]); diff --git a/modules/concepts/hooks/list-of-hooks/actionFormModifier.md b/modules/concepts/hooks/list-of-hooks/actionFormModifier.md index 6d44cce03d..6d9286b35a 100644 --- a/modules/concepts/hooks/list-of-hooks/actionFormModifier.md +++ b/modules/concepts/hooks/list-of-hooks/actionFormModifier.md @@ -6,26 +6,24 @@ hookTitle: files: - classes/controller/AdminController.php locations: - - backoffice -type: - - action + - back office +type: action hookAliases: --- -# Hook actionFormModifier +# Hook action<Controller>FormModifier ## Information Hook locations: - - backoffice + - back office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/AdminController.php](classes/controller/AdminController.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('action' . $this->controller_name . 'FormModifier', [ diff --git a/modules/concepts/hooks/list-of-hooks/actionListingFieldsModifier.md b/modules/concepts/hooks/list-of-hooks/actionListingFieldsModifier.md index 8d36bacd55..15c12ee915 100644 --- a/modules/concepts/hooks/list-of-hooks/actionListingFieldsModifier.md +++ b/modules/concepts/hooks/list-of-hooks/actionListingFieldsModifier.md @@ -6,26 +6,24 @@ hookTitle: files: - classes/controller/AdminController.php locations: - - backoffice -type: - - action + - back office +type: action hookAliases: --- -# Hook actionListingFieldsModifier +# Hook action<Controller>ListingFieldsModifier ## Information Hook locations: - - backoffice + - back office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/AdminController.php](classes/controller/AdminController.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('action' . $this->controller_name . 'ListingFieldsModifier', [ diff --git a/modules/concepts/hooks/list-of-hooks/actionListingResultsModifier.md b/modules/concepts/hooks/list-of-hooks/actionListingResultsModifier.md index c375446ec8..1cb2c629fa 100644 --- a/modules/concepts/hooks/list-of-hooks/actionListingResultsModifier.md +++ b/modules/concepts/hooks/list-of-hooks/actionListingResultsModifier.md @@ -6,26 +6,24 @@ hookTitle: files: - classes/controller/AdminController.php locations: - - backoffice -type: - - action + - back office +type: action hookAliases: --- -# Hook actionListingResultsModifier +# Hook action<Controller>ListingResultsModifier ## Information Hook locations: - - backoffice + - back office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/AdminController.php](classes/controller/AdminController.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('action' . $this->controller_name . 'ListingResultsModifier', [ diff --git a/modules/concepts/hooks/list-of-hooks/actionOptionsModifier.md b/modules/concepts/hooks/list-of-hooks/actionOptionsModifier.md index 6c6d41ead1..9f496df02f 100644 --- a/modules/concepts/hooks/list-of-hooks/actionOptionsModifier.md +++ b/modules/concepts/hooks/list-of-hooks/actionOptionsModifier.md @@ -6,26 +6,24 @@ hookTitle: files: - classes/controller/AdminController.php locations: - - backoffice -type: - - action + - back office +type: action hookAliases: --- -# Hook actionOptionsModifier +# Hook action<Controller>OptionsModifier ## Information Hook locations: - - backoffice + - back office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/AdminController.php](classes/controller/AdminController.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('action' . $this->controller_name . 'OptionsModifier', [ diff --git a/modules/concepts/hooks/list-of-hooks/actionGridPresenterModifier.md b/modules/concepts/hooks/list-of-hooks/actionGridPresenterModifier.md index 8cb2514919..7d184621d0 100644 --- a/modules/concepts/hooks/list-of-hooks/actionGridPresenterModifier.md +++ b/modules/concepts/hooks/list-of-hooks/actionGridPresenterModifier.md @@ -6,26 +6,24 @@ hookTitle: files: - src/Core/Grid/Presenter/GridPresenter.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: --- -# Hook actionGridPresenterModifier +# Hook action<DefinitionId>GridPresenterModifier ## Information Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Core/Grid/Presenter/GridPresenter.php](src/Core/Grid/Presenter/GridPresenter.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php dispatchWithParameters('action' . Container::camelize($definition->getId()) . 'GridPresenterModifier', [ diff --git a/modules/concepts/hooks/list-of-hooks/actionFormDataProviderDefaultData.md b/modules/concepts/hooks/list-of-hooks/actionFormDataProviderDefaultData.md index a9a77fe613..56d5890448 100644 --- a/modules/concepts/hooks/list-of-hooks/actionFormDataProviderDefaultData.md +++ b/modules/concepts/hooks/list-of-hooks/actionFormDataProviderDefaultData.md @@ -6,26 +6,24 @@ hookTitle: files: - src/Core/Form/IdentifiableObject/Builder/FormBuilder.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: --- -# Hook actionFormDataProviderDefaultData +# Hook action<FormName>FormDataProviderDefaultData ## Information Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Core/Form/IdentifiableObject/Builder/FormBuilder.php](src/Core/Form/IdentifiableObject/Builder/FormBuilder.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php dispatchWithParameters( diff --git a/modules/concepts/hooks/list-of-hooks/actionListingFieldsModifier.md b/modules/concepts/hooks/list-of-hooks/actionListingFieldsModifier.md index 09d6318cc9..40049b7b7c 100644 --- a/modules/concepts/hooks/list-of-hooks/actionListingFieldsModifier.md +++ b/modules/concepts/hooks/list-of-hooks/actionListingFieldsModifier.md @@ -6,26 +6,24 @@ hookTitle: files: - src/PrestaShopBundle/Bridge/Helper/Listing/HelperBridge/HelperListBridge.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: --- -# Hook actionListingFieldsModifier +# Hook action<LegacyControllerName>ListingFieldsModifier ## Information Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Bridge/Helper/Listing/HelperBridge/HelperListBridge.php](src/PrestaShopBundle/Bridge/Helper/Listing/HelperBridge/HelperListBridge.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php dispatchWithParameters('action' . $helperListConfiguration->legacyControllerName . 'ListingFieldsModifier', [ diff --git a/modules/concepts/hooks/list-of-hooks/actionListingResultsModifier.md b/modules/concepts/hooks/list-of-hooks/actionListingResultsModifier.md index 625c64bbb7..ef336451d3 100644 --- a/modules/concepts/hooks/list-of-hooks/actionListingResultsModifier.md +++ b/modules/concepts/hooks/list-of-hooks/actionListingResultsModifier.md @@ -6,26 +6,24 @@ hookTitle: files: - src/PrestaShopBundle/Bridge/Helper/Listing/HelperBridge/HelperListBridge.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: --- -# Hook actionListingResultsModifier +# Hook action<LegacyControllerName>ListingResultsModifier ## Information Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Bridge/Helper/Listing/HelperBridge/HelperListBridge.php](src/PrestaShopBundle/Bridge/Helper/Listing/HelperBridge/HelperListBridge.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php dispatchWithParameters('action' . $helperListConfiguration->legacyControllerName . 'ListingResultsModifier', [ diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminAfter.md b/modules/concepts/hooks/list-of-hooks/actionAdminAfter.md index 92367d9ab8..ff807d9439 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminAfter.md @@ -6,26 +6,24 @@ hookTitle: files: - classes/controller/AdminController.php locations: - - backoffice -type: - - action + - back office +type: action hookAliases: --- -# Hook actionAdminAfter +# Hook actionAdmin<Action>After ## Information Hook locations: - - backoffice + - back office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/AdminController.php](classes/controller/AdminController.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionAdmin' . ucfirst($this->action) . 'After', ['controller' => $this, 'return' => $return]); diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminBefore.md index f7fb9f65f8..720538f0da 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminBefore.md @@ -6,26 +6,24 @@ hookTitle: files: - classes/controller/AdminController.php locations: - - backoffice -type: - - action + - back office +type: action hookAliases: --- -# Hook actionAdminBefore +# Hook actionAdmin<Action>Before ## Information Hook locations: - - backoffice + - back office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/AdminController.php](classes/controller/AdminController.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionAdmin' . ucfirst($this->action) . 'Before', ['controller' => $this]); diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminActivateAfter.md b/modules/concepts/hooks/list-of-hooks/actionAdminActivateAfter.md index 1868463212..a3cd5a6afc 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminActivateAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminActivateAfter.md @@ -6,9 +6,8 @@ hookTitle: files: - src/PrestaShopBundle/Controller/Admin/ProductController.php locations: - - backoffice -type: - - action + - back office +type: action hookAliases: --- @@ -17,15 +16,14 @@ hookAliases: ## Information Hook locations: - - backoffice + - back office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/ProductController.php](src/PrestaShopBundle/Controller/Admin/ProductController.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php dispatchWithParameters( diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminActivateBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminActivateBefore.md index a22a3e24a6..ba3a206f09 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminActivateBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminActivateBefore.md @@ -6,9 +6,8 @@ hookTitle: files: - src/PrestaShopBundle/Controller/Admin/ProductController.php locations: - - backoffice -type: - - action + - back office +type: action hookAliases: --- @@ -17,15 +16,14 @@ hookAliases: ## Information Hook locations: - - backoffice + - back office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/ProductController.php](src/PrestaShopBundle/Controller/Admin/ProductController.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php dispatchWithParameters( diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminAdminShopParametersMetaControllerPostProcessBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminAdminShopParametersMetaControllerPostProcessBefore.md index ce0b74aba7..77bce65605 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminAdminShopParametersMetaControllerPostProcessBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminAdminShopParametersMetaControllerPostProcessBefore.md @@ -6,9 +6,8 @@ hookTitle: On post-process in Admin Configure Shop Parameters Meta Controller files: - src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/MetaController.php locations: - - backoffice -type: - - action + - back office +type: action hookAliases: --- @@ -23,15 +22,14 @@ This hook is called on Admin Configure Shop Parameters Meta post-process before {{% /notice %}} Hook locations: - - backoffice + - back office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/MetaController.php](src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/MetaController.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php dispatchHook('actionAdminAdminShopParametersMetaControllerPostProcessBefore', ['controller' => $this]) diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminAdminWebserviceControllerPostProcessBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminAdminWebserviceControllerPostProcessBefore.md index 61dbe7839f..1fba778669 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminAdminWebserviceControllerPostProcessBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminAdminWebserviceControllerPostProcessBefore.md @@ -6,9 +6,8 @@ hookTitle: files: - src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/WebserviceController.php locations: - - backoffice -type: - - action + - back office +type: action hookAliases: --- @@ -17,15 +16,14 @@ hookAliases: ## Information Hook locations: - - backoffice + - back office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/WebserviceController.php](src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/WebserviceController.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php dispatchHook('actionAdminAdminWebserviceControllerPostProcessBefore', ['controller' => $this]) diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminAdministrationControllerPostProcessBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminAdministrationControllerPostProcessBefore.md index 7d343d1ee2..7b12b586a9 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminAdministrationControllerPostProcessBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminAdministrationControllerPostProcessBefore.md @@ -6,26 +6,24 @@ hookTitle: files: - src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/AdministrationController.php locations: - - backoffice -type: - - action + - back office +type: action hookAliases: --- -# Hook actionAdminAdministrationControllerPostProcessBefore +# Hook actionAdminAdministrationControllerPostProcess<HookName>Before ## Information Hook locations: - - backoffice + - back office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/AdministrationController.php](src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/AdministrationController.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php dispatchHook( diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminAdministrationControllerPostProcessBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminAdministrationControllerPostProcessBefore.md index b293ef1a51..312dfdf0fc 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminAdministrationControllerPostProcessBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminAdministrationControllerPostProcessBefore.md @@ -6,9 +6,8 @@ hookTitle: On post-process in Admin Configure Advanced Parameters Administration files: - src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/AdministrationController.php locations: - - backoffice -type: - - action + - back office +type: action hookAliases: --- @@ -23,15 +22,14 @@ This hook is called on Admin Configure Advanced Parameters Administration post-p {{% /notice %}} Hook locations: - - backoffice + - back office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/AdministrationController.php](src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/AdministrationController.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php dispatchHook('actionAdminAdministrationControllerPostProcessBefore', ['controller' => $this]) diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminAdvancedParametersPerformanceControllerPostProcessBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminAdvancedParametersPerformanceControllerPostProcessBefore.md index a038a1eff8..9e706ac55f 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminAdvancedParametersPerformanceControllerPostProcessBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminAdvancedParametersPerformanceControllerPostProcessBefore.md @@ -6,26 +6,24 @@ hookTitle: files: - src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/PerformanceController.php locations: - - backoffice -type: - - action + - back office +type: action hookAliases: --- -# Hook actionAdminAdvancedParametersPerformanceControllerPostProcessBefore +# Hook actionAdminAdvancedParametersPerformanceControllerPostProcess<HookName>Before ## Information Hook locations: - - backoffice + - back office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/PerformanceController.php](src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/PerformanceController.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php dispatchHook( diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminAdvancedParametersPerformanceControllerPostProcessBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminAdvancedParametersPerformanceControllerPostProcessBefore.md index d377783f4b..74dcfa5065 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminAdvancedParametersPerformanceControllerPostProcessBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminAdvancedParametersPerformanceControllerPostProcessBefore.md @@ -6,9 +6,8 @@ hookTitle: On post-process in Admin Configure Advanced Parameters Performance Co files: - src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/PerformanceController.php locations: - - backoffice -type: - - action + - back office +type: action hookAliases: --- @@ -23,15 +22,14 @@ This hook is called on Admin Configure Advanced Parameters Performance post-proc {{% /notice %}} Hook locations: - - backoffice + - back office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/PerformanceController.php](src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/PerformanceController.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php dispatchHook('actionAdminAdvancedParametersPerformanceControllerPostProcessBefore', ['controller' => $this]) diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminControllerInitAfter.md b/modules/concepts/hooks/list-of-hooks/actionAdminControllerInitAfter.md index 5801329545..1c1f3ec553 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminControllerInitAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminControllerInitAfter.md @@ -6,9 +6,8 @@ hookTitle: Perform actions after admin controller initialization files: - classes/controller/AdminController.php locations: - - backoffice -type: - - action + - back office +type: action hookAliases: --- @@ -23,15 +22,14 @@ This hook is launched after the initialization of all admin controllers {{% /notice %}} Hook locations: - - backoffice + - back office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/AdminController.php](classes/controller/AdminController.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec( diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminControllerInitBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminControllerInitBefore.md index 05a508545f..caf22836e9 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminControllerInitBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminControllerInitBefore.md @@ -6,9 +6,8 @@ hookTitle: Perform actions before admin controller initialization files: - classes/controller/AdminController.php locations: - - backoffice -type: - - action + - back office +type: action hookAliases: --- @@ -23,15 +22,14 @@ This hook is launched before the initialization of all admin controllers {{% /notice %}} Hook locations: - - backoffice + - back office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/AdminController.php](classes/controller/AdminController.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec( diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminControllerSetMedia.md b/modules/concepts/hooks/list-of-hooks/actionAdminControllerSetMedia.md index af33868fd9..d72ffa91d7 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminControllerSetMedia.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminControllerSetMedia.md @@ -6,9 +6,8 @@ hookTitle: files: - src/PrestaShopBundle/Bridge/AdminController/LegacyControllerBridge.php locations: - - backoffice -type: - - action + - back office +type: action hookAliases: --- @@ -17,15 +16,14 @@ hookAliases: ## Information Hook locations: - - backoffice + - back office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Bridge/AdminController/LegacyControllerBridge.php](src/PrestaShopBundle/Bridge/AdminController/LegacyControllerBridge.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php dispatchWithParameters('actionAdminControllerSetMedia') diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminDeactivateAfter.md b/modules/concepts/hooks/list-of-hooks/actionAdminDeactivateAfter.md index 2af7850c2b..448c32ada4 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminDeactivateAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminDeactivateAfter.md @@ -6,9 +6,8 @@ hookTitle: files: - src/PrestaShopBundle/Controller/Admin/ProductController.php locations: - - backoffice -type: - - action + - back office +type: action hookAliases: --- @@ -17,15 +16,14 @@ hookAliases: ## Information Hook locations: - - backoffice + - back office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/ProductController.php](src/PrestaShopBundle/Controller/Admin/ProductController.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php dispatchWithParameters( diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminDeactivateBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminDeactivateBefore.md index cfac876f4a..171ba33b3a 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminDeactivateBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminDeactivateBefore.md @@ -6,9 +6,8 @@ hookTitle: files: - src/PrestaShopBundle/Controller/Admin/ProductController.php locations: - - backoffice -type: - - action + - back office +type: action hookAliases: --- @@ -17,15 +16,14 @@ hookAliases: ## Information Hook locations: - - backoffice + - back office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/ProductController.php](src/PrestaShopBundle/Controller/Admin/ProductController.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php dispatchWithParameters( diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminDeleteAfter.md b/modules/concepts/hooks/list-of-hooks/actionAdminDeleteAfter.md index d613777993..8676c18609 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminDeleteAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminDeleteAfter.md @@ -6,9 +6,8 @@ hookTitle: files: - src/PrestaShopBundle/Controller/Admin/ProductController.php locations: - - backoffice -type: - - action + - back office +type: action hookAliases: --- @@ -17,15 +16,14 @@ hookAliases: ## Information Hook locations: - - backoffice + - back office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/ProductController.php](src/PrestaShopBundle/Controller/Admin/ProductController.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php dispatchWithParameters( diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminDeleteBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminDeleteBefore.md index 9f1de835a9..993b9c9e76 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminDeleteBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminDeleteBefore.md @@ -6,9 +6,8 @@ hookTitle: files: - src/PrestaShopBundle/Controller/Admin/ProductController.php locations: - - backoffice -type: - - action + - back office +type: action hookAliases: --- @@ -17,15 +16,14 @@ hookAliases: ## Information Hook locations: - - backoffice + - back office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/ProductController.php](src/PrestaShopBundle/Controller/Admin/ProductController.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php dispatchWithParameters( diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminDuplicateAfter.md b/modules/concepts/hooks/list-of-hooks/actionAdminDuplicateAfter.md index 99a7f0c5d1..52d5b662f5 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminDuplicateAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminDuplicateAfter.md @@ -6,9 +6,8 @@ hookTitle: files: - src/PrestaShopBundle/Controller/Admin/ProductController.php locations: - - backoffice -type: - - action + - back office +type: action hookAliases: --- @@ -17,15 +16,14 @@ hookAliases: ## Information Hook locations: - - backoffice + - back office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/ProductController.php](src/PrestaShopBundle/Controller/Admin/ProductController.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php dispatchWithParameters( diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminDuplicateBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminDuplicateBefore.md index 6bdc0c679c..4804942dd7 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminDuplicateBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminDuplicateBefore.md @@ -6,9 +6,8 @@ hookTitle: files: - src/PrestaShopBundle/Controller/Admin/ProductController.php locations: - - backoffice -type: - - action + - back office +type: action hookAliases: --- @@ -17,15 +16,14 @@ hookAliases: ## Information Hook locations: - - backoffice + - back office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/ProductController.php](src/PrestaShopBundle/Controller/Admin/ProductController.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php dispatchWithParameters( diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminInternationalGeolocationControllerPostProcessBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminInternationalGeolocationControllerPostProcessBefore.md index eccdf51f27..2d64dc3e71 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminInternationalGeolocationControllerPostProcessBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminInternationalGeolocationControllerPostProcessBefore.md @@ -6,26 +6,24 @@ hookTitle: files: - src/PrestaShopBundle/Controller/Admin/Improve/International/GeolocationController.php locations: - - backoffice -type: - - action + - back office +type: action hookAliases: --- -# Hook actionAdminInternationalGeolocationControllerPostProcessBefore +# Hook actionAdminInternationalGeolocationControllerPostProcess<HookName>Before ## Information Hook locations: - - backoffice + - back office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/Improve/International/GeolocationController.php](src/PrestaShopBundle/Controller/Admin/Improve/International/GeolocationController.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php dispatchHook( diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminInternationalGeolocationControllerPostProcessBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminInternationalGeolocationControllerPostProcessBefore.md index 6b3b767747..048c5a1713 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminInternationalGeolocationControllerPostProcessBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminInternationalGeolocationControllerPostProcessBefore.md @@ -6,9 +6,8 @@ hookTitle: On post-process in Admin Improve International Geolocation Controller files: - src/PrestaShopBundle/Controller/Admin/Improve/International/GeolocationController.php locations: - - backoffice -type: - - action + - back office +type: action hookAliases: --- @@ -23,15 +22,14 @@ This hook is called on Admin Improve International Geolocation post-process befo {{% /notice %}} Hook locations: - - backoffice + - back office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/Improve/International/GeolocationController.php](src/PrestaShopBundle/Controller/Admin/Improve/International/GeolocationController.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php dispatchHook('actionAdminInternationalGeolocationControllerPostProcessBefore', ['controller' => $this]) diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminInternationalLocalizationControllerPostProcessBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminInternationalLocalizationControllerPostProcessBefore.md index 8728ee5192..7ea88874b5 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminInternationalLocalizationControllerPostProcessBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminInternationalLocalizationControllerPostProcessBefore.md @@ -6,26 +6,24 @@ hookTitle: files: - src/PrestaShopBundle/Controller/Admin/Improve/International/LocalizationController.php locations: - - backoffice -type: - - action + - back office +type: action hookAliases: --- -# Hook actionAdminInternationalLocalizationControllerPostProcessBefore +# Hook actionAdminInternationalLocalizationControllerPostProcess<HookName>Before ## Information Hook locations: - - backoffice + - back office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/Improve/International/LocalizationController.php](src/PrestaShopBundle/Controller/Admin/Improve/International/LocalizationController.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php dispatchHook( diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminInternationalLocalizationControllerPostProcessBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminInternationalLocalizationControllerPostProcessBefore.md index 31d5dc3acd..c99c93dc5a 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminInternationalLocalizationControllerPostProcessBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminInternationalLocalizationControllerPostProcessBefore.md @@ -6,9 +6,8 @@ hookTitle: On post-process in Admin Improve International Localization Controlle files: - src/PrestaShopBundle/Controller/Admin/Improve/International/LocalizationController.php locations: - - backoffice -type: - - action + - back office +type: action hookAliases: --- @@ -23,15 +22,14 @@ This hook is called on Admin Improve International Localization post-process bef {{% /notice %}} Hook locations: - - backoffice + - back office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/Improve/International/LocalizationController.php](src/PrestaShopBundle/Controller/Admin/Improve/International/LocalizationController.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php dispatchHook('actionAdminInternationalLocalizationControllerPostProcessBefore', ['controller' => $this]) diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminLoginControllerBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminLoginControllerBefore.md index e2cff566c8..2e84f295cd 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminLoginControllerBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminLoginControllerBefore.md @@ -6,9 +6,8 @@ hookTitle: Perform actions before admin login controller initialization files: - controllers/admin/AdminLoginController.php locations: - - backoffice -type: - - action + - back office +type: action hookAliases: --- @@ -23,15 +22,14 @@ This hook is launched before the initialization of the login controller {{% /notice %}} Hook locations: - - backoffice + - back office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/admin/AdminLoginController.php](controllers/admin/AdminLoginController.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec( diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminLoginControllerForgotAfter.md b/modules/concepts/hooks/list-of-hooks/actionAdminLoginControllerForgotAfter.md index f70f9f7df0..6b3cbf91fc 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminLoginControllerForgotAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminLoginControllerForgotAfter.md @@ -6,9 +6,8 @@ hookTitle: Perform actions after admin login controller forgot action initializa files: - controllers/admin/AdminLoginController.php locations: - - backoffice -type: - - action + - back office +type: action hookAliases: --- @@ -23,15 +22,14 @@ This hook is launched after the initialization of the forgot action in login con {{% /notice %}} Hook locations: - - backoffice + - back office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/admin/AdminLoginController.php](controllers/admin/AdminLoginController.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec( diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminLoginControllerForgotBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminLoginControllerForgotBefore.md index 36377c79c5..bf49e4a46e 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminLoginControllerForgotBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminLoginControllerForgotBefore.md @@ -6,9 +6,8 @@ hookTitle: Perform actions before admin login controller forgot action initializ files: - controllers/admin/AdminLoginController.php locations: - - backoffice -type: - - action + - back office +type: action hookAliases: --- @@ -23,15 +22,14 @@ This hook is launched before the initialization of the forgot action in login co {{% /notice %}} Hook locations: - - backoffice + - back office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/admin/AdminLoginController.php](controllers/admin/AdminLoginController.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec( diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminLoginControllerLoginAfter.md b/modules/concepts/hooks/list-of-hooks/actionAdminLoginControllerLoginAfter.md index 48afd13e0d..6768f3ec29 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminLoginControllerLoginAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminLoginControllerLoginAfter.md @@ -6,9 +6,8 @@ hookTitle: Perform actions after admin login controller login action initializat files: - controllers/admin/AdminLoginController.php locations: - - backoffice -type: - - action + - back office +type: action hookAliases: --- @@ -23,15 +22,14 @@ This hook is launched after the initialization of the login action in login cont {{% /notice %}} Hook locations: - - backoffice + - back office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/admin/AdminLoginController.php](controllers/admin/AdminLoginController.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec( diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminLoginControllerLoginBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminLoginControllerLoginBefore.md index a61bcb6b73..4c43e07e8c 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminLoginControllerLoginBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminLoginControllerLoginBefore.md @@ -6,9 +6,8 @@ hookTitle: Perform actions before admin login controller login action initializa files: - controllers/admin/AdminLoginController.php locations: - - backoffice -type: - - action + - back office +type: action hookAliases: --- @@ -23,15 +22,14 @@ This hook is launched before the initialization of the login action in login con {{% /notice %}} Hook locations: - - backoffice + - back office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/admin/AdminLoginController.php](controllers/admin/AdminLoginController.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec( diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminLoginControllerResetAfter.md b/modules/concepts/hooks/list-of-hooks/actionAdminLoginControllerResetAfter.md index f66403b57e..eef0e96498 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminLoginControllerResetAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminLoginControllerResetAfter.md @@ -6,9 +6,8 @@ hookTitle: Perform actions after admin login controller reset action initializat files: - controllers/admin/AdminLoginController.php locations: - - backoffice -type: - - action + - back office +type: action hookAliases: --- @@ -23,15 +22,14 @@ This hook is launched after the initialization of the reset action in login cont {{% /notice %}} Hook locations: - - backoffice + - back office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/admin/AdminLoginController.php](controllers/admin/AdminLoginController.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec( diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminLoginControllerResetBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminLoginControllerResetBefore.md index c9aa011ce0..88013e18e9 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminLoginControllerResetBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminLoginControllerResetBefore.md @@ -6,9 +6,8 @@ hookTitle: Perform actions before admin login controller reset action initializa files: - controllers/admin/AdminLoginController.php locations: - - backoffice -type: - - action + - back office +type: action hookAliases: --- @@ -23,15 +22,14 @@ This hook is launched before the initialization of the reset action in login con {{% /notice %}} Hook locations: - - backoffice + - back office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/admin/AdminLoginController.php](controllers/admin/AdminLoginController.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec( diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminLoginControllerSetMedia.md b/modules/concepts/hooks/list-of-hooks/actionAdminLoginControllerSetMedia.md index 80dde89d66..09949635a1 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminLoginControllerSetMedia.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminLoginControllerSetMedia.md @@ -6,9 +6,8 @@ hookTitle: Set media on admin login page header files: - controllers/admin/AdminLoginController.php locations: - - backoffice -type: - - action + - back office +type: action hookAliases: --- @@ -23,15 +22,14 @@ This hook is called after adding media to admin login page header {{% /notice %}} Hook locations: - - backoffice + - back office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/admin/AdminLoginController.php](controllers/admin/AdminLoginController.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec( diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminLogsControllerPostProcessBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminLogsControllerPostProcessBefore.md index be6babbc28..6cacd6f4fe 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminLogsControllerPostProcessBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminLogsControllerPostProcessBefore.md @@ -6,9 +6,8 @@ hookTitle: files: - src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/LogsController.php locations: - - backoffice -type: - - action + - back office +type: action hookAliases: --- @@ -17,15 +16,14 @@ hookAliases: ## Information Hook locations: - - backoffice + - back office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/LogsController.php](src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/LogsController.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php dispatchHook('actionAdminLogsControllerPostProcessBefore', ['controller' => $this]) diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminMaintenanceControllerPostProcessBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminMaintenanceControllerPostProcessBefore.md index 2713cd053d..57952b081b 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminMaintenanceControllerPostProcessBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminMaintenanceControllerPostProcessBefore.md @@ -6,9 +6,8 @@ hookTitle: files: - src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/MaintenanceController.php locations: - - backoffice -type: - - action + - back office +type: action hookAliases: --- @@ -17,15 +16,14 @@ hookAliases: ## Information Hook locations: - - backoffice + - back office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/MaintenanceController.php](src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/MaintenanceController.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php dispatchHook('actionAdminMaintenanceControllerPostProcessBefore', ['controller' => $this]) diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminMetaAfterWriteRobotsFile.md b/modules/concepts/hooks/list-of-hooks/actionAdminMetaAfterWriteRobotsFile.md index c4af6fe1c7..be954e8b86 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminMetaAfterWriteRobotsFile.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminMetaAfterWriteRobotsFile.md @@ -6,9 +6,8 @@ hookTitle: files: - classes/Tools.php locations: - - backoffice -type: - - action + - back office +type: action hookAliases: --- @@ -17,10 +16,9 @@ hookAliases: ## Information Hook locations: - - backoffice + - back office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Tools.php](classes/Tools.php) @@ -35,7 +33,7 @@ Located in: ); ``` -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionAdminMetaAfterWriteRobotsFile', [ diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminMetaBeforeWriteRobotsFile.md b/modules/concepts/hooks/list-of-hooks/actionAdminMetaBeforeWriteRobotsFile.md index c48bc4b6fa..ea32ba05c4 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminMetaBeforeWriteRobotsFile.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminMetaBeforeWriteRobotsFile.md @@ -6,9 +6,8 @@ hookTitle: files: - classes/Tools.php locations: - - backoffice -type: - - action + - back office +type: action hookAliases: --- @@ -17,10 +16,9 @@ hookAliases: ## Information Hook locations: - - backoffice + - back office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Tools.php](classes/Tools.php) @@ -34,7 +32,7 @@ Located in: ); ``` -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionAdminMetaBeforeWriteRobotsFile', [ diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminMetaSave.md b/modules/concepts/hooks/list-of-hooks/actionAdminMetaSave.md index 372366e848..2e5bf4b237 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminMetaSave.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminMetaSave.md @@ -6,9 +6,8 @@ hookTitle: After saving the configuration in AdminMeta files: - src/Adapter/Meta/CommandHandler/AddMetaHandler.php locations: - - backoffice -type: - - action + - back office +type: action hookAliases: - afterSaveAdminMeta --- @@ -29,15 +28,14 @@ This hook is displayed after saving the configuration in AdminMeta {{% /notice %}} Hook locations: - - backoffice + - back office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Meta/CommandHandler/AddMetaHandler.php](src/Adapter/Meta/CommandHandler/AddMetaHandler.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php dispatchWithParameters('actionAdminMetaSave') diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminOrdersTrackingNumberUpdate.md b/modules/concepts/hooks/list-of-hooks/actionAdminOrdersTrackingNumberUpdate.md index b92f0e0ecd..fbc4300dfb 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminOrdersTrackingNumberUpdate.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminOrdersTrackingNumberUpdate.md @@ -6,9 +6,8 @@ hookTitle: After setting the tracking number for the order files: - src/Adapter/Order/CommandHandler/UpdateOrderShippingDetailsHandler.php locations: - - backoffice -type: - - action + - back office +type: action hookAliases: --- @@ -23,10 +22,9 @@ This hook allows you to execute code after the unique tracking number for the or {{% /notice %}} Hook locations: - - backoffice + - back office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Order/CommandHandler/UpdateOrderShippingDetailsHandler.php](src/Adapter/Order/CommandHandler/UpdateOrderShippingDetailsHandler.php) @@ -42,7 +40,7 @@ Located in: ); ``` -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionAdminOrdersTrackingNumberUpdate', [ diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminPreferencesControllerPostProcessBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminPreferencesControllerPostProcessBefore.md index 6b8bcbaaa3..59e8806355 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminPreferencesControllerPostProcessBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminPreferencesControllerPostProcessBefore.md @@ -6,9 +6,8 @@ hookTitle: files: - src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/PreferencesController.php locations: - - backoffice -type: - - action + - back office +type: action hookAliases: --- @@ -17,15 +16,14 @@ hookAliases: ## Information Hook locations: - - backoffice + - back office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/PreferencesController.php](src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/PreferencesController.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php dispatchHook('actionAdminPreferencesControllerPostProcessBefore', ['controller' => $this]) diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerActivateAfter.md b/modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerActivateAfter.md index 7c7a4d289b..67b7553564 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerActivateAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerActivateAfter.md @@ -6,9 +6,8 @@ hookTitle: files: - src/PrestaShopBundle/Controller/Admin/ProductController.php locations: - - backoffice -type: - - action + - back office +type: action hookAliases: --- @@ -17,15 +16,14 @@ hookAliases: ## Information Hook locations: - - backoffice + - back office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/ProductController.php](src/PrestaShopBundle/Controller/Admin/ProductController.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php dispatchWithParameters( diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerActivateBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerActivateBefore.md index f6668e3c2f..cbad8864db 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerActivateBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerActivateBefore.md @@ -6,9 +6,8 @@ hookTitle: files: - src/PrestaShopBundle/Controller/Admin/ProductController.php locations: - - backoffice -type: - - action + - back office +type: action hookAliases: --- @@ -17,15 +16,14 @@ hookAliases: ## Information Hook locations: - - backoffice + - back office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/ProductController.php](src/PrestaShopBundle/Controller/Admin/ProductController.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php dispatchWithParameters( diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerDeactivateAfter.md b/modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerDeactivateAfter.md index 3aa2c6e088..1b2ca74727 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerDeactivateAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerDeactivateAfter.md @@ -6,9 +6,8 @@ hookTitle: files: - src/PrestaShopBundle/Controller/Admin/ProductController.php locations: - - backoffice -type: - - action + - back office +type: action hookAliases: --- @@ -17,15 +16,14 @@ hookAliases: ## Information Hook locations: - - backoffice + - back office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/ProductController.php](src/PrestaShopBundle/Controller/Admin/ProductController.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php dispatchWithParameters( diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerDeactivateBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerDeactivateBefore.md index 51d0db3667..82066c0cc4 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerDeactivateBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerDeactivateBefore.md @@ -6,9 +6,8 @@ hookTitle: files: - src/PrestaShopBundle/Controller/Admin/ProductController.php locations: - - backoffice -type: - - action + - back office +type: action hookAliases: --- @@ -17,15 +16,14 @@ hookAliases: ## Information Hook locations: - - backoffice + - back office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/ProductController.php](src/PrestaShopBundle/Controller/Admin/ProductController.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php dispatchWithParameters( diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerDeleteAfter.md b/modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerDeleteAfter.md index 9031d2731f..246695e39a 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerDeleteAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerDeleteAfter.md @@ -6,9 +6,8 @@ hookTitle: files: - src/PrestaShopBundle/Controller/Admin/ProductController.php locations: - - backoffice -type: - - action + - back office +type: action hookAliases: --- @@ -17,15 +16,14 @@ hookAliases: ## Information Hook locations: - - backoffice + - back office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/ProductController.php](src/PrestaShopBundle/Controller/Admin/ProductController.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php dispatchWithParameters( diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerDeleteBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerDeleteBefore.md index ddd62aaaef..c1f3e3c339 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerDeleteBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerDeleteBefore.md @@ -6,9 +6,8 @@ hookTitle: files: - src/PrestaShopBundle/Controller/Admin/ProductController.php locations: - - backoffice -type: - - action + - back office +type: action hookAliases: --- @@ -17,15 +16,14 @@ hookAliases: ## Information Hook locations: - - backoffice + - back office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/ProductController.php](src/PrestaShopBundle/Controller/Admin/ProductController.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php dispatchWithParameters( diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerDuplicateAfter.md b/modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerDuplicateAfter.md index 97ee5e51ec..50ed7861e8 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerDuplicateAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerDuplicateAfter.md @@ -6,9 +6,8 @@ hookTitle: files: - src/PrestaShopBundle/Controller/Admin/ProductController.php locations: - - backoffice -type: - - action + - back office +type: action hookAliases: --- @@ -17,15 +16,14 @@ hookAliases: ## Information Hook locations: - - backoffice + - back office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/ProductController.php](src/PrestaShopBundle/Controller/Admin/ProductController.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php dispatchWithParameters( diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerDuplicateBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerDuplicateBefore.md index 40285f8c2f..e5c948ef74 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerDuplicateBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerDuplicateBefore.md @@ -6,9 +6,8 @@ hookTitle: files: - src/PrestaShopBundle/Controller/Admin/ProductController.php locations: - - backoffice -type: - - action + - back office +type: action hookAliases: --- @@ -17,15 +16,14 @@ hookAliases: ## Information Hook locations: - - backoffice + - back office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/ProductController.php](src/PrestaShopBundle/Controller/Admin/ProductController.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php dispatchWithParameters( diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerSortAfter.md b/modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerSortAfter.md index 2b2f436853..aa79ea6272 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerSortAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerSortAfter.md @@ -6,9 +6,8 @@ hookTitle: files: - src/PrestaShopBundle/Controller/Admin/ProductController.php locations: - - backoffice -type: - - action + - back office +type: action hookAliases: --- @@ -17,15 +16,14 @@ hookAliases: ## Information Hook locations: - - backoffice + - back office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/ProductController.php](src/PrestaShopBundle/Controller/Admin/ProductController.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php dispatchWithParameters( diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerSortBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerSortBefore.md index b86dfffb18..43ff8b62fa 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerSortBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerSortBefore.md @@ -6,9 +6,8 @@ hookTitle: files: - src/PrestaShopBundle/Controller/Admin/ProductController.php locations: - - backoffice -type: - - action + - back office +type: action hookAliases: --- @@ -17,15 +16,14 @@ hookAliases: ## Information Hook locations: - - backoffice + - back office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/ProductController.php](src/PrestaShopBundle/Controller/Admin/ProductController.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php dispatchWithParameters( diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminProductsListingFieldsModifier.md b/modules/concepts/hooks/list-of-hooks/actionAdminProductsListingFieldsModifier.md index 8f61e71ca5..217dfe03ee 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminProductsListingFieldsModifier.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminProductsListingFieldsModifier.md @@ -6,9 +6,8 @@ hookTitle: files: - src/Adapter/Product/AdminProductDataProvider.php locations: - - backoffice -type: - - action + - back office +type: action hookAliases: --- @@ -17,10 +16,9 @@ hookAliases: ## Information Hook locations: - - backoffice + - back office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Product/AdminProductDataProvider.php](src/Adapter/Product/AdminProductDataProvider.php) @@ -39,7 +37,7 @@ Located in: ); ``` -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionAdminProductsListingFieldsModifier', [ diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminProductsListingResultsModifier.md b/modules/concepts/hooks/list-of-hooks/actionAdminProductsListingResultsModifier.md index 196478a15e..199ff9e6df 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminProductsListingResultsModifier.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminProductsListingResultsModifier.md @@ -6,9 +6,8 @@ hookTitle: files: - src/Adapter/Product/AdminProductDataProvider.php locations: - - backoffice -type: - - action + - back office +type: action hookAliases: --- @@ -17,10 +16,9 @@ hookAliases: ## Information Hook locations: - - backoffice + - back office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Product/AdminProductDataProvider.php](src/Adapter/Product/AdminProductDataProvider.php) @@ -36,7 +34,7 @@ Located in: ); ``` -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionAdminProductsListingResultsModifier', [ diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminSecurityControllerPostProcessBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminSecurityControllerPostProcessBefore.md index e396fae58f..d7364fedc7 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminSecurityControllerPostProcessBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminSecurityControllerPostProcessBefore.md @@ -6,9 +6,8 @@ hookTitle: On post-process in Admin Security Controller files: - src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/SecurityController.php locations: - - backoffice -type: - - action + - back office +type: action hookAliases: --- @@ -23,15 +22,14 @@ This hook is called on Admin Security Controller post-process before processing {{% /notice %}} Hook locations: - - backoffice + - back office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/SecurityController.php](src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/SecurityController.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php dispatchHook('actionAdminSecurityControllerPostProcessBefore', ['controller' => $this]) diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminShippingPreferencesControllerPostProcessBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminShippingPreferencesControllerPostProcessBefore.md index 14424e4eed..aca7e75f05 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminShippingPreferencesControllerPostProcessBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminShippingPreferencesControllerPostProcessBefore.md @@ -6,9 +6,8 @@ hookTitle: On post-process in Admin Improve Shipping Preferences Controller files: - src/PrestaShopBundle/Controller/Admin/Improve/Shipping/PreferencesController.php locations: - - backoffice -type: - - action + - back office +type: action hookAliases: --- @@ -23,15 +22,14 @@ This hook is called on Admin Improve Shipping Preferences post-process before pr {{% /notice %}} Hook locations: - - backoffice + - back office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/Improve/Shipping/PreferencesController.php](src/PrestaShopBundle/Controller/Admin/Improve/Shipping/PreferencesController.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php dispatchHook('actionAdminShippingPreferencesControllerPostProcessBefore', ['controller' => $this]) diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminShippingPreferencesControllerPostProcessCarrierOptionsBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminShippingPreferencesControllerPostProcessCarrierOptionsBefore.md index 144b633925..fce4156448 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminShippingPreferencesControllerPostProcessCarrierOptionsBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminShippingPreferencesControllerPostProcessCarrierOptionsBefore.md @@ -6,9 +6,8 @@ hookTitle: On post-process in Admin Improve Shipping Preferences Controller files: - src/PrestaShopBundle/Controller/Admin/Improve/Shipping/PreferencesController.php locations: - - backoffice -type: - - action + - back office +type: action hookAliases: --- @@ -23,15 +22,14 @@ This hook is called on Admin Improve Shipping Preferences post-process before pr {{% /notice %}} Hook locations: - - backoffice + - back office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/Improve/Shipping/PreferencesController.php](src/PrestaShopBundle/Controller/Admin/Improve/Shipping/PreferencesController.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php dispatchHook( diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminShippingPreferencesControllerPostProcessHandlingBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminShippingPreferencesControllerPostProcessHandlingBefore.md index 60ebd330d1..bee77664da 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminShippingPreferencesControllerPostProcessHandlingBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminShippingPreferencesControllerPostProcessHandlingBefore.md @@ -6,9 +6,8 @@ hookTitle: On post-process in Admin Improve Shipping Preferences Controller files: - src/PrestaShopBundle/Controller/Admin/Improve/Shipping/PreferencesController.php locations: - - backoffice -type: - - action + - back office +type: action hookAliases: --- @@ -23,15 +22,14 @@ This hook is called on Admin Improve Shipping Preferences post-process before pr {{% /notice %}} Hook locations: - - backoffice + - back office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/Improve/Shipping/PreferencesController.php](src/PrestaShopBundle/Controller/Admin/Improve/Shipping/PreferencesController.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php dispatchHook( diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminShopParametersMetaControllerPostProcessBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminShopParametersMetaControllerPostProcessBefore.md index 1b4cdc1836..a1192aa079 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminShopParametersMetaControllerPostProcessBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminShopParametersMetaControllerPostProcessBefore.md @@ -6,26 +6,24 @@ hookTitle: files: - src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/MetaController.php locations: - - backoffice -type: - - action + - back office +type: action hookAliases: --- -# Hook actionAdminShopParametersMetaControllerPostProcessBefore +# Hook actionAdminShopParametersMetaControllerPostProcess<HookName>Before ## Information Hook locations: - - backoffice + - back office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/MetaController.php](src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/MetaController.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php dispatchHook( diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminShopParametersOrderPreferencesControllerPostProcessBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminShopParametersOrderPreferencesControllerPostProcessBefore.md index 91190276a7..5ebc8e49a7 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminShopParametersOrderPreferencesControllerPostProcessBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminShopParametersOrderPreferencesControllerPostProcessBefore.md @@ -6,26 +6,24 @@ hookTitle: files: - src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/OrderPreferencesController.php locations: - - backoffice -type: - - action + - back office +type: action hookAliases: --- -# Hook actionAdminShopParametersOrderPreferencesControllerPostProcessBefore +# Hook actionAdminShopParametersOrderPreferencesControllerPostProcess<HookName>Before ## Information Hook locations: - - backoffice + - back office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/OrderPreferencesController.php](src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/OrderPreferencesController.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php dispatchHook( diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminShopParametersOrderPreferencesControllerPostProcessBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminShopParametersOrderPreferencesControllerPostProcessBefore.md index a49b58965f..10842345a6 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminShopParametersOrderPreferencesControllerPostProcessBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminShopParametersOrderPreferencesControllerPostProcessBefore.md @@ -6,9 +6,8 @@ hookTitle: On post-process in Admin Configure Shop Parameters Order Preferences files: - src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/OrderPreferencesController.php locations: - - backoffice -type: - - action + - back office +type: action hookAliases: --- @@ -23,15 +22,14 @@ This hook is called on Admin Configure Shop Parameters Order Preferences post-pr {{% /notice %}} Hook locations: - - backoffice + - back office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/OrderPreferencesController.php](src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/OrderPreferencesController.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php dispatchHook('actionAdminShopParametersOrderPreferencesControllerPostProcessBefore', ['controller' => $this]) diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminShopParametersProductPreferencesControllerPostProcessBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminShopParametersProductPreferencesControllerPostProcessBefore.md index 68bf687c3b..07cdffb2f8 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminShopParametersProductPreferencesControllerPostProcessBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminShopParametersProductPreferencesControllerPostProcessBefore.md @@ -6,26 +6,24 @@ hookTitle: files: - src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/ProductPreferencesController.php locations: - - backoffice -type: - - action + - back office +type: action hookAliases: --- -# Hook actionAdminShopParametersProductPreferencesControllerPostProcessBefore +# Hook actionAdminShopParametersProductPreferencesControllerPostProcess<HookName>Before ## Information Hook locations: - - backoffice + - back office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/ProductPreferencesController.php](src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/ProductPreferencesController.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php dispatchHook( diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminShopParametersProductPreferencesControllerPostProcessBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminShopParametersProductPreferencesControllerPostProcessBefore.md index d6538737be..20bf5c86c8 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminShopParametersProductPreferencesControllerPostProcessBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminShopParametersProductPreferencesControllerPostProcessBefore.md @@ -6,9 +6,8 @@ hookTitle: files: - src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/ProductPreferencesController.php locations: - - backoffice -type: - - action + - back office +type: action hookAliases: --- @@ -17,15 +16,14 @@ hookAliases: ## Information Hook locations: - - backoffice + - back office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/ProductPreferencesController.php](src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/ProductPreferencesController.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php dispatchHook('actionAdminShopParametersProductPreferencesControllerPostProcessBefore', ['controller' => $this]) diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminSortAfter.md b/modules/concepts/hooks/list-of-hooks/actionAdminSortAfter.md index c47644653f..eccf9cdae7 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminSortAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminSortAfter.md @@ -6,9 +6,8 @@ hookTitle: files: - src/PrestaShopBundle/Controller/Admin/ProductController.php locations: - - backoffice -type: - - action + - back office +type: action hookAliases: --- @@ -17,15 +16,14 @@ hookAliases: ## Information Hook locations: - - backoffice + - back office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/ProductController.php](src/PrestaShopBundle/Controller/Admin/ProductController.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php dispatchWithParameters( diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminSortBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminSortBefore.md index 5385915bad..5b123fcc9d 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminSortBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminSortBefore.md @@ -6,9 +6,8 @@ hookTitle: files: - src/PrestaShopBundle/Controller/Admin/ProductController.php locations: - - backoffice -type: - - action + - back office +type: action hookAliases: --- @@ -17,15 +16,14 @@ hookAliases: ## Information Hook locations: - - backoffice + - back office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/ProductController.php](src/PrestaShopBundle/Controller/Admin/ProductController.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php dispatchWithParameters( diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminThemesControllerUpdateoptionsAfter.md b/modules/concepts/hooks/list-of-hooks/actionAdminThemesControllerUpdateoptionsAfter.md index d501822f8f..d4175ed74f 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminThemesControllerUpdateoptionsAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminThemesControllerUpdateoptionsAfter.md @@ -6,9 +6,8 @@ hookTitle: files: - src/Adapter/Shop/CommandHandler/UploadLogosHandler.php locations: - - backoffice -type: - - action + - back office +type: action hookAliases: --- @@ -17,15 +16,14 @@ hookAliases: ## Information Hook locations: - - backoffice + - back office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Shop/CommandHandler/UploadLogosHandler.php](src/Adapter/Shop/CommandHandler/UploadLogosHandler.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php dispatchWithParameters('actionAdminThemesControllerUpdate_optionsAfter') diff --git a/modules/concepts/hooks/list-of-hooks/actionAfterCreateFormHandler.md b/modules/concepts/hooks/list-of-hooks/actionAfterCreateFormHandler.md index 4e60529b15..d38412f8a9 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAfterCreateFormHandler.md +++ b/modules/concepts/hooks/list-of-hooks/actionAfterCreateFormHandler.md @@ -6,26 +6,24 @@ hookTitle: files: - src/Core/Form/IdentifiableObject/Handler/FormHandler.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: --- -# Hook actionAfterCreateFormHandler +# Hook actionAfterCreate<FormName>FormHandler ## Information Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Core/Form/IdentifiableObject/Handler/FormHandler.php](src/Core/Form/IdentifiableObject/Handler/FormHandler.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php dispatchWithParameters('actionAfterCreate' . Container::camelize($form->getName()) . 'FormHandler', [ diff --git a/modules/concepts/hooks/list-of-hooks/actionAfterUpdateFormHandler.md b/modules/concepts/hooks/list-of-hooks/actionAfterUpdateFormHandler.md index a9b0455cf1..11db838621 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAfterUpdateFormHandler.md +++ b/modules/concepts/hooks/list-of-hooks/actionAfterUpdateFormHandler.md @@ -6,26 +6,24 @@ hookTitle: files: - src/Core/Form/IdentifiableObject/Handler/FormHandler.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: --- -# Hook actionAfterUpdateFormHandler +# Hook actionAfterUpdate<FormName>FormHandler ## Information Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Core/Form/IdentifiableObject/Handler/FormHandler.php](src/Core/Form/IdentifiableObject/Handler/FormHandler.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php dispatchWithParameters('actionAfterUpdate' . Container::camelize($form->getName()) . 'FormHandler', [ diff --git a/modules/concepts/hooks/list-of-hooks/actionAjaxDieBefore.md b/modules/concepts/hooks/list-of-hooks/actionAjaxDieBefore.md index 44468ef07c..6831880eb0 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAjaxDieBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAjaxDieBefore.md @@ -6,26 +6,24 @@ hookTitle: files: - classes/controller/Controller.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: --- -# Hook actionAjaxDieBefore +# Hook actionAjaxDie<Controller><Method>Before ## Information Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/Controller.php](classes/controller/Controller.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionAjaxDie' . $controller . $method . 'Before', ['value' => $value]) diff --git a/modules/concepts/hooks/list-of-hooks/actionAjaxDieBefore.md b/modules/concepts/hooks/list-of-hooks/actionAjaxDieBefore.md index ecc2eee018..7440dcfd66 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAjaxDieBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAjaxDieBefore.md @@ -6,9 +6,8 @@ hookTitle: files: - classes/controller/Controller.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: - actionBeforeAjaxDie --- @@ -27,15 +26,14 @@ Aliases: {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/Controller.php](classes/controller/Controller.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionAjaxDieBefore', ['controller' => $controller, 'method' => $method, 'value' => $value]) diff --git a/modules/concepts/hooks/list-of-hooks/actionAttributeCombinationDelete.md b/modules/concepts/hooks/list-of-hooks/actionAttributeCombinationDelete.md index 0ac5983b33..ec14364c8f 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAttributeCombinationDelete.md +++ b/modules/concepts/hooks/list-of-hooks/actionAttributeCombinationDelete.md @@ -6,9 +6,8 @@ hookTitle: files: - classes/Combination.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: --- @@ -17,15 +16,14 @@ hookAliases: ## Information Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Combination.php](classes/Combination.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionAttributeCombinationDelete', ['id_product_attribute' => (int) $this->id]) diff --git a/modules/concepts/hooks/list-of-hooks/actionAttributeCombinationSave.md b/modules/concepts/hooks/list-of-hooks/actionAttributeCombinationSave.md index 1b4ef85ec0..33a9a72c87 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAttributeCombinationSave.md +++ b/modules/concepts/hooks/list-of-hooks/actionAttributeCombinationSave.md @@ -6,9 +6,8 @@ hookTitle: files: - classes/Combination.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: --- @@ -17,15 +16,14 @@ hookAliases: ## Information Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Combination.php](classes/Combination.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionAttributeCombinationSave', ['id_product_attribute' => (int) $this->id, 'id_attributes' => $idsAttribute]) diff --git a/modules/concepts/hooks/list-of-hooks/actionAttributeDelete.md b/modules/concepts/hooks/list-of-hooks/actionAttributeDelete.md index 47cd8ecdc6..f4049c68d9 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAttributeDelete.md +++ b/modules/concepts/hooks/list-of-hooks/actionAttributeDelete.md @@ -6,9 +6,8 @@ hookTitle: Deleting an attributes features value files: - classes/ProductAttribute.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: - afterDeleteAttribute --- @@ -29,15 +28,14 @@ This hook is called while deleting an attributes features value {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/ProductAttribute.php](classes/ProductAttribute.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionAttributeDelete', ['id_attribute' => $this->id]) diff --git a/modules/concepts/hooks/list-of-hooks/actionAttributeGroupDelete.md b/modules/concepts/hooks/list-of-hooks/actionAttributeGroupDelete.md index d9fe8fb563..134822e498 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAttributeGroupDelete.md +++ b/modules/concepts/hooks/list-of-hooks/actionAttributeGroupDelete.md @@ -6,9 +6,8 @@ hookTitle: Deleting attribute group files: - classes/AttributeGroup.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: - afterDeleteAttributeGroup --- @@ -29,15 +28,14 @@ This hook is called while deleting an attributes group {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/AttributeGroup.php](classes/AttributeGroup.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionAttributeGroupDelete', ['id_attribute_group' => $this->id]) diff --git a/modules/concepts/hooks/list-of-hooks/actionAttributeGroupSave.md b/modules/concepts/hooks/list-of-hooks/actionAttributeGroupSave.md index 28efed0187..8bf7847368 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAttributeGroupSave.md +++ b/modules/concepts/hooks/list-of-hooks/actionAttributeGroupSave.md @@ -6,9 +6,8 @@ hookTitle: Saving an attribute group files: - classes/AttributeGroup.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: - afterSaveAttributeGroup --- @@ -29,15 +28,14 @@ This hook is called while saving an attributes group {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/AttributeGroup.php](classes/AttributeGroup.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionAttributeGroupSave', ['id_attribute_group' => $this->id]) diff --git a/modules/concepts/hooks/list-of-hooks/actionAttributeSave.md b/modules/concepts/hooks/list-of-hooks/actionAttributeSave.md index e74e86d31f..a9d7b5be7b 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAttributeSave.md +++ b/modules/concepts/hooks/list-of-hooks/actionAttributeSave.md @@ -6,9 +6,8 @@ hookTitle: Saving an attributes features value files: - classes/ProductAttribute.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: - afterSaveAttribute --- @@ -29,15 +28,14 @@ This hook is called while saving an attributes features value {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/ProductAttribute.php](classes/ProductAttribute.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionAttributeSave', ['id_attribute' => $this->id]) diff --git a/modules/concepts/hooks/list-of-hooks/actionAuthentication.md b/modules/concepts/hooks/list-of-hooks/actionAuthentication.md index f7367f05f9..5891e932b8 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAuthentication.md +++ b/modules/concepts/hooks/list-of-hooks/actionAuthentication.md @@ -6,9 +6,8 @@ hookTitle: Successful customer authentication files: - classes/form/CustomerLoginForm.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: - authentication --- @@ -29,15 +28,14 @@ This hook is displayed after a customer successfully signs in {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/form/CustomerLoginForm.php](classes/form/CustomerLoginForm.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionAuthentication', ['customer' => $this->context->customer]) diff --git a/modules/concepts/hooks/list-of-hooks/actionAuthenticationBefore.md b/modules/concepts/hooks/list-of-hooks/actionAuthenticationBefore.md index 94e95ec9ee..99665c3458 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAuthenticationBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAuthenticationBefore.md @@ -6,9 +6,8 @@ hookTitle: files: - classes/form/CustomerLoginForm.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: - actionBeforeAuthentication --- @@ -23,15 +22,14 @@ Aliases: ## Information Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/form/CustomerLoginForm.php](classes/form/CustomerLoginForm.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionAuthenticationBefore') diff --git a/modules/concepts/hooks/list-of-hooks/actionBeforeAjaxDie.md b/modules/concepts/hooks/list-of-hooks/actionBeforeAjaxDie.md index ccbd90b9c9..7e4cb7a343 100644 --- a/modules/concepts/hooks/list-of-hooks/actionBeforeAjaxDie.md +++ b/modules/concepts/hooks/list-of-hooks/actionBeforeAjaxDie.md @@ -6,26 +6,24 @@ hookTitle: files: - classes/controller/Controller.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: --- -# Hook actionBeforeAjaxDie +# Hook actionBeforeAjaxDie<Controller><Method> ## Information Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/Controller.php](classes/controller/Controller.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionBeforeAjaxDie' . $controller . $method, ['value' => $value]) diff --git a/modules/concepts/hooks/list-of-hooks/actionBeforeCreateFormHandler.md b/modules/concepts/hooks/list-of-hooks/actionBeforeCreateFormHandler.md index 8e1eb39edd..6cea723063 100644 --- a/modules/concepts/hooks/list-of-hooks/actionBeforeCreateFormHandler.md +++ b/modules/concepts/hooks/list-of-hooks/actionBeforeCreateFormHandler.md @@ -6,26 +6,24 @@ hookTitle: files: - src/Core/Form/IdentifiableObject/Handler/FormHandler.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: --- -# Hook actionBeforeCreateFormHandler +# Hook actionBeforeCreate<FormName>FormHandler ## Information Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Core/Form/IdentifiableObject/Handler/FormHandler.php](src/Core/Form/IdentifiableObject/Handler/FormHandler.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php dispatchWithParameters( diff --git a/modules/concepts/hooks/list-of-hooks/actionBeforeUpdateFormHandler.md b/modules/concepts/hooks/list-of-hooks/actionBeforeUpdateFormHandler.md index ceee6f9425..0fa7e32f88 100644 --- a/modules/concepts/hooks/list-of-hooks/actionBeforeUpdateFormHandler.md +++ b/modules/concepts/hooks/list-of-hooks/actionBeforeUpdateFormHandler.md @@ -6,26 +6,24 @@ hookTitle: files: - src/Core/Form/IdentifiableObject/Handler/FormHandler.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: --- -# Hook actionBeforeUpdateFormHandler +# Hook actionBeforeUpdate<FormName>FormHandler ## Information Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Core/Form/IdentifiableObject/Handler/FormHandler.php](src/Core/Form/IdentifiableObject/Handler/FormHandler.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php dispatchWithParameters('actionBeforeUpdate' . Container::camelize($form->getName()) . 'FormHandler', [ diff --git a/modules/concepts/hooks/list-of-hooks/actionBuildFrontEndObject.md b/modules/concepts/hooks/list-of-hooks/actionBuildFrontEndObject.md index a3beb0ab9f..3759dea6ac 100644 --- a/modules/concepts/hooks/list-of-hooks/actionBuildFrontEndObject.md +++ b/modules/concepts/hooks/list-of-hooks/actionBuildFrontEndObject.md @@ -6,9 +6,8 @@ hookTitle: Manage elements added to the "prestashop" javascript object files: - classes/controller/FrontController.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: --- @@ -23,15 +22,14 @@ This hook allows you to customize the "prestashop" javascript object that is inc {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/FrontController.php](classes/controller/FrontController.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionBuildFrontEndObject', [ diff --git a/modules/concepts/hooks/list-of-hooks/actionBuildMailLayoutVariables.md b/modules/concepts/hooks/list-of-hooks/actionBuildMailLayoutVariables.md index 19d47edf25..408e392dd4 100644 --- a/modules/concepts/hooks/list-of-hooks/actionBuildMailLayoutVariables.md +++ b/modules/concepts/hooks/list-of-hooks/actionBuildMailLayoutVariables.md @@ -6,9 +6,8 @@ hookTitle: Build the variables used in email layout rendering files: - src/Core/MailTemplate/Layout/LayoutVariablesBuilder.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: --- @@ -23,15 +22,14 @@ This hook allows to change the variables used when an email layout is rendered {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Core/MailTemplate/Layout/LayoutVariablesBuilder.php](src/Core/MailTemplate/Layout/LayoutVariablesBuilder.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php dispatchWithParameters( diff --git a/modules/concepts/hooks/list-of-hooks/actionCarrierProcess.md b/modules/concepts/hooks/list-of-hooks/actionCarrierProcess.md index 80e945118e..7f46197896 100644 --- a/modules/concepts/hooks/list-of-hooks/actionCarrierProcess.md +++ b/modules/concepts/hooks/list-of-hooks/actionCarrierProcess.md @@ -6,9 +6,8 @@ hookTitle: Carrier process files: - classes/checkout/CheckoutDeliveryStep.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: - processCarrier --- @@ -29,15 +28,14 @@ Aliases: {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/checkout/CheckoutDeliveryStep.php](classes/checkout/CheckoutDeliveryStep.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionCarrierProcess', ['cart' => $this->getCheckoutSession()->getCart()]) diff --git a/modules/concepts/hooks/list-of-hooks/actionCarrierUpdate.md b/modules/concepts/hooks/list-of-hooks/actionCarrierUpdate.md index 362b766671..7543bdc7f1 100644 --- a/modules/concepts/hooks/list-of-hooks/actionCarrierUpdate.md +++ b/modules/concepts/hooks/list-of-hooks/actionCarrierUpdate.md @@ -6,9 +6,8 @@ hookTitle: Carrier Update files: - controllers/admin/AdminCarriersController.php locations: - - backoffice -type: - - action + - back office +type: action hookAliases: - updateCarrier --- @@ -29,15 +28,14 @@ This hook is called when a carrier is updated {{% /notice %}} Hook locations: - - backoffice + - back office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/admin/AdminCarriersController.php](controllers/admin/AdminCarriersController.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionCarrierUpdate', [ diff --git a/modules/concepts/hooks/list-of-hooks/actionCartSave.md b/modules/concepts/hooks/list-of-hooks/actionCartSave.md index 6e2eb74e64..c4346683d6 100644 --- a/modules/concepts/hooks/list-of-hooks/actionCartSave.md +++ b/modules/concepts/hooks/list-of-hooks/actionCartSave.md @@ -6,9 +6,8 @@ hookTitle: Cart creation and update files: - classes/Cart.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: - cart --- @@ -29,15 +28,14 @@ This hook is displayed when a product is added to the cart or if the cart's cont {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Cart.php](classes/Cart.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionCartSave', ['cart' => $this]) diff --git a/modules/concepts/hooks/list-of-hooks/actionCartSummary.md b/modules/concepts/hooks/list-of-hooks/actionCartSummary.md index 2d6e6d4ebe..2a64c05b68 100644 --- a/modules/concepts/hooks/list-of-hooks/actionCartSummary.md +++ b/modules/concepts/hooks/list-of-hooks/actionCartSummary.md @@ -6,9 +6,8 @@ hookTitle: files: - classes/Cart.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: --- @@ -17,15 +16,14 @@ hookAliases: ## Information Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Cart.php](classes/Cart.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionCartSummary', $summary, null, true) diff --git a/modules/concepts/hooks/list-of-hooks/actionCartUpdateQuantityBefore.md b/modules/concepts/hooks/list-of-hooks/actionCartUpdateQuantityBefore.md index 71ab241e93..5fa7822e7d 100644 --- a/modules/concepts/hooks/list-of-hooks/actionCartUpdateQuantityBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionCartUpdateQuantityBefore.md @@ -6,9 +6,8 @@ hookTitle: files: - classes/Cart.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: - actionBeforeCartUpdateQty --- @@ -23,15 +22,14 @@ Aliases: ## Information Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Cart.php](classes/Cart.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionCartUpdateQuantityBefore', $data) diff --git a/modules/concepts/hooks/list-of-hooks/actionCategoryAdd.md b/modules/concepts/hooks/list-of-hooks/actionCategoryAdd.md index be5728c79a..c6f76bee06 100644 --- a/modules/concepts/hooks/list-of-hooks/actionCategoryAdd.md +++ b/modules/concepts/hooks/list-of-hooks/actionCategoryAdd.md @@ -6,9 +6,8 @@ hookTitle: Category creation files: - classes/Category.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: - categoryAddition --- @@ -29,15 +28,14 @@ This hook is displayed when a category is created {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Category.php](classes/Category.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionCategoryAdd', ['category' => $this]) diff --git a/modules/concepts/hooks/list-of-hooks/actionCategoryDelete.md b/modules/concepts/hooks/list-of-hooks/actionCategoryDelete.md index 55e94633b5..092aa3e972 100644 --- a/modules/concepts/hooks/list-of-hooks/actionCategoryDelete.md +++ b/modules/concepts/hooks/list-of-hooks/actionCategoryDelete.md @@ -6,9 +6,8 @@ hookTitle: Category deletion files: - classes/Category.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: - categoryDeletion --- @@ -29,15 +28,14 @@ This hook is displayed when a category is deleted {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Category.php](classes/Category.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionCategoryDelete', ['category' => $this, 'deleted_children' => $deletedChildren]) diff --git a/modules/concepts/hooks/list-of-hooks/actionCategoryUpdate.md b/modules/concepts/hooks/list-of-hooks/actionCategoryUpdate.md index 950406c01a..a3b2b95207 100644 --- a/modules/concepts/hooks/list-of-hooks/actionCategoryUpdate.md +++ b/modules/concepts/hooks/list-of-hooks/actionCategoryUpdate.md @@ -6,9 +6,8 @@ hookTitle: Category modification files: - controllers/admin/AdminProductsController.php locations: - - backoffice -type: - - action + - back office +type: action hookAliases: - categoryUpdate --- @@ -29,15 +28,14 @@ This hook is displayed when a category is modified {{% /notice %}} Hook locations: - - backoffice + - back office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/admin/AdminProductsController.php](controllers/admin/AdminProductsController.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionCategoryUpdate', ['category' => $category]) diff --git a/modules/concepts/hooks/list-of-hooks/actionCheckoutRender.md b/modules/concepts/hooks/list-of-hooks/actionCheckoutRender.md index 20123c9b1c..1a416afe82 100644 --- a/modules/concepts/hooks/list-of-hooks/actionCheckoutRender.md +++ b/modules/concepts/hooks/list-of-hooks/actionCheckoutRender.md @@ -6,9 +6,8 @@ hookTitle: Modify checkout process files: - controllers/front/OrderController.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: --- @@ -23,15 +22,14 @@ This hook is called when constructing the checkout process {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/front/OrderController.php](controllers/front/OrderController.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionCheckoutRender', ['checkoutProcess' => &$this->checkoutProcess]) diff --git a/modules/concepts/hooks/list-of-hooks/actionClearCache.md b/modules/concepts/hooks/list-of-hooks/actionClearCache.md index 219401f5a4..4a83e65094 100644 --- a/modules/concepts/hooks/list-of-hooks/actionClearCache.md +++ b/modules/concepts/hooks/list-of-hooks/actionClearCache.md @@ -6,9 +6,8 @@ hookTitle: Clear smarty cache files: - classes/Tools.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: --- @@ -23,15 +22,14 @@ This hook is called when smarty's cache is cleared {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Tools.php](classes/Tools.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionClearCache') diff --git a/modules/concepts/hooks/list-of-hooks/actionClearCompileCache.md b/modules/concepts/hooks/list-of-hooks/actionClearCompileCache.md index dd4ceedcb0..b9b323e041 100644 --- a/modules/concepts/hooks/list-of-hooks/actionClearCompileCache.md +++ b/modules/concepts/hooks/list-of-hooks/actionClearCompileCache.md @@ -6,9 +6,8 @@ hookTitle: Clear smarty compile cache files: - classes/Tools.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: --- @@ -23,15 +22,14 @@ This hook is called when smarty's compile cache is cleared {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Tools.php](classes/Tools.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionClearCompileCache') diff --git a/modules/concepts/hooks/list-of-hooks/actionClearSf2Cache.md b/modules/concepts/hooks/list-of-hooks/actionClearSf2Cache.md index a7a44afadf..daf9b3744f 100644 --- a/modules/concepts/hooks/list-of-hooks/actionClearSf2Cache.md +++ b/modules/concepts/hooks/list-of-hooks/actionClearSf2Cache.md @@ -6,9 +6,8 @@ hookTitle: Clear Sf2 cache files: - src/Adapter/Cache/Clearer/SymfonyCacheClearer.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: --- @@ -23,15 +22,14 @@ This hook is called when the Symfony cache is cleared {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Cache/Clearer/SymfonyCacheClearer.php](src/Adapter/Cache/Clearer/SymfonyCacheClearer.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionClearSf2Cache') diff --git a/modules/concepts/hooks/list-of-hooks/actionControllerInitAfter.md b/modules/concepts/hooks/list-of-hooks/actionControllerInitAfter.md index 280ff72615..42ab5932b4 100644 --- a/modules/concepts/hooks/list-of-hooks/actionControllerInitAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionControllerInitAfter.md @@ -6,9 +6,8 @@ hookTitle: Perform actions after controller initialization files: - classes/controller/Controller.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: --- @@ -23,15 +22,14 @@ This hook is launched after the initialization of all controllers {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/Controller.php](classes/controller/Controller.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec( diff --git a/modules/concepts/hooks/list-of-hooks/actionControllerInitBefore.md b/modules/concepts/hooks/list-of-hooks/actionControllerInitBefore.md index f13ac20ea3..037168580e 100644 --- a/modules/concepts/hooks/list-of-hooks/actionControllerInitBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionControllerInitBefore.md @@ -6,9 +6,8 @@ hookTitle: Perform actions before controller initialization files: - classes/controller/Controller.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: --- @@ -23,15 +22,14 @@ This hook is launched before the initialization of all controllers {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/Controller.php](classes/controller/Controller.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec( diff --git a/modules/concepts/hooks/list-of-hooks/actionCustomerAccountAdd.md b/modules/concepts/hooks/list-of-hooks/actionCustomerAccountAdd.md index fac955781c..fd6f880527 100644 --- a/modules/concepts/hooks/list-of-hooks/actionCustomerAccountAdd.md +++ b/modules/concepts/hooks/list-of-hooks/actionCustomerAccountAdd.md @@ -6,9 +6,8 @@ hookTitle: Successful customer account creation files: - classes/form/CustomerPersister.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: - createAccount --- @@ -29,10 +28,9 @@ This hook is called when a new customer creates an account successfully {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/form/CustomerPersister.php](classes/form/CustomerPersister.php) @@ -46,7 +44,7 @@ Located in: ); ``` -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionCustomerAccountAdd', [ diff --git a/modules/concepts/hooks/list-of-hooks/actionCustomerAccountUpdate.md b/modules/concepts/hooks/list-of-hooks/actionCustomerAccountUpdate.md index b93d33dcdd..509ead8398 100644 --- a/modules/concepts/hooks/list-of-hooks/actionCustomerAccountUpdate.md +++ b/modules/concepts/hooks/list-of-hooks/actionCustomerAccountUpdate.md @@ -6,9 +6,8 @@ hookTitle: Successful customer account update files: - classes/form/CustomerPersister.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: --- @@ -23,15 +22,14 @@ This hook is called when a customer updates its account successfully {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/form/CustomerPersister.php](classes/form/CustomerPersister.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionCustomerAccountUpdate', [ diff --git a/modules/concepts/hooks/list-of-hooks/actionCustomerAddGroups.md b/modules/concepts/hooks/list-of-hooks/actionCustomerAddGroups.md index 4435d602c6..8b83d1e803 100644 --- a/modules/concepts/hooks/list-of-hooks/actionCustomerAddGroups.md +++ b/modules/concepts/hooks/list-of-hooks/actionCustomerAddGroups.md @@ -6,9 +6,8 @@ hookTitle: files: - classes/Customer.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: --- @@ -17,15 +16,14 @@ hookAliases: ## Information Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Customer.php](classes/Customer.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionCustomerAddGroups', ['id_customer' => $this->id, 'groups' => $groups]) diff --git a/modules/concepts/hooks/list-of-hooks/actionCustomerBeforeUpdateGroup.md b/modules/concepts/hooks/list-of-hooks/actionCustomerBeforeUpdateGroup.md index 8629109e4b..0eab712194 100644 --- a/modules/concepts/hooks/list-of-hooks/actionCustomerBeforeUpdateGroup.md +++ b/modules/concepts/hooks/list-of-hooks/actionCustomerBeforeUpdateGroup.md @@ -6,9 +6,8 @@ hookTitle: files: - classes/Customer.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: --- @@ -17,15 +16,14 @@ hookAliases: ## Information Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Customer.php](classes/Customer.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionCustomerBeforeUpdateGroup', ['id_customer' => $this->id, 'groups' => $list]) diff --git a/modules/concepts/hooks/list-of-hooks/actionCustomerLogoutAfter.md b/modules/concepts/hooks/list-of-hooks/actionCustomerLogoutAfter.md index caa5a4462d..2bf6a674a5 100644 --- a/modules/concepts/hooks/list-of-hooks/actionCustomerLogoutAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionCustomerLogoutAfter.md @@ -6,9 +6,8 @@ hookTitle: After customer logout files: - classes/Customer.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: --- @@ -23,15 +22,14 @@ This hook allows you to execute code after customer logout {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Customer.php](classes/Customer.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionCustomerLogoutAfter', ['customer' => $this]) diff --git a/modules/concepts/hooks/list-of-hooks/actionCustomerLogoutBefore.md b/modules/concepts/hooks/list-of-hooks/actionCustomerLogoutBefore.md index 1826a3256d..e8387ac074 100644 --- a/modules/concepts/hooks/list-of-hooks/actionCustomerLogoutBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionCustomerLogoutBefore.md @@ -6,9 +6,8 @@ hookTitle: Before customer logout files: - classes/Customer.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: --- @@ -23,15 +22,14 @@ This hook allows you to execute code before customer logout {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Customer.php](classes/Customer.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionCustomerLogoutBefore', ['customer' => $this]) diff --git a/modules/concepts/hooks/list-of-hooks/actionDeleteGDPRCustomer.md b/modules/concepts/hooks/list-of-hooks/actionDeleteGDPRCustomer.md index ee45aa8a80..1e8655f770 100644 --- a/modules/concepts/hooks/list-of-hooks/actionDeleteGDPRCustomer.md +++ b/modules/concepts/hooks/list-of-hooks/actionDeleteGDPRCustomer.md @@ -6,9 +6,8 @@ hookTitle: files: - modules/psgdpr/psgdpr.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: --- @@ -17,15 +16,14 @@ hookAliases: ## Information Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/modules/psgdpr/psgdpr.php](modules/psgdpr/psgdpr.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionDeleteGDPRCustomer', $customer, $module['id_module']) diff --git a/modules/concepts/hooks/list-of-hooks/actionDeliveryPriceByPrice.md b/modules/concepts/hooks/list-of-hooks/actionDeliveryPriceByPrice.md index 5c2a486987..375640e76e 100644 --- a/modules/concepts/hooks/list-of-hooks/actionDeliveryPriceByPrice.md +++ b/modules/concepts/hooks/list-of-hooks/actionDeliveryPriceByPrice.md @@ -6,9 +6,8 @@ hookTitle: files: - classes/Carrier.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: --- @@ -17,15 +16,14 @@ hookAliases: ## Information Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Carrier.php](classes/Carrier.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionDeliveryPriceByPrice', ['id_carrier' => $id_carrier, 'order_total' => $order_total, 'id_zone' => $id_zone]) diff --git a/modules/concepts/hooks/list-of-hooks/actionDeliveryPriceByWeight.md b/modules/concepts/hooks/list-of-hooks/actionDeliveryPriceByWeight.md index 7e53103af4..9734ca5d47 100644 --- a/modules/concepts/hooks/list-of-hooks/actionDeliveryPriceByWeight.md +++ b/modules/concepts/hooks/list-of-hooks/actionDeliveryPriceByWeight.md @@ -6,9 +6,8 @@ hookTitle: files: - classes/Carrier.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: --- @@ -17,15 +16,14 @@ hookAliases: ## Information Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Carrier.php](classes/Carrier.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionDeliveryPriceByWeight', ['id_carrier' => $id_carrier, 'total_weight' => $total_weight, 'id_zone' => $id_zone]) diff --git a/modules/concepts/hooks/list-of-hooks/actionDispatcher.md b/modules/concepts/hooks/list-of-hooks/actionDispatcher.md index a2c07d3de6..d9132ff175 100644 --- a/modules/concepts/hooks/list-of-hooks/actionDispatcher.md +++ b/modules/concepts/hooks/list-of-hooks/actionDispatcher.md @@ -6,9 +6,8 @@ hookTitle: files: - classes/Dispatcher.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: --- @@ -17,15 +16,14 @@ hookAliases: ## Information Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Dispatcher.php](classes/Dispatcher.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionDispatcher', $params_hook_action_dispatcher) diff --git a/modules/concepts/hooks/list-of-hooks/actionDispatcherAfter.md b/modules/concepts/hooks/list-of-hooks/actionDispatcherAfter.md index 8c9b7718fa..07eb51ba86 100644 --- a/modules/concepts/hooks/list-of-hooks/actionDispatcherAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionDispatcherAfter.md @@ -6,9 +6,8 @@ hookTitle: After dispatch files: - src/PrestaShopBundle/EventListener/ActionDispatcherLegacyHooksSubscriber.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: --- @@ -23,15 +22,14 @@ This hook is called at the end of the dispatch method of the Dispatcher {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/EventListener/ActionDispatcherLegacyHooksSubscriber.php](src/PrestaShopBundle/EventListener/ActionDispatcherLegacyHooksSubscriber.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php dispatchWithParameters(self::DISPATCHER_AFTER_ACTION, [ diff --git a/modules/concepts/hooks/list-of-hooks/actionDispatcherBefore.md b/modules/concepts/hooks/list-of-hooks/actionDispatcherBefore.md index 538378fcb0..7aa2eedb2a 100644 --- a/modules/concepts/hooks/list-of-hooks/actionDispatcherBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionDispatcherBefore.md @@ -6,9 +6,8 @@ hookTitle: Before dispatch files: - src/PrestaShopBundle/EventListener/ActionDispatcherLegacyHooksSubscriber.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: --- @@ -23,15 +22,14 @@ This hook is called at the beginning of the dispatch method of the Dispatcher {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/EventListener/ActionDispatcherLegacyHooksSubscriber.php](src/PrestaShopBundle/EventListener/ActionDispatcherLegacyHooksSubscriber.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php dispatchWithParameters(self::DISPATCHER_BEFORE_ACTION, [ diff --git a/modules/concepts/hooks/list-of-hooks/actionDownloadAttachment.md b/modules/concepts/hooks/list-of-hooks/actionDownloadAttachment.md index f3e91e16b8..25f3e1b48a 100644 --- a/modules/concepts/hooks/list-of-hooks/actionDownloadAttachment.md +++ b/modules/concepts/hooks/list-of-hooks/actionDownloadAttachment.md @@ -6,9 +6,8 @@ hookTitle: files: - controllers/front/AttachmentController.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: --- @@ -17,15 +16,14 @@ hookAliases: ## Information Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/front/AttachmentController.php](controllers/front/AttachmentController.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionDownloadAttachment', ['attachment' => &$attachment]) diff --git a/modules/concepts/hooks/list-of-hooks/actionEmailAddAfterContent.md b/modules/concepts/hooks/list-of-hooks/actionEmailAddAfterContent.md index 8f2ca9ae6e..a1db504c08 100644 --- a/modules/concepts/hooks/list-of-hooks/actionEmailAddAfterContent.md +++ b/modules/concepts/hooks/list-of-hooks/actionEmailAddAfterContent.md @@ -6,9 +6,8 @@ hookTitle: Add extra content after mail content files: - classes/Mail.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: --- @@ -23,17 +22,16 @@ This hook is called just after fetching mail template {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Mail.php](classes/Mail.php) This hook has an `$array_return` parameter set to `true` (module output will be set by name in an array, [see explaination here]({{< relref "/8/development/components/hook/dispatching-hook">}})). -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec( diff --git a/modules/concepts/hooks/list-of-hooks/actionEmailAddBeforeContent.md b/modules/concepts/hooks/list-of-hooks/actionEmailAddBeforeContent.md index 88dd347708..da6a77246e 100644 --- a/modules/concepts/hooks/list-of-hooks/actionEmailAddBeforeContent.md +++ b/modules/concepts/hooks/list-of-hooks/actionEmailAddBeforeContent.md @@ -6,9 +6,8 @@ hookTitle: Add extra content before mail content files: - classes/Mail.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: --- @@ -23,17 +22,16 @@ This hook is called just before fetching mail template {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Mail.php](classes/Mail.php) This hook has an `$array_return` parameter set to `true` (module output will be set by name in an array, [see explaination here]({{< relref "/8/development/components/hook/dispatching-hook">}})). -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec( diff --git a/modules/concepts/hooks/list-of-hooks/actionEmailSendBefore.md b/modules/concepts/hooks/list-of-hooks/actionEmailSendBefore.md index e30f7524eb..bd6b9a4b19 100644 --- a/modules/concepts/hooks/list-of-hooks/actionEmailSendBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionEmailSendBefore.md @@ -6,9 +6,8 @@ hookTitle: Before sending an email files: - classes/Mail.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: --- @@ -23,17 +22,16 @@ This hook is used to filter the content or the metadata of an email before sendi {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Mail.php](classes/Mail.php) This hook has an `$array_return` parameter set to `true` (module output will be set by name in an array, [see explaination here]({{< relref "/8/development/components/hook/dispatching-hook">}})). -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec( diff --git a/modules/concepts/hooks/list-of-hooks/actionExportGDPRData.md b/modules/concepts/hooks/list-of-hooks/actionExportGDPRData.md index eb7168f336..25ad190ce4 100644 --- a/modules/concepts/hooks/list-of-hooks/actionExportGDPRData.md +++ b/modules/concepts/hooks/list-of-hooks/actionExportGDPRData.md @@ -6,9 +6,8 @@ hookTitle: files: - modules/psgdpr/psgdpr.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: --- @@ -17,15 +16,14 @@ hookAliases: ## Information Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/modules/psgdpr/psgdpr.php](modules/psgdpr/psgdpr.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionExportGDPRData', $customer, $module['id_module']) diff --git a/modules/concepts/hooks/list-of-hooks/actionFeatureDelete.md b/modules/concepts/hooks/list-of-hooks/actionFeatureDelete.md index f2b2d3fbb3..08c7272b9e 100644 --- a/modules/concepts/hooks/list-of-hooks/actionFeatureDelete.md +++ b/modules/concepts/hooks/list-of-hooks/actionFeatureDelete.md @@ -6,9 +6,8 @@ hookTitle: Deleting attributes' features files: - classes/Feature.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: - afterDeleteFeature --- @@ -29,15 +28,14 @@ This hook is called while deleting an attributes features {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Feature.php](classes/Feature.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionFeatureDelete', ['id_feature' => $this->id]) diff --git a/modules/concepts/hooks/list-of-hooks/actionFeatureSave.md b/modules/concepts/hooks/list-of-hooks/actionFeatureSave.md index 89e0ccc532..e4d9fb8e77 100644 --- a/modules/concepts/hooks/list-of-hooks/actionFeatureSave.md +++ b/modules/concepts/hooks/list-of-hooks/actionFeatureSave.md @@ -6,9 +6,8 @@ hookTitle: Saving attributes' features files: - classes/Feature.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: - afterSaveFeature --- @@ -29,15 +28,14 @@ This hook is called while saving an attributes features {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Feature.php](classes/Feature.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionFeatureSave', ['id_feature' => $this->id]) diff --git a/modules/concepts/hooks/list-of-hooks/actionFeatureValueDelete.md b/modules/concepts/hooks/list-of-hooks/actionFeatureValueDelete.md index 29bf6f8bdf..7bdc666130 100644 --- a/modules/concepts/hooks/list-of-hooks/actionFeatureValueDelete.md +++ b/modules/concepts/hooks/list-of-hooks/actionFeatureValueDelete.md @@ -6,9 +6,8 @@ hookTitle: Deleting attributes' features' values files: - classes/FeatureValue.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: - afterDeleteFeatureValue --- @@ -29,15 +28,14 @@ This hook is called while deleting an attributes features value {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/FeatureValue.php](classes/FeatureValue.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionFeatureValueDelete', ['id_feature_value' => $this->id]) diff --git a/modules/concepts/hooks/list-of-hooks/actionFeatureValueSave.md b/modules/concepts/hooks/list-of-hooks/actionFeatureValueSave.md index 3b242cb269..9f7d92f0b1 100644 --- a/modules/concepts/hooks/list-of-hooks/actionFeatureValueSave.md +++ b/modules/concepts/hooks/list-of-hooks/actionFeatureValueSave.md @@ -6,9 +6,8 @@ hookTitle: Saving an attributes features value files: - classes/FeatureValue.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: - afterSaveFeatureValue --- @@ -29,15 +28,14 @@ This hook is called while saving an attributes features value {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/FeatureValue.php](classes/FeatureValue.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionFeatureValueSave', ['id_feature_value' => $this->id]) diff --git a/modules/concepts/hooks/list-of-hooks/actionFilterDeliveryOptionList.md b/modules/concepts/hooks/list-of-hooks/actionFilterDeliveryOptionList.md index a8bbfffe9f..9badb8d4c6 100644 --- a/modules/concepts/hooks/list-of-hooks/actionFilterDeliveryOptionList.md +++ b/modules/concepts/hooks/list-of-hooks/actionFilterDeliveryOptionList.md @@ -6,9 +6,8 @@ hookTitle: Modify delivery option list result files: - classes/Cart.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: --- @@ -23,10 +22,9 @@ This hook allows you to modify delivery option list {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Cart.php](classes/Cart.php) @@ -40,7 +38,7 @@ Located in: ] ``` -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec( diff --git a/modules/concepts/hooks/list-of-hooks/actionFrontControllerInitAfter.md b/modules/concepts/hooks/list-of-hooks/actionFrontControllerInitAfter.md index 2501e66c09..de8fe4c8ce 100644 --- a/modules/concepts/hooks/list-of-hooks/actionFrontControllerInitAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionFrontControllerInitAfter.md @@ -6,9 +6,8 @@ hookTitle: Perform actions after front office controller initialization files: - classes/controller/FrontController.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: - actionFrontControllerAfterInit --- @@ -29,15 +28,14 @@ This hook is launched after the initialization of all front office controllers {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/FrontController.php](classes/controller/FrontController.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec( diff --git a/modules/concepts/hooks/list-of-hooks/actionFrontControllerInitBefore.md b/modules/concepts/hooks/list-of-hooks/actionFrontControllerInitBefore.md index da0abaa845..3deacdbae1 100644 --- a/modules/concepts/hooks/list-of-hooks/actionFrontControllerInitBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionFrontControllerInitBefore.md @@ -6,9 +6,8 @@ hookTitle: Perform actions before front office controller initialization files: - classes/controller/FrontController.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: --- @@ -23,15 +22,14 @@ This hook is launched before the initialization of all front office controllers {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/FrontController.php](classes/controller/FrontController.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec( diff --git a/modules/concepts/hooks/list-of-hooks/actionFrontControllerSetMedia.md b/modules/concepts/hooks/list-of-hooks/actionFrontControllerSetMedia.md index d748364286..fd99e83265 100644 --- a/modules/concepts/hooks/list-of-hooks/actionFrontControllerSetMedia.md +++ b/modules/concepts/hooks/list-of-hooks/actionFrontControllerSetMedia.md @@ -6,9 +6,8 @@ hookTitle: files: - classes/controller/FrontController.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: --- @@ -17,15 +16,14 @@ hookAliases: ## Information Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/FrontController.php](classes/controller/FrontController.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionFrontControllerSetMedia', []) diff --git a/modules/concepts/hooks/list-of-hooks/actionFrontControllerSetVariables.md b/modules/concepts/hooks/list-of-hooks/actionFrontControllerSetVariables.md index a05b9d30af..03fbcf2478 100644 --- a/modules/concepts/hooks/list-of-hooks/actionFrontControllerSetVariables.md +++ b/modules/concepts/hooks/list-of-hooks/actionFrontControllerSetVariables.md @@ -6,9 +6,8 @@ hookTitle: Add variables in JavaScript object and Smarty templates files: - classes/controller/FrontController.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: --- @@ -23,10 +22,9 @@ Add variables to javascript object that is available in Front Office. These are {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/FrontController.php](classes/controller/FrontController.php) @@ -50,7 +48,7 @@ This hook has an `$array_return` parameter set to `true` (module output will be } ``` -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec( diff --git a/modules/concepts/hooks/list-of-hooks/actionGetAdminOrderButtons.md b/modules/concepts/hooks/list-of-hooks/actionGetAdminOrderButtons.md index 270440cd57..c10f0a8740 100644 --- a/modules/concepts/hooks/list-of-hooks/actionGetAdminOrderButtons.md +++ b/modules/concepts/hooks/list-of-hooks/actionGetAdminOrderButtons.md @@ -6,9 +6,8 @@ hookTitle: Admin Order Buttons files: - src/PrestaShopBundle/Controller/Admin/Sell/Order/OrderController.php locations: - - backoffice -type: - - action + - back office +type: action hookAliases: --- @@ -23,10 +22,9 @@ This hook is used to generate the buttons collection on the order view page (see {{% /notice %}} Hook locations: - - backoffice + - back office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/Sell/Order/OrderController.php](src/PrestaShopBundle/Controller/Admin/Sell/Order/OrderController.php) @@ -42,7 +40,7 @@ Located in: ); ``` -## Hook call in codebase +## Call of the Hook in the origin file ```php dispatchHook( @@ -50,7 +48,7 @@ dispatchHook( [ 'controller' => $this, 'id_order' => $orderId, - 'actions_bar_buttons_collection' => $backOfficeOrderButtons, + 'actions_bar_buttons_collection' => $back officeOrderButtons, ] ) ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionGetAdminToolbarButtons.md b/modules/concepts/hooks/list-of-hooks/actionGetAdminToolbarButtons.md index 50c6f47461..6584606e91 100644 --- a/modules/concepts/hooks/list-of-hooks/actionGetAdminToolbarButtons.md +++ b/modules/concepts/hooks/list-of-hooks/actionGetAdminToolbarButtons.md @@ -6,9 +6,8 @@ hookTitle: Allows to add buttons in any toolbar in the back office files: - classes/controller/AdminController.php locations: - - backoffice -type: - - action + - back office +type: action hookAliases: --- @@ -23,10 +22,9 @@ This hook allows you to define descriptions of buttons to add in any toolbar of {{% /notice %}} Hook locations: - - backoffice + - back office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/AdminController.php](classes/controller/AdminController.php) @@ -41,7 +39,7 @@ Located in: ] ``` -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionGetAdminToolbarButtons', [ diff --git a/modules/concepts/hooks/list-of-hooks/actionGetAlternativeSearchPanels.md b/modules/concepts/hooks/list-of-hooks/actionGetAlternativeSearchPanels.md index 4e7160fcf0..fdc31f2e2f 100644 --- a/modules/concepts/hooks/list-of-hooks/actionGetAlternativeSearchPanels.md +++ b/modules/concepts/hooks/list-of-hooks/actionGetAlternativeSearchPanels.md @@ -6,9 +6,8 @@ hookTitle: Additional search panel files: - controllers/admin/AdminSearchController.php locations: - - backoffice -type: - - action + - back office +type: action hookAliases: --- @@ -23,10 +22,9 @@ This hook allows to add an additional search panel for external providers in Pre {{% /notice %}} Hook locations: - - backoffice + - back office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/admin/AdminSearchController.php](controllers/admin/AdminSearchController.php) @@ -43,7 +41,7 @@ This hook has an `$array_return` parameter set to `true` (module output will be ] ``` -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec( diff --git a/modules/concepts/hooks/list-of-hooks/actionGetExtraMailTemplateVars.md b/modules/concepts/hooks/list-of-hooks/actionGetExtraMailTemplateVars.md index a6046c87b8..37ebbafd9c 100644 --- a/modules/concepts/hooks/list-of-hooks/actionGetExtraMailTemplateVars.md +++ b/modules/concepts/hooks/list-of-hooks/actionGetExtraMailTemplateVars.md @@ -6,9 +6,8 @@ hookTitle: files: - classes/Mail.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: --- @@ -17,17 +16,16 @@ hookAliases: ## Information Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Mail.php](classes/Mail.php) This hook has an `$array_return` parameter set to `true` (module output will be set by name in an array, [see explaination here]({{< relref "/8/development/components/hook/dispatching-hook">}})). -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec( diff --git a/modules/concepts/hooks/list-of-hooks/actionGetIDZoneByAddressID.md b/modules/concepts/hooks/list-of-hooks/actionGetIDZoneByAddressID.md index f3c31935f2..e87f0243b3 100644 --- a/modules/concepts/hooks/list-of-hooks/actionGetIDZoneByAddressID.md +++ b/modules/concepts/hooks/list-of-hooks/actionGetIDZoneByAddressID.md @@ -6,9 +6,8 @@ hookTitle: files: - classes/Address.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: --- @@ -17,15 +16,14 @@ hookAliases: ## Information Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Address.php](classes/Address.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionGetIDZoneByAddressID', ['id_address' => $id_address]) diff --git a/modules/concepts/hooks/list-of-hooks/actionGetMailLayoutTransformations.md b/modules/concepts/hooks/list-of-hooks/actionGetMailLayoutTransformations.md index dd25400b4f..ae59429e72 100644 --- a/modules/concepts/hooks/list-of-hooks/actionGetMailLayoutTransformations.md +++ b/modules/concepts/hooks/list-of-hooks/actionGetMailLayoutTransformations.md @@ -6,9 +6,8 @@ hookTitle: Define the transformation to apply on layout files: - src/Adapter/MailTemplate/MailTemplateTwigRenderer.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: --- @@ -23,15 +22,14 @@ This hook allows to add/remove TransformationInterface used to generate an email {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/MailTemplate/MailTemplateTwigRenderer.php](src/Adapter/MailTemplate/MailTemplateTwigRenderer.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php dispatchWithParameters( diff --git a/modules/concepts/hooks/list-of-hooks/actionGetProductPropertiesAfter.md b/modules/concepts/hooks/list-of-hooks/actionGetProductPropertiesAfter.md index 8eb920f493..20244825c1 100644 --- a/modules/concepts/hooks/list-of-hooks/actionGetProductPropertiesAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionGetProductPropertiesAfter.md @@ -6,9 +6,8 @@ hookTitle: files: - classes/Product.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: --- @@ -21,15 +20,14 @@ hookAliases: {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Product.php](classes/Product.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionGetProductPropertiesAfter', [ diff --git a/modules/concepts/hooks/list-of-hooks/actionGetProductPropertiesAfterUnitPrice.md b/modules/concepts/hooks/list-of-hooks/actionGetProductPropertiesAfterUnitPrice.md index ea554a3de9..9124ebccbd 100644 --- a/modules/concepts/hooks/list-of-hooks/actionGetProductPropertiesAfterUnitPrice.md +++ b/modules/concepts/hooks/list-of-hooks/actionGetProductPropertiesAfterUnitPrice.md @@ -6,9 +6,8 @@ hookTitle: Product Properties files: - classes/Product.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: --- @@ -23,15 +22,14 @@ This hook is called after defining the properties of a product {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Product.php](classes/Product.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionGetProductPropertiesAfterUnitPrice', [ diff --git a/modules/concepts/hooks/list-of-hooks/actionGetProductPropertiesBefore.md b/modules/concepts/hooks/list-of-hooks/actionGetProductPropertiesBefore.md index 3b5d1fed6b..8892c57d10 100644 --- a/modules/concepts/hooks/list-of-hooks/actionGetProductPropertiesBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionGetProductPropertiesBefore.md @@ -6,9 +6,8 @@ hookTitle: files: - classes/Product.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: --- @@ -17,15 +16,14 @@ hookAliases: ## Information Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Product.php](classes/Product.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionGetProductPropertiesBefore', [ diff --git a/modules/concepts/hooks/list-of-hooks/actionHtaccessCreate.md b/modules/concepts/hooks/list-of-hooks/actionHtaccessCreate.md index 69f1a516d6..19f0aa5a69 100644 --- a/modules/concepts/hooks/list-of-hooks/actionHtaccessCreate.md +++ b/modules/concepts/hooks/list-of-hooks/actionHtaccessCreate.md @@ -6,9 +6,8 @@ hookTitle: After htaccess creation files: - classes/Tools.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: - afterCreateHtaccess --- @@ -29,15 +28,14 @@ This hook is displayed after the htaccess creation {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Tools.php](classes/Tools.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionHtaccessCreate') diff --git a/modules/concepts/hooks/list-of-hooks/actionInvoiceNumberFormatted.md b/modules/concepts/hooks/list-of-hooks/actionInvoiceNumberFormatted.md index 8c7bfc8f64..68d903f1e1 100644 --- a/modules/concepts/hooks/list-of-hooks/actionInvoiceNumberFormatted.md +++ b/modules/concepts/hooks/list-of-hooks/actionInvoiceNumberFormatted.md @@ -6,9 +6,8 @@ hookTitle: files: - classes/order/OrderInvoice.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: --- @@ -17,15 +16,14 @@ hookAliases: ## Information Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/order/OrderInvoice.php](classes/order/OrderInvoice.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionInvoiceNumberFormatted', [ diff --git a/modules/concepts/hooks/list-of-hooks/actionListMailThemes.md b/modules/concepts/hooks/list-of-hooks/actionListMailThemes.md index 71edd31b62..5892f6b1bc 100644 --- a/modules/concepts/hooks/list-of-hooks/actionListMailThemes.md +++ b/modules/concepts/hooks/list-of-hooks/actionListMailThemes.md @@ -6,9 +6,8 @@ hookTitle: List the available email themes and layouts files: - src/Core/MailTemplate/FolderThemeCatalog.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: --- @@ -23,15 +22,14 @@ This hook allows to add/remove available email themes (ThemeInterface) and/or to {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Core/MailTemplate/FolderThemeCatalog.php](src/Core/MailTemplate/FolderThemeCatalog.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php dispatchWithParameters( diff --git a/modules/concepts/hooks/list-of-hooks/actionMailAlterMessageBeforeSend.md b/modules/concepts/hooks/list-of-hooks/actionMailAlterMessageBeforeSend.md index d366260334..c7e6445152 100644 --- a/modules/concepts/hooks/list-of-hooks/actionMailAlterMessageBeforeSend.md +++ b/modules/concepts/hooks/list-of-hooks/actionMailAlterMessageBeforeSend.md @@ -6,9 +6,8 @@ hookTitle: files: - classes/Mail.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: --- @@ -17,15 +16,14 @@ hookAliases: ## Information Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Mail.php](classes/Mail.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionMailAlterMessageBeforeSend', [ diff --git a/modules/concepts/hooks/list-of-hooks/actionModuleInstallAfter.md b/modules/concepts/hooks/list-of-hooks/actionModuleInstallAfter.md index af21871cb8..42863ec436 100644 --- a/modules/concepts/hooks/list-of-hooks/actionModuleInstallAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionModuleInstallAfter.md @@ -6,9 +6,8 @@ hookTitle: actionModuleInstallAfter files: - classes/module/Module.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: --- @@ -23,15 +22,14 @@ hookAliases: {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/module/Module.php](classes/module/Module.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionModuleInstallAfter', ['object' => $this]) diff --git a/modules/concepts/hooks/list-of-hooks/actionModuleInstallBefore.md b/modules/concepts/hooks/list-of-hooks/actionModuleInstallBefore.md index 4bc87c19b2..bd23a07d22 100644 --- a/modules/concepts/hooks/list-of-hooks/actionModuleInstallBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionModuleInstallBefore.md @@ -6,9 +6,8 @@ hookTitle: actionModuleInstallBefore files: - classes/module/Module.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: --- @@ -23,15 +22,14 @@ hookAliases: {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/module/Module.php](classes/module/Module.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionModuleInstallBefore', ['object' => $this]) diff --git a/modules/concepts/hooks/list-of-hooks/actionModuleMailAlertSendCustomer.md b/modules/concepts/hooks/list-of-hooks/actionModuleMailAlertSendCustomer.md index 5960e23369..a4afa874dd 100644 --- a/modules/concepts/hooks/list-of-hooks/actionModuleMailAlertSendCustomer.md +++ b/modules/concepts/hooks/list-of-hooks/actionModuleMailAlertSendCustomer.md @@ -6,9 +6,8 @@ hookTitle: files: - modules/ps_emailalerts/MailAlert.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: --- @@ -17,15 +16,14 @@ hookAliases: ## Information Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/modules/ps_emailalerts/MailAlert.php](modules/ps_emailalerts/MailAlert.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec( diff --git a/modules/concepts/hooks/list-of-hooks/actionModuleRegisterHookAfter.md b/modules/concepts/hooks/list-of-hooks/actionModuleRegisterHookAfter.md index de36fc9a85..caa53c5757 100644 --- a/modules/concepts/hooks/list-of-hooks/actionModuleRegisterHookAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionModuleRegisterHookAfter.md @@ -6,9 +6,8 @@ hookTitle: files: - classes/Hook.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: --- @@ -17,15 +16,14 @@ hookAliases: ## Information Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Hook.php](classes/Hook.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec( diff --git a/modules/concepts/hooks/list-of-hooks/actionModuleRegisterHookBefore.md b/modules/concepts/hooks/list-of-hooks/actionModuleRegisterHookBefore.md index 0100221082..47e6bba922 100644 --- a/modules/concepts/hooks/list-of-hooks/actionModuleRegisterHookBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionModuleRegisterHookBefore.md @@ -6,9 +6,8 @@ hookTitle: files: - classes/Hook.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: --- @@ -17,15 +16,14 @@ hookAliases: ## Information Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Hook.php](classes/Hook.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec( diff --git a/modules/concepts/hooks/list-of-hooks/actionModuleUnRegisterHookAfter.md b/modules/concepts/hooks/list-of-hooks/actionModuleUnRegisterHookAfter.md index 4fa8c0c20b..8333093708 100644 --- a/modules/concepts/hooks/list-of-hooks/actionModuleUnRegisterHookAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionModuleUnRegisterHookAfter.md @@ -6,9 +6,8 @@ hookTitle: files: - classes/Hook.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: --- @@ -17,15 +16,14 @@ hookAliases: ## Information Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Hook.php](classes/Hook.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec( diff --git a/modules/concepts/hooks/list-of-hooks/actionModuleUnRegisterHookBefore.md b/modules/concepts/hooks/list-of-hooks/actionModuleUnRegisterHookBefore.md index 4c57284514..348731119a 100644 --- a/modules/concepts/hooks/list-of-hooks/actionModuleUnRegisterHookBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionModuleUnRegisterHookBefore.md @@ -6,9 +6,8 @@ hookTitle: files: - classes/Hook.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: --- @@ -17,15 +16,14 @@ hookAliases: ## Information Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Hook.php](classes/Hook.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionModuleUnRegisterHookBefore', ['object' => $module_instance, 'hook_name' => $hook_name]) diff --git a/modules/concepts/hooks/list-of-hooks/actionModuleUninstallAfter.md b/modules/concepts/hooks/list-of-hooks/actionModuleUninstallAfter.md index b8a7f4cd7d..3651a7a448 100644 --- a/modules/concepts/hooks/list-of-hooks/actionModuleUninstallAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionModuleUninstallAfter.md @@ -6,9 +6,8 @@ hookTitle: actionModuleUninstallAfter files: - classes/module/Module.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: --- @@ -23,15 +22,14 @@ hookAliases: {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/module/Module.php](classes/module/Module.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionModuleUninstallAfter', ['object' => $this]) diff --git a/modules/concepts/hooks/list-of-hooks/actionModuleUninstallBefore.md b/modules/concepts/hooks/list-of-hooks/actionModuleUninstallBefore.md index 0ea1b95ff0..26bd59404d 100644 --- a/modules/concepts/hooks/list-of-hooks/actionModuleUninstallBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionModuleUninstallBefore.md @@ -6,9 +6,8 @@ hookTitle: actionModuleUninstallBefore files: - classes/module/Module.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: --- @@ -23,15 +22,14 @@ hookAliases: {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/module/Module.php](classes/module/Module.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionModuleUninstallBefore', ['object' => $this]) diff --git a/modules/concepts/hooks/list-of-hooks/actionNewsletterRegistrationAfter.md b/modules/concepts/hooks/list-of-hooks/actionNewsletterRegistrationAfter.md index 86c66a5a83..405129867a 100644 --- a/modules/concepts/hooks/list-of-hooks/actionNewsletterRegistrationAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionNewsletterRegistrationAfter.md @@ -6,9 +6,8 @@ hookTitle: files: - modules/ps_emailsubscription/ps_emailsubscription.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: --- @@ -17,15 +16,14 @@ hookAliases: ## Information Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/modules/ps_emailsubscription/ps_emailsubscription.php](modules/ps_emailsubscription/ps_emailsubscription.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec( diff --git a/modules/concepts/hooks/list-of-hooks/actionNewsletterRegistrationBefore.md b/modules/concepts/hooks/list-of-hooks/actionNewsletterRegistrationBefore.md index a40e607f16..66f9cf2743 100644 --- a/modules/concepts/hooks/list-of-hooks/actionNewsletterRegistrationBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionNewsletterRegistrationBefore.md @@ -6,9 +6,8 @@ hookTitle: files: - modules/ps_emailsubscription/ps_emailsubscription.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: --- @@ -17,15 +16,14 @@ hookAliases: ## Information Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/modules/ps_emailsubscription/ps_emailsubscription.php](modules/ps_emailsubscription/ps_emailsubscription.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec( diff --git a/modules/concepts/hooks/list-of-hooks/actionObjectAddAfter.md b/modules/concepts/hooks/list-of-hooks/actionObjectAddAfter.md index 0f2300e6c5..23b5f9ef3f 100644 --- a/modules/concepts/hooks/list-of-hooks/actionObjectAddAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionObjectAddAfter.md @@ -6,28 +6,26 @@ hookTitle: files: - classes/ObjectModel.php locations: - - backoffice - - frontoffice -type: - - action + - back office + - front office +type: action hookAliases: --- -# Hook actionObjectAddAfter +# Hook actionObject<ClassName>AddAfter ## Information Hook locations: - - backoffice - - frontoffice + - back office + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/ObjectModel.php](classes/ObjectModel.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionObject' . $this->getFullyQualifiedName() . 'AddAfter', ['object' => $this]); diff --git a/modules/concepts/hooks/list-of-hooks/actionObjectAddBefore.md b/modules/concepts/hooks/list-of-hooks/actionObjectAddBefore.md index 89384c6ce9..3fc32f10c8 100644 --- a/modules/concepts/hooks/list-of-hooks/actionObjectAddBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionObjectAddBefore.md @@ -6,28 +6,26 @@ hookTitle: files: - classes/ObjectModel.php locations: - - backoffice - - frontoffice -type: - - action + - back office + - front office +type: action hookAliases: --- -# Hook actionObjectAddBefore +# Hook actionObject<ClassName>AddBefore ## Information Hook locations: - - backoffice - - frontoffice + - back office + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/ObjectModel.php](classes/ObjectModel.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionObject' . $this->getFullyQualifiedName() . 'AddBefore', ['object' => $this]); diff --git a/modules/concepts/hooks/list-of-hooks/actionObjectDeleteAfter.md b/modules/concepts/hooks/list-of-hooks/actionObjectDeleteAfter.md index 1b2d3d88c2..0b7b6b8f50 100644 --- a/modules/concepts/hooks/list-of-hooks/actionObjectDeleteAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionObjectDeleteAfter.md @@ -6,28 +6,26 @@ hookTitle: files: - classes/ObjectModel.php locations: - - backoffice - - frontoffice -type: - - action + - back office + - front office +type: action hookAliases: --- -# Hook actionObjectDeleteAfter +# Hook actionObject<ClassName>DeleteAfter ## Information Hook locations: - - backoffice - - frontoffice + - back office + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/ObjectModel.php](classes/ObjectModel.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionObject' . $this->getFullyQualifiedName() . 'DeleteAfter', ['object' => $this]); diff --git a/modules/concepts/hooks/list-of-hooks/actionObjectDeleteBefore.md b/modules/concepts/hooks/list-of-hooks/actionObjectDeleteBefore.md index 21b349478a..02a1a032d7 100644 --- a/modules/concepts/hooks/list-of-hooks/actionObjectDeleteBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionObjectDeleteBefore.md @@ -6,28 +6,26 @@ hookTitle: files: - classes/ObjectModel.php locations: - - backoffice - - frontoffice -type: - - action + - back office + - front office +type: action hookAliases: --- -# Hook actionObjectDeleteBefore +# Hook actionObject<ClassName>DeleteBefore ## Information Hook locations: - - backoffice - - frontoffice + - back office + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/ObjectModel.php](classes/ObjectModel.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionObject' . $this->getFullyQualifiedName() . 'DeleteBefore', ['object' => $this]); diff --git a/modules/concepts/hooks/list-of-hooks/actionObjectUpdateAfter.md b/modules/concepts/hooks/list-of-hooks/actionObjectUpdateAfter.md index dbe7b50a1e..7e3a8da1d5 100644 --- a/modules/concepts/hooks/list-of-hooks/actionObjectUpdateAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionObjectUpdateAfter.md @@ -6,28 +6,26 @@ hookTitle: files: - classes/ObjectModel.php locations: - - backoffice - - frontoffice -type: - - action + - back office + - front office +type: action hookAliases: --- -# Hook actionObjectUpdateAfter +# Hook actionObject<ClassName>UpdateAfter ## Information Hook locations: - - backoffice - - frontoffice + - back office + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/ObjectModel.php](classes/ObjectModel.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionObject' . $this->getFullyQualifiedName() . 'UpdateAfter', ['object' => $this]); diff --git a/modules/concepts/hooks/list-of-hooks/actionObjectUpdateBefore.md b/modules/concepts/hooks/list-of-hooks/actionObjectUpdateBefore.md index a96f6327e1..5796b4ce80 100644 --- a/modules/concepts/hooks/list-of-hooks/actionObjectUpdateBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionObjectUpdateBefore.md @@ -6,28 +6,26 @@ hookTitle: files: - classes/ObjectModel.php locations: - - backoffice - - frontoffice -type: - - action + - back office + - front office +type: action hookAliases: --- -# Hook actionObjectUpdateBefore +# Hook actionObject<ClassName>UpdateBefore ## Information Hook locations: - - backoffice - - frontoffice + - back office + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/ObjectModel.php](classes/ObjectModel.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionObject' . $this->getFullyQualifiedName() . 'UpdateBefore', ['object' => $this]); diff --git a/modules/concepts/hooks/list-of-hooks/actionObjectAddAfter.md b/modules/concepts/hooks/list-of-hooks/actionObjectAddAfter.md index 727243f368..ca0b6589a0 100644 --- a/modules/concepts/hooks/list-of-hooks/actionObjectAddAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionObjectAddAfter.md @@ -6,10 +6,9 @@ hookTitle: files: - classes/ObjectModel.php locations: - - backoffice - - frontoffice -type: - - action + - back office + - front office +type: action hookAliases: --- @@ -18,16 +17,15 @@ hookAliases: ## Information Hook locations: - - backoffice - - frontoffice + - back office + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/ObjectModel.php](classes/ObjectModel.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionObjectAddAfter', ['object' => $this]) diff --git a/modules/concepts/hooks/list-of-hooks/actionObjectAddBefore.md b/modules/concepts/hooks/list-of-hooks/actionObjectAddBefore.md index b9f56ad129..e1096b8262 100644 --- a/modules/concepts/hooks/list-of-hooks/actionObjectAddBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionObjectAddBefore.md @@ -6,10 +6,9 @@ hookTitle: files: - classes/ObjectModel.php locations: - - backoffice - - frontoffice -type: - - action + - back office + - front office +type: action hookAliases: --- @@ -18,16 +17,15 @@ hookAliases: ## Information Hook locations: - - backoffice - - frontoffice + - back office + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/ObjectModel.php](classes/ObjectModel.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionObjectAddBefore', ['object' => $this]) diff --git a/modules/concepts/hooks/list-of-hooks/actionObjectAttributeAddBefore.md b/modules/concepts/hooks/list-of-hooks/actionObjectAttributeAddBefore.md index 312d06b183..44383a26df 100644 --- a/modules/concepts/hooks/list-of-hooks/actionObjectAttributeAddBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionObjectAttributeAddBefore.md @@ -6,10 +6,9 @@ hookTitle: files: - controllers/admin/AdminAttributesGroupsController.php locations: - - backoffice - - frontoffice -type: - - action + - back office + - front office +type: action hookAliases: --- @@ -18,16 +17,15 @@ hookAliases: ## Information Hook locations: - - backoffice - - frontoffice + - back office + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/admin/AdminAttributesGroupsController.php](controllers/admin/AdminAttributesGroupsController.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionObjectAttributeAddBefore') diff --git a/modules/concepts/hooks/list-of-hooks/actionObjectAttributeGroupAddBefore.md b/modules/concepts/hooks/list-of-hooks/actionObjectAttributeGroupAddBefore.md index 3cbd22f94f..a37ef84305 100644 --- a/modules/concepts/hooks/list-of-hooks/actionObjectAttributeGroupAddBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionObjectAttributeGroupAddBefore.md @@ -6,10 +6,9 @@ hookTitle: files: - controllers/admin/AdminAttributesGroupsController.php locations: - - backoffice - - frontoffice -type: - - action + - back office + - front office +type: action hookAliases: --- @@ -18,16 +17,15 @@ hookAliases: ## Information Hook locations: - - backoffice - - frontoffice + - back office + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/admin/AdminAttributesGroupsController.php](controllers/admin/AdminAttributesGroupsController.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionObjectAttributeGroupAddBefore') diff --git a/modules/concepts/hooks/list-of-hooks/actionObjectDeleteAfter.md b/modules/concepts/hooks/list-of-hooks/actionObjectDeleteAfter.md index 19d409e3c7..b038c06f18 100644 --- a/modules/concepts/hooks/list-of-hooks/actionObjectDeleteAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionObjectDeleteAfter.md @@ -6,10 +6,9 @@ hookTitle: files: - classes/ObjectModel.php locations: - - backoffice - - frontoffice -type: - - action + - back office + - front office +type: action hookAliases: --- @@ -18,16 +17,15 @@ hookAliases: ## Information Hook locations: - - backoffice - - frontoffice + - back office + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/ObjectModel.php](classes/ObjectModel.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionObjectDeleteAfter', ['object' => $this]) diff --git a/modules/concepts/hooks/list-of-hooks/actionObjectDeleteBefore.md b/modules/concepts/hooks/list-of-hooks/actionObjectDeleteBefore.md index 8e0ba5963b..531a4221b2 100644 --- a/modules/concepts/hooks/list-of-hooks/actionObjectDeleteBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionObjectDeleteBefore.md @@ -6,10 +6,9 @@ hookTitle: files: - classes/ObjectModel.php locations: - - backoffice - - frontoffice -type: - - action + - back office + - front office +type: action hookAliases: --- @@ -18,16 +17,15 @@ hookAliases: ## Information Hook locations: - - backoffice - - frontoffice + - back office + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/ObjectModel.php](classes/ObjectModel.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionObjectDeleteBefore', ['object' => $this]) diff --git a/modules/concepts/hooks/list-of-hooks/actionObjectProductCommentValidateAfter.md b/modules/concepts/hooks/list-of-hooks/actionObjectProductCommentValidateAfter.md index 1a31ef05a8..289256d0b1 100644 --- a/modules/concepts/hooks/list-of-hooks/actionObjectProductCommentValidateAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionObjectProductCommentValidateAfter.md @@ -6,10 +6,9 @@ hookTitle: files: - modules/productcomments/ProductComment.php locations: - - backoffice - - frontoffice -type: - - action + - back office + - front office +type: action hookAliases: --- @@ -18,16 +17,15 @@ hookAliases: ## Information Hook locations: - - backoffice - - frontoffice + - back office + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/modules/productcomments/ProductComment.php](modules/productcomments/ProductComment.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionObjectProductCommentValidateAfter', ['object' => $this]) diff --git a/modules/concepts/hooks/list-of-hooks/actionObjectProductInCartDeleteAfter.md b/modules/concepts/hooks/list-of-hooks/actionObjectProductInCartDeleteAfter.md index 85c8f0506c..52af6de034 100644 --- a/modules/concepts/hooks/list-of-hooks/actionObjectProductInCartDeleteAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionObjectProductInCartDeleteAfter.md @@ -6,10 +6,9 @@ hookTitle: Cart product removal files: - controllers/front/CartController.php locations: - - backoffice - - frontoffice -type: - - action + - back office + - front office +type: action hookAliases: --- @@ -24,16 +23,15 @@ This hook is called after a product is removed from a cart {{% /notice %}} Hook locations: - - backoffice - - frontoffice + - back office + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/front/CartController.php](controllers/front/CartController.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionObjectProductInCartDeleteAfter', $data) diff --git a/modules/concepts/hooks/list-of-hooks/actionObjectProductInCartDeleteBefore.md b/modules/concepts/hooks/list-of-hooks/actionObjectProductInCartDeleteBefore.md index e9bd6e2bd3..a9e7c867f8 100644 --- a/modules/concepts/hooks/list-of-hooks/actionObjectProductInCartDeleteBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionObjectProductInCartDeleteBefore.md @@ -6,10 +6,9 @@ hookTitle: Cart product removal files: - controllers/front/CartController.php locations: - - backoffice - - frontoffice -type: - - action + - back office + - front office +type: action hookAliases: --- @@ -24,18 +23,17 @@ This hook is called before a product is removed from a cart {{% /notice %}} Hook locations: - - backoffice - - frontoffice + - back office + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/front/CartController.php](controllers/front/CartController.php) This hook has an `$array_return` parameter set to `true` (module output will be set by name in an array, [see explaination here]({{< relref "/8/development/components/hook/dispatching-hook">}})). -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionObjectProductInCartDeleteBefore', $data, null, true) diff --git a/modules/concepts/hooks/list-of-hooks/actionObjectUpdateAfter.md b/modules/concepts/hooks/list-of-hooks/actionObjectUpdateAfter.md index aaa29a0c79..3fff3378aa 100644 --- a/modules/concepts/hooks/list-of-hooks/actionObjectUpdateAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionObjectUpdateAfter.md @@ -6,10 +6,9 @@ hookTitle: files: - classes/ObjectModel.php locations: - - backoffice - - frontoffice -type: - - action + - back office + - front office +type: action hookAliases: --- @@ -18,16 +17,15 @@ hookAliases: ## Information Hook locations: - - backoffice - - frontoffice + - back office + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/ObjectModel.php](classes/ObjectModel.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionObjectUpdateAfter', ['object' => $this]) diff --git a/modules/concepts/hooks/list-of-hooks/actionObjectUpdateBefore.md b/modules/concepts/hooks/list-of-hooks/actionObjectUpdateBefore.md index d851986890..78d9569063 100644 --- a/modules/concepts/hooks/list-of-hooks/actionObjectUpdateBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionObjectUpdateBefore.md @@ -6,10 +6,9 @@ hookTitle: files: - classes/ObjectModel.php locations: - - backoffice - - frontoffice -type: - - action + - back office + - front office +type: action hookAliases: --- @@ -18,16 +17,15 @@ hookAliases: ## Information Hook locations: - - backoffice - - frontoffice + - back office + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/ObjectModel.php](classes/ObjectModel.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionObjectUpdateBefore', ['object' => $this]) diff --git a/modules/concepts/hooks/list-of-hooks/actionOnImageCutAfter.md b/modules/concepts/hooks/list-of-hooks/actionOnImageCutAfter.md index 830b30c5f2..b6567fc526 100644 --- a/modules/concepts/hooks/list-of-hooks/actionOnImageCutAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionOnImageCutAfter.md @@ -6,9 +6,8 @@ hookTitle: files: - classes/ImageManager.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: --- @@ -17,15 +16,14 @@ hookAliases: ## Information Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/ImageManager.php](classes/ImageManager.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionOnImageCutAfter', ['dst_file' => $dstFile, 'file_type' => $fileType]) diff --git a/modules/concepts/hooks/list-of-hooks/actionOnImageResizeAfter.md b/modules/concepts/hooks/list-of-hooks/actionOnImageResizeAfter.md index e9985a88bc..7798844987 100644 --- a/modules/concepts/hooks/list-of-hooks/actionOnImageResizeAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionOnImageResizeAfter.md @@ -6,9 +6,8 @@ hookTitle: files: - classes/ImageManager.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: --- @@ -17,15 +16,14 @@ hookAliases: ## Information Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/ImageManager.php](classes/ImageManager.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionOnImageResizeAfter', ['dst_file' => $destinationFile, 'file_type' => $fileType]) diff --git a/modules/concepts/hooks/list-of-hooks/actionOrderEdited.md b/modules/concepts/hooks/list-of-hooks/actionOrderEdited.md index d01097e399..9bae78af85 100644 --- a/modules/concepts/hooks/list-of-hooks/actionOrderEdited.md +++ b/modules/concepts/hooks/list-of-hooks/actionOrderEdited.md @@ -6,9 +6,8 @@ hookTitle: Order edited files: - src/Adapter/Order/CommandHandler/UpdateProductInOrderHandler.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: --- @@ -23,10 +22,9 @@ This hook is called when an order is edited {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Order/CommandHandler/UpdateProductInOrderHandler.php](src/Adapter/Order/CommandHandler/UpdateProductInOrderHandler.php) @@ -39,7 +37,7 @@ Located in: ); ``` -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionOrderEdited', ['order' => $order]) diff --git a/modules/concepts/hooks/list-of-hooks/actionOrderHistoryAddAfter.md b/modules/concepts/hooks/list-of-hooks/actionOrderHistoryAddAfter.md index e71c86f640..2488d7e36b 100644 --- a/modules/concepts/hooks/list-of-hooks/actionOrderHistoryAddAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionOrderHistoryAddAfter.md @@ -6,9 +6,8 @@ hookTitle: files: - classes/order/OrderHistory.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: --- @@ -17,15 +16,14 @@ hookAliases: ## Information Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/order/OrderHistory.php](classes/order/OrderHistory.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionOrderHistoryAddAfter', ['order_history' => $this], null, false, true, false, $order->id_shop) diff --git a/modules/concepts/hooks/list-of-hooks/actionOrderReturn.md b/modules/concepts/hooks/list-of-hooks/actionOrderReturn.md index 7f83fd955e..4e6bf8cf38 100644 --- a/modules/concepts/hooks/list-of-hooks/actionOrderReturn.md +++ b/modules/concepts/hooks/list-of-hooks/actionOrderReturn.md @@ -6,9 +6,8 @@ hookTitle: Returned product files: - controllers/front/OrderFollowController.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: - orderReturn --- @@ -29,10 +28,9 @@ This hook is displayed when a customer returns a product {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/front/OrderFollowController.php](controllers/front/OrderFollowController.php) @@ -46,7 +44,7 @@ Located in: ); ``` -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionOrderReturn', ['orderReturn' => $orderReturn]) diff --git a/modules/concepts/hooks/list-of-hooks/actionOrderSlipAdd.md b/modules/concepts/hooks/list-of-hooks/actionOrderSlipAdd.md index e7329ce058..3bc07f547a 100644 --- a/modules/concepts/hooks/list-of-hooks/actionOrderSlipAdd.md +++ b/modules/concepts/hooks/list-of-hooks/actionOrderSlipAdd.md @@ -6,9 +6,8 @@ hookTitle: Order slip creation files: - src/Adapter/Order/Refund/OrderSlipCreator.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: - orderSlip --- @@ -29,10 +28,9 @@ This hook is called when a new credit slip is added regarding client order {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Order/Refund/OrderSlipCreator.php](src/Adapter/Order/Refund/OrderSlipCreator.php) @@ -59,7 +57,7 @@ Located in: The order of IDs and quantities is important! ``` -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionOrderSlipAdd', [ diff --git a/modules/concepts/hooks/list-of-hooks/actionOrderStatusPostUpdate.md b/modules/concepts/hooks/list-of-hooks/actionOrderStatusPostUpdate.md index bf28f18890..a167511841 100644 --- a/modules/concepts/hooks/list-of-hooks/actionOrderStatusPostUpdate.md +++ b/modules/concepts/hooks/list-of-hooks/actionOrderStatusPostUpdate.md @@ -6,9 +6,8 @@ hookTitle: Post update of order status files: - classes/order/OrderHistory.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: - postUpdateOrderStatus --- @@ -29,10 +28,9 @@ Aliases: {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/order/OrderHistory.php](classes/order/OrderHistory.php) @@ -48,7 +46,7 @@ Located in: ); ``` -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionOrderStatusPostUpdate', [ diff --git a/modules/concepts/hooks/list-of-hooks/actionOrderStatusUpdate.md b/modules/concepts/hooks/list-of-hooks/actionOrderStatusUpdate.md index 21ce50b77b..deebc7a04f 100644 --- a/modules/concepts/hooks/list-of-hooks/actionOrderStatusUpdate.md +++ b/modules/concepts/hooks/list-of-hooks/actionOrderStatusUpdate.md @@ -6,9 +6,8 @@ hookTitle: Order status update - Event files: - classes/order/OrderHistory.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: - updateOrderStatus --- @@ -29,10 +28,9 @@ This hook launches modules when the status of an order changes {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/order/OrderHistory.php](classes/order/OrderHistory.php) @@ -48,7 +46,7 @@ Located in: ); ``` -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionOrderStatusUpdate', [ diff --git a/modules/concepts/hooks/list-of-hooks/actionOutputHTMLBefore.md b/modules/concepts/hooks/list-of-hooks/actionOutputHTMLBefore.md index e904d22b0d..9a43666df5 100644 --- a/modules/concepts/hooks/list-of-hooks/actionOutputHTMLBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionOutputHTMLBefore.md @@ -6,9 +6,8 @@ hookTitle: Before HTML output files: - classes/controller/FrontController.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: --- @@ -23,15 +22,14 @@ This hook is used to filter the whole HTML page before it is rendered (only fron {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/FrontController.php](classes/controller/FrontController.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionOutputHTMLBefore', ['html' => &$html]) diff --git a/modules/concepts/hooks/list-of-hooks/actionOverrideEmployeeImage.md b/modules/concepts/hooks/list-of-hooks/actionOverrideEmployeeImage.md index a4b5177d2c..8eddba72cf 100644 --- a/modules/concepts/hooks/list-of-hooks/actionOverrideEmployeeImage.md +++ b/modules/concepts/hooks/list-of-hooks/actionOverrideEmployeeImage.md @@ -6,9 +6,8 @@ hookTitle: Get Employee Image files: - classes/Employee.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: --- @@ -23,15 +22,14 @@ This hook is used to get the employee image {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Employee.php](classes/Employee.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec( diff --git a/modules/concepts/hooks/list-of-hooks/actionPDFInvoiceRender.md b/modules/concepts/hooks/list-of-hooks/actionPDFInvoiceRender.md index 4f0c481ae3..c545eb3883 100644 --- a/modules/concepts/hooks/list-of-hooks/actionPDFInvoiceRender.md +++ b/modules/concepts/hooks/list-of-hooks/actionPDFInvoiceRender.md @@ -6,9 +6,8 @@ hookTitle: files: - src/Adapter/PDF/OrderInvoicePdfGenerator.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: --- @@ -17,15 +16,14 @@ hookAliases: ## Information Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/PDF/OrderInvoicePdfGenerator.php](src/Adapter/PDF/OrderInvoicePdfGenerator.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionPDFInvoiceRender', ['order_invoice_list' => $order_invoice_list]) diff --git a/modules/concepts/hooks/list-of-hooks/actionPasswordRenew.md b/modules/concepts/hooks/list-of-hooks/actionPasswordRenew.md index fae16bf676..33dc0b25ff 100644 --- a/modules/concepts/hooks/list-of-hooks/actionPasswordRenew.md +++ b/modules/concepts/hooks/list-of-hooks/actionPasswordRenew.md @@ -6,9 +6,8 @@ hookTitle: files: - controllers/front/PasswordController.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: --- @@ -17,15 +16,14 @@ hookAliases: ## Information Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/front/PasswordController.php](controllers/front/PasswordController.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionPasswordRenew', ['customer' => $customer, 'password' => $password]) diff --git a/modules/concepts/hooks/list-of-hooks/actionPaymentCCAdd.md b/modules/concepts/hooks/list-of-hooks/actionPaymentCCAdd.md index aba9880cfc..e7975d2059 100644 --- a/modules/concepts/hooks/list-of-hooks/actionPaymentCCAdd.md +++ b/modules/concepts/hooks/list-of-hooks/actionPaymentCCAdd.md @@ -6,9 +6,8 @@ hookTitle: Payment CC added files: - classes/order/OrderPayment.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: - paymentCCAdded --- @@ -29,10 +28,9 @@ Aliases: {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/order/OrderPayment.php](classes/order/OrderPayment.php) @@ -46,7 +44,7 @@ Located in: ); ``` -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionPaymentCCAdd', ['paymentCC' => $this]) diff --git a/modules/concepts/hooks/list-of-hooks/actionPaymentConfirmation.md b/modules/concepts/hooks/list-of-hooks/actionPaymentConfirmation.md index eaa4fbe295..ac2fdf6bc9 100644 --- a/modules/concepts/hooks/list-of-hooks/actionPaymentConfirmation.md +++ b/modules/concepts/hooks/list-of-hooks/actionPaymentConfirmation.md @@ -6,9 +6,8 @@ hookTitle: Payment confirmation files: - classes/order/OrderHistory.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: - paymentConfirm --- @@ -29,10 +28,9 @@ This hook displays new elements after the payment is validated {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/order/OrderHistory.php](classes/order/OrderHistory.php) @@ -46,7 +44,7 @@ Located in: ); ``` -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionPaymentConfirmation', ['id_order' => (int) $order->id], null, false, true, false, $order->id_shop) diff --git a/modules/concepts/hooks/list-of-hooks/actionPresentCart.md b/modules/concepts/hooks/list-of-hooks/actionPresentCart.md index 82aa396b91..1d65e4d07e 100644 --- a/modules/concepts/hooks/list-of-hooks/actionPresentCart.md +++ b/modules/concepts/hooks/list-of-hooks/actionPresentCart.md @@ -6,9 +6,8 @@ hookTitle: Cart Presenter files: - src/Adapter/Presenter/Cart/CartPresenter.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: --- @@ -23,15 +22,14 @@ This hook is called before a cart is presented {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Presenter/Cart/CartPresenter.php](src/Adapter/Presenter/Cart/CartPresenter.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionPresentCart', diff --git a/modules/concepts/hooks/list-of-hooks/actionPresentModule.md b/modules/concepts/hooks/list-of-hooks/actionPresentModule.md index 50189edc66..2b1ec994d9 100644 --- a/modules/concepts/hooks/list-of-hooks/actionPresentModule.md +++ b/modules/concepts/hooks/list-of-hooks/actionPresentModule.md @@ -6,9 +6,8 @@ hookTitle: files: - src/Adapter/Presenter/Module/ModulePresenter.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: --- @@ -17,15 +16,14 @@ hookAliases: ## Information Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Presenter/Module/ModulePresenter.php](src/Adapter/Presenter/Module/ModulePresenter.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionPresentModule', diff --git a/modules/concepts/hooks/list-of-hooks/actionPresentOrder.md b/modules/concepts/hooks/list-of-hooks/actionPresentOrder.md index 1759a4f525..2b8283f7ed 100644 --- a/modules/concepts/hooks/list-of-hooks/actionPresentOrder.md +++ b/modules/concepts/hooks/list-of-hooks/actionPresentOrder.md @@ -6,9 +6,8 @@ hookTitle: Order Presenter files: - src/Adapter/Presenter/Order/OrderPresenter.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: --- @@ -23,15 +22,14 @@ This hook is called before an order is presented {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Presenter/Order/OrderPresenter.php](src/Adapter/Presenter/Order/OrderPresenter.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionPresentOrder', diff --git a/modules/concepts/hooks/list-of-hooks/actionPresentOrderReturn.md b/modules/concepts/hooks/list-of-hooks/actionPresentOrderReturn.md index daf7d1cd5d..4648a42ae9 100644 --- a/modules/concepts/hooks/list-of-hooks/actionPresentOrderReturn.md +++ b/modules/concepts/hooks/list-of-hooks/actionPresentOrderReturn.md @@ -6,9 +6,8 @@ hookTitle: Order Return Presenter files: - src/Adapter/Presenter/Order/OrderReturnPresenter.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: --- @@ -23,15 +22,14 @@ This hook is called before an order return is presented {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Presenter/Order/OrderReturnPresenter.php](src/Adapter/Presenter/Order/OrderReturnPresenter.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionPresentOrderReturn', diff --git a/modules/concepts/hooks/list-of-hooks/actionPresentPaymentOptions.md b/modules/concepts/hooks/list-of-hooks/actionPresentPaymentOptions.md index e431a0772e..5e5f74e618 100644 --- a/modules/concepts/hooks/list-of-hooks/actionPresentPaymentOptions.md +++ b/modules/concepts/hooks/list-of-hooks/actionPresentPaymentOptions.md @@ -6,9 +6,8 @@ hookTitle: Payment options Presenter files: - classes/checkout/PaymentOptionsFinder.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: --- @@ -23,10 +22,9 @@ This hook is called before payment options are presented {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/checkout/PaymentOptionsFinder.php](classes/checkout/PaymentOptionsFinder.php) @@ -40,7 +38,7 @@ Located in: ] ``` -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionPresentPaymentOptions', diff --git a/modules/concepts/hooks/list-of-hooks/actionPresentProduct.md b/modules/concepts/hooks/list-of-hooks/actionPresentProduct.md index 0dbf9c19c2..9cc2d8eebd 100644 --- a/modules/concepts/hooks/list-of-hooks/actionPresentProduct.md +++ b/modules/concepts/hooks/list-of-hooks/actionPresentProduct.md @@ -6,9 +6,8 @@ hookTitle: Product Presenter files: - src/Adapter/Presenter/Product/ProductPresenter.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: --- @@ -23,15 +22,14 @@ This hook is called before a product is presented {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Presenter/Product/ProductPresenter.php](src/Adapter/Presenter/Product/ProductPresenter.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionPresentProduct', diff --git a/modules/concepts/hooks/list-of-hooks/actionPresentProductListing.md b/modules/concepts/hooks/list-of-hooks/actionPresentProductListing.md index 5018609cc8..71675d25c1 100644 --- a/modules/concepts/hooks/list-of-hooks/actionPresentProductListing.md +++ b/modules/concepts/hooks/list-of-hooks/actionPresentProductListing.md @@ -6,9 +6,8 @@ hookTitle: Product Listing Presenter files: - src/Adapter/Presenter/Product/ProductListingPresenter.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: --- @@ -23,15 +22,14 @@ This hook is called before a product listing is presented {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Presenter/Product/ProductListingPresenter.php](src/Adapter/Presenter/Product/ProductListingPresenter.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionPresentProductListing', diff --git a/modules/concepts/hooks/list-of-hooks/actionProductActivation.md b/modules/concepts/hooks/list-of-hooks/actionProductActivation.md index 2a3c0cc163..464d2bd2ab 100644 --- a/modules/concepts/hooks/list-of-hooks/actionProductActivation.md +++ b/modules/concepts/hooks/list-of-hooks/actionProductActivation.md @@ -6,9 +6,8 @@ hookTitle: files: - src/Adapter/Product/AdminProductDataUpdater.php locations: - - backoffice -type: - - action + - back office +type: action hookAliases: --- @@ -17,15 +16,14 @@ hookAliases: ## Information Hook locations: - - backoffice + - back office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Product/AdminProductDataUpdater.php](src/Adapter/Product/AdminProductDataUpdater.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php dispatchWithParameters('actionProductActivation', ['id_product' => (int) $product->id, 'product' => $product, 'activated' => $activate]) diff --git a/modules/concepts/hooks/list-of-hooks/actionProductAdd.md b/modules/concepts/hooks/list-of-hooks/actionProductAdd.md index faa3480bd7..7cf2c54a49 100644 --- a/modules/concepts/hooks/list-of-hooks/actionProductAdd.md +++ b/modules/concepts/hooks/list-of-hooks/actionProductAdd.md @@ -6,9 +6,8 @@ hookTitle: Product creation files: - src/Adapter/Product/ProductDuplicator.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: - addproduct --- @@ -29,15 +28,14 @@ This hook is displayed after a product is created {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Product/ProductDuplicator.php](src/Adapter/Product/ProductDuplicator.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php dispatchWithParameters( diff --git a/modules/concepts/hooks/list-of-hooks/actionProductAttributeDelete.md b/modules/concepts/hooks/list-of-hooks/actionProductAttributeDelete.md index 9c50f4c7f4..380bb77887 100644 --- a/modules/concepts/hooks/list-of-hooks/actionProductAttributeDelete.md +++ b/modules/concepts/hooks/list-of-hooks/actionProductAttributeDelete.md @@ -6,9 +6,8 @@ hookTitle: Product attribute deletion files: - classes/Product.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: - deleteProductAttribute --- @@ -29,15 +28,14 @@ This hook is displayed when a product's attribute is deleted {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Product.php](classes/Product.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionProductAttributeDelete', ['id_product_attribute' => 0, 'id_product' => (int) $this->id, 'deleteAllAttributes' => true]) diff --git a/modules/concepts/hooks/list-of-hooks/actionProductAttributeUpdate.md b/modules/concepts/hooks/list-of-hooks/actionProductAttributeUpdate.md index 2d699cbc50..b9cf0e28f4 100644 --- a/modules/concepts/hooks/list-of-hooks/actionProductAttributeUpdate.md +++ b/modules/concepts/hooks/list-of-hooks/actionProductAttributeUpdate.md @@ -6,9 +6,8 @@ hookTitle: Product attribute update files: - classes/Product.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: - updateProductAttribute --- @@ -29,15 +28,14 @@ This hook is displayed when a product's attribute is updated {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Product.php](classes/Product.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionProductAttributeUpdate', ['id_product_attribute' => (int) $id_product_attribute]) diff --git a/modules/concepts/hooks/list-of-hooks/actionProductCancel.md b/modules/concepts/hooks/list-of-hooks/actionProductCancel.md index 1bdcee8c3d..f4840fbae6 100644 --- a/modules/concepts/hooks/list-of-hooks/actionProductCancel.md +++ b/modules/concepts/hooks/list-of-hooks/actionProductCancel.md @@ -6,9 +6,8 @@ hookTitle: Product cancelled files: - src/Adapter/Order/CommandHandler/IssueStandardRefundHandler.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: - cancelProduct --- @@ -29,15 +28,14 @@ This hook is called when you cancel a product in an order {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Order/CommandHandler/IssueStandardRefundHandler.php](src/Adapter/Order/CommandHandler/IssueStandardRefundHandler.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionProductCancel', ['order' => $order, 'id_order_detail' => (int) $orderDetailId, 'cancel_quantity' => $productRefund['quantity'], 'action' => CancellationActionType::STANDARD_REFUND], null, false, true, false, $order->id_shop) diff --git a/modules/concepts/hooks/list-of-hooks/actionProductCoverage.md b/modules/concepts/hooks/list-of-hooks/actionProductCoverage.md index 9720335d37..1dfe678512 100644 --- a/modules/concepts/hooks/list-of-hooks/actionProductCoverage.md +++ b/modules/concepts/hooks/list-of-hooks/actionProductCoverage.md @@ -6,9 +6,8 @@ hookTitle: files: - classes/stock/StockManager.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: --- @@ -17,15 +16,14 @@ hookAliases: ## Information Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/stock/StockManager.php](classes/stock/StockManager.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec( diff --git a/modules/concepts/hooks/list-of-hooks/actionProductDelete.md b/modules/concepts/hooks/list-of-hooks/actionProductDelete.md index 924a1899e1..ab2a97c287 100644 --- a/modules/concepts/hooks/list-of-hooks/actionProductDelete.md +++ b/modules/concepts/hooks/list-of-hooks/actionProductDelete.md @@ -6,9 +6,8 @@ hookTitle: Product deletion files: - classes/Product.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: - deleteproduct --- @@ -29,15 +28,14 @@ This hook is called when a product is deleted {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Product.php](classes/Product.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionProductDelete', ['id_product' => (int) $this->id, 'product' => $this]) diff --git a/modules/concepts/hooks/list-of-hooks/actionProductOutOfStock.md b/modules/concepts/hooks/list-of-hooks/actionProductOutOfStock.md index f3c1e543b5..6fe06fbfce 100644 --- a/modules/concepts/hooks/list-of-hooks/actionProductOutOfStock.md +++ b/modules/concepts/hooks/list-of-hooks/actionProductOutOfStock.md @@ -6,9 +6,8 @@ hookTitle: Out-of-stock product files: - themes/classic/templates/catalog/_partials/product-details.tpl locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: - productOutOfStock --- @@ -29,15 +28,14 @@ This hook displays new action buttons if a product is out of stock {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/catalog/_partials/product-details.tpl](themes/classic/templates/catalog/_partials/product-details.tpl) -## Hook call in codebase +## Call of the Hook in the origin file ```php {hook h='actionProductOutOfStock' product=$product} diff --git a/modules/concepts/hooks/list-of-hooks/actionProductSave.md b/modules/concepts/hooks/list-of-hooks/actionProductSave.md index baaf627469..d7dd5b087d 100644 --- a/modules/concepts/hooks/list-of-hooks/actionProductSave.md +++ b/modules/concepts/hooks/list-of-hooks/actionProductSave.md @@ -6,9 +6,8 @@ hookTitle: Saving products files: - classes/Product.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: - afterSaveProduct --- @@ -29,15 +28,14 @@ This hook is called while saving products {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Product.php](classes/Product.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionProductSave', ['id_product' => (int) $this->id, 'product' => $this]) diff --git a/modules/concepts/hooks/list-of-hooks/actionProductSearchAfter.md b/modules/concepts/hooks/list-of-hooks/actionProductSearchAfter.md index 0bc686a740..51858c36f7 100644 --- a/modules/concepts/hooks/list-of-hooks/actionProductSearchAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionProductSearchAfter.md @@ -6,9 +6,8 @@ hookTitle: Event triggered after search product completed files: - modules/blockwishlist/controllers/front/view.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: --- @@ -23,15 +22,14 @@ This hook is called after the product search. Parameters are already filter {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/modules/blockwishlist/controllers/front/view.php](modules/blockwishlist/controllers/front/view.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionProductSearchAfter', $searchVariables) diff --git a/modules/concepts/hooks/list-of-hooks/actionProductSearchProviderRunQueryAfter.md b/modules/concepts/hooks/list-of-hooks/actionProductSearchProviderRunQueryAfter.md index cb23d69486..86a47a6dc0 100644 --- a/modules/concepts/hooks/list-of-hooks/actionProductSearchProviderRunQueryAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionProductSearchProviderRunQueryAfter.md @@ -6,9 +6,8 @@ hookTitle: Runs an action after ProductSearchProviderInterface::RunQuery() files: - classes/controller/ProductListingFrontController.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: --- @@ -23,15 +22,14 @@ Required to return a previous state of an SQL query or/and to change a result of {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/ProductListingFrontController.php](classes/controller/ProductListingFrontController.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionProductSearchProviderRunQueryAfter', [ diff --git a/modules/concepts/hooks/list-of-hooks/actionProductSearchProviderRunQueryBefore.md b/modules/concepts/hooks/list-of-hooks/actionProductSearchProviderRunQueryBefore.md index 2ac5ffd02c..d718b1ced2 100644 --- a/modules/concepts/hooks/list-of-hooks/actionProductSearchProviderRunQueryBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionProductSearchProviderRunQueryBefore.md @@ -6,9 +6,8 @@ hookTitle: Runs an action before ProductSearchProviderInterface::RunQuery() files: - classes/controller/ProductListingFrontController.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: --- @@ -23,15 +22,14 @@ Required to modify an SQL query before executing it {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/ProductListingFrontController.php](classes/controller/ProductListingFrontController.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionProductSearchProviderRunQueryBefore', [ diff --git a/modules/concepts/hooks/list-of-hooks/actionProductUpdate.md b/modules/concepts/hooks/list-of-hooks/actionProductUpdate.md index a65d871a98..6705b13287 100644 --- a/modules/concepts/hooks/list-of-hooks/actionProductUpdate.md +++ b/modules/concepts/hooks/list-of-hooks/actionProductUpdate.md @@ -6,9 +6,8 @@ hookTitle: Product update files: - src/Adapter/Product/AdminProductWrapper.php locations: - - backoffice -type: - - action + - back office +type: action hookAliases: - updateproduct --- @@ -29,15 +28,14 @@ This hook is displayed after a product has been updated {{% /notice %}} Hook locations: - - backoffice + - back office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Product/AdminProductWrapper.php](src/Adapter/Product/AdminProductWrapper.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionProductUpdate', ['id_product' => (int) $product->id, 'product' => $product]) diff --git a/modules/concepts/hooks/list-of-hooks/actionSearch.md b/modules/concepts/hooks/list-of-hooks/actionSearch.md index 69e313d365..c621fef85a 100644 --- a/modules/concepts/hooks/list-of-hooks/actionSearch.md +++ b/modules/concepts/hooks/list-of-hooks/actionSearch.md @@ -6,9 +6,8 @@ hookTitle: files: - src/Adapter/Search/SearchProductSearchProvider.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: --- @@ -17,10 +16,9 @@ hookAliases: ## Information Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Search/SearchProductSearchProvider.php](src/Adapter/Search/SearchProductSearchProvider.php) @@ -35,7 +33,7 @@ Located in: ); ``` -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionSearch', [ diff --git a/modules/concepts/hooks/list-of-hooks/actionSetInvoice.md b/modules/concepts/hooks/list-of-hooks/actionSetInvoice.md index a526e55897..4d15ecc00e 100644 --- a/modules/concepts/hooks/list-of-hooks/actionSetInvoice.md +++ b/modules/concepts/hooks/list-of-hooks/actionSetInvoice.md @@ -6,9 +6,8 @@ hookTitle: files: - classes/order/Order.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: --- @@ -17,10 +16,9 @@ hookAliases: ## Information Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/order/Order.php](classes/order/Order.php) @@ -36,7 +34,7 @@ Located in: ); ``` -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionSetInvoice', [ diff --git a/modules/concepts/hooks/list-of-hooks/actionShopDataDuplication.md b/modules/concepts/hooks/list-of-hooks/actionShopDataDuplication.md index 414bdf681e..ce8cf220db 100644 --- a/modules/concepts/hooks/list-of-hooks/actionShopDataDuplication.md +++ b/modules/concepts/hooks/list-of-hooks/actionShopDataDuplication.md @@ -6,9 +6,8 @@ hookTitle: files: - classes/shop/Shop.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: --- @@ -17,10 +16,9 @@ hookAliases: ## Information Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/shop/Shop.php](classes/shop/Shop.php) @@ -35,7 +33,7 @@ Located in: ); ``` -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionShopDataDuplication', [ diff --git a/modules/concepts/hooks/list-of-hooks/actionSubmitAccountBefore.md b/modules/concepts/hooks/list-of-hooks/actionSubmitAccountBefore.md index eba4c1c690..b9387add30 100644 --- a/modules/concepts/hooks/list-of-hooks/actionSubmitAccountBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionSubmitAccountBefore.md @@ -6,9 +6,8 @@ hookTitle: files: - controllers/front/RegistrationController.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: - actionBeforeSubmitAccount --- @@ -23,15 +22,14 @@ Aliases: ## Information Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/front/RegistrationController.php](controllers/front/RegistrationController.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionSubmitAccountBefore', [], null, true) diff --git a/modules/concepts/hooks/list-of-hooks/actionSubmitCustomerAddressForm.md b/modules/concepts/hooks/list-of-hooks/actionSubmitCustomerAddressForm.md index 1559606f8e..a1e23602f2 100644 --- a/modules/concepts/hooks/list-of-hooks/actionSubmitCustomerAddressForm.md +++ b/modules/concepts/hooks/list-of-hooks/actionSubmitCustomerAddressForm.md @@ -6,9 +6,8 @@ hookTitle: files: - classes/form/CustomerAddressForm.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: --- @@ -17,15 +16,14 @@ hookAliases: ## Information Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/form/CustomerAddressForm.php](classes/form/CustomerAddressForm.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionSubmitCustomerAddressForm', ['address' => &$address]) diff --git a/modules/concepts/hooks/list-of-hooks/actionUpdateLangAfter.md b/modules/concepts/hooks/list-of-hooks/actionUpdateLangAfter.md index d8f8b66ab0..6a4508d479 100644 --- a/modules/concepts/hooks/list-of-hooks/actionUpdateLangAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionUpdateLangAfter.md @@ -6,9 +6,8 @@ hookTitle: Update "lang" tables files: - classes/Language.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: --- @@ -23,15 +22,14 @@ Update "lang" tables after adding or updating a language {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Language.php](classes/Language.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionUpdateLangAfter', ['lang' => $language]) diff --git a/modules/concepts/hooks/list-of-hooks/actionUpdateQuantity.md b/modules/concepts/hooks/list-of-hooks/actionUpdateQuantity.md index 3106d63d9b..6139ec75a2 100644 --- a/modules/concepts/hooks/list-of-hooks/actionUpdateQuantity.md +++ b/modules/concepts/hooks/list-of-hooks/actionUpdateQuantity.md @@ -6,9 +6,8 @@ hookTitle: Quantity update files: - classes/stock/StockAvailable.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: - updateQuantity --- @@ -29,10 +28,9 @@ Quantity is updated only when a customer effectively places their order {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/stock/StockAvailable.php](classes/stock/StockAvailable.php) @@ -48,7 +46,7 @@ Located in: ); ``` -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec( diff --git a/modules/concepts/hooks/list-of-hooks/actionValidateCustomerAddressForm.md b/modules/concepts/hooks/list-of-hooks/actionValidateCustomerAddressForm.md index ca473f2290..97f4d7fe65 100644 --- a/modules/concepts/hooks/list-of-hooks/actionValidateCustomerAddressForm.md +++ b/modules/concepts/hooks/list-of-hooks/actionValidateCustomerAddressForm.md @@ -6,9 +6,8 @@ hookTitle: Customer address form validation files: - classes/form/CustomerAddressForm.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: --- @@ -23,10 +22,9 @@ This hook is called when a customer submit its address form {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/form/CustomerAddressForm.php](classes/form/CustomerAddressForm.php) @@ -40,7 +38,7 @@ Located in: ); ``` -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionValidateCustomerAddressForm', ['form' => $this]) diff --git a/modules/concepts/hooks/list-of-hooks/actionValidateOrder.md b/modules/concepts/hooks/list-of-hooks/actionValidateOrder.md index 5dcf1982ef..26b1b113c3 100644 --- a/modules/concepts/hooks/list-of-hooks/actionValidateOrder.md +++ b/modules/concepts/hooks/list-of-hooks/actionValidateOrder.md @@ -6,9 +6,8 @@ hookTitle: New orders files: - classes/PaymentModule.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: - newOrder --- @@ -29,10 +28,9 @@ Aliases: {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/PaymentModule.php](classes/PaymentModule.php) @@ -50,7 +48,7 @@ Located in: ); ``` -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionValidateOrder', [ diff --git a/modules/concepts/hooks/list-of-hooks/actionValidateOrderAfter.md b/modules/concepts/hooks/list-of-hooks/actionValidateOrderAfter.md index 6492a1718d..4a6a2949db 100644 --- a/modules/concepts/hooks/list-of-hooks/actionValidateOrderAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionValidateOrderAfter.md @@ -6,9 +6,8 @@ hookTitle: After validating an order files: - classes/PaymentModule.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: --- @@ -23,10 +22,9 @@ This hook is called after validating an order by core {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/PaymentModule.php](classes/PaymentModule.php) @@ -45,7 +43,7 @@ Located in: ] ``` -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec( diff --git a/modules/concepts/hooks/list-of-hooks/actionValidateStepComplete.md b/modules/concepts/hooks/list-of-hooks/actionValidateStepComplete.md index 20e4dfa9d6..769ce562d9 100644 --- a/modules/concepts/hooks/list-of-hooks/actionValidateStepComplete.md +++ b/modules/concepts/hooks/list-of-hooks/actionValidateStepComplete.md @@ -6,9 +6,8 @@ hookTitle: files: - classes/checkout/CheckoutDeliveryStep.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: --- @@ -17,10 +16,9 @@ hookAliases: ## Information Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/checkout/CheckoutDeliveryStep.php](classes/checkout/CheckoutDeliveryStep.php) @@ -36,7 +34,7 @@ Located in: ); ``` -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec( diff --git a/modules/concepts/hooks/list-of-hooks/actionWatermark.md b/modules/concepts/hooks/list-of-hooks/actionWatermark.md index 56cacef1af..c9708e701b 100644 --- a/modules/concepts/hooks/list-of-hooks/actionWatermark.md +++ b/modules/concepts/hooks/list-of-hooks/actionWatermark.md @@ -6,9 +6,8 @@ hookTitle: Watermark files: - src/Adapter/Product/Image/Uploader/ProductImageUploader.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: - watermark --- @@ -29,10 +28,9 @@ Aliases: {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Product/Image/Uploader/ProductImageUploader.php](src/Adapter/Product/Image/Uploader/ProductImageUploader.php) @@ -47,7 +45,7 @@ Located in: ); ``` -## Hook call in codebase +## Call of the Hook in the origin file ```php dispatchWithParameters( diff --git a/modules/concepts/hooks/list-of-hooks/actionWishlistAddProduct.md b/modules/concepts/hooks/list-of-hooks/actionWishlistAddProduct.md index 8146e9a9be..d822a132da 100644 --- a/modules/concepts/hooks/list-of-hooks/actionWishlistAddProduct.md +++ b/modules/concepts/hooks/list-of-hooks/actionWishlistAddProduct.md @@ -6,9 +6,8 @@ hookTitle: files: - modules/blockwishlist/controllers/front/action.php locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: --- @@ -17,15 +16,14 @@ hookAliases: ## Information Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/modules/blockwishlist/controllers/front/action.php](modules/blockwishlist/controllers/front/action.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('actionWishlistAddProduct', [ diff --git a/modules/concepts/hooks/list-of-hooks/addWebserviceResources.md b/modules/concepts/hooks/list-of-hooks/addWebserviceResources.md index 709b8d3a3d..7ffd66c207 100644 --- a/modules/concepts/hooks/list-of-hooks/addWebserviceResources.md +++ b/modules/concepts/hooks/list-of-hooks/addWebserviceResources.md @@ -6,9 +6,8 @@ hookTitle: Add extra webservice resource files: - classes/webservice/WebserviceRequest.php locations: - - frontoffice -type: - - + - front office +type: hookAliases: --- @@ -23,10 +22,9 @@ This hook is called when webservice resources list in webservice controller {{% /notice %}} Hook locations: - - frontoffice + - front office Hook type: - - Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/webservice/WebserviceRequest.php](classes/webservice/WebserviceRequest.php) @@ -35,7 +33,7 @@ This hook has an `$array_return` parameter set to `true` (module output will be This hook has a `$check_exceptions` parameter set to `false` (check permission exceptions, [see explaination here]({{< relref "/8/development/components/hook/dispatching-hook">}})). -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('addWebserviceResources', ['resources' => $resources], null, true, false) diff --git a/modules/concepts/hooks/list-of-hooks/additionalCustomerAddressFields.md b/modules/concepts/hooks/list-of-hooks/additionalCustomerAddressFields.md index c72394abbb..c8a43d806e 100644 --- a/modules/concepts/hooks/list-of-hooks/additionalCustomerAddressFields.md +++ b/modules/concepts/hooks/list-of-hooks/additionalCustomerAddressFields.md @@ -6,9 +6,8 @@ hookTitle: Add fields to the Customer address form files: - classes/form/CustomerAddressFormatter.php locations: - - frontoffice -type: - - + - front office +type: hookAliases: --- @@ -23,17 +22,16 @@ This hook returns an array of FormFields to add them to the customer address reg {{% /notice %}} Hook locations: - - frontoffice + - front office Hook type: - - Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/form/CustomerAddressFormatter.php](classes/form/CustomerAddressFormatter.php) This hook has an `$array_return` parameter set to `true` (module output will be set by name in an array, [see explaination here]({{< relref "/8/development/components/hook/dispatching-hook">}})). -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('additionalCustomerAddressFields', ['fields' => &$format], null, true) diff --git a/modules/concepts/hooks/list-of-hooks/additionalCustomerFormFields.md b/modules/concepts/hooks/list-of-hooks/additionalCustomerFormFields.md index 8a2647ad9b..a9f6625192 100644 --- a/modules/concepts/hooks/list-of-hooks/additionalCustomerFormFields.md +++ b/modules/concepts/hooks/list-of-hooks/additionalCustomerFormFields.md @@ -6,9 +6,8 @@ hookTitle: Add fields to the Customer form files: - classes/form/CustomerFormatter.php locations: - - frontoffice -type: - - + - front office +type: hookAliases: --- @@ -23,17 +22,16 @@ This hook returns an array of FormFields to add them to the customer registratio {{% /notice %}} Hook locations: - - frontoffice + - front office Hook type: - - Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/form/CustomerFormatter.php](classes/form/CustomerFormatter.php) This hook has an `$array_return` parameter set to `true` (module output will be set by name in an array, [see explaination here]({{< relref "/8/development/components/hook/dispatching-hook">}})). -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('additionalCustomerFormFields', ['fields' => &$format], null, true) diff --git a/modules/concepts/hooks/list-of-hooks/dashboardData.md b/modules/concepts/hooks/list-of-hooks/dashboardData.md index b8d6af8840..3e7da19d2c 100644 --- a/modules/concepts/hooks/list-of-hooks/dashboardData.md +++ b/modules/concepts/hooks/list-of-hooks/dashboardData.md @@ -6,9 +6,8 @@ hookTitle: files: - controllers/admin/AdminDashboardController.php locations: - - backoffice -type: - - + - back office +type: hookAliases: --- @@ -17,17 +16,16 @@ hookAliases: ## Information Hook locations: - - backoffice + - back office Hook type: - - Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/admin/AdminDashboardController.php](controllers/admin/AdminDashboardController.php) This hook has an `$array_return` parameter set to `true` (module output will be set by name in an array, [see explaination here]({{< relref "/8/development/components/hook/dispatching-hook">}})). -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('dashboardData', $params, $id_module, true) diff --git a/modules/concepts/hooks/list-of-hooks/dashboardZoneOne.md b/modules/concepts/hooks/list-of-hooks/dashboardZoneOne.md index 142ca75d66..339e51b94a 100644 --- a/modules/concepts/hooks/list-of-hooks/dashboardZoneOne.md +++ b/modules/concepts/hooks/list-of-hooks/dashboardZoneOne.md @@ -6,9 +6,8 @@ hookTitle: files: - controllers/admin/AdminDashboardController.php locations: - - backoffice -type: - - + - back office +type: hookAliases: --- @@ -17,15 +16,14 @@ hookAliases: ## Information Hook locations: - - backoffice + - back office Hook type: - - Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/admin/AdminDashboardController.php](controllers/admin/AdminDashboardController.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('dashboardZoneOne', $params) diff --git a/modules/concepts/hooks/list-of-hooks/dashboardZoneThree.md b/modules/concepts/hooks/list-of-hooks/dashboardZoneThree.md index 656694f28a..4a7f0f874f 100644 --- a/modules/concepts/hooks/list-of-hooks/dashboardZoneThree.md +++ b/modules/concepts/hooks/list-of-hooks/dashboardZoneThree.md @@ -6,9 +6,8 @@ hookTitle: Dashboard column three files: - controllers/admin/AdminDashboardController.php locations: - - backoffice -type: - - + - back office +type: hookAliases: --- @@ -23,10 +22,9 @@ This hook is displayed in the third column of the dashboard {{% /notice %}} Hook locations: - - backoffice + - back office Hook type: - - Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/admin/AdminDashboardController.php](controllers/admin/AdminDashboardController.php) @@ -41,7 +39,7 @@ Located in: ] ``` -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('dashboardZoneThree', $params) diff --git a/modules/concepts/hooks/list-of-hooks/dashboardZoneTwo.md b/modules/concepts/hooks/list-of-hooks/dashboardZoneTwo.md index e735753448..a4ed2d4b99 100644 --- a/modules/concepts/hooks/list-of-hooks/dashboardZoneTwo.md +++ b/modules/concepts/hooks/list-of-hooks/dashboardZoneTwo.md @@ -6,9 +6,8 @@ hookTitle: files: - controllers/admin/AdminDashboardController.php locations: - - backoffice -type: - - + - back office +type: hookAliases: --- @@ -17,15 +16,14 @@ hookAliases: ## Information Hook locations: - - backoffice + - back office Hook type: - - Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/admin/AdminDashboardController.php](controllers/admin/AdminDashboardController.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('dashboardZoneTwo', $params) diff --git a/modules/concepts/hooks/list-of-hooks/deleteProductAttribute.md b/modules/concepts/hooks/list-of-hooks/deleteProductAttribute.md index ce05cadcea..a8b3e16095 100644 --- a/modules/concepts/hooks/list-of-hooks/deleteProductAttribute.md +++ b/modules/concepts/hooks/list-of-hooks/deleteProductAttribute.md @@ -6,9 +6,8 @@ hookTitle: files: - classes/Product.php locations: - - frontoffice -type: - - + - front office +type: hookAliases: --- @@ -17,15 +16,14 @@ hookAliases: ## Information Hook locations: - - frontoffice + - front office Hook type: - - Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Product.php](classes/Product.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec( diff --git a/modules/concepts/hooks/list-of-hooks/displayAdditionalCustomerAddressFields.md b/modules/concepts/hooks/list-of-hooks/displayAdditionalCustomerAddressFields.md index cb6ce34683..2a22e84acc 100644 --- a/modules/concepts/hooks/list-of-hooks/displayAdditionalCustomerAddressFields.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdditionalCustomerAddressFields.md @@ -6,9 +6,8 @@ hookTitle: Display additional customer address fields files: - themes/classic/templates/customer/_partials/block-address.tpl locations: - - frontoffice -type: - - display + - front office +type: display hookAliases: --- @@ -23,15 +22,14 @@ This hook allows to display extra field values added in an address form using ho {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - display +Hook type: display Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/customer/_partials/block-address.tpl](themes/classic/templates/customer/_partials/block-address.tpl) -## Hook call in codebase +## Call of the Hook in the origin file ```php {hook h='displayAdditionalCustomerAddressFields' address=$address} diff --git a/modules/concepts/hooks/list-of-hooks/displayAdminAfterHeader.md b/modules/concepts/hooks/list-of-hooks/displayAdminAfterHeader.md index 9e7d3aa7ce..9515787e93 100644 --- a/modules/concepts/hooks/list-of-hooks/displayAdminAfterHeader.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminAfterHeader.md @@ -6,9 +6,8 @@ hookTitle: files: - admin784x07v4swfhm9fgvc0/themes/new-theme/template/light_display_layout.tpl locations: - - backoffice -type: - - display + - back office +type: display hookAliases: --- @@ -17,15 +16,14 @@ hookAliases: ## Information Hook locations: - - backoffice + - back office -Hook type: - - display +Hook type: display Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/admin784x07v4swfhm9fgvc0/themes/new-theme/template/light_display_layout.tpl](admin784x07v4swfhm9fgvc0/themes/new-theme/template/light_display_layout.tpl) -## Hook call in codebase +## Call of the Hook in the origin file ```php {hook h='displayAdminAfterHeader'} diff --git a/modules/concepts/hooks/list-of-hooks/displayAdminCustomers.md b/modules/concepts/hooks/list-of-hooks/displayAdminCustomers.md index f146c19f61..04b71f88bb 100644 --- a/modules/concepts/hooks/list-of-hooks/displayAdminCustomers.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminCustomers.md @@ -6,9 +6,8 @@ hookTitle: Display new elements in the Back Office, tab AdminCustomers files: - src/PrestaShopBundle/Resources/views/Admin/Sell/Customer/view.html.twig locations: - - backoffice -type: - - display + - back office +type: display hookAliases: - adminCustomers --- @@ -29,10 +28,9 @@ This hook launches modules when the AdminCustomers tab is displayed in the Back {{% /notice %}} Hook locations: - - backoffice + - back office -Hook type: - - display +Hook type: display Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Resources/views/Admin/Sell/Customer/view.html.twig](src/PrestaShopBundle/Resources/views/Admin/Sell/Customer/view.html.twig) @@ -46,7 +44,7 @@ Located in: ); ``` -## Hook call in codebase +## Call of the Hook in the origin file ```php {{ renderhook('displayAdminCustomers', {'id_customer': customerInformation.customerId.value}) }} diff --git a/modules/concepts/hooks/list-of-hooks/displayAdminEndContent.md b/modules/concepts/hooks/list-of-hooks/displayAdminEndContent.md index d50c983022..f7b9abb7dc 100644 --- a/modules/concepts/hooks/list-of-hooks/displayAdminEndContent.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminEndContent.md @@ -6,9 +6,8 @@ hookTitle: Administration end of content files: - admin784x07v4swfhm9fgvc0/themes/new-theme/template/light_display_layout.tpl locations: - - backoffice -type: - - display + - back office +type: display hookAliases: --- @@ -23,15 +22,14 @@ This hook is displayed at the end of the main content, before the footer {{% /notice %}} Hook locations: - - backoffice + - back office -Hook type: - - display +Hook type: display Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/admin784x07v4swfhm9fgvc0/themes/new-theme/template/light_display_layout.tpl](admin784x07v4swfhm9fgvc0/themes/new-theme/template/light_display_layout.tpl) -## Hook call in codebase +## Call of the Hook in the origin file ```php {hook h='displayAdminEndContent'} diff --git a/modules/concepts/hooks/list-of-hooks/displayAdminForm.md b/modules/concepts/hooks/list-of-hooks/displayAdminForm.md index 300644b5c8..2aa89a2028 100644 --- a/modules/concepts/hooks/list-of-hooks/displayAdminForm.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminForm.md @@ -6,9 +6,8 @@ hookTitle: files: - admin784x07v4swfhm9fgvc0/themes/default/template/helpers/form/form.tpl locations: - - backoffice -type: - - display + - back office +type: display hookAliases: --- @@ -17,15 +16,14 @@ hookAliases: ## Information Hook locations: - - backoffice + - back office -Hook type: - - display +Hook type: display Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/admin784x07v4swfhm9fgvc0/themes/default/template/helpers/form/form.tpl](admin784x07v4swfhm9fgvc0/themes/default/template/helpers/form/form.tpl) -## Hook call in codebase +## Call of the Hook in the origin file ```php {hook h='displayAdminForm' fieldset=$f} diff --git a/modules/concepts/hooks/list-of-hooks/displayAdminGridTableAfter.md b/modules/concepts/hooks/list-of-hooks/displayAdminGridTableAfter.md index 4707f82a41..232e24af39 100644 --- a/modules/concepts/hooks/list-of-hooks/displayAdminGridTableAfter.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminGridTableAfter.md @@ -6,9 +6,8 @@ hookTitle: Display after Grid table files: - src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Blocks/table.html.twig locations: - - backoffice -type: - - display + - back office +type: display hookAliases: - displayAdminListAfter --- @@ -29,10 +28,9 @@ This hook adds new blocks after Grid component table {{% /notice %}} Hook locations: - - backoffice + - back office -Hook type: - - display +Hook type: display Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Blocks/table.html.twig](src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Blocks/table.html.twig) @@ -48,7 +46,7 @@ Located in: ); ``` -## Hook call in codebase +## Call of the Hook in the origin file ```php {{ renderhook('displayAdminGridTableAfter', { diff --git a/modules/concepts/hooks/list-of-hooks/displayAdminGridTableBefore.md b/modules/concepts/hooks/list-of-hooks/displayAdminGridTableBefore.md index 1dbc183dba..1bce3d7301 100644 --- a/modules/concepts/hooks/list-of-hooks/displayAdminGridTableBefore.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminGridTableBefore.md @@ -6,9 +6,8 @@ hookTitle: Display before Grid table files: - src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Blocks/table.html.twig locations: - - backoffice -type: - - display + - back office +type: display hookAliases: - displayAdminListBefore --- @@ -29,10 +28,9 @@ This hook adds new blocks before Grid component table {{% /notice %}} Hook locations: - - backoffice + - back office -Hook type: - - display +Hook type: display Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Blocks/table.html.twig](src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Blocks/table.html.twig) @@ -48,7 +46,7 @@ Located in: ); ``` -## Hook call in codebase +## Call of the Hook in the origin file ```php {{ renderhook('displayAdminGridTableBefore', { diff --git a/modules/concepts/hooks/list-of-hooks/displayAdminListAfter.md b/modules/concepts/hooks/list-of-hooks/displayAdminListAfter.md index aa088dd34f..8bc72db610 100644 --- a/modules/concepts/hooks/list-of-hooks/displayAdminListAfter.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminListAfter.md @@ -6,9 +6,8 @@ hookTitle: files: - admin784x07v4swfhm9fgvc0/themes/default/template/helpers/list/list_footer.tpl locations: - - backoffice -type: - - display + - back office +type: display hookAliases: --- @@ -17,15 +16,14 @@ hookAliases: ## Information Hook locations: - - backoffice + - back office -Hook type: - - display +Hook type: display Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/admin784x07v4swfhm9fgvc0/themes/default/template/helpers/list/list_footer.tpl](admin784x07v4swfhm9fgvc0/themes/default/template/helpers/list/list_footer.tpl) -## Hook call in codebase +## Call of the Hook in the origin file ```php {hook h='displayAdminListAfter'} diff --git a/modules/concepts/hooks/list-of-hooks/displayAdminListBefore.md b/modules/concepts/hooks/list-of-hooks/displayAdminListBefore.md index 06d2f9ff4e..c11cbc8209 100644 --- a/modules/concepts/hooks/list-of-hooks/displayAdminListBefore.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminListBefore.md @@ -6,9 +6,8 @@ hookTitle: files: - admin784x07v4swfhm9fgvc0/themes/default/template/helpers/list/list_header.tpl locations: - - backoffice -type: - - display + - back office +type: display hookAliases: --- @@ -17,15 +16,14 @@ hookAliases: ## Information Hook locations: - - backoffice + - back office -Hook type: - - display +Hook type: display Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/admin784x07v4swfhm9fgvc0/themes/default/template/helpers/list/list_header.tpl](admin784x07v4swfhm9fgvc0/themes/default/template/helpers/list/list_header.tpl) -## Hook call in codebase +## Call of the Hook in the origin file ```php {hook h='displayAdminListBefore'} diff --git a/modules/concepts/hooks/list-of-hooks/displayAdminNavBarBeforeEnd.md b/modules/concepts/hooks/list-of-hooks/displayAdminNavBarBeforeEnd.md index 84d0ca775b..62a293daee 100644 --- a/modules/concepts/hooks/list-of-hooks/displayAdminNavBarBeforeEnd.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminNavBarBeforeEnd.md @@ -6,9 +6,8 @@ hookTitle: files: - admin784x07v4swfhm9fgvc0/themes/new-theme/template/components/layout/nav_bar.tpl locations: - - backoffice -type: - - display + - back office +type: display hookAliases: --- @@ -17,15 +16,14 @@ hookAliases: ## Information Hook locations: - - backoffice + - back office -Hook type: - - display +Hook type: display Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/admin784x07v4swfhm9fgvc0/themes/new-theme/template/components/layout/nav_bar.tpl](admin784x07v4swfhm9fgvc0/themes/new-theme/template/components/layout/nav_bar.tpl) -## Hook call in codebase +## Call of the Hook in the origin file ```php {hook h='displayAdminNavBarBeforeEnd'} diff --git a/modules/concepts/hooks/list-of-hooks/displayAdminOptions.md b/modules/concepts/hooks/list-of-hooks/displayAdminOptions.md index ccbcb93147..27bea81cb6 100644 --- a/modules/concepts/hooks/list-of-hooks/displayAdminOptions.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminOptions.md @@ -6,9 +6,8 @@ hookTitle: files: - admin784x07v4swfhm9fgvc0/themes/default/template/helpers/options/options.tpl locations: - - backoffice -type: - - display + - back office +type: display hookAliases: --- @@ -17,15 +16,14 @@ hookAliases: ## Information Hook locations: - - backoffice + - back office -Hook type: - - display +Hook type: display Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/admin784x07v4swfhm9fgvc0/themes/default/template/helpers/options/options.tpl](admin784x07v4swfhm9fgvc0/themes/default/template/helpers/options/options.tpl) -## Hook call in codebase +## Call of the Hook in the origin file ```php {hook h='displayAdminOptions'} diff --git a/modules/concepts/hooks/list-of-hooks/displayAdminOrder.md b/modules/concepts/hooks/list-of-hooks/displayAdminOrder.md index e107ce2d67..ae3167dbbc 100644 --- a/modules/concepts/hooks/list-of-hooks/displayAdminOrder.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminOrder.md @@ -6,9 +6,8 @@ hookTitle: Display new elements in the Back Office, tab AdminOrder files: - src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/view.html.twig locations: - - backoffice -type: - - display + - back office +type: display hookAliases: - adminOrder --- @@ -29,10 +28,9 @@ This hook launches modules when the AdminOrder tab is displayed in the Back Offi {{% /notice %}} Hook locations: - - backoffice + - back office -Hook type: - - display +Hook type: display Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/view.html.twig](src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/view.html.twig) @@ -46,7 +44,7 @@ Located in: ); ``` -## Hook call in codebase +## Call of the Hook in the origin file ```php {{ renderhook('displayAdminOrder', {'id_order': orderForViewing.id}) }} diff --git a/modules/concepts/hooks/list-of-hooks/displayAdminOrderCreateExtraButtons.md b/modules/concepts/hooks/list-of-hooks/displayAdminOrderCreateExtraButtons.md index 4d96052069..72429893c2 100644 --- a/modules/concepts/hooks/list-of-hooks/displayAdminOrderCreateExtraButtons.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminOrderCreateExtraButtons.md @@ -6,9 +6,8 @@ hookTitle: Add buttons on the create order page dropdown files: - src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/Create/summary.html.twig locations: - - backoffice -type: - - display + - back office +type: display hookAliases: --- @@ -23,15 +22,14 @@ Add buttons on the create order page dropdown {{% /notice %}} Hook locations: - - backoffice + - back office -Hook type: - - display +Hook type: display Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/Create/summary.html.twig](src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/Create/summary.html.twig) -## Hook call in codebase +## Call of the Hook in the origin file ```php {{ renderhook('displayAdminOrderCreateExtraButtons') }} diff --git a/modules/concepts/hooks/list-of-hooks/displayAdminOrderMain.md b/modules/concepts/hooks/list-of-hooks/displayAdminOrderMain.md index 636b01feb9..f348e34a49 100644 --- a/modules/concepts/hooks/list-of-hooks/displayAdminOrderMain.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminOrderMain.md @@ -6,9 +6,8 @@ hookTitle: Admin Order Main Column files: - src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/view.html.twig locations: - - backoffice -type: - - display + - back office +type: display hookAliases: --- @@ -23,10 +22,9 @@ This hook displays content in the order view page in the main column under the d {{% /notice %}} Hook locations: - - backoffice + - back office -Hook type: - - display +Hook type: display Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/view.html.twig](src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/view.html.twig) @@ -40,7 +38,7 @@ Located in: ); ``` -## Hook call in codebase +## Call of the Hook in the origin file ```php {{ renderhook('displayAdminOrderMain', {'id_order': orderForViewing.id}) }} diff --git a/modules/concepts/hooks/list-of-hooks/displayAdminOrderMainBottom.md b/modules/concepts/hooks/list-of-hooks/displayAdminOrderMainBottom.md index 6223cfcd3f..7c0bc2a056 100644 --- a/modules/concepts/hooks/list-of-hooks/displayAdminOrderMainBottom.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminOrderMainBottom.md @@ -6,9 +6,8 @@ hookTitle: Admin Order Main Column Bottom files: - src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/view.html.twig locations: - - backoffice -type: - - display + - back office +type: display hookAliases: --- @@ -23,10 +22,9 @@ This hook displays content in the order view page at the bottom of the main colu {{% /notice %}} Hook locations: - - backoffice + - back office -Hook type: - - display +Hook type: display Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/view.html.twig](src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/view.html.twig) @@ -40,7 +38,7 @@ Located in: ); ``` -## Hook call in codebase +## Call of the Hook in the origin file ```php {{ renderhook('displayAdminOrderMainBottom', {'id_order': orderForViewing.id}) }} diff --git a/modules/concepts/hooks/list-of-hooks/displayAdminOrderSide.md b/modules/concepts/hooks/list-of-hooks/displayAdminOrderSide.md index d085368ff4..bed14a5773 100644 --- a/modules/concepts/hooks/list-of-hooks/displayAdminOrderSide.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminOrderSide.md @@ -6,17 +6,16 @@ hookTitle: Admin Order Side Column files: - src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/view.html.twig locations: - - backoffice -type: - - display + - back office +type: display hookAliases: - - displayBackOfficeOrderActions + - displayback officeOrderActions --- # Hook displayAdminOrderSide Aliases: - - displayBackOfficeOrderActions + - displayback officeOrderActions @@ -29,10 +28,9 @@ This hook displays content in the order view page in the side column under the c {{% /notice %}} Hook locations: - - backoffice + - back office -Hook type: - - display +Hook type: display Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/view.html.twig](src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/view.html.twig) @@ -46,7 +44,7 @@ Located in: ); ``` -## Hook call in codebase +## Call of the Hook in the origin file ```php {{ renderhook('displayAdminOrderSide', {'id_order': orderForViewing.id}) }} diff --git a/modules/concepts/hooks/list-of-hooks/displayAdminOrderSideBottom.md b/modules/concepts/hooks/list-of-hooks/displayAdminOrderSideBottom.md index aeb253cc03..7e6e85d3ed 100644 --- a/modules/concepts/hooks/list-of-hooks/displayAdminOrderSideBottom.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminOrderSideBottom.md @@ -6,9 +6,8 @@ hookTitle: files: - src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/view.html.twig locations: - - backoffice -type: - - display + - back office +type: display hookAliases: --- @@ -17,10 +16,9 @@ hookAliases: ## Information Hook locations: - - backoffice + - back office -Hook type: - - display +Hook type: display Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/view.html.twig](src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/view.html.twig) @@ -34,7 +32,7 @@ Located in: ); ``` -## Hook call in codebase +## Call of the Hook in the origin file ```php {{ renderhook('displayAdminOrderSideBottom', {'id_order': orderForViewing.id}) }} diff --git a/modules/concepts/hooks/list-of-hooks/displayAdminProductsCombinationBottom.md b/modules/concepts/hooks/list-of-hooks/displayAdminProductsCombinationBottom.md index d40a6de9fd..365a185d60 100644 --- a/modules/concepts/hooks/list-of-hooks/displayAdminProductsCombinationBottom.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminProductsCombinationBottom.md @@ -6,9 +6,8 @@ hookTitle: Display new elements in back office product page, Combination tab files: - src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Forms/form_combination.html.twig locations: - - backoffice -type: - - display + - back office +type: display hookAliases: --- @@ -23,15 +22,14 @@ This hook launches modules when the back office product page is displayed {{% /notice %}} Hook locations: - - backoffice + - back office -Hook type: - - display +Hook type: display Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Forms/form_combination.html.twig](src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Forms/form_combination.html.twig) -## Hook call in codebase +## Call of the Hook in the origin file ```php {{ renderhook('displayAdminProductsCombinationBottom', { 'id_product': form.vars.value.id_product, 'id_product_attribute': form.vars.value.id_product_attribute }) }} diff --git a/modules/concepts/hooks/list-of-hooks/displayAdminProductsMainStepLeftColumnBottom.md b/modules/concepts/hooks/list-of-hooks/displayAdminProductsMainStepLeftColumnBottom.md index 57e4848637..b9ae9df53f 100644 --- a/modules/concepts/hooks/list-of-hooks/displayAdminProductsMainStepLeftColumnBottom.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminProductsMainStepLeftColumnBottom.md @@ -6,9 +6,8 @@ hookTitle: Display new elements in back office product page, left column of the files: - src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/essentials.html.twig locations: - - backoffice -type: - - display + - back office +type: display hookAliases: --- @@ -23,15 +22,14 @@ This hook launches modules when the back office product page is displayed {{% /notice %}} Hook locations: - - backoffice + - back office -Hook type: - - display +Hook type: display Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/essentials.html.twig](src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/essentials.html.twig) -## Hook call in codebase +## Call of the Hook in the origin file ```php {{ renderhook('displayAdminProductsMainStepLeftColumnBottom', { 'id_product': productId }) }} diff --git a/modules/concepts/hooks/list-of-hooks/displayAdminProductsMainStepLeftColumnMiddle.md b/modules/concepts/hooks/list-of-hooks/displayAdminProductsMainStepLeftColumnMiddle.md index 6e41185b5a..c1002d9cdf 100644 --- a/modules/concepts/hooks/list-of-hooks/displayAdminProductsMainStepLeftColumnMiddle.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminProductsMainStepLeftColumnMiddle.md @@ -6,9 +6,8 @@ hookTitle: Display new elements in back office product page, left column of the files: - src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/essentials.html.twig locations: - - backoffice -type: - - display + - back office +type: display hookAliases: --- @@ -23,15 +22,14 @@ This hook launches modules when the back office product page is displayed {{% /notice %}} Hook locations: - - backoffice + - back office -Hook type: - - display +Hook type: display Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/essentials.html.twig](src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/essentials.html.twig) -## Hook call in codebase +## Call of the Hook in the origin file ```php {{ renderhook('displayAdminProductsMainStepLeftColumnMiddle', { 'id_product': productId }) }} diff --git a/modules/concepts/hooks/list-of-hooks/displayAdminProductsMainStepRightColumnBottom.md b/modules/concepts/hooks/list-of-hooks/displayAdminProductsMainStepRightColumnBottom.md index c259b2112e..4b68846d37 100644 --- a/modules/concepts/hooks/list-of-hooks/displayAdminProductsMainStepRightColumnBottom.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminProductsMainStepRightColumnBottom.md @@ -6,9 +6,8 @@ hookTitle: Display new elements in back office product page, right column of the files: - src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/essentials.html.twig locations: - - backoffice -type: - - display + - back office +type: display hookAliases: --- @@ -23,15 +22,14 @@ This hook launches modules when the back office product page is displayed {{% /notice %}} Hook locations: - - backoffice + - back office -Hook type: - - display +Hook type: display Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/essentials.html.twig](src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/essentials.html.twig) -## Hook call in codebase +## Call of the Hook in the origin file ```php {{ renderhook('displayAdminProductsMainStepRightColumnBottom', { 'id_product': productId }) }} diff --git a/modules/concepts/hooks/list-of-hooks/displayAdminProductsOptionsStepBottom.md b/modules/concepts/hooks/list-of-hooks/displayAdminProductsOptionsStepBottom.md index 2368331880..7df17c7a28 100644 --- a/modules/concepts/hooks/list-of-hooks/displayAdminProductsOptionsStepBottom.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminProductsOptionsStepBottom.md @@ -6,9 +6,8 @@ hookTitle: Display new elements in back office product page, Options tab files: - src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/options.html.twig locations: - - backoffice -type: - - display + - back office +type: display hookAliases: --- @@ -23,15 +22,14 @@ This hook launches modules when the back office product page is displayed {{% /notice %}} Hook locations: - - backoffice + - back office -Hook type: - - display +Hook type: display Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/options.html.twig](src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/options.html.twig) -## Hook call in codebase +## Call of the Hook in the origin file ```php {{ renderhook('displayAdminProductsOptionsStepBottom', { 'id_product': productId }) }} diff --git a/modules/concepts/hooks/list-of-hooks/displayAdminProductsOptionsStepTop.md b/modules/concepts/hooks/list-of-hooks/displayAdminProductsOptionsStepTop.md index 900027d07e..fbc840038e 100644 --- a/modules/concepts/hooks/list-of-hooks/displayAdminProductsOptionsStepTop.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminProductsOptionsStepTop.md @@ -6,9 +6,8 @@ hookTitle: Display new elements in back office product page, Options tab files: - src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/options.html.twig locations: - - backoffice -type: - - display + - back office +type: display hookAliases: --- @@ -23,15 +22,14 @@ This hook launches modules when the back office product page is displayed {{% /notice %}} Hook locations: - - backoffice + - back office -Hook type: - - display +Hook type: display Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/options.html.twig](src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/options.html.twig) -## Hook call in codebase +## Call of the Hook in the origin file ```php {{ renderhook('displayAdminProductsOptionsStepTop', { 'id_product': productId }) }} diff --git a/modules/concepts/hooks/list-of-hooks/displayAdminProductsPriceStepBottom.md b/modules/concepts/hooks/list-of-hooks/displayAdminProductsPriceStepBottom.md index 4ad9a9463a..b1f82bb9a1 100644 --- a/modules/concepts/hooks/list-of-hooks/displayAdminProductsPriceStepBottom.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminProductsPriceStepBottom.md @@ -6,9 +6,8 @@ hookTitle: Display new elements in back office product page, Price tab files: - src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/pricing.html.twig locations: - - backoffice -type: - - display + - back office +type: display hookAliases: --- @@ -23,15 +22,14 @@ This hook launches modules when the back office product page is displayed {{% /notice %}} Hook locations: - - backoffice + - back office -Hook type: - - display +Hook type: display Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/pricing.html.twig](src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/pricing.html.twig) -## Hook call in codebase +## Call of the Hook in the origin file ```php {{ renderhook('displayAdminProductsPriceStepBottom', { 'id_product': productId }) }} diff --git a/modules/concepts/hooks/list-of-hooks/displayAdminProductsQuantitiesStepBottom.md b/modules/concepts/hooks/list-of-hooks/displayAdminProductsQuantitiesStepBottom.md index 091b875ef4..65c1474075 100644 --- a/modules/concepts/hooks/list-of-hooks/displayAdminProductsQuantitiesStepBottom.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminProductsQuantitiesStepBottom.md @@ -6,9 +6,8 @@ hookTitle: Display new elements in back office product page, Quantities/Combinat files: - src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/combinations.html.twig locations: - - backoffice -type: - - display + - back office +type: display hookAliases: --- @@ -23,15 +22,14 @@ This hook launches modules when the back office product page is displayed {{% /notice %}} Hook locations: - - backoffice + - back office -Hook type: - - display +Hook type: display Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/combinations.html.twig](src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/combinations.html.twig) -## Hook call in codebase +## Call of the Hook in the origin file ```php {{ renderhook('displayAdminProductsQuantitiesStepBottom', { 'id_product': productId }) }} diff --git a/modules/concepts/hooks/list-of-hooks/displayAdminProductsSeoStepBottom.md b/modules/concepts/hooks/list-of-hooks/displayAdminProductsSeoStepBottom.md index 32f2819431..8c09cb31c3 100644 --- a/modules/concepts/hooks/list-of-hooks/displayAdminProductsSeoStepBottom.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminProductsSeoStepBottom.md @@ -6,9 +6,8 @@ hookTitle: Display new elements in back office product page, SEO tab files: - src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Forms/form_seo.html.twig locations: - - backoffice -type: - - display + - back office +type: display hookAliases: --- @@ -23,15 +22,14 @@ This hook launches modules when the back office product page is displayed {{% /notice %}} Hook locations: - - backoffice + - back office -Hook type: - - display +Hook type: display Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Forms/form_seo.html.twig](src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Forms/form_seo.html.twig) -## Hook call in codebase +## Call of the Hook in the origin file ```php {{ renderhook('displayAdminProductsSeoStepBottom', { 'id_product': productId }) }} diff --git a/modules/concepts/hooks/list-of-hooks/displayAdminProductsShippingStepBottom.md b/modules/concepts/hooks/list-of-hooks/displayAdminProductsShippingStepBottom.md index a5e8cc2ec3..f3fb2743cc 100644 --- a/modules/concepts/hooks/list-of-hooks/displayAdminProductsShippingStepBottom.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminProductsShippingStepBottom.md @@ -6,9 +6,8 @@ hookTitle: Display new elements in back office product page, Shipping tab files: - src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Forms/form_shipping.html.twig locations: - - backoffice -type: - - display + - back office +type: display hookAliases: --- @@ -23,15 +22,14 @@ This hook launches modules when the back office product page is displayed {{% /notice %}} Hook locations: - - backoffice + - back office -Hook type: - - display +Hook type: display Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Forms/form_shipping.html.twig](src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Forms/form_shipping.html.twig) -## Hook call in codebase +## Call of the Hook in the origin file ```php {{ renderhook('displayAdminProductsShippingStepBottom', { 'id_product': id_product }) }} diff --git a/modules/concepts/hooks/list-of-hooks/displayAdminStatsModules.md b/modules/concepts/hooks/list-of-hooks/displayAdminStatsModules.md index b8f753d333..71b8a2a4e3 100644 --- a/modules/concepts/hooks/list-of-hooks/displayAdminStatsModules.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminStatsModules.md @@ -6,9 +6,8 @@ hookTitle: Stats - Modules files: - controllers/admin/AdminStatsTabController.php locations: - - backoffice -type: - - display + - back office +type: display hookAliases: - AdminStatsModules --- @@ -29,15 +28,14 @@ Aliases: {{% /notice %}} Hook locations: - - backoffice + - back office -Hook type: - - display +Hook type: display Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/admin/AdminStatsTabController.php](controllers/admin/AdminStatsTabController.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('displayAdminStatsModules', [], $module_instance->id) diff --git a/modules/concepts/hooks/list-of-hooks/displayAdminThemesListAfter.md b/modules/concepts/hooks/list-of-hooks/displayAdminThemesListAfter.md index 960a60c715..5308a3cd95 100644 --- a/modules/concepts/hooks/list-of-hooks/displayAdminThemesListAfter.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminThemesListAfter.md @@ -6,9 +6,8 @@ hookTitle: BO themes list extra content files: - src/PrestaShopBundle/Resources/views/Admin/Improve/Design/Theme/index.html.twig locations: - - backoffice -type: - - display + - back office +type: display hookAliases: --- @@ -23,10 +22,9 @@ This hook displays content after the themes list in the back office {{% /notice %}} Hook locations: - - backoffice + - back office -Hook type: - - display +Hook type: display Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Resources/views/Admin/Improve/Design/Theme/index.html.twig](src/PrestaShopBundle/Resources/views/Admin/Improve/Design/Theme/index.html.twig) @@ -40,7 +38,7 @@ Located in: ); ``` -## Hook call in codebase +## Call of the Hook in the origin file ```php {{ renderhook('displayAdminThemesListAfter', { 'current_theme_name': currentlyUsedTheme.get('name') }) }} diff --git a/modules/concepts/hooks/list-of-hooks/displayAdminView.md b/modules/concepts/hooks/list-of-hooks/displayAdminView.md index 7b8a83dcbf..68206ed793 100644 --- a/modules/concepts/hooks/list-of-hooks/displayAdminView.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminView.md @@ -6,9 +6,8 @@ hookTitle: files: - admin784x07v4swfhm9fgvc0/themes/default/template/helpers/view/view.tpl locations: - - backoffice -type: - - display + - back office +type: display hookAliases: --- @@ -17,15 +16,14 @@ hookAliases: ## Information Hook locations: - - backoffice + - back office -Hook type: - - display +Hook type: display Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/admin784x07v4swfhm9fgvc0/themes/default/template/helpers/view/view.tpl](admin784x07v4swfhm9fgvc0/themes/default/template/helpers/view/view.tpl) -## Hook call in codebase +## Call of the Hook in the origin file ```php {hook h='displayAdminView'} diff --git a/modules/concepts/hooks/list-of-hooks/displayAfterBodyOpeningTag.md b/modules/concepts/hooks/list-of-hooks/displayAfterBodyOpeningTag.md index 367fba9939..c4bf409e21 100644 --- a/modules/concepts/hooks/list-of-hooks/displayAfterBodyOpeningTag.md +++ b/modules/concepts/hooks/list-of-hooks/displayAfterBodyOpeningTag.md @@ -6,9 +6,8 @@ hookTitle: Very top of pages files: - themes/classic/templates/layouts/layout-both-columns.tpl locations: - - frontoffice -type: - - display + - front office +type: display hookAliases: --- @@ -23,15 +22,14 @@ Use this hook for advertisement or modals you want to load first {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - display +Hook type: display Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/layouts/layout-both-columns.tpl](themes/classic/templates/layouts/layout-both-columns.tpl) -## Hook call in codebase +## Call of the Hook in the origin file ```php {hook h='displayAfterBodyOpeningTag'} diff --git a/modules/concepts/hooks/list-of-hooks/displayAfterCarrier.md b/modules/concepts/hooks/list-of-hooks/displayAfterCarrier.md index c14dec1750..99df80699b 100644 --- a/modules/concepts/hooks/list-of-hooks/displayAfterCarrier.md +++ b/modules/concepts/hooks/list-of-hooks/displayAfterCarrier.md @@ -6,9 +6,8 @@ hookTitle: After carriers list files: - classes/checkout/CheckoutDeliveryStep.php locations: - - frontoffice -type: - - display + - front office +type: display hookAliases: --- @@ -23,15 +22,14 @@ This hook is displayed after the carrier list in Front Office {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - display +Hook type: display Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/checkout/CheckoutDeliveryStep.php](classes/checkout/CheckoutDeliveryStep.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('displayAfterCarrier', ['cart' => $this->getCheckoutSession()->getCart()]) diff --git a/modules/concepts/hooks/list-of-hooks/displayAfterProductThumbs.md b/modules/concepts/hooks/list-of-hooks/displayAfterProductThumbs.md index 30676d1b25..824cc72b7b 100644 --- a/modules/concepts/hooks/list-of-hooks/displayAfterProductThumbs.md +++ b/modules/concepts/hooks/list-of-hooks/displayAfterProductThumbs.md @@ -6,9 +6,8 @@ hookTitle: Display extra content below product thumbs files: - themes/classic/templates/catalog/_partials/product-cover-thumbnails.tpl locations: - - frontoffice -type: - - display + - front office +type: display hookAliases: --- @@ -23,15 +22,14 @@ This hook displays new elements below product images ex. additional media {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - display +Hook type: display Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/catalog/_partials/product-cover-thumbnails.tpl](themes/classic/templates/catalog/_partials/product-cover-thumbnails.tpl) -## Hook call in codebase +## Call of the Hook in the origin file ```php {hook h='displayAfterProductThumbs' product=$product} diff --git a/modules/concepts/hooks/list-of-hooks/displayAfterTitleTag.md b/modules/concepts/hooks/list-of-hooks/displayAfterTitleTag.md index f61ae98ac3..3fcab59466 100644 --- a/modules/concepts/hooks/list-of-hooks/displayAfterTitleTag.md +++ b/modules/concepts/hooks/list-of-hooks/displayAfterTitleTag.md @@ -6,9 +6,8 @@ hookTitle: After title tag files: - themes/classic/templates/_partials/head.tpl locations: - - frontoffice -type: - - display + - front office +type: display hookAliases: --- @@ -23,15 +22,14 @@ Use this hook to add content after title tag {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - display +Hook type: display Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/_partials/head.tpl](themes/classic/templates/_partials/head.tpl) -## Hook call in codebase +## Call of the Hook in the origin file ```php {hook h='displayAfterTitleTag'} diff --git a/modules/concepts/hooks/list-of-hooks/displayBackOfficeCategory.md b/modules/concepts/hooks/list-of-hooks/displayBackOfficeCategory.md index 6f5d90da8f..03e228e259 100644 --- a/modules/concepts/hooks/list-of-hooks/displayBackOfficeCategory.md +++ b/modules/concepts/hooks/list-of-hooks/displayBackOfficeCategory.md @@ -1,18 +1,17 @@ --- -menuTitle: displayBackOfficeCategory -Title: displayBackOfficeCategory +menuTitle: displayback officeCategory +Title: displayback officeCategory hidden: true hookTitle: Display new elements in the Back Office, tab AdminCategories files: - src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Categories/Blocks/form.html.twig locations: - - backoffice -type: - - display + - back office +type: display hookAliases: --- -# Hook displayBackOfficeCategory +# Hook displayback officeCategory ## Information @@ -23,16 +22,15 @@ This hook launches modules when the AdminCategories tab is displayed in the Back {{% /notice %}} Hook locations: - - backoffice + - back office -Hook type: - - display +Hook type: display Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Categories/Blocks/form.html.twig](src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Categories/Blocks/form.html.twig) -## Hook call in codebase +## Call of the Hook in the origin file ```php -{{ renderhook('displayBackOfficeCategory') }} +{{ renderhook('displayback officeCategory') }} ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/displayBackOfficeEmployeeMenu.md b/modules/concepts/hooks/list-of-hooks/displayBackOfficeEmployeeMenu.md index 59170be450..95334e22ac 100644 --- a/modules/concepts/hooks/list-of-hooks/displayBackOfficeEmployeeMenu.md +++ b/modules/concepts/hooks/list-of-hooks/displayBackOfficeEmployeeMenu.md @@ -1,18 +1,17 @@ --- -menuTitle: displayBackOfficeEmployeeMenu -Title: displayBackOfficeEmployeeMenu +menuTitle: displayback officeEmployeeMenu +Title: displayback officeEmployeeMenu hidden: true hookTitle: Administration Employee menu files: - src/PrestaShopBundle/Bridge/Smarty/HeaderConfigurator.php locations: - - frontoffice -type: - - display + - front office +type: display hookAliases: --- -# Hook displayBackOfficeEmployeeMenu +# Hook displayback officeEmployeeMenu ## Information @@ -23,10 +22,9 @@ This hook is displayed in the employee menu {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - display +Hook type: display Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Bridge/Smarty/HeaderConfigurator.php](src/PrestaShopBundle/Bridge/Smarty/HeaderConfigurator.php) @@ -40,11 +38,11 @@ Located in: ] ``` -## Hook call in codebase +## Call of the Hook in the origin file ```php dispatchWithParameters( - 'displayBackOfficeEmployeeMenu', + 'displayback officeEmployeeMenu', [ 'links' => $menuLinksCollections, ] diff --git a/modules/concepts/hooks/list-of-hooks/displayBackOfficeHeader.md b/modules/concepts/hooks/list-of-hooks/displayBackOfficeHeader.md index 5300626a9e..9a6330d3e9 100644 --- a/modules/concepts/hooks/list-of-hooks/displayBackOfficeHeader.md +++ b/modules/concepts/hooks/list-of-hooks/displayBackOfficeHeader.md @@ -1,22 +1,21 @@ --- -menuTitle: displayBackOfficeHeader -Title: displayBackOfficeHeader +menuTitle: displayback officeHeader +Title: displayback officeHeader hidden: true hookTitle: Administration panel header files: - classes/controller/AdminController.php locations: - - backoffice -type: - - display + - back office +type: display hookAliases: - - backOfficeHeader + - back officeHeader --- -# Hook displayBackOfficeHeader +# Hook displayback officeHeader Aliases: - - backOfficeHeader + - back officeHeader @@ -29,16 +28,15 @@ This hook is displayed in the header of the admin panel {{% /notice %}} Hook locations: - - backoffice + - back office -Hook type: - - display +Hook type: display Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/AdminController.php](classes/controller/AdminController.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php -Hook::exec('displayBackOfficeHeader') +Hook::exec('displayback officeHeader') ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/displayBackOfficeTop.md b/modules/concepts/hooks/list-of-hooks/displayBackOfficeTop.md index 8166eea5b0..cffc25ede9 100644 --- a/modules/concepts/hooks/list-of-hooks/displayBackOfficeTop.md +++ b/modules/concepts/hooks/list-of-hooks/displayBackOfficeTop.md @@ -1,22 +1,21 @@ --- -menuTitle: displayBackOfficeTop -Title: displayBackOfficeTop +menuTitle: displayback officeTop +Title: displayback officeTop hidden: true hookTitle: Administration panel hover the tabs files: - classes/controller/AdminController.php locations: - - backoffice -type: - - display + - back office +type: display hookAliases: - - backOfficeTop + - back officeTop --- -# Hook displayBackOfficeTop +# Hook displayback officeTop Aliases: - - backOfficeTop + - back officeTop @@ -29,16 +28,15 @@ This hook is displayed on the roll hover of the tabs within the admin panel {{% /notice %}} Hook locations: - - backoffice + - back office -Hook type: - - display +Hook type: display Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/AdminController.php](classes/controller/AdminController.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php -Hook::exec('displayBackOfficeTop') +Hook::exec('displayback officeTop') ``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/displayBanner.md b/modules/concepts/hooks/list-of-hooks/displayBanner.md index 1fa06eb976..a1110de199 100644 --- a/modules/concepts/hooks/list-of-hooks/displayBanner.md +++ b/modules/concepts/hooks/list-of-hooks/displayBanner.md @@ -6,9 +6,8 @@ hookTitle: Very top of pages files: - themes/classic/templates/_partials/header.tpl locations: - - frontoffice -type: - - display + - front office +type: display hookAliases: --- @@ -23,15 +22,14 @@ Use this hook for banners on top of every pages {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - display +Hook type: display Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/_partials/header.tpl](themes/classic/templates/_partials/header.tpl) -## Hook call in codebase +## Call of the Hook in the origin file ```php {hook h='displayBanner'} diff --git a/modules/concepts/hooks/list-of-hooks/displayBeforeBodyClosingTag.md b/modules/concepts/hooks/list-of-hooks/displayBeforeBodyClosingTag.md index fa15efdd0b..c263fef035 100644 --- a/modules/concepts/hooks/list-of-hooks/displayBeforeBodyClosingTag.md +++ b/modules/concepts/hooks/list-of-hooks/displayBeforeBodyClosingTag.md @@ -6,9 +6,8 @@ hookTitle: Very bottom of pages files: - themes/classic/templates/layouts/layout-both-columns.tpl locations: - - frontoffice -type: - - display + - front office +type: display hookAliases: --- @@ -23,15 +22,14 @@ Use this hook for your modals or any content you want to load at the very end {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - display +Hook type: display Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/layouts/layout-both-columns.tpl](themes/classic/templates/layouts/layout-both-columns.tpl) -## Hook call in codebase +## Call of the Hook in the origin file ```php {hook h='displayBeforeBodyClosingTag'} diff --git a/modules/concepts/hooks/list-of-hooks/displayBeforeCarrier.md b/modules/concepts/hooks/list-of-hooks/displayBeforeCarrier.md index 7ee4bf0597..8905666c24 100644 --- a/modules/concepts/hooks/list-of-hooks/displayBeforeCarrier.md +++ b/modules/concepts/hooks/list-of-hooks/displayBeforeCarrier.md @@ -6,9 +6,8 @@ hookTitle: Before carriers list files: - classes/checkout/CheckoutDeliveryStep.php locations: - - frontoffice -type: - - display + - front office +type: display hookAliases: - beforeCarrier --- @@ -29,10 +28,9 @@ This hook is displayed before the carrier list in Front Office {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - display +Hook type: display Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/checkout/CheckoutDeliveryStep.php](classes/checkout/CheckoutDeliveryStep.php) @@ -84,7 +82,7 @@ Located in: ); ``` -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('displayBeforeCarrier', ['cart' => $this->getCheckoutSession()->getCart()]) diff --git a/modules/concepts/hooks/list-of-hooks/displayCMSDisputeInformation.md b/modules/concepts/hooks/list-of-hooks/displayCMSDisputeInformation.md index 4d39d316ad..dcacf40cca 100644 --- a/modules/concepts/hooks/list-of-hooks/displayCMSDisputeInformation.md +++ b/modules/concepts/hooks/list-of-hooks/displayCMSDisputeInformation.md @@ -6,9 +6,8 @@ hookTitle: files: - themes/classic/templates/cms/page.tpl locations: - - frontoffice -type: - - display + - front office +type: display hookAliases: --- @@ -17,15 +16,14 @@ hookAliases: ## Information Hook locations: - - frontoffice + - front office -Hook type: - - display +Hook type: display Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/cms/page.tpl](themes/classic/templates/cms/page.tpl) -## Hook call in codebase +## Call of the Hook in the origin file ```php {hook h='displayCMSDisputeInformation'} diff --git a/modules/concepts/hooks/list-of-hooks/displayCMSPrintButton.md b/modules/concepts/hooks/list-of-hooks/displayCMSPrintButton.md index 4674911a04..e7cba4cd44 100644 --- a/modules/concepts/hooks/list-of-hooks/displayCMSPrintButton.md +++ b/modules/concepts/hooks/list-of-hooks/displayCMSPrintButton.md @@ -6,9 +6,8 @@ hookTitle: files: - themes/classic/templates/cms/page.tpl locations: - - frontoffice -type: - - display + - front office +type: display hookAliases: --- @@ -17,15 +16,14 @@ hookAliases: ## Information Hook locations: - - frontoffice + - front office -Hook type: - - display +Hook type: display Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/cms/page.tpl](themes/classic/templates/cms/page.tpl) -## Hook call in codebase +## Call of the Hook in the origin file ```php {hook h='displayCMSPrintButton'} diff --git a/modules/concepts/hooks/list-of-hooks/displayCarrierExtraContent.md b/modules/concepts/hooks/list-of-hooks/displayCarrierExtraContent.md index e71f6b0872..8de4c994b9 100644 --- a/modules/concepts/hooks/list-of-hooks/displayCarrierExtraContent.md +++ b/modules/concepts/hooks/list-of-hooks/displayCarrierExtraContent.md @@ -6,9 +6,8 @@ hookTitle: Display additional content for a carrier (e.g pickup points) files: - classes/checkout/DeliveryOptionsFinder.php locations: - - frontoffice -type: - - display + - front office +type: display hookAliases: --- @@ -23,15 +22,14 @@ This hook calls only the module related to the carrier, in order to add options {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - display +Hook type: display Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/checkout/DeliveryOptionsFinder.php](classes/checkout/DeliveryOptionsFinder.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('displayCarrierExtraContent', ['carrier' => $carrier], $moduleId) diff --git a/modules/concepts/hooks/list-of-hooks/displayCartExtraProductActions.md b/modules/concepts/hooks/list-of-hooks/displayCartExtraProductActions.md index 9598162603..0bfa542b82 100644 --- a/modules/concepts/hooks/list-of-hooks/displayCartExtraProductActions.md +++ b/modules/concepts/hooks/list-of-hooks/displayCartExtraProductActions.md @@ -6,9 +6,8 @@ hookTitle: Extra buttons in shopping cart files: - themes/classic/templates/checkout/_partials/cart-detailed-product-line.tpl locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: --- @@ -23,15 +22,14 @@ This hook adds extra buttons to the product lines, in the shopping cart {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/checkout/_partials/cart-detailed-product-line.tpl](themes/classic/templates/checkout/_partials/cart-detailed-product-line.tpl) -## Hook call in codebase +## Call of the Hook in the origin file ```php {hook h='displayCartExtraProductActions' product=$product} diff --git a/modules/concepts/hooks/list-of-hooks/displayCartModalContent.md b/modules/concepts/hooks/list-of-hooks/displayCartModalContent.md index 5a67b621a9..2c143d7ca7 100644 --- a/modules/concepts/hooks/list-of-hooks/displayCartModalContent.md +++ b/modules/concepts/hooks/list-of-hooks/displayCartModalContent.md @@ -6,9 +6,8 @@ hookTitle: Content of Add-to-cart modal files: - themes/classic/modules/ps_shoppingcart/modal.tpl locations: - - frontoffice -type: - - display + - front office +type: display hookAliases: --- @@ -23,15 +22,14 @@ This hook displays content in the middle of the window that appears after adding {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - display +Hook type: display Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/modules/ps_shoppingcart/modal.tpl](themes/classic/modules/ps_shoppingcart/modal.tpl) -## Hook call in codebase +## Call of the Hook in the origin file ```php {hook h='displayCartModalContent' product=$product} diff --git a/modules/concepts/hooks/list-of-hooks/displayCartModalFooter.md b/modules/concepts/hooks/list-of-hooks/displayCartModalFooter.md index a9b360700c..d46fc0fc29 100644 --- a/modules/concepts/hooks/list-of-hooks/displayCartModalFooter.md +++ b/modules/concepts/hooks/list-of-hooks/displayCartModalFooter.md @@ -6,9 +6,8 @@ hookTitle: Bottom of Add-to-cart modal files: - themes/classic/modules/ps_shoppingcart/modal.tpl locations: - - frontoffice -type: - - display + - front office +type: display hookAliases: --- @@ -23,15 +22,14 @@ This hook displays content in the bottom of window that appears after adding pro {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - display +Hook type: display Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/modules/ps_shoppingcart/modal.tpl](themes/classic/modules/ps_shoppingcart/modal.tpl) -## Hook call in codebase +## Call of the Hook in the origin file ```php {hook h='displayCartModalFooter' product=$product} diff --git a/modules/concepts/hooks/list-of-hooks/displayCheckoutBeforeConfirmation.md b/modules/concepts/hooks/list-of-hooks/displayCheckoutBeforeConfirmation.md index 1d69cdc3af..0ad2c090c5 100644 --- a/modules/concepts/hooks/list-of-hooks/displayCheckoutBeforeConfirmation.md +++ b/modules/concepts/hooks/list-of-hooks/displayCheckoutBeforeConfirmation.md @@ -6,9 +6,8 @@ hookTitle: Show custom content before checkout confirmation files: - themes/classic/templates/checkout/_partials/steps/payment.tpl locations: - - frontoffice -type: - - display + - front office +type: display hookAliases: --- @@ -23,15 +22,14 @@ This hook allows you to display custom content at the end of checkout process {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - display +Hook type: display Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/checkout/_partials/steps/payment.tpl](themes/classic/templates/checkout/_partials/steps/payment.tpl) -## Hook call in codebase +## Call of the Hook in the origin file ```php {hook h='displayCheckoutBeforeConfirmation'} diff --git a/modules/concepts/hooks/list-of-hooks/displayCheckoutSubtotalDetails.md b/modules/concepts/hooks/list-of-hooks/displayCheckoutSubtotalDetails.md index b71af139d9..75961cfb75 100644 --- a/modules/concepts/hooks/list-of-hooks/displayCheckoutSubtotalDetails.md +++ b/modules/concepts/hooks/list-of-hooks/displayCheckoutSubtotalDetails.md @@ -6,9 +6,8 @@ hookTitle: files: - themes/classic/templates/checkout/_partials/cart-detailed-totals.tpl locations: - - frontoffice -type: - - display + - front office +type: display hookAliases: --- @@ -17,15 +16,14 @@ hookAliases: ## Information Hook locations: - - frontoffice + - front office -Hook type: - - display +Hook type: display Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/checkout/_partials/cart-detailed-totals.tpl](themes/classic/templates/checkout/_partials/cart-detailed-totals.tpl) -## Hook call in codebase +## Call of the Hook in the origin file ```php {hook h='displayCheckoutSubtotalDetails' subtotal=$subtotal} diff --git a/modules/concepts/hooks/list-of-hooks/displayCheckoutSummaryTop.md b/modules/concepts/hooks/list-of-hooks/displayCheckoutSummaryTop.md index 5e808f8233..6cf4ad1822 100644 --- a/modules/concepts/hooks/list-of-hooks/displayCheckoutSummaryTop.md +++ b/modules/concepts/hooks/list-of-hooks/displayCheckoutSummaryTop.md @@ -6,9 +6,8 @@ hookTitle: Cart summary top files: - themes/classic/templates/checkout/_partials/cart-summary-top.tpl locations: - - frontoffice -type: - - display + - front office +type: display hookAliases: --- @@ -23,15 +22,14 @@ This hook allows you to display new elements in top of cart summary {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - display +Hook type: display Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/checkout/_partials/cart-summary-top.tpl](themes/classic/templates/checkout/_partials/cart-summary-top.tpl) -## Hook call in codebase +## Call of the Hook in the origin file ```php {hook h='displayCheckoutSummaryTop'} diff --git a/modules/concepts/hooks/list-of-hooks/displayCrossSellingShoppingCart.md b/modules/concepts/hooks/list-of-hooks/displayCrossSellingShoppingCart.md index c4b7fd75bc..71dab2ae54 100644 --- a/modules/concepts/hooks/list-of-hooks/displayCrossSellingShoppingCart.md +++ b/modules/concepts/hooks/list-of-hooks/displayCrossSellingShoppingCart.md @@ -6,9 +6,8 @@ hookTitle: files: - themes/classic/templates/checkout/cart.tpl locations: - - frontoffice -type: - - display + - front office +type: display hookAliases: --- @@ -17,15 +16,14 @@ hookAliases: ## Information Hook locations: - - frontoffice + - front office -Hook type: - - display +Hook type: display Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/checkout/cart.tpl](themes/classic/templates/checkout/cart.tpl) -## Hook call in codebase +## Call of the Hook in the origin file ```php {hook h='displayCrossSellingShoppingCart'} diff --git a/modules/concepts/hooks/list-of-hooks/displayCustomerAccount.md b/modules/concepts/hooks/list-of-hooks/displayCustomerAccount.md index ae1af7e55c..785321c7f1 100644 --- a/modules/concepts/hooks/list-of-hooks/displayCustomerAccount.md +++ b/modules/concepts/hooks/list-of-hooks/displayCustomerAccount.md @@ -6,9 +6,8 @@ hookTitle: Customer account displayed in Front Office files: - themes/classic/templates/customer/my-account.tpl locations: - - frontoffice -type: - - display + - front office +type: display hookAliases: - customerAccount --- @@ -29,15 +28,14 @@ This hook displays new elements on the customer account page {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - display +Hook type: display Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/customer/my-account.tpl](themes/classic/templates/customer/my-account.tpl) -## Hook call in codebase +## Call of the Hook in the origin file ```php {hook h='displayCustomerAccount'} diff --git a/modules/concepts/hooks/list-of-hooks/displayCustomerAccountForm.md b/modules/concepts/hooks/list-of-hooks/displayCustomerAccountForm.md index beb729dcb6..2da82c7939 100644 --- a/modules/concepts/hooks/list-of-hooks/displayCustomerAccountForm.md +++ b/modules/concepts/hooks/list-of-hooks/displayCustomerAccountForm.md @@ -6,9 +6,8 @@ hookTitle: Customer account creation form files: - classes/form/CustomerForm.php locations: - - frontoffice -type: - - display + - front office +type: display hookAliases: - createAccountForm --- @@ -29,15 +28,14 @@ This hook displays some information on the form to create a customer account {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - display +Hook type: display Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/form/CustomerForm.php](classes/form/CustomerForm.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('displayCustomerAccountForm') diff --git a/modules/concepts/hooks/list-of-hooks/displayCustomerAccountFormTop.md b/modules/concepts/hooks/list-of-hooks/displayCustomerAccountFormTop.md index 78f1c45cc0..f23104a364 100644 --- a/modules/concepts/hooks/list-of-hooks/displayCustomerAccountFormTop.md +++ b/modules/concepts/hooks/list-of-hooks/displayCustomerAccountFormTop.md @@ -6,9 +6,8 @@ hookTitle: Block above the form for create an account files: - controllers/front/RegistrationController.php locations: - - frontoffice -type: - - display + - front office +type: display hookAliases: - createAccountTop --- @@ -29,15 +28,14 @@ This hook is displayed above the customer's account creation form {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - display +Hook type: display Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/front/RegistrationController.php](controllers/front/RegistrationController.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('displayCustomerAccountFormTop') diff --git a/modules/concepts/hooks/list-of-hooks/displayCustomerLoginFormAfter.md b/modules/concepts/hooks/list-of-hooks/displayCustomerLoginFormAfter.md index 53b213af8f..827f1f5eed 100644 --- a/modules/concepts/hooks/list-of-hooks/displayCustomerLoginFormAfter.md +++ b/modules/concepts/hooks/list-of-hooks/displayCustomerLoginFormAfter.md @@ -6,9 +6,8 @@ hookTitle: Display elements after login form files: - themes/classic/templates/customer/authentication.tpl locations: - - frontoffice -type: - - display + - front office +type: display hookAliases: --- @@ -23,15 +22,14 @@ This hook displays new elements after the login form {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - display +Hook type: display Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/customer/authentication.tpl](themes/classic/templates/customer/authentication.tpl) -## Hook call in codebase +## Call of the Hook in the origin file ```php {hook h='displayCustomerLoginFormAfter'} diff --git a/modules/concepts/hooks/list-of-hooks/displayCustomization.md b/modules/concepts/hooks/list-of-hooks/displayCustomization.md index f78f01d33a..bab148e5e9 100644 --- a/modules/concepts/hooks/list-of-hooks/displayCustomization.md +++ b/modules/concepts/hooks/list-of-hooks/displayCustomization.md @@ -6,9 +6,8 @@ hookTitle: files: - classes/Product.php locations: - - frontoffice -type: - - display + - front office +type: display hookAliases: --- @@ -17,15 +16,14 @@ hookAliases: ## Information Hook locations: - - frontoffice + - front office -Hook type: - - display +Hook type: display Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Product.php](classes/Product.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('displayCustomization', ['customization' => $row], (int) $row['id_module']) diff --git a/modules/concepts/hooks/list-of-hooks/displayDashboardToolbarIcons.md b/modules/concepts/hooks/list-of-hooks/displayDashboardToolbarIcons.md index 2bcba6f8de..3066cd3fcd 100644 --- a/modules/concepts/hooks/list-of-hooks/displayDashboardToolbarIcons.md +++ b/modules/concepts/hooks/list-of-hooks/displayDashboardToolbarIcons.md @@ -6,9 +6,8 @@ hookTitle: Display new elements in back office page with dashboard, on icons lis files: - src/PrestaShopBundle/Resources/views/Admin/Product/CatalogPage/Blocks/tools.html.twig locations: - - backoffice -type: - - display + - back office +type: display hookAliases: --- @@ -23,15 +22,14 @@ This hook launches modules when the back office with dashboard is displayed {{% /notice %}} Hook locations: - - backoffice + - back office -Hook type: - - display +Hook type: display Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Resources/views/Admin/Product/CatalogPage/Blocks/tools.html.twig](src/PrestaShopBundle/Resources/views/Admin/Product/CatalogPage/Blocks/tools.html.twig) -## Hook call in codebase +## Call of the Hook in the origin file ```php {{ renderhook('displayDashboardToolbarIcons', {}) }} diff --git a/modules/concepts/hooks/list-of-hooks/displayDashboardToolbarTopMenu.md b/modules/concepts/hooks/list-of-hooks/displayDashboardToolbarTopMenu.md index 7a62d5b970..1110d9f13c 100644 --- a/modules/concepts/hooks/list-of-hooks/displayDashboardToolbarTopMenu.md +++ b/modules/concepts/hooks/list-of-hooks/displayDashboardToolbarTopMenu.md @@ -6,9 +6,8 @@ hookTitle: Display new elements in back office page with a dashboard, on top Men files: - admin784x07v4swfhm9fgvc0/themes/new-theme/template/page_header_toolbar.tpl locations: - - frontoffice -type: - - display + - front office +type: display hookAliases: --- @@ -23,15 +22,14 @@ This hook launches modules when a page with a dashboard is displayed {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - display +Hook type: display Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/admin784x07v4swfhm9fgvc0/themes/new-theme/template/page_header_toolbar.tpl](admin784x07v4swfhm9fgvc0/themes/new-theme/template/page_header_toolbar.tpl) -## Hook call in codebase +## Call of the Hook in the origin file ```php {hook h='displayDashboardToolbarTopMenu'} diff --git a/modules/concepts/hooks/list-of-hooks/displayDashboardTop.md b/modules/concepts/hooks/list-of-hooks/displayDashboardTop.md index 3817d98d01..56c2bf8a41 100644 --- a/modules/concepts/hooks/list-of-hooks/displayDashboardTop.md +++ b/modules/concepts/hooks/list-of-hooks/displayDashboardTop.md @@ -6,9 +6,8 @@ hookTitle: Dashboard Top files: - admin784x07v4swfhm9fgvc0/themes/new-theme/template/page_header_toolbar.tpl locations: - - frontoffice -type: - - display + - front office +type: display hookAliases: --- @@ -23,15 +22,14 @@ Displays the content in the dashboard's top area {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - display +Hook type: display Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/admin784x07v4swfhm9fgvc0/themes/new-theme/template/page_header_toolbar.tpl](admin784x07v4swfhm9fgvc0/themes/new-theme/template/page_header_toolbar.tpl) -## Hook call in codebase +## Call of the Hook in the origin file ```php {hook h='displayDashboardTop'} diff --git a/modules/concepts/hooks/list-of-hooks/displayEmptyModuleCategoryExtraMessage.md b/modules/concepts/hooks/list-of-hooks/displayEmptyModuleCategoryExtraMessage.md index e3c46bd8a7..2e27ef9eea 100644 --- a/modules/concepts/hooks/list-of-hooks/displayEmptyModuleCategoryExtraMessage.md +++ b/modules/concepts/hooks/list-of-hooks/displayEmptyModuleCategoryExtraMessage.md @@ -6,9 +6,8 @@ hookTitle: Extra message to display for an empty modules category files: - src/PrestaShopBundle/Resources/views/Admin/Module/Includes/grid_manage_empty.html.twig locations: - - backoffice -type: - - display + - back office +type: display hookAliases: --- @@ -23,10 +22,9 @@ This hook allows to add an extra message to display in the Module manager page w {{% /notice %}} Hook locations: - - backoffice + - back office -Hook type: - - display +Hook type: display Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Resources/views/Admin/Module/Includes/grid_manage_empty.html.twig](src/PrestaShopBundle/Resources/views/Admin/Module/Includes/grid_manage_empty.html.twig) @@ -39,7 +37,7 @@ Located in: } ``` -## Hook call in codebase +## Call of the Hook in the origin file ```php {{ renderhook('displayEmptyModuleCategoryExtraMessage', {'category_name': category.name}) }} diff --git a/modules/concepts/hooks/list-of-hooks/displayExpressCheckout.md b/modules/concepts/hooks/list-of-hooks/displayExpressCheckout.md index d811e551ee..58e6738605 100644 --- a/modules/concepts/hooks/list-of-hooks/displayExpressCheckout.md +++ b/modules/concepts/hooks/list-of-hooks/displayExpressCheckout.md @@ -6,9 +6,8 @@ hookTitle: files: - themes/classic/templates/checkout/_partials/cart-detailed-actions.tpl locations: - - frontoffice -type: - - display + - front office +type: display hookAliases: --- @@ -17,15 +16,14 @@ hookAliases: ## Information Hook locations: - - frontoffice + - front office -Hook type: - - display +Hook type: display Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/checkout/_partials/cart-detailed-actions.tpl](themes/classic/templates/checkout/_partials/cart-detailed-actions.tpl) -## Hook call in codebase +## Call of the Hook in the origin file ```php {hook h='displayExpressCheckout'} diff --git a/modules/concepts/hooks/list-of-hooks/displayFeatureForm.md b/modules/concepts/hooks/list-of-hooks/displayFeatureForm.md index 1899328705..fdf0650085 100644 --- a/modules/concepts/hooks/list-of-hooks/displayFeatureForm.md +++ b/modules/concepts/hooks/list-of-hooks/displayFeatureForm.md @@ -6,9 +6,8 @@ hookTitle: Add fields to the form 'feature' files: - src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Features/Blocks/form.html.twig locations: - - backoffice -type: - - display + - back office +type: display hookAliases: - featureForm --- @@ -29,15 +28,14 @@ This hook adds fields to the form 'feature' {{% /notice %}} Hook locations: - - backoffice + - back office -Hook type: - - display +Hook type: display Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Features/Blocks/form.html.twig](src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Features/Blocks/form.html.twig) -## Hook call in codebase +## Call of the Hook in the origin file ```php {{ renderhook('displayFeatureForm', {'id_feature': featureId}) }} diff --git a/modules/concepts/hooks/list-of-hooks/displayFeaturePostProcess.md b/modules/concepts/hooks/list-of-hooks/displayFeaturePostProcess.md index d988fc71d5..67dcb4f448 100644 --- a/modules/concepts/hooks/list-of-hooks/displayFeaturePostProcess.md +++ b/modules/concepts/hooks/list-of-hooks/displayFeaturePostProcess.md @@ -6,9 +6,8 @@ hookTitle: On post-process in admin feature files: - controllers/admin/AdminFeaturesController.php locations: - - backoffice -type: - - display + - back office +type: display hookAliases: - postProcessFeature --- @@ -29,15 +28,14 @@ This hook is called on post-process in admin feature {{% /notice %}} Hook locations: - - backoffice + - back office -Hook type: - - display +Hook type: display Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/admin/AdminFeaturesController.php](controllers/admin/AdminFeaturesController.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec( diff --git a/modules/concepts/hooks/list-of-hooks/displayFeatureValuePostProcess.md b/modules/concepts/hooks/list-of-hooks/displayFeatureValuePostProcess.md index 3fd3eba1af..ddf4443fc1 100644 --- a/modules/concepts/hooks/list-of-hooks/displayFeatureValuePostProcess.md +++ b/modules/concepts/hooks/list-of-hooks/displayFeatureValuePostProcess.md @@ -6,9 +6,8 @@ hookTitle: On post-process in admin feature value files: - controllers/admin/AdminFeaturesController.php locations: - - backoffice -type: - - display + - back office +type: display hookAliases: - postProcessFeatureValue --- @@ -29,15 +28,14 @@ This hook is called on post-process in admin feature value {{% /notice %}} Hook locations: - - backoffice + - back office -Hook type: - - display +Hook type: display Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/admin/AdminFeaturesController.php](controllers/admin/AdminFeaturesController.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec( diff --git a/modules/concepts/hooks/list-of-hooks/displayFooter.md b/modules/concepts/hooks/list-of-hooks/displayFooter.md index 69ef8e737a..e7bdc3fdbb 100644 --- a/modules/concepts/hooks/list-of-hooks/displayFooter.md +++ b/modules/concepts/hooks/list-of-hooks/displayFooter.md @@ -6,9 +6,8 @@ hookTitle: Footer files: - themes/classic/templates/_partials/footer.tpl locations: - - frontoffice -type: - - display + - front office +type: display hookAliases: - footer --- @@ -29,15 +28,14 @@ This hook displays new blocks in the footer {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - display +Hook type: display Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/_partials/footer.tpl](themes/classic/templates/_partials/footer.tpl) -## Hook call in codebase +## Call of the Hook in the origin file ```php {hook h='displayFooter'} diff --git a/modules/concepts/hooks/list-of-hooks/displayFooterAfter.md b/modules/concepts/hooks/list-of-hooks/displayFooterAfter.md index 5bce1bf4ed..2befc497a9 100644 --- a/modules/concepts/hooks/list-of-hooks/displayFooterAfter.md +++ b/modules/concepts/hooks/list-of-hooks/displayFooterAfter.md @@ -6,9 +6,8 @@ hookTitle: files: - themes/classic/templates/_partials/footer.tpl locations: - - frontoffice -type: - - display + - front office +type: display hookAliases: --- @@ -17,15 +16,14 @@ hookAliases: ## Information Hook locations: - - frontoffice + - front office -Hook type: - - display +Hook type: display Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/_partials/footer.tpl](themes/classic/templates/_partials/footer.tpl) -## Hook call in codebase +## Call of the Hook in the origin file ```php {hook h='displayFooterAfter'} diff --git a/modules/concepts/hooks/list-of-hooks/displayFooterBefore.md b/modules/concepts/hooks/list-of-hooks/displayFooterBefore.md index cca6a37080..2104e95e9d 100644 --- a/modules/concepts/hooks/list-of-hooks/displayFooterBefore.md +++ b/modules/concepts/hooks/list-of-hooks/displayFooterBefore.md @@ -6,9 +6,8 @@ hookTitle: files: - themes/classic/templates/_partials/footer.tpl locations: - - frontoffice -type: - - display + - front office +type: display hookAliases: --- @@ -17,15 +16,14 @@ hookAliases: ## Information Hook locations: - - frontoffice + - front office -Hook type: - - display +Hook type: display Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/_partials/footer.tpl](themes/classic/templates/_partials/footer.tpl) -## Hook call in codebase +## Call of the Hook in the origin file ```php {hook h='displayFooterBefore'} diff --git a/modules/concepts/hooks/list-of-hooks/displayFooterProduct.md b/modules/concepts/hooks/list-of-hooks/displayFooterProduct.md index be4500a23e..a58298f2f0 100644 --- a/modules/concepts/hooks/list-of-hooks/displayFooterProduct.md +++ b/modules/concepts/hooks/list-of-hooks/displayFooterProduct.md @@ -6,9 +6,8 @@ hookTitle: Product footer files: - themes/classic/templates/catalog/product.tpl locations: - - frontoffice -type: - - display + - front office +type: display hookAliases: - productfooter --- @@ -29,15 +28,14 @@ This hook adds new blocks under the product's description {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - display +Hook type: display Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/catalog/product.tpl](themes/classic/templates/catalog/product.tpl) -## Hook call in codebase +## Call of the Hook in the origin file ```php {hook h='displayFooterProduct' product=$product category=$category} diff --git a/modules/concepts/hooks/list-of-hooks/displayGDPRConsent.md b/modules/concepts/hooks/list-of-hooks/displayGDPRConsent.md index 1ba7c07d70..a2e98017b5 100644 --- a/modules/concepts/hooks/list-of-hooks/displayGDPRConsent.md +++ b/modules/concepts/hooks/list-of-hooks/displayGDPRConsent.md @@ -6,9 +6,8 @@ hookTitle: files: - themes/classic/modules/ps_emailsubscription/views/templates/hook/ps_emailsubscription.tpl locations: - - frontoffice -type: - - display + - front office +type: display hookAliases: --- @@ -17,15 +16,14 @@ hookAliases: ## Information Hook locations: - - frontoffice + - front office -Hook type: - - display +Hook type: display Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/modules/ps_emailsubscription/views/templates/hook/ps_emailsubscription.tpl](themes/classic/modules/ps_emailsubscription/views/templates/hook/ps_emailsubscription.tpl) -## Hook call in codebase +## Call of the Hook in the origin file ```php {hook h='displayGDPRConsent' id_module=$id_module} diff --git a/modules/concepts/hooks/list-of-hooks/displayHeader.md b/modules/concepts/hooks/list-of-hooks/displayHeader.md index b2abc7f382..9b10f06487 100644 --- a/modules/concepts/hooks/list-of-hooks/displayHeader.md +++ b/modules/concepts/hooks/list-of-hooks/displayHeader.md @@ -6,9 +6,8 @@ hookTitle: Pages html head section files: - classes/controller/FrontController.php locations: - - frontoffice -type: - - display + - front office +type: display hookAliases: - Header --- @@ -29,15 +28,14 @@ This hook adds additional elements in the head section of your pages (head secti {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - display +Hook type: display Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/FrontController.php](classes/controller/FrontController.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('displayHeader') diff --git a/modules/concepts/hooks/list-of-hooks/displayHome.md b/modules/concepts/hooks/list-of-hooks/displayHome.md index 4928640e87..20f1ce3f64 100644 --- a/modules/concepts/hooks/list-of-hooks/displayHome.md +++ b/modules/concepts/hooks/list-of-hooks/displayHome.md @@ -6,9 +6,8 @@ hookTitle: Homepage content files: - controllers/front/IndexController.php locations: - - frontoffice -type: - - display + - front office +type: display hookAliases: - home --- @@ -29,15 +28,14 @@ This hook displays new elements on the homepage {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - display +Hook type: display Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/front/IndexController.php](controllers/front/IndexController.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('displayHome') diff --git a/modules/concepts/hooks/list-of-hooks/displayInvoiceLegalFreeText.md b/modules/concepts/hooks/list-of-hooks/displayInvoiceLegalFreeText.md index 7046ed177b..839acc2bf9 100644 --- a/modules/concepts/hooks/list-of-hooks/displayInvoiceLegalFreeText.md +++ b/modules/concepts/hooks/list-of-hooks/displayInvoiceLegalFreeText.md @@ -6,9 +6,8 @@ hookTitle: PDF Invoice - Legal Free Text files: - classes/pdf/HTMLTemplateInvoice.php locations: - - frontoffice -type: - - display + - front office +type: display hookAliases: --- @@ -23,15 +22,14 @@ This hook allows you to modify the legal free text on PDF invoices {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - display +Hook type: display Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/pdf/HTMLTemplateInvoice.php](classes/pdf/HTMLTemplateInvoice.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('displayInvoiceLegalFreeText', ['order' => $this->order]) diff --git a/modules/concepts/hooks/list-of-hooks/displayLeftColumnProduct.md b/modules/concepts/hooks/list-of-hooks/displayLeftColumnProduct.md index dcb22ffcbe..2a3f804915 100644 --- a/modules/concepts/hooks/list-of-hooks/displayLeftColumnProduct.md +++ b/modules/concepts/hooks/list-of-hooks/displayLeftColumnProduct.md @@ -6,9 +6,8 @@ hookTitle: New elements on the product page (left column) files: - themes/classic/templates/layouts/layout-both-columns.tpl locations: - - frontoffice -type: - - display + - front office +type: display hookAliases: - extraLeft --- @@ -29,15 +28,14 @@ This hook displays new elements in the left-hand column of the product page {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - display +Hook type: display Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/layouts/layout-both-columns.tpl](themes/classic/templates/layouts/layout-both-columns.tpl) -## Hook call in codebase +## Call of the Hook in the origin file ```php {hook h='displayLeftColumnProduct' product=$product category=$category} diff --git a/modules/concepts/hooks/list-of-hooks/displayMaintenance.md b/modules/concepts/hooks/list-of-hooks/displayMaintenance.md index 6076cdcf0a..d1633fbdf7 100644 --- a/modules/concepts/hooks/list-of-hooks/displayMaintenance.md +++ b/modules/concepts/hooks/list-of-hooks/displayMaintenance.md @@ -6,9 +6,8 @@ hookTitle: Maintenance Page files: - classes/controller/FrontController.php locations: - - frontoffice -type: - - display + - front office +type: display hookAliases: --- @@ -23,15 +22,14 @@ This hook displays new elements on the maintenance page {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - display +Hook type: display Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/FrontController.php](classes/controller/FrontController.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('displayMaintenance', []) diff --git a/modules/concepts/hooks/list-of-hooks/displayMyAccountBlock.md b/modules/concepts/hooks/list-of-hooks/displayMyAccountBlock.md index 6811192718..09120e0a67 100644 --- a/modules/concepts/hooks/list-of-hooks/displayMyAccountBlock.md +++ b/modules/concepts/hooks/list-of-hooks/displayMyAccountBlock.md @@ -6,9 +6,8 @@ hookTitle: My account block files: - themes/classic/modules/ps_customeraccountlinks/ps_customeraccountlinks.tpl locations: - - frontoffice -type: - - display + - front office +type: display hookAliases: - myAccountBlock --- @@ -29,15 +28,14 @@ This hook displays extra information within the 'my account' block" {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - display +Hook type: display Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/modules/ps_customeraccountlinks/ps_customeraccountlinks.tpl](themes/classic/modules/ps_customeraccountlinks/ps_customeraccountlinks.tpl) -## Hook call in codebase +## Call of the Hook in the origin file ```php {hook h='displayMyAccountBlock'} diff --git a/modules/concepts/hooks/list-of-hooks/displayNav1.md b/modules/concepts/hooks/list-of-hooks/displayNav1.md index ffe3c40c51..58897c9b94 100644 --- a/modules/concepts/hooks/list-of-hooks/displayNav1.md +++ b/modules/concepts/hooks/list-of-hooks/displayNav1.md @@ -6,9 +6,8 @@ hookTitle: files: - themes/classic/templates/checkout/_partials/header.tpl locations: - - frontoffice -type: - - display + - front office +type: display hookAliases: --- @@ -17,15 +16,14 @@ hookAliases: ## Information Hook locations: - - frontoffice + - front office -Hook type: - - display +Hook type: display Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/checkout/_partials/header.tpl](themes/classic/templates/checkout/_partials/header.tpl) -## Hook call in codebase +## Call of the Hook in the origin file ```php {hook h='displayNav1'} diff --git a/modules/concepts/hooks/list-of-hooks/displayNav2.md b/modules/concepts/hooks/list-of-hooks/displayNav2.md index 7afef6b5db..9917356ff8 100644 --- a/modules/concepts/hooks/list-of-hooks/displayNav2.md +++ b/modules/concepts/hooks/list-of-hooks/displayNav2.md @@ -6,9 +6,8 @@ hookTitle: files: - themes/classic/templates/checkout/_partials/header.tpl locations: - - frontoffice -type: - - display + - front office +type: display hookAliases: --- @@ -17,15 +16,14 @@ hookAliases: ## Information Hook locations: - - frontoffice + - front office -Hook type: - - display +Hook type: display Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/checkout/_partials/header.tpl](themes/classic/templates/checkout/_partials/header.tpl) -## Hook call in codebase +## Call of the Hook in the origin file ```php {hook h='displayNav2'} diff --git a/modules/concepts/hooks/list-of-hooks/displayNavFullWidth.md b/modules/concepts/hooks/list-of-hooks/displayNavFullWidth.md index d3d90ed4c3..019a87c851 100644 --- a/modules/concepts/hooks/list-of-hooks/displayNavFullWidth.md +++ b/modules/concepts/hooks/list-of-hooks/displayNavFullWidth.md @@ -6,9 +6,8 @@ hookTitle: Navigation files: - themes/classic/templates/checkout/_partials/header.tpl locations: - - frontoffice -type: - - display + - front office +type: display hookAliases: --- @@ -23,15 +22,14 @@ This hook displays full width navigation menu at the top of your pages {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - display +Hook type: display Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/checkout/_partials/header.tpl](themes/classic/templates/checkout/_partials/header.tpl) -## Hook call in codebase +## Call of the Hook in the origin file ```php {hook h='displayNavFullWidth'} diff --git a/modules/concepts/hooks/list-of-hooks/displayNewsletterRegistration.md b/modules/concepts/hooks/list-of-hooks/displayNewsletterRegistration.md index 7eb5252289..e53b5d5c90 100644 --- a/modules/concepts/hooks/list-of-hooks/displayNewsletterRegistration.md +++ b/modules/concepts/hooks/list-of-hooks/displayNewsletterRegistration.md @@ -6,9 +6,8 @@ hookTitle: files: - themes/classic/modules/ps_emailsubscription/views/templates/hook/ps_emailsubscription.tpl locations: - - frontoffice -type: - - display + - front office +type: display hookAliases: --- @@ -17,15 +16,14 @@ hookAliases: ## Information Hook locations: - - frontoffice + - front office -Hook type: - - display +Hook type: display Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/modules/ps_emailsubscription/views/templates/hook/ps_emailsubscription.tpl](themes/classic/modules/ps_emailsubscription/views/templates/hook/ps_emailsubscription.tpl) -## Hook call in codebase +## Call of the Hook in the origin file ```php {hook h='displayNewsletterRegistration'} diff --git a/modules/concepts/hooks/list-of-hooks/displayNotFound.md b/modules/concepts/hooks/list-of-hooks/displayNotFound.md index d32f09cdef..bd13857db3 100644 --- a/modules/concepts/hooks/list-of-hooks/displayNotFound.md +++ b/modules/concepts/hooks/list-of-hooks/displayNotFound.md @@ -6,9 +6,8 @@ hookTitle: files: - themes/classic/templates/errors/not-found.tpl locations: - - frontoffice -type: - - display + - front office +type: display hookAliases: --- @@ -17,15 +16,14 @@ hookAliases: ## Information Hook locations: - - frontoffice + - front office -Hook type: - - display +Hook type: display Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/errors/not-found.tpl](themes/classic/templates/errors/not-found.tpl) -## Hook call in codebase +## Call of the Hook in the origin file ```php {hook h='displayNotFound'} diff --git a/modules/concepts/hooks/list-of-hooks/displayOrderConfirmation.md b/modules/concepts/hooks/list-of-hooks/displayOrderConfirmation.md index 9aceeabdf3..1a4895f62e 100644 --- a/modules/concepts/hooks/list-of-hooks/displayOrderConfirmation.md +++ b/modules/concepts/hooks/list-of-hooks/displayOrderConfirmation.md @@ -6,9 +6,8 @@ hookTitle: Order confirmation page files: - controllers/front/OrderConfirmationController.php locations: - - frontoffice -type: - - display + - front office +type: display hookAliases: - orderConfirmation --- @@ -29,10 +28,9 @@ This hook is called within an order's confirmation page {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - display +Hook type: display Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/front/OrderConfirmationController.php](controllers/front/OrderConfirmationController.php) @@ -46,7 +44,7 @@ Located in: ); ``` -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('displayOrderConfirmation', ['order' => $order]) diff --git a/modules/concepts/hooks/list-of-hooks/displayOrderConfirmation1.md b/modules/concepts/hooks/list-of-hooks/displayOrderConfirmation1.md index a1a02c7c3e..a23f16b94b 100644 --- a/modules/concepts/hooks/list-of-hooks/displayOrderConfirmation1.md +++ b/modules/concepts/hooks/list-of-hooks/displayOrderConfirmation1.md @@ -6,9 +6,8 @@ hookTitle: files: - themes/classic/templates/checkout/order-confirmation.tpl locations: - - frontoffice -type: - - display + - front office +type: display hookAliases: --- @@ -17,15 +16,14 @@ hookAliases: ## Information Hook locations: - - frontoffice + - front office -Hook type: - - display +Hook type: display Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/checkout/order-confirmation.tpl](themes/classic/templates/checkout/order-confirmation.tpl) -## Hook call in codebase +## Call of the Hook in the origin file ```php {hook h='displayOrderConfirmation1'} diff --git a/modules/concepts/hooks/list-of-hooks/displayOrderConfirmation2.md b/modules/concepts/hooks/list-of-hooks/displayOrderConfirmation2.md index ca122df5f4..2ccf6053dc 100644 --- a/modules/concepts/hooks/list-of-hooks/displayOrderConfirmation2.md +++ b/modules/concepts/hooks/list-of-hooks/displayOrderConfirmation2.md @@ -6,9 +6,8 @@ hookTitle: files: - themes/classic/templates/checkout/order-confirmation.tpl locations: - - frontoffice -type: - - display + - front office +type: display hookAliases: --- @@ -17,15 +16,14 @@ hookAliases: ## Information Hook locations: - - frontoffice + - front office -Hook type: - - display +Hook type: display Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/checkout/order-confirmation.tpl](themes/classic/templates/checkout/order-confirmation.tpl) -## Hook call in codebase +## Call of the Hook in the origin file ```php {hook h='displayOrderConfirmation2'} diff --git a/modules/concepts/hooks/list-of-hooks/displayOrderDetail.md b/modules/concepts/hooks/list-of-hooks/displayOrderDetail.md index 516ed9d28b..29bd4319ef 100644 --- a/modules/concepts/hooks/list-of-hooks/displayOrderDetail.md +++ b/modules/concepts/hooks/list-of-hooks/displayOrderDetail.md @@ -6,9 +6,8 @@ hookTitle: Order detail files: - controllers/front/OrderDetailController.php locations: - - frontoffice -type: - - display + - front office +type: display hookAliases: - orderDetailDisplayed --- @@ -29,10 +28,9 @@ This hook is displayed within the order's details in Front Office {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - display +Hook type: display Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/front/OrderDetailController.php](controllers/front/OrderDetailController.php) @@ -46,7 +44,7 @@ Located in: ); ``` -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('displayOrderDetail', ['order' => $order]) diff --git a/modules/concepts/hooks/list-of-hooks/displayOrderPreview.md b/modules/concepts/hooks/list-of-hooks/displayOrderPreview.md index 10f487f2e9..8fc2d09ce6 100644 --- a/modules/concepts/hooks/list-of-hooks/displayOrderPreview.md +++ b/modules/concepts/hooks/list-of-hooks/displayOrderPreview.md @@ -6,9 +6,8 @@ hookTitle: files: - src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/preview.html.twig locations: - - backoffice -type: - - display + - back office +type: display hookAliases: --- @@ -17,10 +16,9 @@ hookAliases: ## Information Hook locations: - - backoffice + - back office -Hook type: - - display +Hook type: display Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/preview.html.twig](src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/preview.html.twig) @@ -34,7 +32,7 @@ Located in: ); ``` -## Hook call in codebase +## Call of the Hook in the origin file ```php {{ renderhook('displayOrderPreview', {'order_id': orderId}) }} diff --git a/modules/concepts/hooks/list-of-hooks/displayOverrideTemplate.md b/modules/concepts/hooks/list-of-hooks/displayOverrideTemplate.md index 2b898d0405..368766669b 100644 --- a/modules/concepts/hooks/list-of-hooks/displayOverrideTemplate.md +++ b/modules/concepts/hooks/list-of-hooks/displayOverrideTemplate.md @@ -6,9 +6,8 @@ hookTitle: Change the default template of current controller files: - classes/controller/FrontController.php locations: - - frontoffice -type: - - display + - front office +type: display hookAliases: --- @@ -23,15 +22,14 @@ hookAliases: {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - display +Hook type: display Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/FrontController.php](classes/controller/FrontController.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec( diff --git a/modules/concepts/hooks/list-of-hooks/displayPaymentByBinaries.md b/modules/concepts/hooks/list-of-hooks/displayPaymentByBinaries.md index b75f6d419a..5567ccfc39 100644 --- a/modules/concepts/hooks/list-of-hooks/displayPaymentByBinaries.md +++ b/modules/concepts/hooks/list-of-hooks/displayPaymentByBinaries.md @@ -6,9 +6,8 @@ hookTitle: Payment form generated by binaries files: - themes/classic/templates/checkout/_partials/steps/payment.tpl locations: - - frontoffice -type: - - display + - front office +type: display hookAliases: --- @@ -23,15 +22,14 @@ This hook displays form generated by binaries during the checkout {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - display +Hook type: display Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/checkout/_partials/steps/payment.tpl](themes/classic/templates/checkout/_partials/steps/payment.tpl) -## Hook call in codebase +## Call of the Hook in the origin file ```php {hook h='displayPaymentByBinaries'} diff --git a/modules/concepts/hooks/list-of-hooks/displayPaymentReturn.md b/modules/concepts/hooks/list-of-hooks/displayPaymentReturn.md index 0b3f3ad41c..77a39ea021 100644 --- a/modules/concepts/hooks/list-of-hooks/displayPaymentReturn.md +++ b/modules/concepts/hooks/list-of-hooks/displayPaymentReturn.md @@ -6,9 +6,8 @@ hookTitle: Payment return files: - controllers/front/OrderConfirmationController.php locations: - - frontoffice -type: - - display + - front office +type: display hookAliases: - paymentReturn --- @@ -29,15 +28,14 @@ Aliases: {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - display +Hook type: display Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/front/OrderConfirmationController.php](controllers/front/OrderConfirmationController.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('displayPaymentReturn', ['order' => $order], $this->id_module) diff --git a/modules/concepts/hooks/list-of-hooks/displayPaymentTop.md b/modules/concepts/hooks/list-of-hooks/displayPaymentTop.md index b6f47cbd73..3cae4854d3 100644 --- a/modules/concepts/hooks/list-of-hooks/displayPaymentTop.md +++ b/modules/concepts/hooks/list-of-hooks/displayPaymentTop.md @@ -6,9 +6,8 @@ hookTitle: Top of payment page files: - themes/classic/templates/checkout/_partials/steps/payment.tpl locations: - - frontoffice -type: - - display + - front office +type: display hookAliases: - paymentTop --- @@ -29,15 +28,14 @@ This hook is displayed at the top of the payment page {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - display +Hook type: display Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/checkout/_partials/steps/payment.tpl](themes/classic/templates/checkout/_partials/steps/payment.tpl) -## Hook call in codebase +## Call of the Hook in the origin file ```php {hook h='displayPaymentTop'} diff --git a/modules/concepts/hooks/list-of-hooks/displayPersonalInformationTop.md b/modules/concepts/hooks/list-of-hooks/displayPersonalInformationTop.md index 03d682b06c..2c4ae619e9 100644 --- a/modules/concepts/hooks/list-of-hooks/displayPersonalInformationTop.md +++ b/modules/concepts/hooks/list-of-hooks/displayPersonalInformationTop.md @@ -6,9 +6,8 @@ hookTitle: Content in the checkout funnel, on top of the personal information pa files: - themes/classic/templates/checkout/_partials/steps/personal-information.tpl locations: - - frontoffice -type: - - display + - front office +type: display hookAliases: --- @@ -23,15 +22,14 @@ Display actions or additional content in the personal details tab of the checkou {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - display +Hook type: display Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/checkout/_partials/steps/personal-information.tpl](themes/classic/templates/checkout/_partials/steps/personal-information.tpl) -## Hook call in codebase +## Call of the Hook in the origin file ```php {hook h='displayPersonalInformationTop' customer=$customer} diff --git a/modules/concepts/hooks/list-of-hooks/displayProductActions.md b/modules/concepts/hooks/list-of-hooks/displayProductActions.md index 4203f789ca..175078a39f 100644 --- a/modules/concepts/hooks/list-of-hooks/displayProductActions.md +++ b/modules/concepts/hooks/list-of-hooks/displayProductActions.md @@ -6,9 +6,8 @@ hookTitle: Display additional action button on the product page files: - themes/classic/templates/catalog/_partials/product-add-to-cart.tpl locations: - - frontoffice -type: - - action + - front office +type: action hookAliases: --- @@ -23,15 +22,14 @@ This hook allow additional actions to be triggered, near the add to cart button. {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - action +Hook type: action Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/catalog/_partials/product-add-to-cart.tpl](themes/classic/templates/catalog/_partials/product-add-to-cart.tpl) -## Hook call in codebase +## Call of the Hook in the origin file ```php {hook h='displayProductActions' product=$product} diff --git a/modules/concepts/hooks/list-of-hooks/displayProductAdditionalInfo.md b/modules/concepts/hooks/list-of-hooks/displayProductAdditionalInfo.md index 929f07e7b8..7917773cdd 100644 --- a/modules/concepts/hooks/list-of-hooks/displayProductAdditionalInfo.md +++ b/modules/concepts/hooks/list-of-hooks/displayProductAdditionalInfo.md @@ -6,9 +6,8 @@ hookTitle: Product page additional info files: - themes/classic/templates/catalog/_partials/quickview.tpl locations: - - frontoffice -type: - - display + - front office +type: display hookAliases: - productActions - displayProductButtons @@ -31,15 +30,14 @@ This hook adds additional information on the product page {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - display +Hook type: display Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/catalog/_partials/quickview.tpl](themes/classic/templates/catalog/_partials/quickview.tpl) -## Hook call in codebase +## Call of the Hook in the origin file ```php {hook h='displayProductAdditionalInfo' product=$product} diff --git a/modules/concepts/hooks/list-of-hooks/displayProductListReviews.md b/modules/concepts/hooks/list-of-hooks/displayProductListReviews.md index f4156799c3..9f610f11b7 100644 --- a/modules/concepts/hooks/list-of-hooks/displayProductListReviews.md +++ b/modules/concepts/hooks/list-of-hooks/displayProductListReviews.md @@ -6,9 +6,8 @@ hookTitle: files: - themes/classic/templates/catalog/_partials/miniatures/product.tpl locations: - - frontoffice -type: - - display + - front office +type: display hookAliases: --- @@ -17,15 +16,14 @@ hookAliases: ## Information Hook locations: - - frontoffice + - front office -Hook type: - - display +Hook type: display Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/catalog/_partials/miniatures/product.tpl](themes/classic/templates/catalog/_partials/miniatures/product.tpl) -## Hook call in codebase +## Call of the Hook in the origin file ```php {hook h='displayProductListReviews' product=$product} diff --git a/modules/concepts/hooks/list-of-hooks/displayProductPriceBlock.md b/modules/concepts/hooks/list-of-hooks/displayProductPriceBlock.md index d03f20433a..0c4f27b156 100644 --- a/modules/concepts/hooks/list-of-hooks/displayProductPriceBlock.md +++ b/modules/concepts/hooks/list-of-hooks/displayProductPriceBlock.md @@ -6,9 +6,8 @@ hookTitle: files: - themes/classic/templates/checkout/_partials/order-confirmation-table.tpl locations: - - frontoffice -type: - - display + - front office +type: display hookAliases: --- @@ -17,15 +16,14 @@ hookAliases: ## Information Hook locations: - - frontoffice + - front office -Hook type: - - display +Hook type: display Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/checkout/_partials/order-confirmation-table.tpl](themes/classic/templates/checkout/_partials/order-confirmation-table.tpl) -## Hook call in codebase +## Call of the Hook in the origin file ```php {hook h='displayProductPriceBlock' product=$product type="unit_price"} diff --git a/modules/concepts/hooks/list-of-hooks/displayReassurance.md b/modules/concepts/hooks/list-of-hooks/displayReassurance.md index 95f25be5d6..f342c67e18 100644 --- a/modules/concepts/hooks/list-of-hooks/displayReassurance.md +++ b/modules/concepts/hooks/list-of-hooks/displayReassurance.md @@ -6,9 +6,8 @@ hookTitle: files: - themes/classic/templates/checkout/checkout.tpl locations: - - frontoffice -type: - - display + - front office +type: display hookAliases: --- @@ -17,15 +16,14 @@ hookAliases: ## Information Hook locations: - - frontoffice + - front office -Hook type: - - display +Hook type: display Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/checkout/checkout.tpl](themes/classic/templates/checkout/checkout.tpl) -## Hook call in codebase +## Call of the Hook in the origin file ```php {hook h='displayReassurance'} diff --git a/modules/concepts/hooks/list-of-hooks/displayRightColumnProduct.md b/modules/concepts/hooks/list-of-hooks/displayRightColumnProduct.md index ffd71ae14c..acc3aa1a02 100644 --- a/modules/concepts/hooks/list-of-hooks/displayRightColumnProduct.md +++ b/modules/concepts/hooks/list-of-hooks/displayRightColumnProduct.md @@ -6,9 +6,8 @@ hookTitle: New elements on the product page (right column) files: - themes/classic/templates/layouts/layout-both-columns.tpl locations: - - frontoffice -type: - - display + - front office +type: display hookAliases: - extraRight --- @@ -29,15 +28,14 @@ This hook displays new elements in the right-hand column of the product page {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - display +Hook type: display Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/layouts/layout-both-columns.tpl](themes/classic/templates/layouts/layout-both-columns.tpl) -## Hook call in codebase +## Call of the Hook in the origin file ```php {hook h='displayRightColumnProduct'} diff --git a/modules/concepts/hooks/list-of-hooks/displaySearch.md b/modules/concepts/hooks/list-of-hooks/displaySearch.md index 2d08cdffc9..8412443565 100644 --- a/modules/concepts/hooks/list-of-hooks/displaySearch.md +++ b/modules/concepts/hooks/list-of-hooks/displaySearch.md @@ -6,9 +6,8 @@ hookTitle: files: - themes/classic/templates/errors/not-found.tpl locations: - - frontoffice -type: - - display + - front office +type: display hookAliases: --- @@ -17,15 +16,14 @@ hookAliases: ## Information Hook locations: - - frontoffice + - front office -Hook type: - - display +Hook type: display Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/errors/not-found.tpl](themes/classic/templates/errors/not-found.tpl) -## Hook call in codebase +## Call of the Hook in the origin file ```php {hook h='displaySearch'} diff --git a/modules/concepts/hooks/list-of-hooks/displayShoppingCart.md b/modules/concepts/hooks/list-of-hooks/displayShoppingCart.md index 7dd27d5d24..56e60c8c54 100644 --- a/modules/concepts/hooks/list-of-hooks/displayShoppingCart.md +++ b/modules/concepts/hooks/list-of-hooks/displayShoppingCart.md @@ -6,9 +6,8 @@ hookTitle: Shopping cart - Additional button files: - themes/classic/templates/checkout/cart.tpl locations: - - frontoffice -type: - - display + - front office +type: display hookAliases: - shoppingCartExtra --- @@ -29,15 +28,14 @@ This hook displays new action buttons within the shopping cart {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - display +Hook type: display Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/checkout/cart.tpl](themes/classic/templates/checkout/cart.tpl) -## Hook call in codebase +## Call of the Hook in the origin file ```php {hook h='displayShoppingCart'} diff --git a/modules/concepts/hooks/list-of-hooks/displayShoppingCartFooter.md b/modules/concepts/hooks/list-of-hooks/displayShoppingCartFooter.md index 324d04abc4..782d8047d2 100644 --- a/modules/concepts/hooks/list-of-hooks/displayShoppingCartFooter.md +++ b/modules/concepts/hooks/list-of-hooks/displayShoppingCartFooter.md @@ -6,9 +6,8 @@ hookTitle: Shopping cart footer files: - themes/classic/templates/checkout/cart.tpl locations: - - frontoffice -type: - - display + - front office +type: display hookAliases: - shoppingCart --- @@ -29,15 +28,14 @@ This hook displays some specific information on the shopping cart's page {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - display +Hook type: display Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/checkout/cart.tpl](themes/classic/templates/checkout/cart.tpl) -## Hook call in codebase +## Call of the Hook in the origin file ```php {hook h='displayShoppingCartFooter'} diff --git a/modules/concepts/hooks/list-of-hooks/displayTop.md b/modules/concepts/hooks/list-of-hooks/displayTop.md index 8c18544b44..3706605073 100644 --- a/modules/concepts/hooks/list-of-hooks/displayTop.md +++ b/modules/concepts/hooks/list-of-hooks/displayTop.md @@ -6,9 +6,8 @@ hookTitle: Top of pages files: - themes/classic/templates/checkout/_partials/header.tpl locations: - - frontoffice -type: - - display + - front office +type: display hookAliases: - top --- @@ -29,15 +28,14 @@ This hook displays additional elements at the top of your pages {{% /notice %}} Hook locations: - - frontoffice + - front office -Hook type: - - display +Hook type: display Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/checkout/_partials/header.tpl](themes/classic/templates/checkout/_partials/header.tpl) -## Hook call in codebase +## Call of the Hook in the origin file ```php {hook h='displayTop'} diff --git a/modules/concepts/hooks/list-of-hooks/filterCategoryContent.md b/modules/concepts/hooks/list-of-hooks/filterCategoryContent.md index c73d835ddf..f988c96e35 100644 --- a/modules/concepts/hooks/list-of-hooks/filterCategoryContent.md +++ b/modules/concepts/hooks/list-of-hooks/filterCategoryContent.md @@ -6,9 +6,8 @@ hookTitle: Filter the content page category files: - controllers/front/listing/CategoryController.php locations: - - frontoffice -type: - - + - front office +type: hookAliases: --- @@ -23,7 +22,7 @@ This hook is called just before fetching content page category {{% /notice %}} Hook locations: - - frontoffice + - front office Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/front/listing/CategoryController.php](controllers/front/listing/CategoryController.php) @@ -39,7 +38,7 @@ This hook has a `$chain` parameter set to `true` (hook will chain the return of ), ``` -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec( diff --git a/modules/concepts/hooks/list-of-hooks/filterCmsCategoryContent.md b/modules/concepts/hooks/list-of-hooks/filterCmsCategoryContent.md index 005228a32b..e0f3e9adff 100644 --- a/modules/concepts/hooks/list-of-hooks/filterCmsCategoryContent.md +++ b/modules/concepts/hooks/list-of-hooks/filterCmsCategoryContent.md @@ -6,9 +6,8 @@ hookTitle: Filter the content page category files: - controllers/front/CmsController.php locations: - - frontoffice -type: - - + - front office +type: hookAliases: --- @@ -23,14 +22,14 @@ This hook is called just before fetching content page category {{% /notice %}} Hook locations: - - frontoffice + - front office Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/front/CmsController.php](controllers/front/CmsController.php) This hook has a `$chain` parameter set to `true` (hook will chain the return of hook module, [see explaination here]({{< relref "/8/development/components/hook/dispatching-hook">}})). -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec( diff --git a/modules/concepts/hooks/list-of-hooks/filterCmsContent.md b/modules/concepts/hooks/list-of-hooks/filterCmsContent.md index 6181122023..21a9d6c5e6 100644 --- a/modules/concepts/hooks/list-of-hooks/filterCmsContent.md +++ b/modules/concepts/hooks/list-of-hooks/filterCmsContent.md @@ -6,9 +6,8 @@ hookTitle: Filter the content page files: - controllers/front/CmsController.php locations: - - frontoffice -type: - - + - front office +type: hookAliases: --- @@ -23,14 +22,14 @@ This hook is called just before fetching content page {{% /notice %}} Hook locations: - - frontoffice + - front office Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/front/CmsController.php](controllers/front/CmsController.php) This hook has a `$chain` parameter set to `true` (hook will chain the return of hook module, [see explaination here]({{< relref "/8/development/components/hook/dispatching-hook">}})). -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec( diff --git a/modules/concepts/hooks/list-of-hooks/filterHtmlContent.md b/modules/concepts/hooks/list-of-hooks/filterHtmlContent.md index 3c8373d5b6..8031434949 100644 --- a/modules/concepts/hooks/list-of-hooks/filterHtmlContent.md +++ b/modules/concepts/hooks/list-of-hooks/filterHtmlContent.md @@ -6,9 +6,8 @@ hookTitle: Filter HTML field before rending a page files: - src/Adapter/Presenter/Object/ObjectPresenter.php locations: - - frontoffice -type: - - + - front office +type: hookAliases: --- @@ -23,14 +22,14 @@ This hook is called just before fetching a page on HTML field {{% /notice %}} Hook locations: - - frontoffice + - front office Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Presenter/Object/ObjectPresenter.php](src/Adapter/Presenter/Object/ObjectPresenter.php) This hook has a `$chain` parameter set to `true` (hook will chain the return of hook module, [see explaination here]({{< relref "/8/development/components/hook/dispatching-hook">}})). -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec( diff --git a/modules/concepts/hooks/list-of-hooks/filterManufacturerContent.md b/modules/concepts/hooks/list-of-hooks/filterManufacturerContent.md index f324201769..b6cbb3cd80 100644 --- a/modules/concepts/hooks/list-of-hooks/filterManufacturerContent.md +++ b/modules/concepts/hooks/list-of-hooks/filterManufacturerContent.md @@ -6,9 +6,8 @@ hookTitle: Filter the content page manufacturer files: - controllers/front/listing/ManufacturerController.php locations: - - frontoffice -type: - - + - front office +type: hookAliases: --- @@ -23,14 +22,14 @@ This hook is called just before fetching content page manufacturer {{% /notice %}} Hook locations: - - frontoffice + - front office Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/front/listing/ManufacturerController.php](controllers/front/listing/ManufacturerController.php) This hook has a `$chain` parameter set to `true` (hook will chain the return of hook module, [see explaination here]({{< relref "/8/development/components/hook/dispatching-hook">}})). -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec( diff --git a/modules/concepts/hooks/list-of-hooks/filterProductContent.md b/modules/concepts/hooks/list-of-hooks/filterProductContent.md index c18f8ae439..3a7f7cedf7 100644 --- a/modules/concepts/hooks/list-of-hooks/filterProductContent.md +++ b/modules/concepts/hooks/list-of-hooks/filterProductContent.md @@ -6,9 +6,8 @@ hookTitle: Filter the content page product files: - controllers/front/ProductController.php locations: - - frontoffice -type: - - + - front office +type: hookAliases: --- @@ -23,14 +22,14 @@ This hook is called just before fetching content page product {{% /notice %}} Hook locations: - - frontoffice + - front office Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/front/ProductController.php](controllers/front/ProductController.php) This hook has a `$chain` parameter set to `true` (hook will chain the return of hook module, [see explaination here]({{< relref "/8/development/components/hook/dispatching-hook">}})). -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec( diff --git a/modules/concepts/hooks/list-of-hooks/filterProductSearch.md b/modules/concepts/hooks/list-of-hooks/filterProductSearch.md index 27a0098524..c9be8039ea 100644 --- a/modules/concepts/hooks/list-of-hooks/filterProductSearch.md +++ b/modules/concepts/hooks/list-of-hooks/filterProductSearch.md @@ -6,9 +6,8 @@ hookTitle: Filter search products result files: - modules/blockwishlist/controllers/front/view.php locations: - - frontoffice -type: - - + - front office +type: hookAliases: --- @@ -23,12 +22,12 @@ This hook is called in order to allow to modify search product result {{% /notice %}} Hook locations: - - frontoffice + - front office Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/modules/blockwishlist/controllers/front/view.php](modules/blockwishlist/controllers/front/view.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('filterProductSearch', ['searchVariables' => &$searchVariables]) diff --git a/modules/concepts/hooks/list-of-hooks/filterSupplierContent.md b/modules/concepts/hooks/list-of-hooks/filterSupplierContent.md index 5a5dac5b6b..8671ac09cb 100644 --- a/modules/concepts/hooks/list-of-hooks/filterSupplierContent.md +++ b/modules/concepts/hooks/list-of-hooks/filterSupplierContent.md @@ -6,9 +6,8 @@ hookTitle: Filter the content page supplier files: - controllers/front/listing/SupplierController.php locations: - - frontoffice -type: - - + - front office +type: hookAliases: --- @@ -23,14 +22,14 @@ This hook is called just before fetching content page supplier {{% /notice %}} Hook locations: - - frontoffice + - front office Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/front/listing/SupplierController.php](controllers/front/listing/SupplierController.php) This hook has a `$chain` parameter set to `true` (hook will chain the return of hook module, [see explaination here]({{< relref "/8/development/components/hook/dispatching-hook">}})). -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec( diff --git a/modules/concepts/hooks/list-of-hooks/gSitemapAppendUrls.md b/modules/concepts/hooks/list-of-hooks/gSitemapAppendUrls.md index 54f8cc1a27..2d7a0c2198 100644 --- a/modules/concepts/hooks/list-of-hooks/gSitemapAppendUrls.md +++ b/modules/concepts/hooks/list-of-hooks/gSitemapAppendUrls.md @@ -6,9 +6,8 @@ hookTitle: files: - modules/gsitemap/gsitemap.php locations: - - frontoffice -type: - - + - front office +type: hookAliases: --- @@ -17,14 +16,14 @@ hookAliases: ## Information Hook locations: - - frontoffice + - front office Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/modules/gsitemap/gsitemap.php](modules/gsitemap/gsitemap.php) This hook has an `$array_return` parameter set to `true` (module output will be set by name in an array, [see explaination here]({{< relref "/8/development/components/hook/dispatching-hook">}})). -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec(self::HOOK_ADD_URLS, array( diff --git a/modules/concepts/hooks/list-of-hooks/legacyblockkpi.md b/modules/concepts/hooks/list-of-hooks/legacyblockkpi.md index 0be777f6f1..cdb9f2fa48 100644 --- a/modules/concepts/hooks/list-of-hooks/legacyblockkpi.md +++ b/modules/concepts/hooks/list-of-hooks/legacyblockkpi.md @@ -6,9 +6,8 @@ hookTitle: files: - src/PrestaShopBundle/Resources/views/Admin/Product/CatalogPage/catalog.html.twig locations: - - backoffice -type: - - + - back office +type: hookAliases: --- @@ -17,12 +16,12 @@ hookAliases: ## Information Hook locations: - - backoffice + - back office Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Resources/views/Admin/Product/CatalogPage/catalog.html.twig](src/PrestaShopBundle/Resources/views/Admin/Product/CatalogPage/catalog.html.twig) -## Hook call in codebase +## Call of the Hook in the origin file ```php {{ renderhook('legacy_block_kpi', {'kpi_controller': 'AdminProductsController'}) }} diff --git a/modules/concepts/hooks/list-of-hooks/moduleRoutes.md b/modules/concepts/hooks/list-of-hooks/moduleRoutes.md index 52e499d0bf..5ce5b3658f 100644 --- a/modules/concepts/hooks/list-of-hooks/moduleRoutes.md +++ b/modules/concepts/hooks/list-of-hooks/moduleRoutes.md @@ -6,9 +6,8 @@ hookTitle: files: - classes/Dispatcher.php locations: - - frontoffice -type: - - + - front office +type: hookAliases: --- @@ -17,7 +16,7 @@ hookAliases: ## Information Hook locations: - - frontoffice + - front office Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Dispatcher.php](classes/Dispatcher.php) @@ -26,7 +25,7 @@ This hook has an `$array_return` parameter set to `true` (module output will be This hook has a `$check_exception` parameter set to `false` (check permission exception, [see explaination here]({{< relref "/8/development/components/hook/dispatching-hook">}})). -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('moduleRoutes', ['id_shop' => $id_shop], null, true, false) diff --git a/modules/concepts/hooks/list-of-hooks/overrideLayoutTemplate.md b/modules/concepts/hooks/list-of-hooks/overrideLayoutTemplate.md index f76747f49f..86bf845798 100644 --- a/modules/concepts/hooks/list-of-hooks/overrideLayoutTemplate.md +++ b/modules/concepts/hooks/list-of-hooks/overrideLayoutTemplate.md @@ -6,9 +6,8 @@ hookTitle: files: - classes/controller/FrontController.php locations: - - frontoffice -type: - - + - front office +type: hookAliases: --- @@ -17,12 +16,12 @@ hookAliases: ## Information Hook locations: - - frontoffice + - front office Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/FrontController.php](classes/controller/FrontController.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec( diff --git a/modules/concepts/hooks/list-of-hooks/overrideMinimalPurchasePrice.md b/modules/concepts/hooks/list-of-hooks/overrideMinimalPurchasePrice.md index 18973d3064..69ec8e1a74 100644 --- a/modules/concepts/hooks/list-of-hooks/overrideMinimalPurchasePrice.md +++ b/modules/concepts/hooks/list-of-hooks/overrideMinimalPurchasePrice.md @@ -6,9 +6,8 @@ hookTitle: files: - src/Adapter/Presenter/Cart/CartPresenter.php locations: - - frontoffice -type: - - + - front office +type: hookAliases: --- @@ -17,12 +16,12 @@ hookAliases: ## Information Hook locations: - - frontoffice + - front office Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Presenter/Cart/CartPresenter.php](src/Adapter/Presenter/Cart/CartPresenter.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('overrideMinimalPurchasePrice', [ diff --git a/modules/concepts/hooks/list-of-hooks/productSearchProvider.md b/modules/concepts/hooks/list-of-hooks/productSearchProvider.md index 8af257ba00..a13ff7b12c 100644 --- a/modules/concepts/hooks/list-of-hooks/productSearchProvider.md +++ b/modules/concepts/hooks/list-of-hooks/productSearchProvider.md @@ -6,9 +6,8 @@ hookTitle: files: - classes/controller/ProductListingFrontController.php locations: - - frontoffice -type: - - + - front office +type: hookAliases: --- @@ -17,14 +16,14 @@ hookAliases: ## Information Hook locations: - - frontoffice + - front office Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/ProductListingFrontController.php](classes/controller/ProductListingFrontController.php) This hook has an `$array_return` parameter set to `true` (module output will be set by name in an array, [see explaination here]({{< relref "/8/development/components/hook/dispatching-hook">}})). -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec( diff --git a/modules/concepts/hooks/list-of-hooks/sendMailAlterTemplateVars.md b/modules/concepts/hooks/list-of-hooks/sendMailAlterTemplateVars.md index 1b8a332801..1ac642f7c3 100644 --- a/modules/concepts/hooks/list-of-hooks/sendMailAlterTemplateVars.md +++ b/modules/concepts/hooks/list-of-hooks/sendMailAlterTemplateVars.md @@ -6,9 +6,8 @@ hookTitle: Alter template vars on the fly files: - classes/Mail.php locations: - - frontoffice -type: - - + - front office +type: hookAliases: --- @@ -23,12 +22,12 @@ This hook is called when Mail::send() is called {{% /notice %}} Hook locations: - - frontoffice + - front office Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Mail.php](classes/Mail.php) -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec( diff --git a/modules/concepts/hooks/list-of-hooks/termsAndConditions.md b/modules/concepts/hooks/list-of-hooks/termsAndConditions.md index 016593458b..1aa07e7b19 100644 --- a/modules/concepts/hooks/list-of-hooks/termsAndConditions.md +++ b/modules/concepts/hooks/list-of-hooks/termsAndConditions.md @@ -6,9 +6,8 @@ hookTitle: files: - classes/checkout/ConditionsToApproveFinder.php locations: - - frontoffice -type: - - + - front office +type: hookAliases: --- @@ -17,14 +16,14 @@ hookAliases: ## Information Hook locations: - - frontoffice + - front office Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/checkout/ConditionsToApproveFinder.php](classes/checkout/ConditionsToApproveFinder.php) This hook has an `$array_return` parameter set to `true` (module output will be set by name in an array, [see explaination here]({{< relref "/8/development/components/hook/dispatching-hook">}})). -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('termsAndConditions', [], null, true) diff --git a/modules/concepts/hooks/list-of-hooks/validateCustomerFormFields.md b/modules/concepts/hooks/list-of-hooks/validateCustomerFormFields.md index 5260067620..568a85f302 100644 --- a/modules/concepts/hooks/list-of-hooks/validateCustomerFormFields.md +++ b/modules/concepts/hooks/list-of-hooks/validateCustomerFormFields.md @@ -6,9 +6,8 @@ hookTitle: Customer registration form validation files: - classes/form/CustomerForm.php locations: - - frontoffice -type: - - + - front office +type: hookAliases: --- @@ -23,14 +22,14 @@ This hook is called to a module when it has sent additional fields with addition {{% /notice %}} Hook locations: - - frontoffice + - front office Located in: - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/form/CustomerForm.php](classes/form/CustomerForm.php) This hook has an `$array_return` parameter set to `true` (module output will be set by name in an array, [see explaination here]({{< relref "/8/development/components/hook/dispatching-hook">}})). -## Hook call in codebase +## Call of the Hook in the origin file ```php Hook::exec('validateCustomerFormFields', ['fields' => $formFields], $moduleId, true) From ab187b98cc9df08b18fbb826bf856cef1c5c61a8 Mon Sep 17 00:00:00 2001 From: Thomas Nares Date: Tue, 13 Dec 2022 17:36:24 +0400 Subject: [PATCH 163/310] Change message in hook list about generic hooks --- modules/concepts/hooks/list-of-hooks/_index.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/concepts/hooks/list-of-hooks/_index.md b/modules/concepts/hooks/list-of-hooks/_index.md index c0131d0cde..1961975e54 100644 --- a/modules/concepts/hooks/list-of-hooks/_index.md +++ b/modules/concepts/hooks/list-of-hooks/_index.md @@ -10,7 +10,8 @@ chapter: false {{% notice tip %}} **Search tip:** Some hooks are generated dynamically, so their names are documented in a generic way. -For example, `actionAdminCustomersFormModifier` is documented as `actionFormModifier`, so you won't find it if you search for the exact name. When you see a controller name or action in the hook name and you can't find it, try searching for a part of the hook name, like `FormModifier`. +For example, `actionAdminCustomersFormModifier` is documented as `actionFormModifier`. +A regex based search has been implemented, and generic hooks should be matched. However, when you see a controller name or action in the hook name and you can't find it, try searching for a part of the hook name, like `FormModifier`. {{% /notice %}}
From 490e3d9a4f65d712eaddbfd1a83a7f130d12a6b8 Mon Sep 17 00:00:00 2001 From: Thomas Nares Date: Tue, 13 Dec 2022 18:51:13 +0400 Subject: [PATCH 164/310] change FO/BO to front office / back office --- development/orders-lifecycle/_index.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/development/orders-lifecycle/_index.md b/development/orders-lifecycle/_index.md index 95b109db76..1cd186b161 100644 --- a/development/orders-lifecycle/_index.md +++ b/development/orders-lifecycle/_index.md @@ -14,7 +14,7 @@ Orders can be created from a Cart, either in Front Office (FO) by the Customer o ### Cart in Front Office (FO) -In FO by default, a new empty Cart is created in database everytime a Customer signs in - this behavior can be adjusted in BO +In Front Office by default, a new empty Cart is created in database everytime a Customer signs in - this behavior can be adjusted in BO `Configure -> Shop parameters -> Customer settings`. If Customer is not signed in (guest) - the Cart is created in database once first Product is being added into it. If guest already has a Cart and signs in, the Cart is assigned to him instead of creating a new one. @@ -28,7 +28,7 @@ flowchart LR {{% notice note %}} In FO, browser cookies are used to determine if current guest has a Cart. This way guest can still see his previous Cart if he is visiting the Shop from the same browser in a short period of time (the time depends on cookie settings, which -can be adjusted in BO `Configure -> Administration -> General "lifetime of front office cookies"`). +can be adjusted in Back Office `Configure -> Administration -> General "lifetime of front office cookies"`). {{% /notice %}} ### Cart in Back Office (BO) @@ -59,7 +59,7 @@ flowchart TB Please note that if a Cart contains only Virtual Products, there is no `checkout-addresses-step` and `checkout-delivery-step`. It goes directly from `checkout-personal-information-step` to `checkout-payment-step`. {{% /notice %}} -1. **Associate to Customer** (checkout-personal-information-step): details like name, email, birthday, etc. In FO you can either fill +1. **Associate to Customer** (checkout-personal-information-step): details like name, email, birthday, etc. In Front Office you can either fill this information manually as a guest (and optionally create a new Customer account) or log in as an existing Customer. If you create an Order from BO, you will be asked to select an existing Customer before modifying the existing Cart or creating a new one. 2. **Select shipping and invoice addresses** (checkout-addresses-step): provide the shipping and invoice addresses information. @@ -68,9 +68,9 @@ Please note that if a Cart contains only Virtual Products, there is no `checkout (the same address can also be selected for both - shipping and invoices). 3. **Select a shipping method** (checkout-delivery-step): after this step is complete, you will need to select one of the available Carriers (Carriers are searched by delivery address, sometimes the total weight of the Products, their prices, and information about the Customer (a group to which the Customer belongs) and can be modified by Shop Employees on Improve -> Shipping -> Carriers page). - Note that the Carrier will not be available if a selected country or zone is disabled (in BO International -> Locations) or Carrier shipping and locations settings are not configured. + Note that the Carrier will not be available if a selected country or zone is disabled (in Back Office International -> Locations) or Carrier shipping and locations settings are not configured. 3. **Select payment method** (checkout-payment-step): choose how to pay for the Order. Shop Employees can configure payment methods in - BO Payment -> Payment methods. + Back Office `Payment -> Payment methods`. All payments are handled by payment modules. PrestaShop comes with 3 [payment modules]({{< relref "/8/modules/payment" >}}) by default: * ps_checkpayment - allows check payments. @@ -78,7 +78,7 @@ Please note that if a Cart contains only Virtual Products, there is no `checkout * ps_cashondelivery - allows for cash on delivery payments. {{% notice note %}} -You can restrict the availability of the payment methods in FO by currencies, countries, and groups and map them to Carriers (ship2pay). You can do that in BO `Improve -> Payment -> Preferences`. +You can restrict the availability of the payment methods in Front Office by currencies, countries, and groups and map them to Carriers (ship2pay). You can do that in Back Office `Improve -> Payment -> Preferences`. {{% /notice %}} 4. **Submit Order**: Once the Order is submitted, a unique Order reference is generated, and certain records from a Cart and related @@ -97,7 +97,7 @@ At this step, some important data is duplicated (in `Order_detail`) to ensure Pr 5. After Order is successfully created, an email with the Order information is sent to the Customer. {{% notice note %}} -Email sending settings can be found in BO `Configure -> Advanced parameters -> E-mail`. Email translations and templates +Email sending settings can be found in Back Office `Configure -> Advanced parameters -> E-mail`. Email translations and templates in `Improve -> International -> Translations`. When Order is being created in BO, email with the link to a prefilled Cart can be sent before creating the Order (so the @@ -122,11 +122,11 @@ if "Payment by check" is selected, then Order will be created with the "Awaiting transfer" is selected, the status will be "Awaiting wire payment". Order status changing cycle depends on payment module. Some modules (like the default ones provided above) will require -Shop admin to control the Order status manually, which can be done in BO `Sell -> Orders -> Orders`. Other more +Shop admin to control the Order status manually, which can be done in Back Office `Sell -> Orders -> Orders`. Other more complicated payment modules, which integrates online payments in checkout process, will control the Order status automatically (e.g. when payment is done, the Order status automatically changes to "Payment accepted"). -Order statuses can be configured in BO `Shop parameters -> Order settings -> Statuses`. +Order statuses can be configured in Back Office `Shop parameters -> Order settings -> Statuses`. {{% notice note %}} From 9bb9a0fc5a8836d3b30f051197189799c5d15791 Mon Sep 17 00:00:00 2001 From: Thomas Nares Date: Tue, 13 Dec 2022 18:59:19 +0400 Subject: [PATCH 165/310] change FO/BO to front office / back office --- development/orders-lifecycle/_index.md | 32 +++++++++++++------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/development/orders-lifecycle/_index.md b/development/orders-lifecycle/_index.md index 1cd186b161..fa28098092 100644 --- a/development/orders-lifecycle/_index.md +++ b/development/orders-lifecycle/_index.md @@ -12,9 +12,9 @@ Orders can be created from a Cart, either in Front Office (FO) by the Customer o ## Carts -### Cart in Front Office (FO) +### Cart in Front Office -In Front Office by default, a new empty Cart is created in database everytime a Customer signs in - this behavior can be adjusted in BO +In Front Office by default, a new empty Cart is created in database everytime a Customer signs in - this behavior can be adjusted in Back Office `Configure -> Shop parameters -> Customer settings`. If Customer is not signed in (guest) - the Cart is created in database once first Product is being added into it. If guest already has a Cart and signs in, the Cart is assigned to him instead of creating a new one. @@ -26,20 +26,20 @@ flowchart LR
{{% notice note %}} -In FO, browser cookies are used to determine if current guest has a Cart. This way guest can still see his previous Cart +In Front Office , browser cookies are used to determine if current guest has a Cart. This way guest can still see his previous Cart if he is visiting the Shop from the same browser in a short period of time (the time depends on cookie settings, which can be adjusted in Back Office `Configure -> Administration -> General "lifetime of front office cookies"`). {{% /notice %}} -### Cart in Back Office (BO) +### Cart in Back Office -When creating an Order in the BO, a new empty Cart is created once the Customer is selected. You can also choose an existing Cart (already associated with the Customer) or an existing Order on which the new Cart will base. +When creating an Order in the Back Office , a new empty Cart is created once the Customer is selected. You can also choose an existing Cart (already associated with the Customer) or an existing Order on which the new Cart will base.
flowchart LR - A{{Select Customer}}-->|Create new Cart|E{{Cart creation}}-->G + A{{Select Customer}}-->|Create new Cart|E{{Cart: creation}}-->G A-->|Use existing Cart|B{{Select existing Cart}}-->F - A-->|Create new Cart from Order|C{{Select existing Order}}-->D{{Cart creation from Order content}}-->G{{Associate Cart to Customer}}-->F(Associated Cart) + A-->|Create new Cart from Order|C{{Select existing Order}}-->D{{Cart: creation from Order content}}-->G{{Associate Cart to Customer}}-->F(Cart: associated to Customer)
## The Checkout: from Cart to Order @@ -48,10 +48,10 @@ For a Cart to convert to an Order, the following steps need to be completed:
flowchart TB - A(Cart)-->|checkout-personal-information-step|B(Cart associated) - B-->|checkout-addresses-step|C(Cart addressed) - C-->|checkout-delivery-step|D(Cart shipping configured) - D-->|checkout-payment-step|E(Cart payment configured) + A(Cart)-->|checkout-personal-information-step|B(Cart: associated to Customer) + B-->|checkout-addresses-step|C(Cart: address added) + C-->|checkout-delivery-step|D(Cart: shipping method selected) + D-->|checkout-payment-step|E(Cart: payment method selected) E-->|Submit Order|F(Order)
@@ -61,10 +61,10 @@ Please note that if a Cart contains only Virtual Products, there is no `checkout 1. **Associate to Customer** (checkout-personal-information-step): details like name, email, birthday, etc. In Front Office you can either fill this information manually as a guest (and optionally create a new Customer account) or log in as an existing Customer. - If you create an Order from BO, you will be asked to select an existing Customer before modifying the existing Cart or creating a new one. + If you create an Order from Back Office , you will be asked to select an existing Customer before modifying the existing Cart or creating a new one. 2. **Select shipping and invoice addresses** (checkout-addresses-step): provide the shipping and invoice addresses information. The shipping (a.k.a. delivery) address is where the Ordered Products should be sent, while the invoice address is used as a document billing address. - In FO, you can provide one address to be used as both - shipping and invoice. In BO, you must select shipping and invoice addresses + In Front Office , you can provide one address to be used as both - shipping and invoice. In Back Office , you must select shipping and invoice addresses (the same address can also be selected for both - shipping and invoices). 3. **Select a shipping method** (checkout-delivery-step): after this step is complete, you will need to select one of the available Carriers (Carriers are searched by delivery address, sometimes the total weight of the Products, their prices, and information about the Customer (a group to which the Customer belongs) and can be modified by Shop Employees on Improve -> Shipping -> Carriers page). @@ -100,7 +100,7 @@ At this step, some important data is duplicated (in `Order_detail`) to ensure Pr Email sending settings can be found in Back Office `Configure -> Advanced parameters -> E-mail`. Email translations and templates in `Improve -> International -> Translations`. -When Order is being created in BO, email with the link to a prefilled Cart can be sent before creating the Order (so the +When Order is being created in Back Office , email with the link to a prefilled Cart can be sent before creating the Order (so the Customer can finish up the checkout process). To do that click `More actions -> Send pre-filled Order to the Customer by email` in summary block. {{% /notice %}} @@ -117,7 +117,7 @@ Learn how it works under the hood by looking at: ## Order status -When creating Order from the FO, the initial Order status will differ depending on selected payment method. For example, +When creating Order from the Front Office , the initial Order status will differ depending on selected payment method. For example, if "Payment by check" is selected, then Order will be created with the "Awaiting check payment" status, or if "Bank transfer" is selected, the status will be "Awaiting wire payment". @@ -130,6 +130,6 @@ Order statuses can be configured in Back Office `Shop parameters -> Order settin {{% notice note %}} -When creating Order from the BO, the initial Order status must be selected manually. +When creating Order from the Back Office , the initial Order status must be selected manually. {{% /notice %}} \ No newline at end of file From 33104100afaebf8eb43c58040a6328be3ed542d6 Mon Sep 17 00:00:00 2001 From: Thomas Nares Date: Tue, 13 Dec 2022 19:31:38 +0400 Subject: [PATCH 166/310] explain PS_CART_FOLLOWING --- development/orders-lifecycle/_index.md | 29 +++++++++++++++----------- 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/development/orders-lifecycle/_index.md b/development/orders-lifecycle/_index.md index fa28098092..88c347ae5d 100644 --- a/development/orders-lifecycle/_index.md +++ b/development/orders-lifecycle/_index.md @@ -14,26 +14,31 @@ Orders can be created from a Cart, either in Front Office (FO) by the Customer o ### Cart in Front Office -In Front Office by default, a new empty Cart is created in database everytime a Customer signs in - this behavior can be adjusted in Back Office -`Configure -> Shop parameters -> Customer settings`. If Customer is not signed in (guest) - the Cart is created in database once -first Product is being added into it. If guest already has a Cart and signs in, the Cart is assigned to him instead of -creating a new one. +The Cart is created in database once first Product is being added into it. +- If Customer is not signed in (Guest), and he adds a Product to Cart, the Cart is created, but not associated to a Customer. +- If a Guest already has a Cart and signs in, the Cart is assigned to him instead of creating a new one. + +{{% notice note %}} +When a Customer signs-in, has an empty Cart in its Cookie (or does not have a Cart) and has a previous non ordered Cart in its profile, the default behaviour of PrestaShop is to reload its most recent non ordered Cart. That behaviour can be adjusted in `Configure -> Shop parameters -> Customer settings`, the related setting is `PS_CART_FOLLOWING` : `Re-display cart at login`. +This setting is implemented in: [Context.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Context.php#L365). +{{% /notice %}}
flowchart LR A(Guest with empty Cart)-->|Add item to Cart|B{{Cart creation}}-->C(Cart)-->|Login|D{{Associate Cart to Customer}}-->F - A-->|Login|G{{Cart creation}}-->E{{Associate Cart to Customer}}-->F(Associated Cart) + A-->|Login|G{PS_CART_FOLLOWING
and
has non ordered Cart}-->|No|E{{Cart will be created later when a product is added}} + G-->|Yes|F(Cart: Associated to Customer)
{{% notice note %}} -In Front Office , browser cookies are used to determine if current guest has a Cart. This way guest can still see his previous Cart +In Front Office, browser cookies are used to determine if current guest has a Cart. This way guest can still see his previous Cart if he is visiting the Shop from the same browser in a short period of time (the time depends on cookie settings, which can be adjusted in Back Office `Configure -> Administration -> General "lifetime of front office cookies"`). {{% /notice %}} ### Cart in Back Office -When creating an Order in the Back Office , a new empty Cart is created once the Customer is selected. You can also choose an existing Cart (already associated with the Customer) or an existing Order on which the new Cart will base. +When creating an Order in the Back Office, a new empty Cart is created once the Customer is selected. You can also choose an existing Cart (already associated with the Customer) or an existing Order on which the new Cart will base.
flowchart LR @@ -61,10 +66,10 @@ Please note that if a Cart contains only Virtual Products, there is no `checkout 1. **Associate to Customer** (checkout-personal-information-step): details like name, email, birthday, etc. In Front Office you can either fill this information manually as a guest (and optionally create a new Customer account) or log in as an existing Customer. - If you create an Order from Back Office , you will be asked to select an existing Customer before modifying the existing Cart or creating a new one. + If you create an Order from Back Office, you will be asked to select an existing Customer before modifying the existing Cart or creating a new one. 2. **Select shipping and invoice addresses** (checkout-addresses-step): provide the shipping and invoice addresses information. The shipping (a.k.a. delivery) address is where the Ordered Products should be sent, while the invoice address is used as a document billing address. - In Front Office , you can provide one address to be used as both - shipping and invoice. In Back Office , you must select shipping and invoice addresses + In Front Office, you can provide one address to be used as both - shipping and invoice. In Back Office, you must select shipping and invoice addresses (the same address can also be selected for both - shipping and invoices). 3. **Select a shipping method** (checkout-delivery-step): after this step is complete, you will need to select one of the available Carriers (Carriers are searched by delivery address, sometimes the total weight of the Products, their prices, and information about the Customer (a group to which the Customer belongs) and can be modified by Shop Employees on Improve -> Shipping -> Carriers page). @@ -100,7 +105,7 @@ At this step, some important data is duplicated (in `Order_detail`) to ensure Pr Email sending settings can be found in Back Office `Configure -> Advanced parameters -> E-mail`. Email translations and templates in `Improve -> International -> Translations`. -When Order is being created in Back Office , email with the link to a prefilled Cart can be sent before creating the Order (so the +When Order is being created in Back Office, email with the link to a prefilled Cart can be sent before creating the Order (so the Customer can finish up the checkout process). To do that click `More actions -> Send pre-filled Order to the Customer by email` in summary block. {{% /notice %}} @@ -117,7 +122,7 @@ Learn how it works under the hood by looking at: ## Order status -When creating Order from the Front Office , the initial Order status will differ depending on selected payment method. For example, +When creating Order from the Front Office, the initial Order status will differ depending on selected payment method. For example, if "Payment by check" is selected, then Order will be created with the "Awaiting check payment" status, or if "Bank transfer" is selected, the status will be "Awaiting wire payment". @@ -130,6 +135,6 @@ Order statuses can be configured in Back Office `Shop parameters -> Order settin {{% notice note %}} -When creating Order from the Back Office , the initial Order status must be selected manually. +When creating Order from the Back Office, the initial Order status must be selected manually. {{% /notice %}} \ No newline at end of file From f11e5c5d4125130e623a612008322273bf184aec Mon Sep 17 00:00:00 2001 From: leemyongpakvn Date: Thu, 15 Dec 2022 12:36:29 +0700 Subject: [PATCH 167/310] PrestaShop 8.0 is using Doctrine version 2.7 --- modules/concepts/doctrine/_index.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/concepts/doctrine/_index.md b/modules/concepts/doctrine/_index.md index f2f1223e2b..5b430c323d 100644 --- a/modules/concepts/doctrine/_index.md +++ b/modules/concepts/doctrine/_index.md @@ -9,11 +9,11 @@ weight: 5 From the 1.7.6 version of PrestaShop we integrate support of Doctrine services and entities for modules. Doctrine is a powerful ORM allowing you to manage your database data via objects. It offers an abstract layer allowing you to perform insert/update actions via a simple `$entity->setData('update')` call. But you can also create your own repositories to fetch -specific data via left join, add conditions and so on... +specific data via left join, add conditions and so on ... Doctrine is the default ORM integrated with Symfony which is why we added it for modules in legacy context. If you want -more details about Doctrine and its features you can check [their documentation](https://www.doctrine-project.org/projects/doctrine-orm/en/2.5/index.html) -or the [Symfony documentation](https://symfony.com/doc/4.4/doctrine.html). PrestaShop is currently using Doctrine version 2.5. +more details about Doctrine and its features you can check [their documentation](https://www.doctrine-project.org/projects/doctrine-orm/en/2.7/index.html) +or the [Symfony documentation](https://symfony.com/doc/4.4/doctrine.html). PrestaShop is currently using Doctrine version 2.7. ## Module integration From 9ba3978380c083045979f4600bb772270d8554b0 Mon Sep 17 00:00:00 2001 From: leemyongpakvn Date: Thu, 15 Dec 2022 12:46:33 +0700 Subject: [PATCH 168/310] switch to 8.x branch --- .../doctrine/how-to-handle-multi-lang-doctrine-entity.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/concepts/doctrine/how-to-handle-multi-lang-doctrine-entity.md b/modules/concepts/doctrine/how-to-handle-multi-lang-doctrine-entity.md index 00a0bb1481..5688651dc7 100644 --- a/modules/concepts/doctrine/how-to-handle-multi-lang-doctrine-entity.md +++ b/modules/concepts/doctrine/how-to-handle-multi-lang-doctrine-entity.md @@ -25,7 +25,7 @@ There are several Doctrine plugins which allows to handle multi lang fields easi {{% notice note %}} **Namespace and autoload** -The content of this documentation relies on **namespaces** which need to be defined in your module's autoload, we won't cover this part here if you need more information please read [how to setup composer in a module]({{< ref "1.7/modules/concepts/composer#setup-composer-in-a-module" >}}) +The content of this documentation relies on **namespaces** which need to be defined in your module's autoload, we won't cover this part here if you need more information please read [how to setup composer in a module]({{< ref "8/modules/concepts/composer#setup-composer-in-a-module" >}}) {{% /notice %}} {{% notice tip %}} From 28a6791c9a793fb3f73ff1550be7ff16399368cb Mon Sep 17 00:00:00 2001 From: Thomas Nares Date: Thu, 15 Dec 2022 15:11:04 +0400 Subject: [PATCH 169/310] Fix inverted markdown links --- .../hooks/list-of-hooks/actionAfter.md | 2 +- .../hooks/list-of-hooks/actionBefore.md | 2 +- .../hooks/list-of-hooks/actionFormModifier.md | 2 +- .../list-of-hooks/actionListingFieldsModifier.md | 2 +- .../list-of-hooks/actionListingResultsModifier.md | 2 +- .../hooks/list-of-hooks/actionOptionsModifier.md | 2 +- .../list-of-hooks/actionGridPresenterModifier.md | 2 +- .../actionFormDataProviderDefaultData.md | 2 +- .../actionListingFieldsModifier.md | 2 +- .../actionListingResultsModifier.md | 2 +- .../concepts/hooks/list-of-hooks/actionAdminAfter.md | 2 +- .../concepts/hooks/list-of-hooks/actionAdminBefore.md | 2 +- .../concepts/hooks/list-of-hooks/actionAdminActivateAfter.md | 2 +- .../concepts/hooks/list-of-hooks/actionAdminActivateBefore.md | 2 +- ...onAdminAdminShopParametersMetaControllerPostProcessBefore.md | 2 +- .../actionAdminAdminWebserviceControllerPostProcessBefore.md | 2 +- ...nAdminAdministrationControllerPostProcessBefore.md | 2 +- .../actionAdminAdministrationControllerPostProcessBefore.md | 2 +- ...arametersPerformanceControllerPostProcessBefore.md | 2 +- ...nAdvancedParametersPerformanceControllerPostProcessBefore.md | 2 +- .../hooks/list-of-hooks/actionAdminControllerInitAfter.md | 2 +- .../hooks/list-of-hooks/actionAdminControllerInitBefore.md | 2 +- .../hooks/list-of-hooks/actionAdminControllerSetMedia.md | 2 +- .../concepts/hooks/list-of-hooks/actionAdminDeactivateAfter.md | 2 +- .../concepts/hooks/list-of-hooks/actionAdminDeactivateBefore.md | 2 +- modules/concepts/hooks/list-of-hooks/actionAdminDeleteAfter.md | 2 +- modules/concepts/hooks/list-of-hooks/actionAdminDeleteBefore.md | 2 +- .../concepts/hooks/list-of-hooks/actionAdminDuplicateAfter.md | 2 +- .../concepts/hooks/list-of-hooks/actionAdminDuplicateBefore.md | 2 +- ...rnationalGeolocationControllerPostProcessBefore.md | 2 +- ...nAdminInternationalGeolocationControllerPostProcessBefore.md | 2 +- ...nationalLocalizationControllerPostProcessBefore.md | 2 +- ...AdminInternationalLocalizationControllerPostProcessBefore.md | 2 +- .../hooks/list-of-hooks/actionAdminLoginControllerBefore.md | 2 +- .../list-of-hooks/actionAdminLoginControllerForgotAfter.md | 2 +- .../list-of-hooks/actionAdminLoginControllerForgotBefore.md | 2 +- .../hooks/list-of-hooks/actionAdminLoginControllerLoginAfter.md | 2 +- .../list-of-hooks/actionAdminLoginControllerLoginBefore.md | 2 +- .../hooks/list-of-hooks/actionAdminLoginControllerResetAfter.md | 2 +- .../list-of-hooks/actionAdminLoginControllerResetBefore.md | 2 +- .../hooks/list-of-hooks/actionAdminLoginControllerSetMedia.md | 2 +- .../list-of-hooks/actionAdminLogsControllerPostProcessBefore.md | 2 +- .../actionAdminMaintenanceControllerPostProcessBefore.md | 2 +- .../hooks/list-of-hooks/actionAdminMetaAfterWriteRobotsFile.md | 2 +- .../hooks/list-of-hooks/actionAdminMetaBeforeWriteRobotsFile.md | 2 +- modules/concepts/hooks/list-of-hooks/actionAdminMetaSave.md | 2 +- .../list-of-hooks/actionAdminOrdersTrackingNumberUpdate.md | 2 +- .../actionAdminPreferencesControllerPostProcessBefore.md | 2 +- .../list-of-hooks/actionAdminProductsControllerActivateAfter.md | 2 +- .../actionAdminProductsControllerActivateBefore.md | 2 +- .../actionAdminProductsControllerDeactivateAfter.md | 2 +- .../actionAdminProductsControllerDeactivateBefore.md | 2 +- .../list-of-hooks/actionAdminProductsControllerDeleteAfter.md | 2 +- .../list-of-hooks/actionAdminProductsControllerDeleteBefore.md | 2 +- .../actionAdminProductsControllerDuplicateAfter.md | 2 +- .../actionAdminProductsControllerDuplicateBefore.md | 2 +- .../list-of-hooks/actionAdminProductsControllerSortAfter.md | 2 +- .../list-of-hooks/actionAdminProductsControllerSortBefore.md | 2 +- .../list-of-hooks/actionAdminProductsListingFieldsModifier.md | 2 +- .../list-of-hooks/actionAdminProductsListingResultsModifier.md | 2 +- .../actionAdminSecurityControllerPostProcessBefore.md | 2 +- ...actionAdminShippingPreferencesControllerPostProcessBefore.md | 2 +- ...ppingPreferencesControllerPostProcessCarrierOptionsBefore.md | 2 +- ...minShippingPreferencesControllerPostProcessHandlingBefore.md | 2 +- ...inShopParametersMetaControllerPostProcessBefore.md | 2 +- ...tersOrderPreferencesControllerPostProcessBefore.md | 2 +- ...ShopParametersOrderPreferencesControllerPostProcessBefore.md | 2 +- ...rsProductPreferencesControllerPostProcessBefore.md | 2 +- ...opParametersProductPreferencesControllerPostProcessBefore.md | 2 +- modules/concepts/hooks/list-of-hooks/actionAdminSortAfter.md | 2 +- modules/concepts/hooks/list-of-hooks/actionAdminSortBefore.md | 2 +- .../actionAdminThemesControllerUpdateoptionsAfter.md | 2 +- .../list-of-hooks/actionAfterCreateFormHandler.md | 2 +- .../list-of-hooks/actionAfterUpdateFormHandler.md | 2 +- .../list-of-hooks/actionAjaxDieBefore.md | 2 +- modules/concepts/hooks/list-of-hooks/actionAjaxDieBefore.md | 2 +- .../hooks/list-of-hooks/actionAttributeCombinationDelete.md | 2 +- .../hooks/list-of-hooks/actionAttributeCombinationSave.md | 2 +- modules/concepts/hooks/list-of-hooks/actionAttributeDelete.md | 2 +- .../concepts/hooks/list-of-hooks/actionAttributeGroupDelete.md | 2 +- .../concepts/hooks/list-of-hooks/actionAttributeGroupSave.md | 2 +- modules/concepts/hooks/list-of-hooks/actionAttributeSave.md | 2 +- modules/concepts/hooks/list-of-hooks/actionAuthentication.md | 2 +- .../concepts/hooks/list-of-hooks/actionAuthenticationBefore.md | 2 +- .../list-of-hooks/actionBeforeAjaxDie.md | 2 +- .../list-of-hooks/actionBeforeCreateFormHandler.md | 2 +- .../list-of-hooks/actionBeforeUpdateFormHandler.md | 2 +- .../concepts/hooks/list-of-hooks/actionBuildFrontEndObject.md | 2 +- .../hooks/list-of-hooks/actionBuildMailLayoutVariables.md | 2 +- modules/concepts/hooks/list-of-hooks/actionCarrierProcess.md | 2 +- modules/concepts/hooks/list-of-hooks/actionCarrierUpdate.md | 2 +- modules/concepts/hooks/list-of-hooks/actionCartSave.md | 2 +- modules/concepts/hooks/list-of-hooks/actionCartSummary.md | 2 +- .../hooks/list-of-hooks/actionCartUpdateQuantityBefore.md | 2 +- modules/concepts/hooks/list-of-hooks/actionCategoryAdd.md | 2 +- modules/concepts/hooks/list-of-hooks/actionCategoryDelete.md | 2 +- modules/concepts/hooks/list-of-hooks/actionCategoryUpdate.md | 2 +- modules/concepts/hooks/list-of-hooks/actionCheckoutRender.md | 2 +- modules/concepts/hooks/list-of-hooks/actionClearCache.md | 2 +- modules/concepts/hooks/list-of-hooks/actionClearCompileCache.md | 2 +- modules/concepts/hooks/list-of-hooks/actionClearSf2Cache.md | 2 +- .../concepts/hooks/list-of-hooks/actionControllerInitAfter.md | 2 +- .../concepts/hooks/list-of-hooks/actionControllerInitBefore.md | 2 +- .../concepts/hooks/list-of-hooks/actionCustomerAccountAdd.md | 2 +- .../concepts/hooks/list-of-hooks/actionCustomerAccountUpdate.md | 2 +- modules/concepts/hooks/list-of-hooks/actionCustomerAddGroups.md | 2 +- .../hooks/list-of-hooks/actionCustomerBeforeUpdateGroup.md | 2 +- .../concepts/hooks/list-of-hooks/actionCustomerLogoutAfter.md | 2 +- .../concepts/hooks/list-of-hooks/actionCustomerLogoutBefore.md | 2 +- .../concepts/hooks/list-of-hooks/actionDeleteGDPRCustomer.md | 2 +- .../concepts/hooks/list-of-hooks/actionDeliveryPriceByPrice.md | 2 +- .../concepts/hooks/list-of-hooks/actionDeliveryPriceByWeight.md | 2 +- modules/concepts/hooks/list-of-hooks/actionDispatcher.md | 2 +- modules/concepts/hooks/list-of-hooks/actionDispatcherAfter.md | 2 +- modules/concepts/hooks/list-of-hooks/actionDispatcherBefore.md | 2 +- .../concepts/hooks/list-of-hooks/actionDownloadAttachment.md | 2 +- .../concepts/hooks/list-of-hooks/actionEmailAddAfterContent.md | 2 +- .../concepts/hooks/list-of-hooks/actionEmailAddBeforeContent.md | 2 +- modules/concepts/hooks/list-of-hooks/actionEmailSendBefore.md | 2 +- modules/concepts/hooks/list-of-hooks/actionExportGDPRData.md | 2 +- modules/concepts/hooks/list-of-hooks/actionFeatureDelete.md | 2 +- modules/concepts/hooks/list-of-hooks/actionFeatureSave.md | 2 +- .../concepts/hooks/list-of-hooks/actionFeatureValueDelete.md | 2 +- modules/concepts/hooks/list-of-hooks/actionFeatureValueSave.md | 2 +- .../hooks/list-of-hooks/actionFilterDeliveryOptionList.md | 2 +- .../hooks/list-of-hooks/actionFrontControllerInitAfter.md | 2 +- .../hooks/list-of-hooks/actionFrontControllerInitBefore.md | 2 +- .../hooks/list-of-hooks/actionFrontControllerSetMedia.md | 2 +- .../hooks/list-of-hooks/actionFrontControllerSetVariables.md | 2 +- .../concepts/hooks/list-of-hooks/actionGetAdminOrderButtons.md | 2 +- .../hooks/list-of-hooks/actionGetAdminToolbarButtons.md | 2 +- .../hooks/list-of-hooks/actionGetAlternativeSearchPanels.md | 2 +- .../hooks/list-of-hooks/actionGetExtraMailTemplateVars.md | 2 +- .../concepts/hooks/list-of-hooks/actionGetIDZoneByAddressID.md | 2 +- .../hooks/list-of-hooks/actionGetMailLayoutTransformations.md | 2 +- .../hooks/list-of-hooks/actionGetProductPropertiesAfter.md | 2 +- .../list-of-hooks/actionGetProductPropertiesAfterUnitPrice.md | 2 +- .../hooks/list-of-hooks/actionGetProductPropertiesBefore.md | 2 +- modules/concepts/hooks/list-of-hooks/actionHtaccessCreate.md | 2 +- .../hooks/list-of-hooks/actionInvoiceNumberFormatted.md | 2 +- modules/concepts/hooks/list-of-hooks/actionListMailThemes.md | 2 +- .../hooks/list-of-hooks/actionMailAlterMessageBeforeSend.md | 2 +- .../concepts/hooks/list-of-hooks/actionModuleInstallAfter.md | 2 +- .../concepts/hooks/list-of-hooks/actionModuleInstallBefore.md | 2 +- .../hooks/list-of-hooks/actionModuleMailAlertSendCustomer.md | 2 +- .../hooks/list-of-hooks/actionModuleRegisterHookAfter.md | 2 +- .../hooks/list-of-hooks/actionModuleRegisterHookBefore.md | 2 +- .../hooks/list-of-hooks/actionModuleUnRegisterHookAfter.md | 2 +- .../hooks/list-of-hooks/actionModuleUnRegisterHookBefore.md | 2 +- .../concepts/hooks/list-of-hooks/actionModuleUninstallAfter.md | 2 +- .../concepts/hooks/list-of-hooks/actionModuleUninstallBefore.md | 2 +- .../hooks/list-of-hooks/actionNewsletterRegistrationAfter.md | 2 +- .../hooks/list-of-hooks/actionNewsletterRegistrationBefore.md | 2 +- .../hooks/list-of-hooks/actionObjectAddAfter.md | 2 +- .../hooks/list-of-hooks/actionObjectAddBefore.md | 2 +- .../hooks/list-of-hooks/actionObjectDeleteAfter.md | 2 +- .../hooks/list-of-hooks/actionObjectDeleteBefore.md | 2 +- .../hooks/list-of-hooks/actionObjectUpdateAfter.md | 2 +- .../hooks/list-of-hooks/actionObjectUpdateBefore.md | 2 +- modules/concepts/hooks/list-of-hooks/actionObjectAddAfter.md | 2 +- modules/concepts/hooks/list-of-hooks/actionObjectAddBefore.md | 2 +- .../hooks/list-of-hooks/actionObjectAttributeAddBefore.md | 2 +- .../hooks/list-of-hooks/actionObjectAttributeGroupAddBefore.md | 2 +- modules/concepts/hooks/list-of-hooks/actionObjectDeleteAfter.md | 2 +- .../concepts/hooks/list-of-hooks/actionObjectDeleteBefore.md | 2 +- .../list-of-hooks/actionObjectProductCommentValidateAfter.md | 2 +- .../hooks/list-of-hooks/actionObjectProductInCartDeleteAfter.md | 2 +- .../list-of-hooks/actionObjectProductInCartDeleteBefore.md | 2 +- modules/concepts/hooks/list-of-hooks/actionObjectUpdateAfter.md | 2 +- .../concepts/hooks/list-of-hooks/actionObjectUpdateBefore.md | 2 +- modules/concepts/hooks/list-of-hooks/actionOnImageCutAfter.md | 2 +- .../concepts/hooks/list-of-hooks/actionOnImageResizeAfter.md | 2 +- modules/concepts/hooks/list-of-hooks/actionOrderEdited.md | 2 +- .../concepts/hooks/list-of-hooks/actionOrderHistoryAddAfter.md | 2 +- modules/concepts/hooks/list-of-hooks/actionOrderReturn.md | 2 +- modules/concepts/hooks/list-of-hooks/actionOrderSlipAdd.md | 2 +- .../concepts/hooks/list-of-hooks/actionOrderStatusPostUpdate.md | 2 +- modules/concepts/hooks/list-of-hooks/actionOrderStatusUpdate.md | 2 +- modules/concepts/hooks/list-of-hooks/actionOutputHTMLBefore.md | 2 +- .../concepts/hooks/list-of-hooks/actionOverrideEmployeeImage.md | 2 +- modules/concepts/hooks/list-of-hooks/actionPDFInvoiceRender.md | 2 +- modules/concepts/hooks/list-of-hooks/actionPasswordRenew.md | 2 +- modules/concepts/hooks/list-of-hooks/actionPaymentCCAdd.md | 2 +- .../concepts/hooks/list-of-hooks/actionPaymentConfirmation.md | 2 +- modules/concepts/hooks/list-of-hooks/actionPresentCart.md | 2 +- modules/concepts/hooks/list-of-hooks/actionPresentModule.md | 2 +- modules/concepts/hooks/list-of-hooks/actionPresentOrder.md | 2 +- .../concepts/hooks/list-of-hooks/actionPresentOrderReturn.md | 2 +- .../concepts/hooks/list-of-hooks/actionPresentPaymentOptions.md | 2 +- modules/concepts/hooks/list-of-hooks/actionPresentProduct.md | 2 +- .../concepts/hooks/list-of-hooks/actionPresentProductListing.md | 2 +- modules/concepts/hooks/list-of-hooks/actionProductActivation.md | 2 +- modules/concepts/hooks/list-of-hooks/actionProductAdd.md | 2 +- .../hooks/list-of-hooks/actionProductAttributeDelete.md | 2 +- .../hooks/list-of-hooks/actionProductAttributeUpdate.md | 2 +- modules/concepts/hooks/list-of-hooks/actionProductCancel.md | 2 +- modules/concepts/hooks/list-of-hooks/actionProductCoverage.md | 2 +- modules/concepts/hooks/list-of-hooks/actionProductDelete.md | 2 +- modules/concepts/hooks/list-of-hooks/actionProductOutOfStock.md | 2 +- modules/concepts/hooks/list-of-hooks/actionProductSave.md | 2 +- .../concepts/hooks/list-of-hooks/actionProductSearchAfter.md | 2 +- .../list-of-hooks/actionProductSearchProviderRunQueryAfter.md | 2 +- .../list-of-hooks/actionProductSearchProviderRunQueryBefore.md | 2 +- modules/concepts/hooks/list-of-hooks/actionProductUpdate.md | 2 +- modules/concepts/hooks/list-of-hooks/actionSearch.md | 2 +- modules/concepts/hooks/list-of-hooks/actionSetInvoice.md | 2 +- .../concepts/hooks/list-of-hooks/actionShopDataDuplication.md | 2 +- .../concepts/hooks/list-of-hooks/actionSubmitAccountBefore.md | 2 +- .../hooks/list-of-hooks/actionSubmitCustomerAddressForm.md | 2 +- modules/concepts/hooks/list-of-hooks/actionUpdateLangAfter.md | 2 +- modules/concepts/hooks/list-of-hooks/actionUpdateQuantity.md | 2 +- .../hooks/list-of-hooks/actionValidateCustomerAddressForm.md | 2 +- modules/concepts/hooks/list-of-hooks/actionValidateOrder.md | 2 +- .../concepts/hooks/list-of-hooks/actionValidateOrderAfter.md | 2 +- .../concepts/hooks/list-of-hooks/actionValidateStepComplete.md | 2 +- modules/concepts/hooks/list-of-hooks/actionWatermark.md | 2 +- .../concepts/hooks/list-of-hooks/actionWishlistAddProduct.md | 2 +- modules/concepts/hooks/list-of-hooks/addWebserviceResources.md | 2 +- .../hooks/list-of-hooks/additionalCustomerAddressFields.md | 2 +- .../hooks/list-of-hooks/additionalCustomerFormFields.md | 2 +- modules/concepts/hooks/list-of-hooks/dashboardData.md | 2 +- modules/concepts/hooks/list-of-hooks/dashboardZoneOne.md | 2 +- modules/concepts/hooks/list-of-hooks/dashboardZoneThree.md | 2 +- modules/concepts/hooks/list-of-hooks/dashboardZoneTwo.md | 2 +- modules/concepts/hooks/list-of-hooks/deleteProductAttribute.md | 2 +- .../list-of-hooks/displayAdditionalCustomerAddressFields.md | 2 +- modules/concepts/hooks/list-of-hooks/displayAdminAfterHeader.md | 2 +- modules/concepts/hooks/list-of-hooks/displayAdminCustomers.md | 2 +- modules/concepts/hooks/list-of-hooks/displayAdminEndContent.md | 2 +- modules/concepts/hooks/list-of-hooks/displayAdminForm.md | 2 +- .../concepts/hooks/list-of-hooks/displayAdminGridTableAfter.md | 2 +- .../concepts/hooks/list-of-hooks/displayAdminGridTableBefore.md | 2 +- modules/concepts/hooks/list-of-hooks/displayAdminListAfter.md | 2 +- modules/concepts/hooks/list-of-hooks/displayAdminListBefore.md | 2 +- .../concepts/hooks/list-of-hooks/displayAdminNavBarBeforeEnd.md | 2 +- modules/concepts/hooks/list-of-hooks/displayAdminOptions.md | 2 +- modules/concepts/hooks/list-of-hooks/displayAdminOrder.md | 2 +- .../hooks/list-of-hooks/displayAdminOrderCreateExtraButtons.md | 2 +- modules/concepts/hooks/list-of-hooks/displayAdminOrderMain.md | 2 +- .../concepts/hooks/list-of-hooks/displayAdminOrderMainBottom.md | 2 +- modules/concepts/hooks/list-of-hooks/displayAdminOrderSide.md | 2 +- .../concepts/hooks/list-of-hooks/displayAdminOrderSideBottom.md | 2 +- .../list-of-hooks/displayAdminProductsCombinationBottom.md | 2 +- .../displayAdminProductsMainStepLeftColumnBottom.md | 2 +- .../displayAdminProductsMainStepLeftColumnMiddle.md | 2 +- .../displayAdminProductsMainStepRightColumnBottom.md | 2 +- .../list-of-hooks/displayAdminProductsOptionsStepBottom.md | 2 +- .../hooks/list-of-hooks/displayAdminProductsOptionsStepTop.md | 2 +- .../hooks/list-of-hooks/displayAdminProductsPriceStepBottom.md | 2 +- .../list-of-hooks/displayAdminProductsQuantitiesStepBottom.md | 2 +- .../hooks/list-of-hooks/displayAdminProductsSeoStepBottom.md | 2 +- .../list-of-hooks/displayAdminProductsShippingStepBottom.md | 2 +- .../concepts/hooks/list-of-hooks/displayAdminStatsModules.md | 2 +- .../concepts/hooks/list-of-hooks/displayAdminThemesListAfter.md | 2 +- modules/concepts/hooks/list-of-hooks/displayAdminView.md | 2 +- .../concepts/hooks/list-of-hooks/displayAfterBodyOpeningTag.md | 2 +- modules/concepts/hooks/list-of-hooks/displayAfterCarrier.md | 2 +- .../concepts/hooks/list-of-hooks/displayAfterProductThumbs.md | 2 +- modules/concepts/hooks/list-of-hooks/displayAfterTitleTag.md | 2 +- .../concepts/hooks/list-of-hooks/displayBackOfficeCategory.md | 2 +- .../hooks/list-of-hooks/displayBackOfficeEmployeeMenu.md | 2 +- modules/concepts/hooks/list-of-hooks/displayBackOfficeHeader.md | 2 +- modules/concepts/hooks/list-of-hooks/displayBackOfficeTop.md | 2 +- modules/concepts/hooks/list-of-hooks/displayBanner.md | 2 +- .../concepts/hooks/list-of-hooks/displayBeforeBodyClosingTag.md | 2 +- modules/concepts/hooks/list-of-hooks/displayBeforeCarrier.md | 2 +- .../hooks/list-of-hooks/displayCMSDisputeInformation.md | 2 +- modules/concepts/hooks/list-of-hooks/displayCMSPrintButton.md | 2 +- .../concepts/hooks/list-of-hooks/displayCarrierExtraContent.md | 2 +- .../hooks/list-of-hooks/displayCartExtraProductActions.md | 2 +- modules/concepts/hooks/list-of-hooks/displayCartModalContent.md | 2 +- modules/concepts/hooks/list-of-hooks/displayCartModalFooter.md | 2 +- .../hooks/list-of-hooks/displayCheckoutBeforeConfirmation.md | 2 +- .../hooks/list-of-hooks/displayCheckoutSubtotalDetails.md | 2 +- .../concepts/hooks/list-of-hooks/displayCheckoutSummaryTop.md | 2 +- .../hooks/list-of-hooks/displayCrossSellingShoppingCart.md | 2 +- modules/concepts/hooks/list-of-hooks/displayCustomerAccount.md | 2 +- .../concepts/hooks/list-of-hooks/displayCustomerAccountForm.md | 2 +- .../hooks/list-of-hooks/displayCustomerAccountFormTop.md | 2 +- .../hooks/list-of-hooks/displayCustomerLoginFormAfter.md | 2 +- modules/concepts/hooks/list-of-hooks/displayCustomization.md | 2 +- .../hooks/list-of-hooks/displayDashboardToolbarIcons.md | 2 +- .../hooks/list-of-hooks/displayDashboardToolbarTopMenu.md | 2 +- modules/concepts/hooks/list-of-hooks/displayDashboardTop.md | 2 +- .../list-of-hooks/displayEmptyModuleCategoryExtraMessage.md | 2 +- modules/concepts/hooks/list-of-hooks/displayExpressCheckout.md | 2 +- modules/concepts/hooks/list-of-hooks/displayFeatureForm.md | 2 +- .../concepts/hooks/list-of-hooks/displayFeaturePostProcess.md | 2 +- .../hooks/list-of-hooks/displayFeatureValuePostProcess.md | 2 +- modules/concepts/hooks/list-of-hooks/displayFooter.md | 2 +- modules/concepts/hooks/list-of-hooks/displayFooterAfter.md | 2 +- modules/concepts/hooks/list-of-hooks/displayFooterBefore.md | 2 +- modules/concepts/hooks/list-of-hooks/displayFooterProduct.md | 2 +- modules/concepts/hooks/list-of-hooks/displayGDPRConsent.md | 2 +- modules/concepts/hooks/list-of-hooks/displayHeader.md | 2 +- modules/concepts/hooks/list-of-hooks/displayHome.md | 2 +- .../concepts/hooks/list-of-hooks/displayInvoiceLegalFreeText.md | 2 +- .../concepts/hooks/list-of-hooks/displayLeftColumnProduct.md | 2 +- modules/concepts/hooks/list-of-hooks/displayMaintenance.md | 2 +- modules/concepts/hooks/list-of-hooks/displayMyAccountBlock.md | 2 +- modules/concepts/hooks/list-of-hooks/displayNav1.md | 2 +- modules/concepts/hooks/list-of-hooks/displayNav2.md | 2 +- modules/concepts/hooks/list-of-hooks/displayNavFullWidth.md | 2 +- .../hooks/list-of-hooks/displayNewsletterRegistration.md | 2 +- modules/concepts/hooks/list-of-hooks/displayNotFound.md | 2 +- .../concepts/hooks/list-of-hooks/displayOrderConfirmation.md | 2 +- .../concepts/hooks/list-of-hooks/displayOrderConfirmation1.md | 2 +- .../concepts/hooks/list-of-hooks/displayOrderConfirmation2.md | 2 +- modules/concepts/hooks/list-of-hooks/displayOrderDetail.md | 2 +- modules/concepts/hooks/list-of-hooks/displayOrderPreview.md | 2 +- modules/concepts/hooks/list-of-hooks/displayOverrideTemplate.md | 2 +- .../concepts/hooks/list-of-hooks/displayPaymentByBinaries.md | 2 +- modules/concepts/hooks/list-of-hooks/displayPaymentReturn.md | 2 +- modules/concepts/hooks/list-of-hooks/displayPaymentTop.md | 2 +- .../hooks/list-of-hooks/displayPersonalInformationTop.md | 2 +- modules/concepts/hooks/list-of-hooks/displayProductActions.md | 2 +- .../hooks/list-of-hooks/displayProductAdditionalInfo.md | 2 +- .../concepts/hooks/list-of-hooks/displayProductListReviews.md | 2 +- .../concepts/hooks/list-of-hooks/displayProductPriceBlock.md | 2 +- modules/concepts/hooks/list-of-hooks/displayReassurance.md | 2 +- .../concepts/hooks/list-of-hooks/displayRightColumnProduct.md | 2 +- modules/concepts/hooks/list-of-hooks/displaySearch.md | 2 +- modules/concepts/hooks/list-of-hooks/displayShoppingCart.md | 2 +- .../concepts/hooks/list-of-hooks/displayShoppingCartFooter.md | 2 +- modules/concepts/hooks/list-of-hooks/displayTop.md | 2 +- modules/concepts/hooks/list-of-hooks/filterCategoryContent.md | 2 +- .../concepts/hooks/list-of-hooks/filterCmsCategoryContent.md | 2 +- modules/concepts/hooks/list-of-hooks/filterCmsContent.md | 2 +- modules/concepts/hooks/list-of-hooks/filterHtmlContent.md | 2 +- .../concepts/hooks/list-of-hooks/filterManufacturerContent.md | 2 +- modules/concepts/hooks/list-of-hooks/filterProductContent.md | 2 +- modules/concepts/hooks/list-of-hooks/filterProductSearch.md | 2 +- modules/concepts/hooks/list-of-hooks/filterSupplierContent.md | 2 +- modules/concepts/hooks/list-of-hooks/gSitemapAppendUrls.md | 2 +- modules/concepts/hooks/list-of-hooks/legacyblockkpi.md | 2 +- modules/concepts/hooks/list-of-hooks/moduleRoutes.md | 2 +- modules/concepts/hooks/list-of-hooks/overrideLayoutTemplate.md | 2 +- .../hooks/list-of-hooks/overrideMinimalPurchasePrice.md | 2 +- modules/concepts/hooks/list-of-hooks/productSearchProvider.md | 2 +- .../concepts/hooks/list-of-hooks/sendMailAlterTemplateVars.md | 2 +- modules/concepts/hooks/list-of-hooks/termsAndConditions.md | 2 +- .../concepts/hooks/list-of-hooks/validateCustomerFormFields.md | 2 +- 342 files changed, 342 insertions(+), 342 deletions(-) diff --git a/modules/concepts/hooks/list-of-hooks/actionAfter.md b/modules/concepts/hooks/list-of-hooks/actionAfter.md index de7c9c8211..3f85d6b7db 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionAfter.md @@ -21,7 +21,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/AdminController.php](classes/controller/AdminController.php) + - [classes/controller/AdminController.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/AdminController.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionBefore.md b/modules/concepts/hooks/list-of-hooks/actionBefore.md index 71d39c5e73..f82c07039d 100644 --- a/modules/concepts/hooks/list-of-hooks/actionBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionBefore.md @@ -21,7 +21,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/AdminController.php](classes/controller/AdminController.php) + - [classes/controller/AdminController.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/AdminController.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionFormModifier.md b/modules/concepts/hooks/list-of-hooks/actionFormModifier.md index 6d9286b35a..1d1f53ea27 100644 --- a/modules/concepts/hooks/list-of-hooks/actionFormModifier.md +++ b/modules/concepts/hooks/list-of-hooks/actionFormModifier.md @@ -21,7 +21,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/AdminController.php](classes/controller/AdminController.php) + - [classes/controller/AdminController.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/AdminController.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionListingFieldsModifier.md b/modules/concepts/hooks/list-of-hooks/actionListingFieldsModifier.md index 15c12ee915..9c109c2e21 100644 --- a/modules/concepts/hooks/list-of-hooks/actionListingFieldsModifier.md +++ b/modules/concepts/hooks/list-of-hooks/actionListingFieldsModifier.md @@ -21,7 +21,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/AdminController.php](classes/controller/AdminController.php) + - [classes/controller/AdminController.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/AdminController.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionListingResultsModifier.md b/modules/concepts/hooks/list-of-hooks/actionListingResultsModifier.md index 1cb2c629fa..5cccabd373 100644 --- a/modules/concepts/hooks/list-of-hooks/actionListingResultsModifier.md +++ b/modules/concepts/hooks/list-of-hooks/actionListingResultsModifier.md @@ -21,7 +21,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/AdminController.php](classes/controller/AdminController.php) + - [classes/controller/AdminController.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/AdminController.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionOptionsModifier.md b/modules/concepts/hooks/list-of-hooks/actionOptionsModifier.md index 9f496df02f..cd37aefa69 100644 --- a/modules/concepts/hooks/list-of-hooks/actionOptionsModifier.md +++ b/modules/concepts/hooks/list-of-hooks/actionOptionsModifier.md @@ -21,7 +21,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/AdminController.php](classes/controller/AdminController.php) + - [classes/controller/AdminController.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/AdminController.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionGridPresenterModifier.md b/modules/concepts/hooks/list-of-hooks/actionGridPresenterModifier.md index 7d184621d0..2bcc99fee4 100644 --- a/modules/concepts/hooks/list-of-hooks/actionGridPresenterModifier.md +++ b/modules/concepts/hooks/list-of-hooks/actionGridPresenterModifier.md @@ -21,7 +21,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Core/Grid/Presenter/GridPresenter.php](src/Core/Grid/Presenter/GridPresenter.php) + - [src/Core/Grid/Presenter/GridPresenter.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Core/Grid/Presenter/GridPresenter.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionFormDataProviderDefaultData.md b/modules/concepts/hooks/list-of-hooks/actionFormDataProviderDefaultData.md index 56d5890448..228ae1e31a 100644 --- a/modules/concepts/hooks/list-of-hooks/actionFormDataProviderDefaultData.md +++ b/modules/concepts/hooks/list-of-hooks/actionFormDataProviderDefaultData.md @@ -21,7 +21,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Core/Form/IdentifiableObject/Builder/FormBuilder.php](src/Core/Form/IdentifiableObject/Builder/FormBuilder.php) + - [src/Core/Form/IdentifiableObject/Builder/FormBuilder.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Core/Form/IdentifiableObject/Builder/FormBuilder.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionListingFieldsModifier.md b/modules/concepts/hooks/list-of-hooks/actionListingFieldsModifier.md index 40049b7b7c..0282f988a8 100644 --- a/modules/concepts/hooks/list-of-hooks/actionListingFieldsModifier.md +++ b/modules/concepts/hooks/list-of-hooks/actionListingFieldsModifier.md @@ -21,7 +21,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Bridge/Helper/Listing/HelperBridge/HelperListBridge.php](src/PrestaShopBundle/Bridge/Helper/Listing/HelperBridge/HelperListBridge.php) + - [src/PrestaShopBundle/Bridge/Helper/Listing/HelperBridge/HelperListBridge.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Bridge/Helper/Listing/HelperBridge/HelperListBridge.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionListingResultsModifier.md b/modules/concepts/hooks/list-of-hooks/actionListingResultsModifier.md index ef336451d3..e60476eac7 100644 --- a/modules/concepts/hooks/list-of-hooks/actionListingResultsModifier.md +++ b/modules/concepts/hooks/list-of-hooks/actionListingResultsModifier.md @@ -21,7 +21,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Bridge/Helper/Listing/HelperBridge/HelperListBridge.php](src/PrestaShopBundle/Bridge/Helper/Listing/HelperBridge/HelperListBridge.php) + - [src/PrestaShopBundle/Bridge/Helper/Listing/HelperBridge/HelperListBridge.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Bridge/Helper/Listing/HelperBridge/HelperListBridge.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminAfter.md b/modules/concepts/hooks/list-of-hooks/actionAdminAfter.md index ff807d9439..42680ecc08 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminAfter.md @@ -21,7 +21,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/AdminController.php](classes/controller/AdminController.php) + - [classes/controller/AdminController.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/AdminController.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminBefore.md index 720538f0da..f1501e8659 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminBefore.md @@ -21,7 +21,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/AdminController.php](classes/controller/AdminController.php) + - [classes/controller/AdminController.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/AdminController.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminActivateAfter.md b/modules/concepts/hooks/list-of-hooks/actionAdminActivateAfter.md index a3cd5a6afc..01fa337bf7 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminActivateAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminActivateAfter.md @@ -21,7 +21,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/ProductController.php](src/PrestaShopBundle/Controller/Admin/ProductController.php) + - [src/PrestaShopBundle/Controller/Admin/ProductController.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/ProductController.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminActivateBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminActivateBefore.md index ba3a206f09..6184bec2fc 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminActivateBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminActivateBefore.md @@ -21,7 +21,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/ProductController.php](src/PrestaShopBundle/Controller/Admin/ProductController.php) + - [src/PrestaShopBundle/Controller/Admin/ProductController.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/ProductController.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminAdminShopParametersMetaControllerPostProcessBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminAdminShopParametersMetaControllerPostProcessBefore.md index 77bce65605..e99b826882 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminAdminShopParametersMetaControllerPostProcessBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminAdminShopParametersMetaControllerPostProcessBefore.md @@ -27,7 +27,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/MetaController.php](src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/MetaController.php) + - [src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/MetaController.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/MetaController.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminAdminWebserviceControllerPostProcessBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminAdminWebserviceControllerPostProcessBefore.md index 1fba778669..faf4dde2af 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminAdminWebserviceControllerPostProcessBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminAdminWebserviceControllerPostProcessBefore.md @@ -21,7 +21,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/WebserviceController.php](src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/WebserviceController.php) + - [src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/WebserviceController.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/WebserviceController.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminAdministrationControllerPostProcessBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminAdministrationControllerPostProcessBefore.md index 7b12b586a9..8e56a9a491 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminAdministrationControllerPostProcessBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminAdministrationControllerPostProcessBefore.md @@ -21,7 +21,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/AdministrationController.php](src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/AdministrationController.php) + - [src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/AdministrationController.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/AdministrationController.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminAdministrationControllerPostProcessBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminAdministrationControllerPostProcessBefore.md index 312dfdf0fc..d4f0eeb2db 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminAdministrationControllerPostProcessBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminAdministrationControllerPostProcessBefore.md @@ -27,7 +27,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/AdministrationController.php](src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/AdministrationController.php) + - [src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/AdministrationController.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/AdministrationController.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminAdvancedParametersPerformanceControllerPostProcessBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminAdvancedParametersPerformanceControllerPostProcessBefore.md index 9e706ac55f..1862f0b2a9 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminAdvancedParametersPerformanceControllerPostProcessBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminAdvancedParametersPerformanceControllerPostProcessBefore.md @@ -21,7 +21,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/PerformanceController.php](src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/PerformanceController.php) + - [src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/PerformanceController.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/PerformanceController.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminAdvancedParametersPerformanceControllerPostProcessBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminAdvancedParametersPerformanceControllerPostProcessBefore.md index 74dcfa5065..f45d2dc628 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminAdvancedParametersPerformanceControllerPostProcessBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminAdvancedParametersPerformanceControllerPostProcessBefore.md @@ -27,7 +27,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/PerformanceController.php](src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/PerformanceController.php) + - [src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/PerformanceController.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/PerformanceController.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminControllerInitAfter.md b/modules/concepts/hooks/list-of-hooks/actionAdminControllerInitAfter.md index 1c1f3ec553..dd539f9292 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminControllerInitAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminControllerInitAfter.md @@ -27,7 +27,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/AdminController.php](classes/controller/AdminController.php) + - [classes/controller/AdminController.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/AdminController.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminControllerInitBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminControllerInitBefore.md index caf22836e9..61352e1996 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminControllerInitBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminControllerInitBefore.md @@ -27,7 +27,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/AdminController.php](classes/controller/AdminController.php) + - [classes/controller/AdminController.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/AdminController.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminControllerSetMedia.md b/modules/concepts/hooks/list-of-hooks/actionAdminControllerSetMedia.md index d72ffa91d7..311f0e2406 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminControllerSetMedia.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminControllerSetMedia.md @@ -21,7 +21,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Bridge/AdminController/LegacyControllerBridge.php](src/PrestaShopBundle/Bridge/AdminController/LegacyControllerBridge.php) + - [src/PrestaShopBundle/Bridge/AdminController/LegacyControllerBridge.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Bridge/AdminController/LegacyControllerBridge.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminDeactivateAfter.md b/modules/concepts/hooks/list-of-hooks/actionAdminDeactivateAfter.md index 448c32ada4..d0a16d7f85 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminDeactivateAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminDeactivateAfter.md @@ -21,7 +21,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/ProductController.php](src/PrestaShopBundle/Controller/Admin/ProductController.php) + - [src/PrestaShopBundle/Controller/Admin/ProductController.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/ProductController.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminDeactivateBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminDeactivateBefore.md index 171ba33b3a..36236706e2 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminDeactivateBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminDeactivateBefore.md @@ -21,7 +21,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/ProductController.php](src/PrestaShopBundle/Controller/Admin/ProductController.php) + - [src/PrestaShopBundle/Controller/Admin/ProductController.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/ProductController.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminDeleteAfter.md b/modules/concepts/hooks/list-of-hooks/actionAdminDeleteAfter.md index 8676c18609..08734f6e6b 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminDeleteAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminDeleteAfter.md @@ -21,7 +21,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/ProductController.php](src/PrestaShopBundle/Controller/Admin/ProductController.php) + - [src/PrestaShopBundle/Controller/Admin/ProductController.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/ProductController.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminDeleteBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminDeleteBefore.md index 993b9c9e76..c885572004 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminDeleteBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminDeleteBefore.md @@ -21,7 +21,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/ProductController.php](src/PrestaShopBundle/Controller/Admin/ProductController.php) + - [src/PrestaShopBundle/Controller/Admin/ProductController.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/ProductController.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminDuplicateAfter.md b/modules/concepts/hooks/list-of-hooks/actionAdminDuplicateAfter.md index 52d5b662f5..1dd5a9b861 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminDuplicateAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminDuplicateAfter.md @@ -21,7 +21,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/ProductController.php](src/PrestaShopBundle/Controller/Admin/ProductController.php) + - [src/PrestaShopBundle/Controller/Admin/ProductController.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/ProductController.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminDuplicateBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminDuplicateBefore.md index 4804942dd7..1e90adca44 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminDuplicateBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminDuplicateBefore.md @@ -21,7 +21,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/ProductController.php](src/PrestaShopBundle/Controller/Admin/ProductController.php) + - [src/PrestaShopBundle/Controller/Admin/ProductController.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/ProductController.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminInternationalGeolocationControllerPostProcessBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminInternationalGeolocationControllerPostProcessBefore.md index 2d64dc3e71..47f09afd9e 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminInternationalGeolocationControllerPostProcessBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminInternationalGeolocationControllerPostProcessBefore.md @@ -21,7 +21,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/Improve/International/GeolocationController.php](src/PrestaShopBundle/Controller/Admin/Improve/International/GeolocationController.php) + - [src/PrestaShopBundle/Controller/Admin/Improve/International/GeolocationController.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/Improve/International/GeolocationController.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminInternationalGeolocationControllerPostProcessBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminInternationalGeolocationControllerPostProcessBefore.md index 048c5a1713..236b207c22 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminInternationalGeolocationControllerPostProcessBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminInternationalGeolocationControllerPostProcessBefore.md @@ -27,7 +27,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/Improve/International/GeolocationController.php](src/PrestaShopBundle/Controller/Admin/Improve/International/GeolocationController.php) + - [src/PrestaShopBundle/Controller/Admin/Improve/International/GeolocationController.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/Improve/International/GeolocationController.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminInternationalLocalizationControllerPostProcessBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminInternationalLocalizationControllerPostProcessBefore.md index 7ea88874b5..3283c4f341 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminInternationalLocalizationControllerPostProcessBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminInternationalLocalizationControllerPostProcessBefore.md @@ -21,7 +21,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/Improve/International/LocalizationController.php](src/PrestaShopBundle/Controller/Admin/Improve/International/LocalizationController.php) + - [src/PrestaShopBundle/Controller/Admin/Improve/International/LocalizationController.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/Improve/International/LocalizationController.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminInternationalLocalizationControllerPostProcessBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminInternationalLocalizationControllerPostProcessBefore.md index c99c93dc5a..2cfe43e37b 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminInternationalLocalizationControllerPostProcessBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminInternationalLocalizationControllerPostProcessBefore.md @@ -27,7 +27,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/Improve/International/LocalizationController.php](src/PrestaShopBundle/Controller/Admin/Improve/International/LocalizationController.php) + - [src/PrestaShopBundle/Controller/Admin/Improve/International/LocalizationController.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/Improve/International/LocalizationController.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminLoginControllerBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminLoginControllerBefore.md index 2e84f295cd..12f9205bc5 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminLoginControllerBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminLoginControllerBefore.md @@ -27,7 +27,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/admin/AdminLoginController.php](controllers/admin/AdminLoginController.php) + - [controllers/admin/AdminLoginController.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/admin/AdminLoginController.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminLoginControllerForgotAfter.md b/modules/concepts/hooks/list-of-hooks/actionAdminLoginControllerForgotAfter.md index 6b3cbf91fc..c4e5a0e325 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminLoginControllerForgotAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminLoginControllerForgotAfter.md @@ -27,7 +27,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/admin/AdminLoginController.php](controllers/admin/AdminLoginController.php) + - [controllers/admin/AdminLoginController.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/admin/AdminLoginController.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminLoginControllerForgotBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminLoginControllerForgotBefore.md index bf49e4a46e..8dc59189e4 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminLoginControllerForgotBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminLoginControllerForgotBefore.md @@ -27,7 +27,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/admin/AdminLoginController.php](controllers/admin/AdminLoginController.php) + - [controllers/admin/AdminLoginController.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/admin/AdminLoginController.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminLoginControllerLoginAfter.md b/modules/concepts/hooks/list-of-hooks/actionAdminLoginControllerLoginAfter.md index 6768f3ec29..b86e779355 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminLoginControllerLoginAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminLoginControllerLoginAfter.md @@ -27,7 +27,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/admin/AdminLoginController.php](controllers/admin/AdminLoginController.php) + - [controllers/admin/AdminLoginController.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/admin/AdminLoginController.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminLoginControllerLoginBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminLoginControllerLoginBefore.md index 4c43e07e8c..d973911162 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminLoginControllerLoginBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminLoginControllerLoginBefore.md @@ -27,7 +27,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/admin/AdminLoginController.php](controllers/admin/AdminLoginController.php) + - [controllers/admin/AdminLoginController.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/admin/AdminLoginController.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminLoginControllerResetAfter.md b/modules/concepts/hooks/list-of-hooks/actionAdminLoginControllerResetAfter.md index eef0e96498..63a0f6d542 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminLoginControllerResetAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminLoginControllerResetAfter.md @@ -27,7 +27,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/admin/AdminLoginController.php](controllers/admin/AdminLoginController.php) + - [controllers/admin/AdminLoginController.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/admin/AdminLoginController.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminLoginControllerResetBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminLoginControllerResetBefore.md index 88013e18e9..e1cc55da35 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminLoginControllerResetBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminLoginControllerResetBefore.md @@ -27,7 +27,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/admin/AdminLoginController.php](controllers/admin/AdminLoginController.php) + - [controllers/admin/AdminLoginController.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/admin/AdminLoginController.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminLoginControllerSetMedia.md b/modules/concepts/hooks/list-of-hooks/actionAdminLoginControllerSetMedia.md index 09949635a1..91a35cb990 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminLoginControllerSetMedia.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminLoginControllerSetMedia.md @@ -27,7 +27,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/admin/AdminLoginController.php](controllers/admin/AdminLoginController.php) + - [controllers/admin/AdminLoginController.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/admin/AdminLoginController.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminLogsControllerPostProcessBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminLogsControllerPostProcessBefore.md index 6cacd6f4fe..530c6e844b 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminLogsControllerPostProcessBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminLogsControllerPostProcessBefore.md @@ -21,7 +21,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/LogsController.php](src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/LogsController.php) + - [src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/LogsController.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/LogsController.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminMaintenanceControllerPostProcessBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminMaintenanceControllerPostProcessBefore.md index 57952b081b..c5b02f4fe0 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminMaintenanceControllerPostProcessBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminMaintenanceControllerPostProcessBefore.md @@ -21,7 +21,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/MaintenanceController.php](src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/MaintenanceController.php) + - [src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/MaintenanceController.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/MaintenanceController.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminMetaAfterWriteRobotsFile.md b/modules/concepts/hooks/list-of-hooks/actionAdminMetaAfterWriteRobotsFile.md index be954e8b86..bfb9ab72de 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminMetaAfterWriteRobotsFile.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminMetaAfterWriteRobotsFile.md @@ -21,7 +21,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Tools.php](classes/Tools.php) + - [classes/Tools.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Tools.php) ## Parameters details diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminMetaBeforeWriteRobotsFile.md b/modules/concepts/hooks/list-of-hooks/actionAdminMetaBeforeWriteRobotsFile.md index ea32ba05c4..5fb4316a7c 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminMetaBeforeWriteRobotsFile.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminMetaBeforeWriteRobotsFile.md @@ -21,7 +21,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Tools.php](classes/Tools.php) + - [classes/Tools.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Tools.php) ## Parameters details diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminMetaSave.md b/modules/concepts/hooks/list-of-hooks/actionAdminMetaSave.md index 2e5bf4b237..55ff27cb54 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminMetaSave.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminMetaSave.md @@ -33,7 +33,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Meta/CommandHandler/AddMetaHandler.php](src/Adapter/Meta/CommandHandler/AddMetaHandler.php) + - [src/Adapter/Meta/CommandHandler/AddMetaHandler.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Meta/CommandHandler/AddMetaHandler.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminOrdersTrackingNumberUpdate.md b/modules/concepts/hooks/list-of-hooks/actionAdminOrdersTrackingNumberUpdate.md index fbc4300dfb..d238fabc04 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminOrdersTrackingNumberUpdate.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminOrdersTrackingNumberUpdate.md @@ -27,7 +27,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Order/CommandHandler/UpdateOrderShippingDetailsHandler.php](src/Adapter/Order/CommandHandler/UpdateOrderShippingDetailsHandler.php) + - [src/Adapter/Order/CommandHandler/UpdateOrderShippingDetailsHandler.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Order/CommandHandler/UpdateOrderShippingDetailsHandler.php) ## Parameters details diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminPreferencesControllerPostProcessBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminPreferencesControllerPostProcessBefore.md index 59e8806355..27129d2c0c 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminPreferencesControllerPostProcessBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminPreferencesControllerPostProcessBefore.md @@ -21,7 +21,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/PreferencesController.php](src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/PreferencesController.php) + - [src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/PreferencesController.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/PreferencesController.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerActivateAfter.md b/modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerActivateAfter.md index 67b7553564..6d6b29d0de 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerActivateAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerActivateAfter.md @@ -21,7 +21,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/ProductController.php](src/PrestaShopBundle/Controller/Admin/ProductController.php) + - [src/PrestaShopBundle/Controller/Admin/ProductController.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/ProductController.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerActivateBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerActivateBefore.md index cbad8864db..0e1d29afa8 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerActivateBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerActivateBefore.md @@ -21,7 +21,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/ProductController.php](src/PrestaShopBundle/Controller/Admin/ProductController.php) + - [src/PrestaShopBundle/Controller/Admin/ProductController.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/ProductController.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerDeactivateAfter.md b/modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerDeactivateAfter.md index 1b2ca74727..9221268117 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerDeactivateAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerDeactivateAfter.md @@ -21,7 +21,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/ProductController.php](src/PrestaShopBundle/Controller/Admin/ProductController.php) + - [src/PrestaShopBundle/Controller/Admin/ProductController.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/ProductController.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerDeactivateBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerDeactivateBefore.md index 82066c0cc4..bc4fa4ec3e 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerDeactivateBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerDeactivateBefore.md @@ -21,7 +21,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/ProductController.php](src/PrestaShopBundle/Controller/Admin/ProductController.php) + - [src/PrestaShopBundle/Controller/Admin/ProductController.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/ProductController.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerDeleteAfter.md b/modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerDeleteAfter.md index 246695e39a..bc438b9c35 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerDeleteAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerDeleteAfter.md @@ -21,7 +21,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/ProductController.php](src/PrestaShopBundle/Controller/Admin/ProductController.php) + - [src/PrestaShopBundle/Controller/Admin/ProductController.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/ProductController.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerDeleteBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerDeleteBefore.md index c1f3e3c339..e947825513 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerDeleteBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerDeleteBefore.md @@ -21,7 +21,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/ProductController.php](src/PrestaShopBundle/Controller/Admin/ProductController.php) + - [src/PrestaShopBundle/Controller/Admin/ProductController.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/ProductController.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerDuplicateAfter.md b/modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerDuplicateAfter.md index 50ed7861e8..2f6ebcd83f 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerDuplicateAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerDuplicateAfter.md @@ -21,7 +21,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/ProductController.php](src/PrestaShopBundle/Controller/Admin/ProductController.php) + - [src/PrestaShopBundle/Controller/Admin/ProductController.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/ProductController.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerDuplicateBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerDuplicateBefore.md index e5c948ef74..7f9db01f69 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerDuplicateBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerDuplicateBefore.md @@ -21,7 +21,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/ProductController.php](src/PrestaShopBundle/Controller/Admin/ProductController.php) + - [src/PrestaShopBundle/Controller/Admin/ProductController.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/ProductController.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerSortAfter.md b/modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerSortAfter.md index aa79ea6272..ce4f70efc2 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerSortAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerSortAfter.md @@ -21,7 +21,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/ProductController.php](src/PrestaShopBundle/Controller/Admin/ProductController.php) + - [src/PrestaShopBundle/Controller/Admin/ProductController.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/ProductController.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerSortBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerSortBefore.md index 43ff8b62fa..45f506d5ba 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerSortBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminProductsControllerSortBefore.md @@ -21,7 +21,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/ProductController.php](src/PrestaShopBundle/Controller/Admin/ProductController.php) + - [src/PrestaShopBundle/Controller/Admin/ProductController.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/ProductController.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminProductsListingFieldsModifier.md b/modules/concepts/hooks/list-of-hooks/actionAdminProductsListingFieldsModifier.md index 217dfe03ee..9b012789a5 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminProductsListingFieldsModifier.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminProductsListingFieldsModifier.md @@ -21,7 +21,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Product/AdminProductDataProvider.php](src/Adapter/Product/AdminProductDataProvider.php) + - [src/Adapter/Product/AdminProductDataProvider.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Product/AdminProductDataProvider.php) ## Parameters details diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminProductsListingResultsModifier.md b/modules/concepts/hooks/list-of-hooks/actionAdminProductsListingResultsModifier.md index 199ff9e6df..e513ce8c40 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminProductsListingResultsModifier.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminProductsListingResultsModifier.md @@ -21,7 +21,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Product/AdminProductDataProvider.php](src/Adapter/Product/AdminProductDataProvider.php) + - [src/Adapter/Product/AdminProductDataProvider.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Product/AdminProductDataProvider.php) ## Parameters details diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminSecurityControllerPostProcessBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminSecurityControllerPostProcessBefore.md index d7364fedc7..c449b67fac 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminSecurityControllerPostProcessBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminSecurityControllerPostProcessBefore.md @@ -27,7 +27,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/SecurityController.php](src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/SecurityController.php) + - [src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/SecurityController.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/SecurityController.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminShippingPreferencesControllerPostProcessBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminShippingPreferencesControllerPostProcessBefore.md index aca7e75f05..c03d465c10 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminShippingPreferencesControllerPostProcessBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminShippingPreferencesControllerPostProcessBefore.md @@ -27,7 +27,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/Improve/Shipping/PreferencesController.php](src/PrestaShopBundle/Controller/Admin/Improve/Shipping/PreferencesController.php) + - [src/PrestaShopBundle/Controller/Admin/Improve/Shipping/PreferencesController.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/Improve/Shipping/PreferencesController.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminShippingPreferencesControllerPostProcessCarrierOptionsBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminShippingPreferencesControllerPostProcessCarrierOptionsBefore.md index fce4156448..5fe482826c 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminShippingPreferencesControllerPostProcessCarrierOptionsBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminShippingPreferencesControllerPostProcessCarrierOptionsBefore.md @@ -27,7 +27,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/Improve/Shipping/PreferencesController.php](src/PrestaShopBundle/Controller/Admin/Improve/Shipping/PreferencesController.php) + - [src/PrestaShopBundle/Controller/Admin/Improve/Shipping/PreferencesController.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/Improve/Shipping/PreferencesController.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminShippingPreferencesControllerPostProcessHandlingBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminShippingPreferencesControllerPostProcessHandlingBefore.md index bee77664da..b446423972 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminShippingPreferencesControllerPostProcessHandlingBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminShippingPreferencesControllerPostProcessHandlingBefore.md @@ -27,7 +27,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/Improve/Shipping/PreferencesController.php](src/PrestaShopBundle/Controller/Admin/Improve/Shipping/PreferencesController.php) + - [src/PrestaShopBundle/Controller/Admin/Improve/Shipping/PreferencesController.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/Improve/Shipping/PreferencesController.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminShopParametersMetaControllerPostProcessBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminShopParametersMetaControllerPostProcessBefore.md index a1192aa079..fd075c32af 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminShopParametersMetaControllerPostProcessBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminShopParametersMetaControllerPostProcessBefore.md @@ -21,7 +21,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/MetaController.php](src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/MetaController.php) + - [src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/MetaController.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/MetaController.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminShopParametersOrderPreferencesControllerPostProcessBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminShopParametersOrderPreferencesControllerPostProcessBefore.md index 5ebc8e49a7..69abcd5896 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminShopParametersOrderPreferencesControllerPostProcessBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminShopParametersOrderPreferencesControllerPostProcessBefore.md @@ -21,7 +21,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/OrderPreferencesController.php](src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/OrderPreferencesController.php) + - [src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/OrderPreferencesController.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/OrderPreferencesController.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminShopParametersOrderPreferencesControllerPostProcessBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminShopParametersOrderPreferencesControllerPostProcessBefore.md index 10842345a6..85059885ce 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminShopParametersOrderPreferencesControllerPostProcessBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminShopParametersOrderPreferencesControllerPostProcessBefore.md @@ -27,7 +27,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/OrderPreferencesController.php](src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/OrderPreferencesController.php) + - [src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/OrderPreferencesController.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/OrderPreferencesController.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminShopParametersProductPreferencesControllerPostProcessBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminShopParametersProductPreferencesControllerPostProcessBefore.md index 07cdffb2f8..722c2e3161 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminShopParametersProductPreferencesControllerPostProcessBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminShopParametersProductPreferencesControllerPostProcessBefore.md @@ -21,7 +21,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/ProductPreferencesController.php](src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/ProductPreferencesController.php) + - [src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/ProductPreferencesController.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/ProductPreferencesController.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminShopParametersProductPreferencesControllerPostProcessBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminShopParametersProductPreferencesControllerPostProcessBefore.md index 20bf5c86c8..e4af444857 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminShopParametersProductPreferencesControllerPostProcessBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminShopParametersProductPreferencesControllerPostProcessBefore.md @@ -21,7 +21,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/ProductPreferencesController.php](src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/ProductPreferencesController.php) + - [src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/ProductPreferencesController.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/ProductPreferencesController.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminSortAfter.md b/modules/concepts/hooks/list-of-hooks/actionAdminSortAfter.md index eccf9cdae7..210c01c537 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminSortAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminSortAfter.md @@ -21,7 +21,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/ProductController.php](src/PrestaShopBundle/Controller/Admin/ProductController.php) + - [src/PrestaShopBundle/Controller/Admin/ProductController.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/ProductController.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminSortBefore.md b/modules/concepts/hooks/list-of-hooks/actionAdminSortBefore.md index 5b123fcc9d..7981b86350 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminSortBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminSortBefore.md @@ -21,7 +21,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/ProductController.php](src/PrestaShopBundle/Controller/Admin/ProductController.php) + - [src/PrestaShopBundle/Controller/Admin/ProductController.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/ProductController.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminThemesControllerUpdateoptionsAfter.md b/modules/concepts/hooks/list-of-hooks/actionAdminThemesControllerUpdateoptionsAfter.md index d4175ed74f..103ec72fb1 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminThemesControllerUpdateoptionsAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminThemesControllerUpdateoptionsAfter.md @@ -21,7 +21,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Shop/CommandHandler/UploadLogosHandler.php](src/Adapter/Shop/CommandHandler/UploadLogosHandler.php) + - [src/Adapter/Shop/CommandHandler/UploadLogosHandler.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Shop/CommandHandler/UploadLogosHandler.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionAfterCreateFormHandler.md b/modules/concepts/hooks/list-of-hooks/actionAfterCreateFormHandler.md index d38412f8a9..fb4acf36ec 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAfterCreateFormHandler.md +++ b/modules/concepts/hooks/list-of-hooks/actionAfterCreateFormHandler.md @@ -21,7 +21,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Core/Form/IdentifiableObject/Handler/FormHandler.php](src/Core/Form/IdentifiableObject/Handler/FormHandler.php) + - [src/Core/Form/IdentifiableObject/Handler/FormHandler.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Core/Form/IdentifiableObject/Handler/FormHandler.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionAfterUpdateFormHandler.md b/modules/concepts/hooks/list-of-hooks/actionAfterUpdateFormHandler.md index 11db838621..fb5864d4ae 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAfterUpdateFormHandler.md +++ b/modules/concepts/hooks/list-of-hooks/actionAfterUpdateFormHandler.md @@ -21,7 +21,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Core/Form/IdentifiableObject/Handler/FormHandler.php](src/Core/Form/IdentifiableObject/Handler/FormHandler.php) + - [src/Core/Form/IdentifiableObject/Handler/FormHandler.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Core/Form/IdentifiableObject/Handler/FormHandler.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionAjaxDieBefore.md b/modules/concepts/hooks/list-of-hooks/actionAjaxDieBefore.md index 6831880eb0..4f93919ea7 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAjaxDieBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAjaxDieBefore.md @@ -21,7 +21,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/Controller.php](classes/controller/Controller.php) + - [classes/controller/Controller.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/Controller.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionAjaxDieBefore.md b/modules/concepts/hooks/list-of-hooks/actionAjaxDieBefore.md index 7440dcfd66..26679989e5 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAjaxDieBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAjaxDieBefore.md @@ -31,7 +31,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/Controller.php](classes/controller/Controller.php) + - [classes/controller/Controller.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/Controller.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionAttributeCombinationDelete.md b/modules/concepts/hooks/list-of-hooks/actionAttributeCombinationDelete.md index ec14364c8f..6cafe75230 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAttributeCombinationDelete.md +++ b/modules/concepts/hooks/list-of-hooks/actionAttributeCombinationDelete.md @@ -21,7 +21,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Combination.php](classes/Combination.php) + - [classes/Combination.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Combination.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionAttributeCombinationSave.md b/modules/concepts/hooks/list-of-hooks/actionAttributeCombinationSave.md index 33a9a72c87..fe0edfc372 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAttributeCombinationSave.md +++ b/modules/concepts/hooks/list-of-hooks/actionAttributeCombinationSave.md @@ -21,7 +21,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Combination.php](classes/Combination.php) + - [classes/Combination.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Combination.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionAttributeDelete.md b/modules/concepts/hooks/list-of-hooks/actionAttributeDelete.md index f4049c68d9..17978b2496 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAttributeDelete.md +++ b/modules/concepts/hooks/list-of-hooks/actionAttributeDelete.md @@ -33,7 +33,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/ProductAttribute.php](classes/ProductAttribute.php) + - [classes/ProductAttribute.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/ProductAttribute.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionAttributeGroupDelete.md b/modules/concepts/hooks/list-of-hooks/actionAttributeGroupDelete.md index 134822e498..ae85c51c28 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAttributeGroupDelete.md +++ b/modules/concepts/hooks/list-of-hooks/actionAttributeGroupDelete.md @@ -33,7 +33,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/AttributeGroup.php](classes/AttributeGroup.php) + - [classes/AttributeGroup.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/AttributeGroup.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionAttributeGroupSave.md b/modules/concepts/hooks/list-of-hooks/actionAttributeGroupSave.md index 8bf7847368..96e832b573 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAttributeGroupSave.md +++ b/modules/concepts/hooks/list-of-hooks/actionAttributeGroupSave.md @@ -33,7 +33,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/AttributeGroup.php](classes/AttributeGroup.php) + - [classes/AttributeGroup.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/AttributeGroup.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionAttributeSave.md b/modules/concepts/hooks/list-of-hooks/actionAttributeSave.md index a9d7b5be7b..d242bbfce6 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAttributeSave.md +++ b/modules/concepts/hooks/list-of-hooks/actionAttributeSave.md @@ -33,7 +33,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/ProductAttribute.php](classes/ProductAttribute.php) + - [classes/ProductAttribute.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/ProductAttribute.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionAuthentication.md b/modules/concepts/hooks/list-of-hooks/actionAuthentication.md index 5891e932b8..130ac7ca8d 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAuthentication.md +++ b/modules/concepts/hooks/list-of-hooks/actionAuthentication.md @@ -33,7 +33,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/form/CustomerLoginForm.php](classes/form/CustomerLoginForm.php) + - [classes/form/CustomerLoginForm.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/form/CustomerLoginForm.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionAuthenticationBefore.md b/modules/concepts/hooks/list-of-hooks/actionAuthenticationBefore.md index 99665c3458..db6abba20c 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAuthenticationBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAuthenticationBefore.md @@ -27,7 +27,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/form/CustomerLoginForm.php](classes/form/CustomerLoginForm.php) + - [classes/form/CustomerLoginForm.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/form/CustomerLoginForm.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionBeforeAjaxDie.md b/modules/concepts/hooks/list-of-hooks/actionBeforeAjaxDie.md index 7e4cb7a343..6ed7674dc3 100644 --- a/modules/concepts/hooks/list-of-hooks/actionBeforeAjaxDie.md +++ b/modules/concepts/hooks/list-of-hooks/actionBeforeAjaxDie.md @@ -21,7 +21,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/Controller.php](classes/controller/Controller.php) + - [classes/controller/Controller.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/Controller.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionBeforeCreateFormHandler.md b/modules/concepts/hooks/list-of-hooks/actionBeforeCreateFormHandler.md index 6cea723063..ee34f16c1e 100644 --- a/modules/concepts/hooks/list-of-hooks/actionBeforeCreateFormHandler.md +++ b/modules/concepts/hooks/list-of-hooks/actionBeforeCreateFormHandler.md @@ -21,7 +21,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Core/Form/IdentifiableObject/Handler/FormHandler.php](src/Core/Form/IdentifiableObject/Handler/FormHandler.php) + - [src/Core/Form/IdentifiableObject/Handler/FormHandler.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Core/Form/IdentifiableObject/Handler/FormHandler.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionBeforeUpdateFormHandler.md b/modules/concepts/hooks/list-of-hooks/actionBeforeUpdateFormHandler.md index 0fa7e32f88..fb5e522500 100644 --- a/modules/concepts/hooks/list-of-hooks/actionBeforeUpdateFormHandler.md +++ b/modules/concepts/hooks/list-of-hooks/actionBeforeUpdateFormHandler.md @@ -21,7 +21,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Core/Form/IdentifiableObject/Handler/FormHandler.php](src/Core/Form/IdentifiableObject/Handler/FormHandler.php) + - [src/Core/Form/IdentifiableObject/Handler/FormHandler.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Core/Form/IdentifiableObject/Handler/FormHandler.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionBuildFrontEndObject.md b/modules/concepts/hooks/list-of-hooks/actionBuildFrontEndObject.md index 3759dea6ac..2823c423ea 100644 --- a/modules/concepts/hooks/list-of-hooks/actionBuildFrontEndObject.md +++ b/modules/concepts/hooks/list-of-hooks/actionBuildFrontEndObject.md @@ -27,7 +27,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/FrontController.php](classes/controller/FrontController.php) + - [classes/controller/FrontController.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/FrontController.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionBuildMailLayoutVariables.md b/modules/concepts/hooks/list-of-hooks/actionBuildMailLayoutVariables.md index 408e392dd4..08a9527e98 100644 --- a/modules/concepts/hooks/list-of-hooks/actionBuildMailLayoutVariables.md +++ b/modules/concepts/hooks/list-of-hooks/actionBuildMailLayoutVariables.md @@ -27,7 +27,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Core/MailTemplate/Layout/LayoutVariablesBuilder.php](src/Core/MailTemplate/Layout/LayoutVariablesBuilder.php) + - [src/Core/MailTemplate/Layout/LayoutVariablesBuilder.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Core/MailTemplate/Layout/LayoutVariablesBuilder.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionCarrierProcess.md b/modules/concepts/hooks/list-of-hooks/actionCarrierProcess.md index 7f46197896..bd4f9c6d61 100644 --- a/modules/concepts/hooks/list-of-hooks/actionCarrierProcess.md +++ b/modules/concepts/hooks/list-of-hooks/actionCarrierProcess.md @@ -33,7 +33,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/checkout/CheckoutDeliveryStep.php](classes/checkout/CheckoutDeliveryStep.php) + - [classes/checkout/CheckoutDeliveryStep.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/checkout/CheckoutDeliveryStep.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionCarrierUpdate.md b/modules/concepts/hooks/list-of-hooks/actionCarrierUpdate.md index 7543bdc7f1..26f11eb5b7 100644 --- a/modules/concepts/hooks/list-of-hooks/actionCarrierUpdate.md +++ b/modules/concepts/hooks/list-of-hooks/actionCarrierUpdate.md @@ -33,7 +33,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/admin/AdminCarriersController.php](controllers/admin/AdminCarriersController.php) + - [controllers/admin/AdminCarriersController.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/admin/AdminCarriersController.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionCartSave.md b/modules/concepts/hooks/list-of-hooks/actionCartSave.md index c4346683d6..c1af317b3f 100644 --- a/modules/concepts/hooks/list-of-hooks/actionCartSave.md +++ b/modules/concepts/hooks/list-of-hooks/actionCartSave.md @@ -33,7 +33,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Cart.php](classes/Cart.php) + - [classes/Cart.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Cart.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionCartSummary.md b/modules/concepts/hooks/list-of-hooks/actionCartSummary.md index 2a64c05b68..8be5ff8dec 100644 --- a/modules/concepts/hooks/list-of-hooks/actionCartSummary.md +++ b/modules/concepts/hooks/list-of-hooks/actionCartSummary.md @@ -21,7 +21,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Cart.php](classes/Cart.php) + - [classes/Cart.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Cart.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionCartUpdateQuantityBefore.md b/modules/concepts/hooks/list-of-hooks/actionCartUpdateQuantityBefore.md index 5fa7822e7d..1b06fa1a3b 100644 --- a/modules/concepts/hooks/list-of-hooks/actionCartUpdateQuantityBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionCartUpdateQuantityBefore.md @@ -27,7 +27,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Cart.php](classes/Cart.php) + - [classes/Cart.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Cart.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionCategoryAdd.md b/modules/concepts/hooks/list-of-hooks/actionCategoryAdd.md index c6f76bee06..a5986b8434 100644 --- a/modules/concepts/hooks/list-of-hooks/actionCategoryAdd.md +++ b/modules/concepts/hooks/list-of-hooks/actionCategoryAdd.md @@ -33,7 +33,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Category.php](classes/Category.php) + - [classes/Category.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Category.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionCategoryDelete.md b/modules/concepts/hooks/list-of-hooks/actionCategoryDelete.md index 092aa3e972..d1af1b50fe 100644 --- a/modules/concepts/hooks/list-of-hooks/actionCategoryDelete.md +++ b/modules/concepts/hooks/list-of-hooks/actionCategoryDelete.md @@ -33,7 +33,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Category.php](classes/Category.php) + - [classes/Category.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Category.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionCategoryUpdate.md b/modules/concepts/hooks/list-of-hooks/actionCategoryUpdate.md index a3b2b95207..3b59680021 100644 --- a/modules/concepts/hooks/list-of-hooks/actionCategoryUpdate.md +++ b/modules/concepts/hooks/list-of-hooks/actionCategoryUpdate.md @@ -33,7 +33,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/admin/AdminProductsController.php](controllers/admin/AdminProductsController.php) + - [controllers/admin/AdminProductsController.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/admin/AdminProductsController.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionCheckoutRender.md b/modules/concepts/hooks/list-of-hooks/actionCheckoutRender.md index 1a416afe82..1ce6917cf5 100644 --- a/modules/concepts/hooks/list-of-hooks/actionCheckoutRender.md +++ b/modules/concepts/hooks/list-of-hooks/actionCheckoutRender.md @@ -27,7 +27,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/front/OrderController.php](controllers/front/OrderController.php) + - [controllers/front/OrderController.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/front/OrderController.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionClearCache.md b/modules/concepts/hooks/list-of-hooks/actionClearCache.md index 4a83e65094..5c38d14fce 100644 --- a/modules/concepts/hooks/list-of-hooks/actionClearCache.md +++ b/modules/concepts/hooks/list-of-hooks/actionClearCache.md @@ -27,7 +27,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Tools.php](classes/Tools.php) + - [classes/Tools.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Tools.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionClearCompileCache.md b/modules/concepts/hooks/list-of-hooks/actionClearCompileCache.md index b9b323e041..b9063e6ddf 100644 --- a/modules/concepts/hooks/list-of-hooks/actionClearCompileCache.md +++ b/modules/concepts/hooks/list-of-hooks/actionClearCompileCache.md @@ -27,7 +27,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Tools.php](classes/Tools.php) + - [classes/Tools.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Tools.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionClearSf2Cache.md b/modules/concepts/hooks/list-of-hooks/actionClearSf2Cache.md index daf9b3744f..fa521292df 100644 --- a/modules/concepts/hooks/list-of-hooks/actionClearSf2Cache.md +++ b/modules/concepts/hooks/list-of-hooks/actionClearSf2Cache.md @@ -27,7 +27,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Cache/Clearer/SymfonyCacheClearer.php](src/Adapter/Cache/Clearer/SymfonyCacheClearer.php) + - [src/Adapter/Cache/Clearer/SymfonyCacheClearer.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Cache/Clearer/SymfonyCacheClearer.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionControllerInitAfter.md b/modules/concepts/hooks/list-of-hooks/actionControllerInitAfter.md index 42ab5932b4..e4b3aed5fd 100644 --- a/modules/concepts/hooks/list-of-hooks/actionControllerInitAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionControllerInitAfter.md @@ -27,7 +27,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/Controller.php](classes/controller/Controller.php) + - [classes/controller/Controller.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/Controller.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionControllerInitBefore.md b/modules/concepts/hooks/list-of-hooks/actionControllerInitBefore.md index 037168580e..83b2d6d16e 100644 --- a/modules/concepts/hooks/list-of-hooks/actionControllerInitBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionControllerInitBefore.md @@ -27,7 +27,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/Controller.php](classes/controller/Controller.php) + - [classes/controller/Controller.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/Controller.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionCustomerAccountAdd.md b/modules/concepts/hooks/list-of-hooks/actionCustomerAccountAdd.md index fd6f880527..0991258ac8 100644 --- a/modules/concepts/hooks/list-of-hooks/actionCustomerAccountAdd.md +++ b/modules/concepts/hooks/list-of-hooks/actionCustomerAccountAdd.md @@ -33,7 +33,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/form/CustomerPersister.php](classes/form/CustomerPersister.php) + - [classes/form/CustomerPersister.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/form/CustomerPersister.php) ## Parameters details diff --git a/modules/concepts/hooks/list-of-hooks/actionCustomerAccountUpdate.md b/modules/concepts/hooks/list-of-hooks/actionCustomerAccountUpdate.md index 509ead8398..68b0c45888 100644 --- a/modules/concepts/hooks/list-of-hooks/actionCustomerAccountUpdate.md +++ b/modules/concepts/hooks/list-of-hooks/actionCustomerAccountUpdate.md @@ -27,7 +27,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/form/CustomerPersister.php](classes/form/CustomerPersister.php) + - [classes/form/CustomerPersister.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/form/CustomerPersister.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionCustomerAddGroups.md b/modules/concepts/hooks/list-of-hooks/actionCustomerAddGroups.md index 8b83d1e803..66e0acd3e5 100644 --- a/modules/concepts/hooks/list-of-hooks/actionCustomerAddGroups.md +++ b/modules/concepts/hooks/list-of-hooks/actionCustomerAddGroups.md @@ -21,7 +21,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Customer.php](classes/Customer.php) + - [classes/Customer.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Customer.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionCustomerBeforeUpdateGroup.md b/modules/concepts/hooks/list-of-hooks/actionCustomerBeforeUpdateGroup.md index 0eab712194..9eef48e939 100644 --- a/modules/concepts/hooks/list-of-hooks/actionCustomerBeforeUpdateGroup.md +++ b/modules/concepts/hooks/list-of-hooks/actionCustomerBeforeUpdateGroup.md @@ -21,7 +21,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Customer.php](classes/Customer.php) + - [classes/Customer.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Customer.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionCustomerLogoutAfter.md b/modules/concepts/hooks/list-of-hooks/actionCustomerLogoutAfter.md index 2bf6a674a5..7d96b759ef 100644 --- a/modules/concepts/hooks/list-of-hooks/actionCustomerLogoutAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionCustomerLogoutAfter.md @@ -27,7 +27,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Customer.php](classes/Customer.php) + - [classes/Customer.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Customer.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionCustomerLogoutBefore.md b/modules/concepts/hooks/list-of-hooks/actionCustomerLogoutBefore.md index e8387ac074..3d5000a54c 100644 --- a/modules/concepts/hooks/list-of-hooks/actionCustomerLogoutBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionCustomerLogoutBefore.md @@ -27,7 +27,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Customer.php](classes/Customer.php) + - [classes/Customer.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Customer.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionDeleteGDPRCustomer.md b/modules/concepts/hooks/list-of-hooks/actionDeleteGDPRCustomer.md index 1e8655f770..5efef5c9e0 100644 --- a/modules/concepts/hooks/list-of-hooks/actionDeleteGDPRCustomer.md +++ b/modules/concepts/hooks/list-of-hooks/actionDeleteGDPRCustomer.md @@ -21,7 +21,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/modules/psgdpr/psgdpr.php](modules/psgdpr/psgdpr.php) + - [modules/psgdpr/psgdpr.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/modules/psgdpr/psgdpr.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionDeliveryPriceByPrice.md b/modules/concepts/hooks/list-of-hooks/actionDeliveryPriceByPrice.md index 375640e76e..3e3159a87e 100644 --- a/modules/concepts/hooks/list-of-hooks/actionDeliveryPriceByPrice.md +++ b/modules/concepts/hooks/list-of-hooks/actionDeliveryPriceByPrice.md @@ -21,7 +21,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Carrier.php](classes/Carrier.php) + - [classes/Carrier.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Carrier.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionDeliveryPriceByWeight.md b/modules/concepts/hooks/list-of-hooks/actionDeliveryPriceByWeight.md index 9734ca5d47..640c323cfd 100644 --- a/modules/concepts/hooks/list-of-hooks/actionDeliveryPriceByWeight.md +++ b/modules/concepts/hooks/list-of-hooks/actionDeliveryPriceByWeight.md @@ -21,7 +21,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Carrier.php](classes/Carrier.php) + - [classes/Carrier.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Carrier.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionDispatcher.md b/modules/concepts/hooks/list-of-hooks/actionDispatcher.md index d9132ff175..ed2398583b 100644 --- a/modules/concepts/hooks/list-of-hooks/actionDispatcher.md +++ b/modules/concepts/hooks/list-of-hooks/actionDispatcher.md @@ -21,7 +21,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Dispatcher.php](classes/Dispatcher.php) + - [classes/Dispatcher.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Dispatcher.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionDispatcherAfter.md b/modules/concepts/hooks/list-of-hooks/actionDispatcherAfter.md index 07eb51ba86..263926dfb7 100644 --- a/modules/concepts/hooks/list-of-hooks/actionDispatcherAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionDispatcherAfter.md @@ -27,7 +27,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/EventListener/ActionDispatcherLegacyHooksSubscriber.php](src/PrestaShopBundle/EventListener/ActionDispatcherLegacyHooksSubscriber.php) + - [src/PrestaShopBundle/EventListener/ActionDispatcherLegacyHooksSubscriber.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/EventListener/ActionDispatcherLegacyHooksSubscriber.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionDispatcherBefore.md b/modules/concepts/hooks/list-of-hooks/actionDispatcherBefore.md index 7aa2eedb2a..f7724cf271 100644 --- a/modules/concepts/hooks/list-of-hooks/actionDispatcherBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionDispatcherBefore.md @@ -27,7 +27,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/EventListener/ActionDispatcherLegacyHooksSubscriber.php](src/PrestaShopBundle/EventListener/ActionDispatcherLegacyHooksSubscriber.php) + - [src/PrestaShopBundle/EventListener/ActionDispatcherLegacyHooksSubscriber.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/EventListener/ActionDispatcherLegacyHooksSubscriber.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionDownloadAttachment.md b/modules/concepts/hooks/list-of-hooks/actionDownloadAttachment.md index 25f3e1b48a..0a0443b318 100644 --- a/modules/concepts/hooks/list-of-hooks/actionDownloadAttachment.md +++ b/modules/concepts/hooks/list-of-hooks/actionDownloadAttachment.md @@ -21,7 +21,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/front/AttachmentController.php](controllers/front/AttachmentController.php) + - [controllers/front/AttachmentController.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/front/AttachmentController.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionEmailAddAfterContent.md b/modules/concepts/hooks/list-of-hooks/actionEmailAddAfterContent.md index a1db504c08..3b10a53f09 100644 --- a/modules/concepts/hooks/list-of-hooks/actionEmailAddAfterContent.md +++ b/modules/concepts/hooks/list-of-hooks/actionEmailAddAfterContent.md @@ -27,7 +27,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Mail.php](classes/Mail.php) + - [classes/Mail.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Mail.php) This hook has an `$array_return` parameter set to `true` (module output will be set by name in an array, [see explaination here]({{< relref "/8/development/components/hook/dispatching-hook">}})). diff --git a/modules/concepts/hooks/list-of-hooks/actionEmailAddBeforeContent.md b/modules/concepts/hooks/list-of-hooks/actionEmailAddBeforeContent.md index da6a77246e..78d6947357 100644 --- a/modules/concepts/hooks/list-of-hooks/actionEmailAddBeforeContent.md +++ b/modules/concepts/hooks/list-of-hooks/actionEmailAddBeforeContent.md @@ -27,7 +27,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Mail.php](classes/Mail.php) + - [classes/Mail.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Mail.php) This hook has an `$array_return` parameter set to `true` (module output will be set by name in an array, [see explaination here]({{< relref "/8/development/components/hook/dispatching-hook">}})). diff --git a/modules/concepts/hooks/list-of-hooks/actionEmailSendBefore.md b/modules/concepts/hooks/list-of-hooks/actionEmailSendBefore.md index bd6b9a4b19..e6c5db7fea 100644 --- a/modules/concepts/hooks/list-of-hooks/actionEmailSendBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionEmailSendBefore.md @@ -27,7 +27,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Mail.php](classes/Mail.php) + - [classes/Mail.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Mail.php) This hook has an `$array_return` parameter set to `true` (module output will be set by name in an array, [see explaination here]({{< relref "/8/development/components/hook/dispatching-hook">}})). diff --git a/modules/concepts/hooks/list-of-hooks/actionExportGDPRData.md b/modules/concepts/hooks/list-of-hooks/actionExportGDPRData.md index 25ad190ce4..73d7ca0e29 100644 --- a/modules/concepts/hooks/list-of-hooks/actionExportGDPRData.md +++ b/modules/concepts/hooks/list-of-hooks/actionExportGDPRData.md @@ -21,7 +21,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/modules/psgdpr/psgdpr.php](modules/psgdpr/psgdpr.php) + - [modules/psgdpr/psgdpr.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/modules/psgdpr/psgdpr.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionFeatureDelete.md b/modules/concepts/hooks/list-of-hooks/actionFeatureDelete.md index 08c7272b9e..43cd1025e8 100644 --- a/modules/concepts/hooks/list-of-hooks/actionFeatureDelete.md +++ b/modules/concepts/hooks/list-of-hooks/actionFeatureDelete.md @@ -33,7 +33,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Feature.php](classes/Feature.php) + - [classes/Feature.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Feature.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionFeatureSave.md b/modules/concepts/hooks/list-of-hooks/actionFeatureSave.md index e4d9fb8e77..5f62ab661a 100644 --- a/modules/concepts/hooks/list-of-hooks/actionFeatureSave.md +++ b/modules/concepts/hooks/list-of-hooks/actionFeatureSave.md @@ -33,7 +33,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Feature.php](classes/Feature.php) + - [classes/Feature.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Feature.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionFeatureValueDelete.md b/modules/concepts/hooks/list-of-hooks/actionFeatureValueDelete.md index 7bdc666130..f22d9980f4 100644 --- a/modules/concepts/hooks/list-of-hooks/actionFeatureValueDelete.md +++ b/modules/concepts/hooks/list-of-hooks/actionFeatureValueDelete.md @@ -33,7 +33,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/FeatureValue.php](classes/FeatureValue.php) + - [classes/FeatureValue.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/FeatureValue.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionFeatureValueSave.md b/modules/concepts/hooks/list-of-hooks/actionFeatureValueSave.md index 9f7d92f0b1..cf44b0ba6d 100644 --- a/modules/concepts/hooks/list-of-hooks/actionFeatureValueSave.md +++ b/modules/concepts/hooks/list-of-hooks/actionFeatureValueSave.md @@ -33,7 +33,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/FeatureValue.php](classes/FeatureValue.php) + - [classes/FeatureValue.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/FeatureValue.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionFilterDeliveryOptionList.md b/modules/concepts/hooks/list-of-hooks/actionFilterDeliveryOptionList.md index 9badb8d4c6..2f008aed6e 100644 --- a/modules/concepts/hooks/list-of-hooks/actionFilterDeliveryOptionList.md +++ b/modules/concepts/hooks/list-of-hooks/actionFilterDeliveryOptionList.md @@ -27,7 +27,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Cart.php](classes/Cart.php) + - [classes/Cart.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Cart.php) ## Parameters details diff --git a/modules/concepts/hooks/list-of-hooks/actionFrontControllerInitAfter.md b/modules/concepts/hooks/list-of-hooks/actionFrontControllerInitAfter.md index de8fe4c8ce..7ce778a152 100644 --- a/modules/concepts/hooks/list-of-hooks/actionFrontControllerInitAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionFrontControllerInitAfter.md @@ -33,7 +33,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/FrontController.php](classes/controller/FrontController.php) + - [classes/controller/FrontController.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/FrontController.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionFrontControllerInitBefore.md b/modules/concepts/hooks/list-of-hooks/actionFrontControllerInitBefore.md index 3deacdbae1..0625f5d57f 100644 --- a/modules/concepts/hooks/list-of-hooks/actionFrontControllerInitBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionFrontControllerInitBefore.md @@ -27,7 +27,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/FrontController.php](classes/controller/FrontController.php) + - [classes/controller/FrontController.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/FrontController.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionFrontControllerSetMedia.md b/modules/concepts/hooks/list-of-hooks/actionFrontControllerSetMedia.md index fd99e83265..fbb220b2b9 100644 --- a/modules/concepts/hooks/list-of-hooks/actionFrontControllerSetMedia.md +++ b/modules/concepts/hooks/list-of-hooks/actionFrontControllerSetMedia.md @@ -21,7 +21,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/FrontController.php](classes/controller/FrontController.php) + - [classes/controller/FrontController.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/FrontController.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionFrontControllerSetVariables.md b/modules/concepts/hooks/list-of-hooks/actionFrontControllerSetVariables.md index 03fbcf2478..272dfa123d 100644 --- a/modules/concepts/hooks/list-of-hooks/actionFrontControllerSetVariables.md +++ b/modules/concepts/hooks/list-of-hooks/actionFrontControllerSetVariables.md @@ -27,7 +27,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/FrontController.php](classes/controller/FrontController.php) + - [classes/controller/FrontController.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/FrontController.php) This hook has an `$array_return` parameter set to `true` (module output will be set by name in an array, [see explaination here]({{< relref "/8/development/components/hook/dispatching-hook">}})). diff --git a/modules/concepts/hooks/list-of-hooks/actionGetAdminOrderButtons.md b/modules/concepts/hooks/list-of-hooks/actionGetAdminOrderButtons.md index c10f0a8740..88e3aeff10 100644 --- a/modules/concepts/hooks/list-of-hooks/actionGetAdminOrderButtons.md +++ b/modules/concepts/hooks/list-of-hooks/actionGetAdminOrderButtons.md @@ -27,7 +27,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/Sell/Order/OrderController.php](src/PrestaShopBundle/Controller/Admin/Sell/Order/OrderController.php) + - [src/PrestaShopBundle/Controller/Admin/Sell/Order/OrderController.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Controller/Admin/Sell/Order/OrderController.php) ## Parameters details diff --git a/modules/concepts/hooks/list-of-hooks/actionGetAdminToolbarButtons.md b/modules/concepts/hooks/list-of-hooks/actionGetAdminToolbarButtons.md index 6584606e91..70739bf46c 100644 --- a/modules/concepts/hooks/list-of-hooks/actionGetAdminToolbarButtons.md +++ b/modules/concepts/hooks/list-of-hooks/actionGetAdminToolbarButtons.md @@ -27,7 +27,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/AdminController.php](classes/controller/AdminController.php) + - [classes/controller/AdminController.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/AdminController.php) ## Parameters details diff --git a/modules/concepts/hooks/list-of-hooks/actionGetAlternativeSearchPanels.md b/modules/concepts/hooks/list-of-hooks/actionGetAlternativeSearchPanels.md index fdc31f2e2f..e108262be8 100644 --- a/modules/concepts/hooks/list-of-hooks/actionGetAlternativeSearchPanels.md +++ b/modules/concepts/hooks/list-of-hooks/actionGetAlternativeSearchPanels.md @@ -27,7 +27,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/admin/AdminSearchController.php](controllers/admin/AdminSearchController.php) + - [controllers/admin/AdminSearchController.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/admin/AdminSearchController.php) This hook has an `$array_return` parameter set to `true` (module output will be set by name in an array, [see explaination here]({{< relref "/8/development/components/hook/dispatching-hook">}})). diff --git a/modules/concepts/hooks/list-of-hooks/actionGetExtraMailTemplateVars.md b/modules/concepts/hooks/list-of-hooks/actionGetExtraMailTemplateVars.md index 37ebbafd9c..e1e8de2364 100644 --- a/modules/concepts/hooks/list-of-hooks/actionGetExtraMailTemplateVars.md +++ b/modules/concepts/hooks/list-of-hooks/actionGetExtraMailTemplateVars.md @@ -21,7 +21,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Mail.php](classes/Mail.php) + - [classes/Mail.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Mail.php) This hook has an `$array_return` parameter set to `true` (module output will be set by name in an array, [see explaination here]({{< relref "/8/development/components/hook/dispatching-hook">}})). diff --git a/modules/concepts/hooks/list-of-hooks/actionGetIDZoneByAddressID.md b/modules/concepts/hooks/list-of-hooks/actionGetIDZoneByAddressID.md index e87f0243b3..cf03630b84 100644 --- a/modules/concepts/hooks/list-of-hooks/actionGetIDZoneByAddressID.md +++ b/modules/concepts/hooks/list-of-hooks/actionGetIDZoneByAddressID.md @@ -21,7 +21,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Address.php](classes/Address.php) + - [classes/Address.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Address.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionGetMailLayoutTransformations.md b/modules/concepts/hooks/list-of-hooks/actionGetMailLayoutTransformations.md index ae59429e72..cb67413824 100644 --- a/modules/concepts/hooks/list-of-hooks/actionGetMailLayoutTransformations.md +++ b/modules/concepts/hooks/list-of-hooks/actionGetMailLayoutTransformations.md @@ -27,7 +27,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/MailTemplate/MailTemplateTwigRenderer.php](src/Adapter/MailTemplate/MailTemplateTwigRenderer.php) + - [src/Adapter/MailTemplate/MailTemplateTwigRenderer.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/MailTemplate/MailTemplateTwigRenderer.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionGetProductPropertiesAfter.md b/modules/concepts/hooks/list-of-hooks/actionGetProductPropertiesAfter.md index 20244825c1..fec6bd33a8 100644 --- a/modules/concepts/hooks/list-of-hooks/actionGetProductPropertiesAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionGetProductPropertiesAfter.md @@ -25,7 +25,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Product.php](classes/Product.php) + - [classes/Product.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Product.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionGetProductPropertiesAfterUnitPrice.md b/modules/concepts/hooks/list-of-hooks/actionGetProductPropertiesAfterUnitPrice.md index 9124ebccbd..a9312f87ae 100644 --- a/modules/concepts/hooks/list-of-hooks/actionGetProductPropertiesAfterUnitPrice.md +++ b/modules/concepts/hooks/list-of-hooks/actionGetProductPropertiesAfterUnitPrice.md @@ -27,7 +27,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Product.php](classes/Product.php) + - [classes/Product.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Product.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionGetProductPropertiesBefore.md b/modules/concepts/hooks/list-of-hooks/actionGetProductPropertiesBefore.md index 8892c57d10..cabf252c98 100644 --- a/modules/concepts/hooks/list-of-hooks/actionGetProductPropertiesBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionGetProductPropertiesBefore.md @@ -21,7 +21,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Product.php](classes/Product.php) + - [classes/Product.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Product.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionHtaccessCreate.md b/modules/concepts/hooks/list-of-hooks/actionHtaccessCreate.md index 19f0aa5a69..d994e85d75 100644 --- a/modules/concepts/hooks/list-of-hooks/actionHtaccessCreate.md +++ b/modules/concepts/hooks/list-of-hooks/actionHtaccessCreate.md @@ -33,7 +33,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Tools.php](classes/Tools.php) + - [classes/Tools.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Tools.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionInvoiceNumberFormatted.md b/modules/concepts/hooks/list-of-hooks/actionInvoiceNumberFormatted.md index 68d903f1e1..984d8325ba 100644 --- a/modules/concepts/hooks/list-of-hooks/actionInvoiceNumberFormatted.md +++ b/modules/concepts/hooks/list-of-hooks/actionInvoiceNumberFormatted.md @@ -21,7 +21,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/order/OrderInvoice.php](classes/order/OrderInvoice.php) + - [classes/order/OrderInvoice.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/order/OrderInvoice.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionListMailThemes.md b/modules/concepts/hooks/list-of-hooks/actionListMailThemes.md index 5892f6b1bc..5452f3f57e 100644 --- a/modules/concepts/hooks/list-of-hooks/actionListMailThemes.md +++ b/modules/concepts/hooks/list-of-hooks/actionListMailThemes.md @@ -27,7 +27,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Core/MailTemplate/FolderThemeCatalog.php](src/Core/MailTemplate/FolderThemeCatalog.php) + - [src/Core/MailTemplate/FolderThemeCatalog.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Core/MailTemplate/FolderThemeCatalog.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionMailAlterMessageBeforeSend.md b/modules/concepts/hooks/list-of-hooks/actionMailAlterMessageBeforeSend.md index c7e6445152..c2fd5e6c00 100644 --- a/modules/concepts/hooks/list-of-hooks/actionMailAlterMessageBeforeSend.md +++ b/modules/concepts/hooks/list-of-hooks/actionMailAlterMessageBeforeSend.md @@ -21,7 +21,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Mail.php](classes/Mail.php) + - [classes/Mail.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Mail.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionModuleInstallAfter.md b/modules/concepts/hooks/list-of-hooks/actionModuleInstallAfter.md index 42863ec436..fb12240bf9 100644 --- a/modules/concepts/hooks/list-of-hooks/actionModuleInstallAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionModuleInstallAfter.md @@ -27,7 +27,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/module/Module.php](classes/module/Module.php) + - [classes/module/Module.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/module/Module.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionModuleInstallBefore.md b/modules/concepts/hooks/list-of-hooks/actionModuleInstallBefore.md index bd23a07d22..d34c63e5b5 100644 --- a/modules/concepts/hooks/list-of-hooks/actionModuleInstallBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionModuleInstallBefore.md @@ -27,7 +27,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/module/Module.php](classes/module/Module.php) + - [classes/module/Module.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/module/Module.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionModuleMailAlertSendCustomer.md b/modules/concepts/hooks/list-of-hooks/actionModuleMailAlertSendCustomer.md index a4afa874dd..b8f6f9d7ed 100644 --- a/modules/concepts/hooks/list-of-hooks/actionModuleMailAlertSendCustomer.md +++ b/modules/concepts/hooks/list-of-hooks/actionModuleMailAlertSendCustomer.md @@ -21,7 +21,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/modules/ps_emailalerts/MailAlert.php](modules/ps_emailalerts/MailAlert.php) + - [modules/ps_emailalerts/MailAlert.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/modules/ps_emailalerts/MailAlert.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionModuleRegisterHookAfter.md b/modules/concepts/hooks/list-of-hooks/actionModuleRegisterHookAfter.md index caa53c5757..1b257f437d 100644 --- a/modules/concepts/hooks/list-of-hooks/actionModuleRegisterHookAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionModuleRegisterHookAfter.md @@ -21,7 +21,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Hook.php](classes/Hook.php) + - [classes/Hook.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Hook.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionModuleRegisterHookBefore.md b/modules/concepts/hooks/list-of-hooks/actionModuleRegisterHookBefore.md index 47e6bba922..5548c72f5e 100644 --- a/modules/concepts/hooks/list-of-hooks/actionModuleRegisterHookBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionModuleRegisterHookBefore.md @@ -21,7 +21,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Hook.php](classes/Hook.php) + - [classes/Hook.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Hook.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionModuleUnRegisterHookAfter.md b/modules/concepts/hooks/list-of-hooks/actionModuleUnRegisterHookAfter.md index 8333093708..151d566611 100644 --- a/modules/concepts/hooks/list-of-hooks/actionModuleUnRegisterHookAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionModuleUnRegisterHookAfter.md @@ -21,7 +21,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Hook.php](classes/Hook.php) + - [classes/Hook.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Hook.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionModuleUnRegisterHookBefore.md b/modules/concepts/hooks/list-of-hooks/actionModuleUnRegisterHookBefore.md index 348731119a..437a202d25 100644 --- a/modules/concepts/hooks/list-of-hooks/actionModuleUnRegisterHookBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionModuleUnRegisterHookBefore.md @@ -21,7 +21,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Hook.php](classes/Hook.php) + - [classes/Hook.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Hook.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionModuleUninstallAfter.md b/modules/concepts/hooks/list-of-hooks/actionModuleUninstallAfter.md index 3651a7a448..0704a35d56 100644 --- a/modules/concepts/hooks/list-of-hooks/actionModuleUninstallAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionModuleUninstallAfter.md @@ -27,7 +27,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/module/Module.php](classes/module/Module.php) + - [classes/module/Module.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/module/Module.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionModuleUninstallBefore.md b/modules/concepts/hooks/list-of-hooks/actionModuleUninstallBefore.md index 26bd59404d..97b2ffd54b 100644 --- a/modules/concepts/hooks/list-of-hooks/actionModuleUninstallBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionModuleUninstallBefore.md @@ -27,7 +27,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/module/Module.php](classes/module/Module.php) + - [classes/module/Module.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/module/Module.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionNewsletterRegistrationAfter.md b/modules/concepts/hooks/list-of-hooks/actionNewsletterRegistrationAfter.md index 405129867a..22636c3dfd 100644 --- a/modules/concepts/hooks/list-of-hooks/actionNewsletterRegistrationAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionNewsletterRegistrationAfter.md @@ -21,7 +21,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/modules/ps_emailsubscription/ps_emailsubscription.php](modules/ps_emailsubscription/ps_emailsubscription.php) + - [modules/ps_emailsubscription/ps_emailsubscription.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/modules/ps_emailsubscription/ps_emailsubscription.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionNewsletterRegistrationBefore.md b/modules/concepts/hooks/list-of-hooks/actionNewsletterRegistrationBefore.md index 66f9cf2743..9f99b6c3e8 100644 --- a/modules/concepts/hooks/list-of-hooks/actionNewsletterRegistrationBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionNewsletterRegistrationBefore.md @@ -21,7 +21,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/modules/ps_emailsubscription/ps_emailsubscription.php](modules/ps_emailsubscription/ps_emailsubscription.php) + - [modules/ps_emailsubscription/ps_emailsubscription.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/modules/ps_emailsubscription/ps_emailsubscription.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionObjectAddAfter.md b/modules/concepts/hooks/list-of-hooks/actionObjectAddAfter.md index 23b5f9ef3f..ba37e709a9 100644 --- a/modules/concepts/hooks/list-of-hooks/actionObjectAddAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionObjectAddAfter.md @@ -23,7 +23,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/ObjectModel.php](classes/ObjectModel.php) + - [classes/ObjectModel.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/ObjectModel.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionObjectAddBefore.md b/modules/concepts/hooks/list-of-hooks/actionObjectAddBefore.md index 3fc32f10c8..d990fb2bf2 100644 --- a/modules/concepts/hooks/list-of-hooks/actionObjectAddBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionObjectAddBefore.md @@ -23,7 +23,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/ObjectModel.php](classes/ObjectModel.php) + - [classes/ObjectModel.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/ObjectModel.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionObjectDeleteAfter.md b/modules/concepts/hooks/list-of-hooks/actionObjectDeleteAfter.md index 0b7b6b8f50..6a7c3c2b66 100644 --- a/modules/concepts/hooks/list-of-hooks/actionObjectDeleteAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionObjectDeleteAfter.md @@ -23,7 +23,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/ObjectModel.php](classes/ObjectModel.php) + - [classes/ObjectModel.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/ObjectModel.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionObjectDeleteBefore.md b/modules/concepts/hooks/list-of-hooks/actionObjectDeleteBefore.md index 02a1a032d7..4082545116 100644 --- a/modules/concepts/hooks/list-of-hooks/actionObjectDeleteBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionObjectDeleteBefore.md @@ -23,7 +23,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/ObjectModel.php](classes/ObjectModel.php) + - [classes/ObjectModel.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/ObjectModel.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionObjectUpdateAfter.md b/modules/concepts/hooks/list-of-hooks/actionObjectUpdateAfter.md index 7e3a8da1d5..295ef5ebea 100644 --- a/modules/concepts/hooks/list-of-hooks/actionObjectUpdateAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionObjectUpdateAfter.md @@ -23,7 +23,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/ObjectModel.php](classes/ObjectModel.php) + - [classes/ObjectModel.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/ObjectModel.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionObjectUpdateBefore.md b/modules/concepts/hooks/list-of-hooks/actionObjectUpdateBefore.md index 5796b4ce80..2ec8cd3167 100644 --- a/modules/concepts/hooks/list-of-hooks/actionObjectUpdateBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionObjectUpdateBefore.md @@ -23,7 +23,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/ObjectModel.php](classes/ObjectModel.php) + - [classes/ObjectModel.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/ObjectModel.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionObjectAddAfter.md b/modules/concepts/hooks/list-of-hooks/actionObjectAddAfter.md index ca0b6589a0..ed5565b37a 100644 --- a/modules/concepts/hooks/list-of-hooks/actionObjectAddAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionObjectAddAfter.md @@ -23,7 +23,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/ObjectModel.php](classes/ObjectModel.php) + - [classes/ObjectModel.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/ObjectModel.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionObjectAddBefore.md b/modules/concepts/hooks/list-of-hooks/actionObjectAddBefore.md index e1096b8262..bc0634d34b 100644 --- a/modules/concepts/hooks/list-of-hooks/actionObjectAddBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionObjectAddBefore.md @@ -23,7 +23,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/ObjectModel.php](classes/ObjectModel.php) + - [classes/ObjectModel.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/ObjectModel.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionObjectAttributeAddBefore.md b/modules/concepts/hooks/list-of-hooks/actionObjectAttributeAddBefore.md index 44383a26df..5a31af6994 100644 --- a/modules/concepts/hooks/list-of-hooks/actionObjectAttributeAddBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionObjectAttributeAddBefore.md @@ -23,7 +23,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/admin/AdminAttributesGroupsController.php](controllers/admin/AdminAttributesGroupsController.php) + - [controllers/admin/AdminAttributesGroupsController.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/admin/AdminAttributesGroupsController.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionObjectAttributeGroupAddBefore.md b/modules/concepts/hooks/list-of-hooks/actionObjectAttributeGroupAddBefore.md index a37ef84305..b771d5f3b0 100644 --- a/modules/concepts/hooks/list-of-hooks/actionObjectAttributeGroupAddBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionObjectAttributeGroupAddBefore.md @@ -23,7 +23,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/admin/AdminAttributesGroupsController.php](controllers/admin/AdminAttributesGroupsController.php) + - [controllers/admin/AdminAttributesGroupsController.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/admin/AdminAttributesGroupsController.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionObjectDeleteAfter.md b/modules/concepts/hooks/list-of-hooks/actionObjectDeleteAfter.md index b038c06f18..d17177cf42 100644 --- a/modules/concepts/hooks/list-of-hooks/actionObjectDeleteAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionObjectDeleteAfter.md @@ -23,7 +23,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/ObjectModel.php](classes/ObjectModel.php) + - [classes/ObjectModel.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/ObjectModel.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionObjectDeleteBefore.md b/modules/concepts/hooks/list-of-hooks/actionObjectDeleteBefore.md index 531a4221b2..78d0b119a0 100644 --- a/modules/concepts/hooks/list-of-hooks/actionObjectDeleteBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionObjectDeleteBefore.md @@ -23,7 +23,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/ObjectModel.php](classes/ObjectModel.php) + - [classes/ObjectModel.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/ObjectModel.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionObjectProductCommentValidateAfter.md b/modules/concepts/hooks/list-of-hooks/actionObjectProductCommentValidateAfter.md index 289256d0b1..b418417744 100644 --- a/modules/concepts/hooks/list-of-hooks/actionObjectProductCommentValidateAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionObjectProductCommentValidateAfter.md @@ -23,7 +23,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/modules/productcomments/ProductComment.php](modules/productcomments/ProductComment.php) + - [modules/productcomments/ProductComment.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/modules/productcomments/ProductComment.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionObjectProductInCartDeleteAfter.md b/modules/concepts/hooks/list-of-hooks/actionObjectProductInCartDeleteAfter.md index 52af6de034..d5583be39d 100644 --- a/modules/concepts/hooks/list-of-hooks/actionObjectProductInCartDeleteAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionObjectProductInCartDeleteAfter.md @@ -29,7 +29,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/front/CartController.php](controllers/front/CartController.php) + - [controllers/front/CartController.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/front/CartController.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionObjectProductInCartDeleteBefore.md b/modules/concepts/hooks/list-of-hooks/actionObjectProductInCartDeleteBefore.md index a9e7c867f8..ac4efab0d0 100644 --- a/modules/concepts/hooks/list-of-hooks/actionObjectProductInCartDeleteBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionObjectProductInCartDeleteBefore.md @@ -29,7 +29,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/front/CartController.php](controllers/front/CartController.php) + - [controllers/front/CartController.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/front/CartController.php) This hook has an `$array_return` parameter set to `true` (module output will be set by name in an array, [see explaination here]({{< relref "/8/development/components/hook/dispatching-hook">}})). diff --git a/modules/concepts/hooks/list-of-hooks/actionObjectUpdateAfter.md b/modules/concepts/hooks/list-of-hooks/actionObjectUpdateAfter.md index 3fff3378aa..8cb2f18c00 100644 --- a/modules/concepts/hooks/list-of-hooks/actionObjectUpdateAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionObjectUpdateAfter.md @@ -23,7 +23,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/ObjectModel.php](classes/ObjectModel.php) + - [classes/ObjectModel.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/ObjectModel.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionObjectUpdateBefore.md b/modules/concepts/hooks/list-of-hooks/actionObjectUpdateBefore.md index 78d9569063..99ae4f2275 100644 --- a/modules/concepts/hooks/list-of-hooks/actionObjectUpdateBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionObjectUpdateBefore.md @@ -23,7 +23,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/ObjectModel.php](classes/ObjectModel.php) + - [classes/ObjectModel.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/ObjectModel.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionOnImageCutAfter.md b/modules/concepts/hooks/list-of-hooks/actionOnImageCutAfter.md index b6567fc526..9562972061 100644 --- a/modules/concepts/hooks/list-of-hooks/actionOnImageCutAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionOnImageCutAfter.md @@ -21,7 +21,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/ImageManager.php](classes/ImageManager.php) + - [classes/ImageManager.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/ImageManager.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionOnImageResizeAfter.md b/modules/concepts/hooks/list-of-hooks/actionOnImageResizeAfter.md index 7798844987..058c285141 100644 --- a/modules/concepts/hooks/list-of-hooks/actionOnImageResizeAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionOnImageResizeAfter.md @@ -21,7 +21,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/ImageManager.php](classes/ImageManager.php) + - [classes/ImageManager.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/ImageManager.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionOrderEdited.md b/modules/concepts/hooks/list-of-hooks/actionOrderEdited.md index 9bae78af85..5a33f4b62c 100644 --- a/modules/concepts/hooks/list-of-hooks/actionOrderEdited.md +++ b/modules/concepts/hooks/list-of-hooks/actionOrderEdited.md @@ -27,7 +27,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Order/CommandHandler/UpdateProductInOrderHandler.php](src/Adapter/Order/CommandHandler/UpdateProductInOrderHandler.php) + - [src/Adapter/Order/CommandHandler/UpdateProductInOrderHandler.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Order/CommandHandler/UpdateProductInOrderHandler.php) ## Parameters details diff --git a/modules/concepts/hooks/list-of-hooks/actionOrderHistoryAddAfter.md b/modules/concepts/hooks/list-of-hooks/actionOrderHistoryAddAfter.md index 2488d7e36b..48ab678313 100644 --- a/modules/concepts/hooks/list-of-hooks/actionOrderHistoryAddAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionOrderHistoryAddAfter.md @@ -21,7 +21,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/order/OrderHistory.php](classes/order/OrderHistory.php) + - [classes/order/OrderHistory.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/order/OrderHistory.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionOrderReturn.md b/modules/concepts/hooks/list-of-hooks/actionOrderReturn.md index 4e6bf8cf38..84772e13b2 100644 --- a/modules/concepts/hooks/list-of-hooks/actionOrderReturn.md +++ b/modules/concepts/hooks/list-of-hooks/actionOrderReturn.md @@ -33,7 +33,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/front/OrderFollowController.php](controllers/front/OrderFollowController.php) + - [controllers/front/OrderFollowController.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/front/OrderFollowController.php) ## Parameters details diff --git a/modules/concepts/hooks/list-of-hooks/actionOrderSlipAdd.md b/modules/concepts/hooks/list-of-hooks/actionOrderSlipAdd.md index 3bc07f547a..ccb40bc64b 100644 --- a/modules/concepts/hooks/list-of-hooks/actionOrderSlipAdd.md +++ b/modules/concepts/hooks/list-of-hooks/actionOrderSlipAdd.md @@ -33,7 +33,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Order/Refund/OrderSlipCreator.php](src/Adapter/Order/Refund/OrderSlipCreator.php) + - [src/Adapter/Order/Refund/OrderSlipCreator.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Order/Refund/OrderSlipCreator.php) ## Parameters details diff --git a/modules/concepts/hooks/list-of-hooks/actionOrderStatusPostUpdate.md b/modules/concepts/hooks/list-of-hooks/actionOrderStatusPostUpdate.md index a167511841..f3932f1882 100644 --- a/modules/concepts/hooks/list-of-hooks/actionOrderStatusPostUpdate.md +++ b/modules/concepts/hooks/list-of-hooks/actionOrderStatusPostUpdate.md @@ -33,7 +33,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/order/OrderHistory.php](classes/order/OrderHistory.php) + - [classes/order/OrderHistory.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/order/OrderHistory.php) ## Parameters details diff --git a/modules/concepts/hooks/list-of-hooks/actionOrderStatusUpdate.md b/modules/concepts/hooks/list-of-hooks/actionOrderStatusUpdate.md index deebc7a04f..e900109a32 100644 --- a/modules/concepts/hooks/list-of-hooks/actionOrderStatusUpdate.md +++ b/modules/concepts/hooks/list-of-hooks/actionOrderStatusUpdate.md @@ -33,7 +33,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/order/OrderHistory.php](classes/order/OrderHistory.php) + - [classes/order/OrderHistory.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/order/OrderHistory.php) ## Parameters details diff --git a/modules/concepts/hooks/list-of-hooks/actionOutputHTMLBefore.md b/modules/concepts/hooks/list-of-hooks/actionOutputHTMLBefore.md index 9a43666df5..f7a6cc0fc0 100644 --- a/modules/concepts/hooks/list-of-hooks/actionOutputHTMLBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionOutputHTMLBefore.md @@ -27,7 +27,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/FrontController.php](classes/controller/FrontController.php) + - [classes/controller/FrontController.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/FrontController.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionOverrideEmployeeImage.md b/modules/concepts/hooks/list-of-hooks/actionOverrideEmployeeImage.md index 8eddba72cf..9aab083998 100644 --- a/modules/concepts/hooks/list-of-hooks/actionOverrideEmployeeImage.md +++ b/modules/concepts/hooks/list-of-hooks/actionOverrideEmployeeImage.md @@ -27,7 +27,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Employee.php](classes/Employee.php) + - [classes/Employee.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Employee.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionPDFInvoiceRender.md b/modules/concepts/hooks/list-of-hooks/actionPDFInvoiceRender.md index c545eb3883..04dcb66283 100644 --- a/modules/concepts/hooks/list-of-hooks/actionPDFInvoiceRender.md +++ b/modules/concepts/hooks/list-of-hooks/actionPDFInvoiceRender.md @@ -21,7 +21,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/PDF/OrderInvoicePdfGenerator.php](src/Adapter/PDF/OrderInvoicePdfGenerator.php) + - [src/Adapter/PDF/OrderInvoicePdfGenerator.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/PDF/OrderInvoicePdfGenerator.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionPasswordRenew.md b/modules/concepts/hooks/list-of-hooks/actionPasswordRenew.md index 33dc0b25ff..e400ce5447 100644 --- a/modules/concepts/hooks/list-of-hooks/actionPasswordRenew.md +++ b/modules/concepts/hooks/list-of-hooks/actionPasswordRenew.md @@ -21,7 +21,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/front/PasswordController.php](controllers/front/PasswordController.php) + - [controllers/front/PasswordController.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/front/PasswordController.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionPaymentCCAdd.md b/modules/concepts/hooks/list-of-hooks/actionPaymentCCAdd.md index e7975d2059..3a7db15490 100644 --- a/modules/concepts/hooks/list-of-hooks/actionPaymentCCAdd.md +++ b/modules/concepts/hooks/list-of-hooks/actionPaymentCCAdd.md @@ -33,7 +33,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/order/OrderPayment.php](classes/order/OrderPayment.php) + - [classes/order/OrderPayment.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/order/OrderPayment.php) ## Parameters details diff --git a/modules/concepts/hooks/list-of-hooks/actionPaymentConfirmation.md b/modules/concepts/hooks/list-of-hooks/actionPaymentConfirmation.md index ac2fdf6bc9..610202c10b 100644 --- a/modules/concepts/hooks/list-of-hooks/actionPaymentConfirmation.md +++ b/modules/concepts/hooks/list-of-hooks/actionPaymentConfirmation.md @@ -33,7 +33,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/order/OrderHistory.php](classes/order/OrderHistory.php) + - [classes/order/OrderHistory.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/order/OrderHistory.php) ## Parameters details diff --git a/modules/concepts/hooks/list-of-hooks/actionPresentCart.md b/modules/concepts/hooks/list-of-hooks/actionPresentCart.md index 1d65e4d07e..e613e17cba 100644 --- a/modules/concepts/hooks/list-of-hooks/actionPresentCart.md +++ b/modules/concepts/hooks/list-of-hooks/actionPresentCart.md @@ -27,7 +27,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Presenter/Cart/CartPresenter.php](src/Adapter/Presenter/Cart/CartPresenter.php) + - [src/Adapter/Presenter/Cart/CartPresenter.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Presenter/Cart/CartPresenter.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionPresentModule.md b/modules/concepts/hooks/list-of-hooks/actionPresentModule.md index 2b1ec994d9..00a898b5bb 100644 --- a/modules/concepts/hooks/list-of-hooks/actionPresentModule.md +++ b/modules/concepts/hooks/list-of-hooks/actionPresentModule.md @@ -21,7 +21,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Presenter/Module/ModulePresenter.php](src/Adapter/Presenter/Module/ModulePresenter.php) + - [src/Adapter/Presenter/Module/ModulePresenter.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Presenter/Module/ModulePresenter.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionPresentOrder.md b/modules/concepts/hooks/list-of-hooks/actionPresentOrder.md index 2b8283f7ed..180afe4084 100644 --- a/modules/concepts/hooks/list-of-hooks/actionPresentOrder.md +++ b/modules/concepts/hooks/list-of-hooks/actionPresentOrder.md @@ -27,7 +27,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Presenter/Order/OrderPresenter.php](src/Adapter/Presenter/Order/OrderPresenter.php) + - [src/Adapter/Presenter/Order/OrderPresenter.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Presenter/Order/OrderPresenter.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionPresentOrderReturn.md b/modules/concepts/hooks/list-of-hooks/actionPresentOrderReturn.md index 4648a42ae9..27632dfcf9 100644 --- a/modules/concepts/hooks/list-of-hooks/actionPresentOrderReturn.md +++ b/modules/concepts/hooks/list-of-hooks/actionPresentOrderReturn.md @@ -27,7 +27,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Presenter/Order/OrderReturnPresenter.php](src/Adapter/Presenter/Order/OrderReturnPresenter.php) + - [src/Adapter/Presenter/Order/OrderReturnPresenter.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Presenter/Order/OrderReturnPresenter.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionPresentPaymentOptions.md b/modules/concepts/hooks/list-of-hooks/actionPresentPaymentOptions.md index 5e5f74e618..e2e4163bf1 100644 --- a/modules/concepts/hooks/list-of-hooks/actionPresentPaymentOptions.md +++ b/modules/concepts/hooks/list-of-hooks/actionPresentPaymentOptions.md @@ -27,7 +27,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/checkout/PaymentOptionsFinder.php](classes/checkout/PaymentOptionsFinder.php) + - [classes/checkout/PaymentOptionsFinder.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/checkout/PaymentOptionsFinder.php) ## Parameters details diff --git a/modules/concepts/hooks/list-of-hooks/actionPresentProduct.md b/modules/concepts/hooks/list-of-hooks/actionPresentProduct.md index 9cc2d8eebd..0c9d891e3e 100644 --- a/modules/concepts/hooks/list-of-hooks/actionPresentProduct.md +++ b/modules/concepts/hooks/list-of-hooks/actionPresentProduct.md @@ -27,7 +27,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Presenter/Product/ProductPresenter.php](src/Adapter/Presenter/Product/ProductPresenter.php) + - [src/Adapter/Presenter/Product/ProductPresenter.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Presenter/Product/ProductPresenter.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionPresentProductListing.md b/modules/concepts/hooks/list-of-hooks/actionPresentProductListing.md index 71675d25c1..0cb78dc7d9 100644 --- a/modules/concepts/hooks/list-of-hooks/actionPresentProductListing.md +++ b/modules/concepts/hooks/list-of-hooks/actionPresentProductListing.md @@ -27,7 +27,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Presenter/Product/ProductListingPresenter.php](src/Adapter/Presenter/Product/ProductListingPresenter.php) + - [src/Adapter/Presenter/Product/ProductListingPresenter.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Presenter/Product/ProductListingPresenter.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionProductActivation.md b/modules/concepts/hooks/list-of-hooks/actionProductActivation.md index 464d2bd2ab..dfdb2c1244 100644 --- a/modules/concepts/hooks/list-of-hooks/actionProductActivation.md +++ b/modules/concepts/hooks/list-of-hooks/actionProductActivation.md @@ -21,7 +21,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Product/AdminProductDataUpdater.php](src/Adapter/Product/AdminProductDataUpdater.php) + - [src/Adapter/Product/AdminProductDataUpdater.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Product/AdminProductDataUpdater.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionProductAdd.md b/modules/concepts/hooks/list-of-hooks/actionProductAdd.md index 7cf2c54a49..a5bd07b5f6 100644 --- a/modules/concepts/hooks/list-of-hooks/actionProductAdd.md +++ b/modules/concepts/hooks/list-of-hooks/actionProductAdd.md @@ -33,7 +33,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Product/ProductDuplicator.php](src/Adapter/Product/ProductDuplicator.php) + - [src/Adapter/Product/ProductDuplicator.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Product/ProductDuplicator.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionProductAttributeDelete.md b/modules/concepts/hooks/list-of-hooks/actionProductAttributeDelete.md index 380bb77887..a8686ac004 100644 --- a/modules/concepts/hooks/list-of-hooks/actionProductAttributeDelete.md +++ b/modules/concepts/hooks/list-of-hooks/actionProductAttributeDelete.md @@ -33,7 +33,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Product.php](classes/Product.php) + - [classes/Product.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Product.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionProductAttributeUpdate.md b/modules/concepts/hooks/list-of-hooks/actionProductAttributeUpdate.md index b9cf0e28f4..970663ccf5 100644 --- a/modules/concepts/hooks/list-of-hooks/actionProductAttributeUpdate.md +++ b/modules/concepts/hooks/list-of-hooks/actionProductAttributeUpdate.md @@ -33,7 +33,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Product.php](classes/Product.php) + - [classes/Product.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Product.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionProductCancel.md b/modules/concepts/hooks/list-of-hooks/actionProductCancel.md index f4840fbae6..7cf078a008 100644 --- a/modules/concepts/hooks/list-of-hooks/actionProductCancel.md +++ b/modules/concepts/hooks/list-of-hooks/actionProductCancel.md @@ -33,7 +33,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Order/CommandHandler/IssueStandardRefundHandler.php](src/Adapter/Order/CommandHandler/IssueStandardRefundHandler.php) + - [src/Adapter/Order/CommandHandler/IssueStandardRefundHandler.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Order/CommandHandler/IssueStandardRefundHandler.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionProductCoverage.md b/modules/concepts/hooks/list-of-hooks/actionProductCoverage.md index 1dfe678512..d2ba0a84de 100644 --- a/modules/concepts/hooks/list-of-hooks/actionProductCoverage.md +++ b/modules/concepts/hooks/list-of-hooks/actionProductCoverage.md @@ -21,7 +21,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/stock/StockManager.php](classes/stock/StockManager.php) + - [classes/stock/StockManager.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/stock/StockManager.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionProductDelete.md b/modules/concepts/hooks/list-of-hooks/actionProductDelete.md index ab2a97c287..c284e71156 100644 --- a/modules/concepts/hooks/list-of-hooks/actionProductDelete.md +++ b/modules/concepts/hooks/list-of-hooks/actionProductDelete.md @@ -33,7 +33,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Product.php](classes/Product.php) + - [classes/Product.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Product.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionProductOutOfStock.md b/modules/concepts/hooks/list-of-hooks/actionProductOutOfStock.md index 6fe06fbfce..f86a68b6ea 100644 --- a/modules/concepts/hooks/list-of-hooks/actionProductOutOfStock.md +++ b/modules/concepts/hooks/list-of-hooks/actionProductOutOfStock.md @@ -33,7 +33,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/catalog/_partials/product-details.tpl](themes/classic/templates/catalog/_partials/product-details.tpl) + - [themes/classic/templates/catalog/_partials/product-details.tpl](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/catalog/_partials/product-details.tpl) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionProductSave.md b/modules/concepts/hooks/list-of-hooks/actionProductSave.md index d7dd5b087d..facc4c7c24 100644 --- a/modules/concepts/hooks/list-of-hooks/actionProductSave.md +++ b/modules/concepts/hooks/list-of-hooks/actionProductSave.md @@ -33,7 +33,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Product.php](classes/Product.php) + - [classes/Product.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Product.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionProductSearchAfter.md b/modules/concepts/hooks/list-of-hooks/actionProductSearchAfter.md index 51858c36f7..86fd4ccbaf 100644 --- a/modules/concepts/hooks/list-of-hooks/actionProductSearchAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionProductSearchAfter.md @@ -27,7 +27,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/modules/blockwishlist/controllers/front/view.php](modules/blockwishlist/controllers/front/view.php) + - [modules/blockwishlist/controllers/front/view.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/modules/blockwishlist/controllers/front/view.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionProductSearchProviderRunQueryAfter.md b/modules/concepts/hooks/list-of-hooks/actionProductSearchProviderRunQueryAfter.md index 86a47a6dc0..09659e7d74 100644 --- a/modules/concepts/hooks/list-of-hooks/actionProductSearchProviderRunQueryAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionProductSearchProviderRunQueryAfter.md @@ -27,7 +27,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/ProductListingFrontController.php](classes/controller/ProductListingFrontController.php) + - [classes/controller/ProductListingFrontController.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/ProductListingFrontController.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionProductSearchProviderRunQueryBefore.md b/modules/concepts/hooks/list-of-hooks/actionProductSearchProviderRunQueryBefore.md index d718b1ced2..4e3351bf86 100644 --- a/modules/concepts/hooks/list-of-hooks/actionProductSearchProviderRunQueryBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionProductSearchProviderRunQueryBefore.md @@ -27,7 +27,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/ProductListingFrontController.php](classes/controller/ProductListingFrontController.php) + - [classes/controller/ProductListingFrontController.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/ProductListingFrontController.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionProductUpdate.md b/modules/concepts/hooks/list-of-hooks/actionProductUpdate.md index 6705b13287..1175054e92 100644 --- a/modules/concepts/hooks/list-of-hooks/actionProductUpdate.md +++ b/modules/concepts/hooks/list-of-hooks/actionProductUpdate.md @@ -33,7 +33,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Product/AdminProductWrapper.php](src/Adapter/Product/AdminProductWrapper.php) + - [src/Adapter/Product/AdminProductWrapper.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Product/AdminProductWrapper.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionSearch.md b/modules/concepts/hooks/list-of-hooks/actionSearch.md index c621fef85a..0b8bd88eb6 100644 --- a/modules/concepts/hooks/list-of-hooks/actionSearch.md +++ b/modules/concepts/hooks/list-of-hooks/actionSearch.md @@ -21,7 +21,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Search/SearchProductSearchProvider.php](src/Adapter/Search/SearchProductSearchProvider.php) + - [src/Adapter/Search/SearchProductSearchProvider.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Search/SearchProductSearchProvider.php) ## Parameters details diff --git a/modules/concepts/hooks/list-of-hooks/actionSetInvoice.md b/modules/concepts/hooks/list-of-hooks/actionSetInvoice.md index 4d15ecc00e..4d4882af77 100644 --- a/modules/concepts/hooks/list-of-hooks/actionSetInvoice.md +++ b/modules/concepts/hooks/list-of-hooks/actionSetInvoice.md @@ -21,7 +21,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/order/Order.php](classes/order/Order.php) + - [classes/order/Order.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/order/Order.php) ## Parameters details diff --git a/modules/concepts/hooks/list-of-hooks/actionShopDataDuplication.md b/modules/concepts/hooks/list-of-hooks/actionShopDataDuplication.md index ce8cf220db..ffe5e972eb 100644 --- a/modules/concepts/hooks/list-of-hooks/actionShopDataDuplication.md +++ b/modules/concepts/hooks/list-of-hooks/actionShopDataDuplication.md @@ -21,7 +21,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/shop/Shop.php](classes/shop/Shop.php) + - [classes/shop/Shop.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/shop/Shop.php) ## Parameters details diff --git a/modules/concepts/hooks/list-of-hooks/actionSubmitAccountBefore.md b/modules/concepts/hooks/list-of-hooks/actionSubmitAccountBefore.md index b9387add30..fcda4e8fe9 100644 --- a/modules/concepts/hooks/list-of-hooks/actionSubmitAccountBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionSubmitAccountBefore.md @@ -27,7 +27,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/front/RegistrationController.php](controllers/front/RegistrationController.php) + - [controllers/front/RegistrationController.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/front/RegistrationController.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionSubmitCustomerAddressForm.md b/modules/concepts/hooks/list-of-hooks/actionSubmitCustomerAddressForm.md index a1e23602f2..6be654633b 100644 --- a/modules/concepts/hooks/list-of-hooks/actionSubmitCustomerAddressForm.md +++ b/modules/concepts/hooks/list-of-hooks/actionSubmitCustomerAddressForm.md @@ -21,7 +21,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/form/CustomerAddressForm.php](classes/form/CustomerAddressForm.php) + - [classes/form/CustomerAddressForm.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/form/CustomerAddressForm.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionUpdateLangAfter.md b/modules/concepts/hooks/list-of-hooks/actionUpdateLangAfter.md index 6a4508d479..83535437e1 100644 --- a/modules/concepts/hooks/list-of-hooks/actionUpdateLangAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionUpdateLangAfter.md @@ -27,7 +27,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Language.php](classes/Language.php) + - [classes/Language.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Language.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/actionUpdateQuantity.md b/modules/concepts/hooks/list-of-hooks/actionUpdateQuantity.md index 6139ec75a2..3fce8a9304 100644 --- a/modules/concepts/hooks/list-of-hooks/actionUpdateQuantity.md +++ b/modules/concepts/hooks/list-of-hooks/actionUpdateQuantity.md @@ -33,7 +33,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/stock/StockAvailable.php](classes/stock/StockAvailable.php) + - [classes/stock/StockAvailable.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/stock/StockAvailable.php) ## Parameters details diff --git a/modules/concepts/hooks/list-of-hooks/actionValidateCustomerAddressForm.md b/modules/concepts/hooks/list-of-hooks/actionValidateCustomerAddressForm.md index 97f4d7fe65..de049506c0 100644 --- a/modules/concepts/hooks/list-of-hooks/actionValidateCustomerAddressForm.md +++ b/modules/concepts/hooks/list-of-hooks/actionValidateCustomerAddressForm.md @@ -27,7 +27,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/form/CustomerAddressForm.php](classes/form/CustomerAddressForm.php) + - [classes/form/CustomerAddressForm.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/form/CustomerAddressForm.php) ## Parameters details diff --git a/modules/concepts/hooks/list-of-hooks/actionValidateOrder.md b/modules/concepts/hooks/list-of-hooks/actionValidateOrder.md index 26b1b113c3..8c5a1b1798 100644 --- a/modules/concepts/hooks/list-of-hooks/actionValidateOrder.md +++ b/modules/concepts/hooks/list-of-hooks/actionValidateOrder.md @@ -33,7 +33,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/PaymentModule.php](classes/PaymentModule.php) + - [classes/PaymentModule.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/PaymentModule.php) ## Parameters details diff --git a/modules/concepts/hooks/list-of-hooks/actionValidateOrderAfter.md b/modules/concepts/hooks/list-of-hooks/actionValidateOrderAfter.md index 4a6a2949db..4bba7372be 100644 --- a/modules/concepts/hooks/list-of-hooks/actionValidateOrderAfter.md +++ b/modules/concepts/hooks/list-of-hooks/actionValidateOrderAfter.md @@ -27,7 +27,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/PaymentModule.php](classes/PaymentModule.php) + - [classes/PaymentModule.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/PaymentModule.php) ## Parameters details diff --git a/modules/concepts/hooks/list-of-hooks/actionValidateStepComplete.md b/modules/concepts/hooks/list-of-hooks/actionValidateStepComplete.md index 769ce562d9..bee115e699 100644 --- a/modules/concepts/hooks/list-of-hooks/actionValidateStepComplete.md +++ b/modules/concepts/hooks/list-of-hooks/actionValidateStepComplete.md @@ -21,7 +21,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/checkout/CheckoutDeliveryStep.php](classes/checkout/CheckoutDeliveryStep.php) + - [classes/checkout/CheckoutDeliveryStep.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/checkout/CheckoutDeliveryStep.php) ## Parameters details diff --git a/modules/concepts/hooks/list-of-hooks/actionWatermark.md b/modules/concepts/hooks/list-of-hooks/actionWatermark.md index c9708e701b..b3aa36d349 100644 --- a/modules/concepts/hooks/list-of-hooks/actionWatermark.md +++ b/modules/concepts/hooks/list-of-hooks/actionWatermark.md @@ -33,7 +33,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Product/Image/Uploader/ProductImageUploader.php](src/Adapter/Product/Image/Uploader/ProductImageUploader.php) + - [src/Adapter/Product/Image/Uploader/ProductImageUploader.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Product/Image/Uploader/ProductImageUploader.php) ## Parameters details diff --git a/modules/concepts/hooks/list-of-hooks/actionWishlistAddProduct.md b/modules/concepts/hooks/list-of-hooks/actionWishlistAddProduct.md index d822a132da..c743931cea 100644 --- a/modules/concepts/hooks/list-of-hooks/actionWishlistAddProduct.md +++ b/modules/concepts/hooks/list-of-hooks/actionWishlistAddProduct.md @@ -21,7 +21,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/modules/blockwishlist/controllers/front/action.php](modules/blockwishlist/controllers/front/action.php) + - [modules/blockwishlist/controllers/front/action.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/modules/blockwishlist/controllers/front/action.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/addWebserviceResources.md b/modules/concepts/hooks/list-of-hooks/addWebserviceResources.md index 7ffd66c207..d5b9dfd511 100644 --- a/modules/concepts/hooks/list-of-hooks/addWebserviceResources.md +++ b/modules/concepts/hooks/list-of-hooks/addWebserviceResources.md @@ -27,7 +27,7 @@ Hook locations: Hook type: Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/webservice/WebserviceRequest.php](classes/webservice/WebserviceRequest.php) + - [classes/webservice/WebserviceRequest.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/webservice/WebserviceRequest.php) This hook has an `$array_return` parameter set to `true` (module output will be set by name in an array, [see explaination here]({{< relref "/8/development/components/hook/dispatching-hook">}})). diff --git a/modules/concepts/hooks/list-of-hooks/additionalCustomerAddressFields.md b/modules/concepts/hooks/list-of-hooks/additionalCustomerAddressFields.md index c8a43d806e..74d47a10ff 100644 --- a/modules/concepts/hooks/list-of-hooks/additionalCustomerAddressFields.md +++ b/modules/concepts/hooks/list-of-hooks/additionalCustomerAddressFields.md @@ -27,7 +27,7 @@ Hook locations: Hook type: Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/form/CustomerAddressFormatter.php](classes/form/CustomerAddressFormatter.php) + - [classes/form/CustomerAddressFormatter.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/form/CustomerAddressFormatter.php) This hook has an `$array_return` parameter set to `true` (module output will be set by name in an array, [see explaination here]({{< relref "/8/development/components/hook/dispatching-hook">}})). diff --git a/modules/concepts/hooks/list-of-hooks/additionalCustomerFormFields.md b/modules/concepts/hooks/list-of-hooks/additionalCustomerFormFields.md index a9f6625192..39c7d9e991 100644 --- a/modules/concepts/hooks/list-of-hooks/additionalCustomerFormFields.md +++ b/modules/concepts/hooks/list-of-hooks/additionalCustomerFormFields.md @@ -27,7 +27,7 @@ Hook locations: Hook type: Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/form/CustomerFormatter.php](classes/form/CustomerFormatter.php) + - [classes/form/CustomerFormatter.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/form/CustomerFormatter.php) This hook has an `$array_return` parameter set to `true` (module output will be set by name in an array, [see explaination here]({{< relref "/8/development/components/hook/dispatching-hook">}})). diff --git a/modules/concepts/hooks/list-of-hooks/dashboardData.md b/modules/concepts/hooks/list-of-hooks/dashboardData.md index 3e7da19d2c..22a7c157d5 100644 --- a/modules/concepts/hooks/list-of-hooks/dashboardData.md +++ b/modules/concepts/hooks/list-of-hooks/dashboardData.md @@ -21,7 +21,7 @@ Hook locations: Hook type: Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/admin/AdminDashboardController.php](controllers/admin/AdminDashboardController.php) + - [controllers/admin/AdminDashboardController.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/admin/AdminDashboardController.php) This hook has an `$array_return` parameter set to `true` (module output will be set by name in an array, [see explaination here]({{< relref "/8/development/components/hook/dispatching-hook">}})). diff --git a/modules/concepts/hooks/list-of-hooks/dashboardZoneOne.md b/modules/concepts/hooks/list-of-hooks/dashboardZoneOne.md index 339e51b94a..4bf6101b67 100644 --- a/modules/concepts/hooks/list-of-hooks/dashboardZoneOne.md +++ b/modules/concepts/hooks/list-of-hooks/dashboardZoneOne.md @@ -21,7 +21,7 @@ Hook locations: Hook type: Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/admin/AdminDashboardController.php](controllers/admin/AdminDashboardController.php) + - [controllers/admin/AdminDashboardController.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/admin/AdminDashboardController.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/dashboardZoneThree.md b/modules/concepts/hooks/list-of-hooks/dashboardZoneThree.md index 4a7f0f874f..3c322a9fc9 100644 --- a/modules/concepts/hooks/list-of-hooks/dashboardZoneThree.md +++ b/modules/concepts/hooks/list-of-hooks/dashboardZoneThree.md @@ -27,7 +27,7 @@ Hook locations: Hook type: Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/admin/AdminDashboardController.php](controllers/admin/AdminDashboardController.php) + - [controllers/admin/AdminDashboardController.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/admin/AdminDashboardController.php) ## Parameters details diff --git a/modules/concepts/hooks/list-of-hooks/dashboardZoneTwo.md b/modules/concepts/hooks/list-of-hooks/dashboardZoneTwo.md index a4ed2d4b99..b3eee325c1 100644 --- a/modules/concepts/hooks/list-of-hooks/dashboardZoneTwo.md +++ b/modules/concepts/hooks/list-of-hooks/dashboardZoneTwo.md @@ -21,7 +21,7 @@ Hook locations: Hook type: Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/admin/AdminDashboardController.php](controllers/admin/AdminDashboardController.php) + - [controllers/admin/AdminDashboardController.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/admin/AdminDashboardController.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/deleteProductAttribute.md b/modules/concepts/hooks/list-of-hooks/deleteProductAttribute.md index a8b3e16095..481d9372bd 100644 --- a/modules/concepts/hooks/list-of-hooks/deleteProductAttribute.md +++ b/modules/concepts/hooks/list-of-hooks/deleteProductAttribute.md @@ -21,7 +21,7 @@ Hook locations: Hook type: Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Product.php](classes/Product.php) + - [classes/Product.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Product.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/displayAdditionalCustomerAddressFields.md b/modules/concepts/hooks/list-of-hooks/displayAdditionalCustomerAddressFields.md index 2a22e84acc..654211cf39 100644 --- a/modules/concepts/hooks/list-of-hooks/displayAdditionalCustomerAddressFields.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdditionalCustomerAddressFields.md @@ -27,7 +27,7 @@ Hook locations: Hook type: display Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/customer/_partials/block-address.tpl](themes/classic/templates/customer/_partials/block-address.tpl) + - [themes/classic/templates/customer/_partials/block-address.tpl](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/customer/_partials/block-address.tpl) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/displayAdminAfterHeader.md b/modules/concepts/hooks/list-of-hooks/displayAdminAfterHeader.md index 9515787e93..e5282797aa 100644 --- a/modules/concepts/hooks/list-of-hooks/displayAdminAfterHeader.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminAfterHeader.md @@ -21,7 +21,7 @@ Hook locations: Hook type: display Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/admin784x07v4swfhm9fgvc0/themes/new-theme/template/light_display_layout.tpl](admin784x07v4swfhm9fgvc0/themes/new-theme/template/light_display_layout.tpl) + - [admin784x07v4swfhm9fgvc0/themes/new-theme/template/light_display_layout.tpl](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/admin784x07v4swfhm9fgvc0/themes/new-theme/template/light_display_layout.tpl) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/displayAdminCustomers.md b/modules/concepts/hooks/list-of-hooks/displayAdminCustomers.md index 04b71f88bb..a2c675160d 100644 --- a/modules/concepts/hooks/list-of-hooks/displayAdminCustomers.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminCustomers.md @@ -33,7 +33,7 @@ Hook locations: Hook type: display Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Resources/views/Admin/Sell/Customer/view.html.twig](src/PrestaShopBundle/Resources/views/Admin/Sell/Customer/view.html.twig) + - [src/PrestaShopBundle/Resources/views/Admin/Sell/Customer/view.html.twig](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Resources/views/Admin/Sell/Customer/view.html.twig) ## Parameters details diff --git a/modules/concepts/hooks/list-of-hooks/displayAdminEndContent.md b/modules/concepts/hooks/list-of-hooks/displayAdminEndContent.md index f7b9abb7dc..2062a601bd 100644 --- a/modules/concepts/hooks/list-of-hooks/displayAdminEndContent.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminEndContent.md @@ -27,7 +27,7 @@ Hook locations: Hook type: display Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/admin784x07v4swfhm9fgvc0/themes/new-theme/template/light_display_layout.tpl](admin784x07v4swfhm9fgvc0/themes/new-theme/template/light_display_layout.tpl) + - [admin784x07v4swfhm9fgvc0/themes/new-theme/template/light_display_layout.tpl](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/admin784x07v4swfhm9fgvc0/themes/new-theme/template/light_display_layout.tpl) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/displayAdminForm.md b/modules/concepts/hooks/list-of-hooks/displayAdminForm.md index 2aa89a2028..5e008d8f0a 100644 --- a/modules/concepts/hooks/list-of-hooks/displayAdminForm.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminForm.md @@ -21,7 +21,7 @@ Hook locations: Hook type: display Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/admin784x07v4swfhm9fgvc0/themes/default/template/helpers/form/form.tpl](admin784x07v4swfhm9fgvc0/themes/default/template/helpers/form/form.tpl) + - [admin784x07v4swfhm9fgvc0/themes/default/template/helpers/form/form.tpl](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/admin784x07v4swfhm9fgvc0/themes/default/template/helpers/form/form.tpl) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/displayAdminGridTableAfter.md b/modules/concepts/hooks/list-of-hooks/displayAdminGridTableAfter.md index 232e24af39..39cb32908a 100644 --- a/modules/concepts/hooks/list-of-hooks/displayAdminGridTableAfter.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminGridTableAfter.md @@ -33,7 +33,7 @@ Hook locations: Hook type: display Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Blocks/table.html.twig](src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Blocks/table.html.twig) + - [src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Blocks/table.html.twig](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Blocks/table.html.twig) ## Parameters details diff --git a/modules/concepts/hooks/list-of-hooks/displayAdminGridTableBefore.md b/modules/concepts/hooks/list-of-hooks/displayAdminGridTableBefore.md index 1bce3d7301..426fdace9f 100644 --- a/modules/concepts/hooks/list-of-hooks/displayAdminGridTableBefore.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminGridTableBefore.md @@ -33,7 +33,7 @@ Hook locations: Hook type: display Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Blocks/table.html.twig](src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Blocks/table.html.twig) + - [src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Blocks/table.html.twig](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Blocks/table.html.twig) ## Parameters details diff --git a/modules/concepts/hooks/list-of-hooks/displayAdminListAfter.md b/modules/concepts/hooks/list-of-hooks/displayAdminListAfter.md index 8bc72db610..c44f200749 100644 --- a/modules/concepts/hooks/list-of-hooks/displayAdminListAfter.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminListAfter.md @@ -21,7 +21,7 @@ Hook locations: Hook type: display Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/admin784x07v4swfhm9fgvc0/themes/default/template/helpers/list/list_footer.tpl](admin784x07v4swfhm9fgvc0/themes/default/template/helpers/list/list_footer.tpl) + - [admin784x07v4swfhm9fgvc0/themes/default/template/helpers/list/list_footer.tpl](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/admin784x07v4swfhm9fgvc0/themes/default/template/helpers/list/list_footer.tpl) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/displayAdminListBefore.md b/modules/concepts/hooks/list-of-hooks/displayAdminListBefore.md index c11cbc8209..8359ec0a78 100644 --- a/modules/concepts/hooks/list-of-hooks/displayAdminListBefore.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminListBefore.md @@ -21,7 +21,7 @@ Hook locations: Hook type: display Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/admin784x07v4swfhm9fgvc0/themes/default/template/helpers/list/list_header.tpl](admin784x07v4swfhm9fgvc0/themes/default/template/helpers/list/list_header.tpl) + - [admin784x07v4swfhm9fgvc0/themes/default/template/helpers/list/list_header.tpl](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/admin784x07v4swfhm9fgvc0/themes/default/template/helpers/list/list_header.tpl) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/displayAdminNavBarBeforeEnd.md b/modules/concepts/hooks/list-of-hooks/displayAdminNavBarBeforeEnd.md index 62a293daee..4f5781dc46 100644 --- a/modules/concepts/hooks/list-of-hooks/displayAdminNavBarBeforeEnd.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminNavBarBeforeEnd.md @@ -21,7 +21,7 @@ Hook locations: Hook type: display Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/admin784x07v4swfhm9fgvc0/themes/new-theme/template/components/layout/nav_bar.tpl](admin784x07v4swfhm9fgvc0/themes/new-theme/template/components/layout/nav_bar.tpl) + - [admin784x07v4swfhm9fgvc0/themes/new-theme/template/components/layout/nav_bar.tpl](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/admin784x07v4swfhm9fgvc0/themes/new-theme/template/components/layout/nav_bar.tpl) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/displayAdminOptions.md b/modules/concepts/hooks/list-of-hooks/displayAdminOptions.md index 27bea81cb6..9138b18255 100644 --- a/modules/concepts/hooks/list-of-hooks/displayAdminOptions.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminOptions.md @@ -21,7 +21,7 @@ Hook locations: Hook type: display Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/admin784x07v4swfhm9fgvc0/themes/default/template/helpers/options/options.tpl](admin784x07v4swfhm9fgvc0/themes/default/template/helpers/options/options.tpl) + - [admin784x07v4swfhm9fgvc0/themes/default/template/helpers/options/options.tpl](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/admin784x07v4swfhm9fgvc0/themes/default/template/helpers/options/options.tpl) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/displayAdminOrder.md b/modules/concepts/hooks/list-of-hooks/displayAdminOrder.md index ae3167dbbc..35cbe481c7 100644 --- a/modules/concepts/hooks/list-of-hooks/displayAdminOrder.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminOrder.md @@ -33,7 +33,7 @@ Hook locations: Hook type: display Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/view.html.twig](src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/view.html.twig) + - [src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/view.html.twig](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/view.html.twig) ## Parameters details diff --git a/modules/concepts/hooks/list-of-hooks/displayAdminOrderCreateExtraButtons.md b/modules/concepts/hooks/list-of-hooks/displayAdminOrderCreateExtraButtons.md index 72429893c2..953665128f 100644 --- a/modules/concepts/hooks/list-of-hooks/displayAdminOrderCreateExtraButtons.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminOrderCreateExtraButtons.md @@ -27,7 +27,7 @@ Hook locations: Hook type: display Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/Create/summary.html.twig](src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/Create/summary.html.twig) + - [src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/Create/summary.html.twig](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/Create/summary.html.twig) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/displayAdminOrderMain.md b/modules/concepts/hooks/list-of-hooks/displayAdminOrderMain.md index f348e34a49..6826e5cee0 100644 --- a/modules/concepts/hooks/list-of-hooks/displayAdminOrderMain.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminOrderMain.md @@ -27,7 +27,7 @@ Hook locations: Hook type: display Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/view.html.twig](src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/view.html.twig) + - [src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/view.html.twig](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/view.html.twig) ## Parameters details diff --git a/modules/concepts/hooks/list-of-hooks/displayAdminOrderMainBottom.md b/modules/concepts/hooks/list-of-hooks/displayAdminOrderMainBottom.md index 7c0bc2a056..e323e6c1bd 100644 --- a/modules/concepts/hooks/list-of-hooks/displayAdminOrderMainBottom.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminOrderMainBottom.md @@ -27,7 +27,7 @@ Hook locations: Hook type: display Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/view.html.twig](src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/view.html.twig) + - [src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/view.html.twig](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/view.html.twig) ## Parameters details diff --git a/modules/concepts/hooks/list-of-hooks/displayAdminOrderSide.md b/modules/concepts/hooks/list-of-hooks/displayAdminOrderSide.md index bed14a5773..e897b6e562 100644 --- a/modules/concepts/hooks/list-of-hooks/displayAdminOrderSide.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminOrderSide.md @@ -33,7 +33,7 @@ Hook locations: Hook type: display Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/view.html.twig](src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/view.html.twig) + - [src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/view.html.twig](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/view.html.twig) ## Parameters details diff --git a/modules/concepts/hooks/list-of-hooks/displayAdminOrderSideBottom.md b/modules/concepts/hooks/list-of-hooks/displayAdminOrderSideBottom.md index 7e6e85d3ed..4460182e5c 100644 --- a/modules/concepts/hooks/list-of-hooks/displayAdminOrderSideBottom.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminOrderSideBottom.md @@ -21,7 +21,7 @@ Hook locations: Hook type: display Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/view.html.twig](src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/view.html.twig) + - [src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/view.html.twig](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/view.html.twig) ## Parameters details diff --git a/modules/concepts/hooks/list-of-hooks/displayAdminProductsCombinationBottom.md b/modules/concepts/hooks/list-of-hooks/displayAdminProductsCombinationBottom.md index 365a185d60..74cc2f280b 100644 --- a/modules/concepts/hooks/list-of-hooks/displayAdminProductsCombinationBottom.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminProductsCombinationBottom.md @@ -27,7 +27,7 @@ Hook locations: Hook type: display Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Forms/form_combination.html.twig](src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Forms/form_combination.html.twig) + - [src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Forms/form_combination.html.twig](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Forms/form_combination.html.twig) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/displayAdminProductsMainStepLeftColumnBottom.md b/modules/concepts/hooks/list-of-hooks/displayAdminProductsMainStepLeftColumnBottom.md index b9ae9df53f..4addb039bb 100644 --- a/modules/concepts/hooks/list-of-hooks/displayAdminProductsMainStepLeftColumnBottom.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminProductsMainStepLeftColumnBottom.md @@ -27,7 +27,7 @@ Hook locations: Hook type: display Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/essentials.html.twig](src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/essentials.html.twig) + - [src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/essentials.html.twig](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/essentials.html.twig) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/displayAdminProductsMainStepLeftColumnMiddle.md b/modules/concepts/hooks/list-of-hooks/displayAdminProductsMainStepLeftColumnMiddle.md index c1002d9cdf..e8d255295c 100644 --- a/modules/concepts/hooks/list-of-hooks/displayAdminProductsMainStepLeftColumnMiddle.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminProductsMainStepLeftColumnMiddle.md @@ -27,7 +27,7 @@ Hook locations: Hook type: display Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/essentials.html.twig](src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/essentials.html.twig) + - [src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/essentials.html.twig](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/essentials.html.twig) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/displayAdminProductsMainStepRightColumnBottom.md b/modules/concepts/hooks/list-of-hooks/displayAdminProductsMainStepRightColumnBottom.md index 4b68846d37..f937d53692 100644 --- a/modules/concepts/hooks/list-of-hooks/displayAdminProductsMainStepRightColumnBottom.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminProductsMainStepRightColumnBottom.md @@ -27,7 +27,7 @@ Hook locations: Hook type: display Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/essentials.html.twig](src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/essentials.html.twig) + - [src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/essentials.html.twig](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/essentials.html.twig) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/displayAdminProductsOptionsStepBottom.md b/modules/concepts/hooks/list-of-hooks/displayAdminProductsOptionsStepBottom.md index 7df17c7a28..3ff1b71dd2 100644 --- a/modules/concepts/hooks/list-of-hooks/displayAdminProductsOptionsStepBottom.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminProductsOptionsStepBottom.md @@ -27,7 +27,7 @@ Hook locations: Hook type: display Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/options.html.twig](src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/options.html.twig) + - [src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/options.html.twig](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/options.html.twig) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/displayAdminProductsOptionsStepTop.md b/modules/concepts/hooks/list-of-hooks/displayAdminProductsOptionsStepTop.md index fbc840038e..b2061c25e2 100644 --- a/modules/concepts/hooks/list-of-hooks/displayAdminProductsOptionsStepTop.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminProductsOptionsStepTop.md @@ -27,7 +27,7 @@ Hook locations: Hook type: display Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/options.html.twig](src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/options.html.twig) + - [src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/options.html.twig](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/options.html.twig) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/displayAdminProductsPriceStepBottom.md b/modules/concepts/hooks/list-of-hooks/displayAdminProductsPriceStepBottom.md index b1f82bb9a1..86a7571b0c 100644 --- a/modules/concepts/hooks/list-of-hooks/displayAdminProductsPriceStepBottom.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminProductsPriceStepBottom.md @@ -27,7 +27,7 @@ Hook locations: Hook type: display Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/pricing.html.twig](src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/pricing.html.twig) + - [src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/pricing.html.twig](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/pricing.html.twig) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/displayAdminProductsQuantitiesStepBottom.md b/modules/concepts/hooks/list-of-hooks/displayAdminProductsQuantitiesStepBottom.md index 65c1474075..5d14e5768b 100644 --- a/modules/concepts/hooks/list-of-hooks/displayAdminProductsQuantitiesStepBottom.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminProductsQuantitiesStepBottom.md @@ -27,7 +27,7 @@ Hook locations: Hook type: display Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/combinations.html.twig](src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/combinations.html.twig) + - [src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/combinations.html.twig](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/combinations.html.twig) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/displayAdminProductsSeoStepBottom.md b/modules/concepts/hooks/list-of-hooks/displayAdminProductsSeoStepBottom.md index 8c09cb31c3..f786e42b41 100644 --- a/modules/concepts/hooks/list-of-hooks/displayAdminProductsSeoStepBottom.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminProductsSeoStepBottom.md @@ -27,7 +27,7 @@ Hook locations: Hook type: display Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Forms/form_seo.html.twig](src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Forms/form_seo.html.twig) + - [src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Forms/form_seo.html.twig](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Forms/form_seo.html.twig) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/displayAdminProductsShippingStepBottom.md b/modules/concepts/hooks/list-of-hooks/displayAdminProductsShippingStepBottom.md index f3fb2743cc..92a0705476 100644 --- a/modules/concepts/hooks/list-of-hooks/displayAdminProductsShippingStepBottom.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminProductsShippingStepBottom.md @@ -27,7 +27,7 @@ Hook locations: Hook type: display Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Forms/form_shipping.html.twig](src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Forms/form_shipping.html.twig) + - [src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Forms/form_shipping.html.twig](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Forms/form_shipping.html.twig) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/displayAdminStatsModules.md b/modules/concepts/hooks/list-of-hooks/displayAdminStatsModules.md index 71b8a2a4e3..fbdcf0cb4c 100644 --- a/modules/concepts/hooks/list-of-hooks/displayAdminStatsModules.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminStatsModules.md @@ -33,7 +33,7 @@ Hook locations: Hook type: display Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/admin/AdminStatsTabController.php](controllers/admin/AdminStatsTabController.php) + - [controllers/admin/AdminStatsTabController.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/admin/AdminStatsTabController.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/displayAdminThemesListAfter.md b/modules/concepts/hooks/list-of-hooks/displayAdminThemesListAfter.md index 5308a3cd95..3eda114280 100644 --- a/modules/concepts/hooks/list-of-hooks/displayAdminThemesListAfter.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminThemesListAfter.md @@ -27,7 +27,7 @@ Hook locations: Hook type: display Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Resources/views/Admin/Improve/Design/Theme/index.html.twig](src/PrestaShopBundle/Resources/views/Admin/Improve/Design/Theme/index.html.twig) + - [src/PrestaShopBundle/Resources/views/Admin/Improve/Design/Theme/index.html.twig](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Resources/views/Admin/Improve/Design/Theme/index.html.twig) ## Parameters details diff --git a/modules/concepts/hooks/list-of-hooks/displayAdminView.md b/modules/concepts/hooks/list-of-hooks/displayAdminView.md index 68206ed793..e122bc142a 100644 --- a/modules/concepts/hooks/list-of-hooks/displayAdminView.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminView.md @@ -21,7 +21,7 @@ Hook locations: Hook type: display Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/admin784x07v4swfhm9fgvc0/themes/default/template/helpers/view/view.tpl](admin784x07v4swfhm9fgvc0/themes/default/template/helpers/view/view.tpl) + - [admin784x07v4swfhm9fgvc0/themes/default/template/helpers/view/view.tpl](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/admin784x07v4swfhm9fgvc0/themes/default/template/helpers/view/view.tpl) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/displayAfterBodyOpeningTag.md b/modules/concepts/hooks/list-of-hooks/displayAfterBodyOpeningTag.md index c4bf409e21..6a89db419f 100644 --- a/modules/concepts/hooks/list-of-hooks/displayAfterBodyOpeningTag.md +++ b/modules/concepts/hooks/list-of-hooks/displayAfterBodyOpeningTag.md @@ -27,7 +27,7 @@ Hook locations: Hook type: display Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/layouts/layout-both-columns.tpl](themes/classic/templates/layouts/layout-both-columns.tpl) + - [themes/classic/templates/layouts/layout-both-columns.tpl](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/layouts/layout-both-columns.tpl) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/displayAfterCarrier.md b/modules/concepts/hooks/list-of-hooks/displayAfterCarrier.md index 99df80699b..9c7fd44c09 100644 --- a/modules/concepts/hooks/list-of-hooks/displayAfterCarrier.md +++ b/modules/concepts/hooks/list-of-hooks/displayAfterCarrier.md @@ -27,7 +27,7 @@ Hook locations: Hook type: display Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/checkout/CheckoutDeliveryStep.php](classes/checkout/CheckoutDeliveryStep.php) + - [classes/checkout/CheckoutDeliveryStep.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/checkout/CheckoutDeliveryStep.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/displayAfterProductThumbs.md b/modules/concepts/hooks/list-of-hooks/displayAfterProductThumbs.md index 824cc72b7b..33635a0d8b 100644 --- a/modules/concepts/hooks/list-of-hooks/displayAfterProductThumbs.md +++ b/modules/concepts/hooks/list-of-hooks/displayAfterProductThumbs.md @@ -27,7 +27,7 @@ Hook locations: Hook type: display Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/catalog/_partials/product-cover-thumbnails.tpl](themes/classic/templates/catalog/_partials/product-cover-thumbnails.tpl) + - [themes/classic/templates/catalog/_partials/product-cover-thumbnails.tpl](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/catalog/_partials/product-cover-thumbnails.tpl) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/displayAfterTitleTag.md b/modules/concepts/hooks/list-of-hooks/displayAfterTitleTag.md index 3fcab59466..abc81e08e8 100644 --- a/modules/concepts/hooks/list-of-hooks/displayAfterTitleTag.md +++ b/modules/concepts/hooks/list-of-hooks/displayAfterTitleTag.md @@ -27,7 +27,7 @@ Hook locations: Hook type: display Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/_partials/head.tpl](themes/classic/templates/_partials/head.tpl) + - [themes/classic/templates/_partials/head.tpl](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/_partials/head.tpl) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/displayBackOfficeCategory.md b/modules/concepts/hooks/list-of-hooks/displayBackOfficeCategory.md index 03e228e259..aaab7938ea 100644 --- a/modules/concepts/hooks/list-of-hooks/displayBackOfficeCategory.md +++ b/modules/concepts/hooks/list-of-hooks/displayBackOfficeCategory.md @@ -27,7 +27,7 @@ Hook locations: Hook type: display Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Categories/Blocks/form.html.twig](src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Categories/Blocks/form.html.twig) + - [src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Categories/Blocks/form.html.twig](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Categories/Blocks/form.html.twig) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/displayBackOfficeEmployeeMenu.md b/modules/concepts/hooks/list-of-hooks/displayBackOfficeEmployeeMenu.md index 95334e22ac..bd66650125 100644 --- a/modules/concepts/hooks/list-of-hooks/displayBackOfficeEmployeeMenu.md +++ b/modules/concepts/hooks/list-of-hooks/displayBackOfficeEmployeeMenu.md @@ -27,7 +27,7 @@ Hook locations: Hook type: display Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Bridge/Smarty/HeaderConfigurator.php](src/PrestaShopBundle/Bridge/Smarty/HeaderConfigurator.php) + - [src/PrestaShopBundle/Bridge/Smarty/HeaderConfigurator.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Bridge/Smarty/HeaderConfigurator.php) ## Parameters details diff --git a/modules/concepts/hooks/list-of-hooks/displayBackOfficeHeader.md b/modules/concepts/hooks/list-of-hooks/displayBackOfficeHeader.md index 9a6330d3e9..579339c6c5 100644 --- a/modules/concepts/hooks/list-of-hooks/displayBackOfficeHeader.md +++ b/modules/concepts/hooks/list-of-hooks/displayBackOfficeHeader.md @@ -33,7 +33,7 @@ Hook locations: Hook type: display Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/AdminController.php](classes/controller/AdminController.php) + - [classes/controller/AdminController.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/AdminController.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/displayBackOfficeTop.md b/modules/concepts/hooks/list-of-hooks/displayBackOfficeTop.md index cffc25ede9..c9fdd4f84b 100644 --- a/modules/concepts/hooks/list-of-hooks/displayBackOfficeTop.md +++ b/modules/concepts/hooks/list-of-hooks/displayBackOfficeTop.md @@ -33,7 +33,7 @@ Hook locations: Hook type: display Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/AdminController.php](classes/controller/AdminController.php) + - [classes/controller/AdminController.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/AdminController.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/displayBanner.md b/modules/concepts/hooks/list-of-hooks/displayBanner.md index a1110de199..b09b01b9e9 100644 --- a/modules/concepts/hooks/list-of-hooks/displayBanner.md +++ b/modules/concepts/hooks/list-of-hooks/displayBanner.md @@ -27,7 +27,7 @@ Hook locations: Hook type: display Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/_partials/header.tpl](themes/classic/templates/_partials/header.tpl) + - [themes/classic/templates/_partials/header.tpl](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/_partials/header.tpl) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/displayBeforeBodyClosingTag.md b/modules/concepts/hooks/list-of-hooks/displayBeforeBodyClosingTag.md index c263fef035..2734add49e 100644 --- a/modules/concepts/hooks/list-of-hooks/displayBeforeBodyClosingTag.md +++ b/modules/concepts/hooks/list-of-hooks/displayBeforeBodyClosingTag.md @@ -27,7 +27,7 @@ Hook locations: Hook type: display Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/layouts/layout-both-columns.tpl](themes/classic/templates/layouts/layout-both-columns.tpl) + - [themes/classic/templates/layouts/layout-both-columns.tpl](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/layouts/layout-both-columns.tpl) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/displayBeforeCarrier.md b/modules/concepts/hooks/list-of-hooks/displayBeforeCarrier.md index 8905666c24..f516595cd2 100644 --- a/modules/concepts/hooks/list-of-hooks/displayBeforeCarrier.md +++ b/modules/concepts/hooks/list-of-hooks/displayBeforeCarrier.md @@ -33,7 +33,7 @@ Hook locations: Hook type: display Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/checkout/CheckoutDeliveryStep.php](classes/checkout/CheckoutDeliveryStep.php) + - [classes/checkout/CheckoutDeliveryStep.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/checkout/CheckoutDeliveryStep.php) ## Parameters details diff --git a/modules/concepts/hooks/list-of-hooks/displayCMSDisputeInformation.md b/modules/concepts/hooks/list-of-hooks/displayCMSDisputeInformation.md index dcacf40cca..3007d79b88 100644 --- a/modules/concepts/hooks/list-of-hooks/displayCMSDisputeInformation.md +++ b/modules/concepts/hooks/list-of-hooks/displayCMSDisputeInformation.md @@ -21,7 +21,7 @@ Hook locations: Hook type: display Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/cms/page.tpl](themes/classic/templates/cms/page.tpl) + - [themes/classic/templates/cms/page.tpl](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/cms/page.tpl) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/displayCMSPrintButton.md b/modules/concepts/hooks/list-of-hooks/displayCMSPrintButton.md index e7cba4cd44..70db095099 100644 --- a/modules/concepts/hooks/list-of-hooks/displayCMSPrintButton.md +++ b/modules/concepts/hooks/list-of-hooks/displayCMSPrintButton.md @@ -21,7 +21,7 @@ Hook locations: Hook type: display Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/cms/page.tpl](themes/classic/templates/cms/page.tpl) + - [themes/classic/templates/cms/page.tpl](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/cms/page.tpl) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/displayCarrierExtraContent.md b/modules/concepts/hooks/list-of-hooks/displayCarrierExtraContent.md index 8de4c994b9..e2992e1989 100644 --- a/modules/concepts/hooks/list-of-hooks/displayCarrierExtraContent.md +++ b/modules/concepts/hooks/list-of-hooks/displayCarrierExtraContent.md @@ -27,7 +27,7 @@ Hook locations: Hook type: display Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/checkout/DeliveryOptionsFinder.php](classes/checkout/DeliveryOptionsFinder.php) + - [classes/checkout/DeliveryOptionsFinder.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/checkout/DeliveryOptionsFinder.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/displayCartExtraProductActions.md b/modules/concepts/hooks/list-of-hooks/displayCartExtraProductActions.md index 0bfa542b82..c0d5ebc7d2 100644 --- a/modules/concepts/hooks/list-of-hooks/displayCartExtraProductActions.md +++ b/modules/concepts/hooks/list-of-hooks/displayCartExtraProductActions.md @@ -27,7 +27,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/checkout/_partials/cart-detailed-product-line.tpl](themes/classic/templates/checkout/_partials/cart-detailed-product-line.tpl) + - [themes/classic/templates/checkout/_partials/cart-detailed-product-line.tpl](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/checkout/_partials/cart-detailed-product-line.tpl) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/displayCartModalContent.md b/modules/concepts/hooks/list-of-hooks/displayCartModalContent.md index 2c143d7ca7..bfbb7c752e 100644 --- a/modules/concepts/hooks/list-of-hooks/displayCartModalContent.md +++ b/modules/concepts/hooks/list-of-hooks/displayCartModalContent.md @@ -27,7 +27,7 @@ Hook locations: Hook type: display Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/modules/ps_shoppingcart/modal.tpl](themes/classic/modules/ps_shoppingcart/modal.tpl) + - [themes/classic/modules/ps_shoppingcart/modal.tpl](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/modules/ps_shoppingcart/modal.tpl) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/displayCartModalFooter.md b/modules/concepts/hooks/list-of-hooks/displayCartModalFooter.md index d46fc0fc29..a248cc18f9 100644 --- a/modules/concepts/hooks/list-of-hooks/displayCartModalFooter.md +++ b/modules/concepts/hooks/list-of-hooks/displayCartModalFooter.md @@ -27,7 +27,7 @@ Hook locations: Hook type: display Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/modules/ps_shoppingcart/modal.tpl](themes/classic/modules/ps_shoppingcart/modal.tpl) + - [themes/classic/modules/ps_shoppingcart/modal.tpl](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/modules/ps_shoppingcart/modal.tpl) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/displayCheckoutBeforeConfirmation.md b/modules/concepts/hooks/list-of-hooks/displayCheckoutBeforeConfirmation.md index 0ad2c090c5..a442a4c62d 100644 --- a/modules/concepts/hooks/list-of-hooks/displayCheckoutBeforeConfirmation.md +++ b/modules/concepts/hooks/list-of-hooks/displayCheckoutBeforeConfirmation.md @@ -27,7 +27,7 @@ Hook locations: Hook type: display Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/checkout/_partials/steps/payment.tpl](themes/classic/templates/checkout/_partials/steps/payment.tpl) + - [themes/classic/templates/checkout/_partials/steps/payment.tpl](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/checkout/_partials/steps/payment.tpl) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/displayCheckoutSubtotalDetails.md b/modules/concepts/hooks/list-of-hooks/displayCheckoutSubtotalDetails.md index 75961cfb75..a6c87fe7bc 100644 --- a/modules/concepts/hooks/list-of-hooks/displayCheckoutSubtotalDetails.md +++ b/modules/concepts/hooks/list-of-hooks/displayCheckoutSubtotalDetails.md @@ -21,7 +21,7 @@ Hook locations: Hook type: display Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/checkout/_partials/cart-detailed-totals.tpl](themes/classic/templates/checkout/_partials/cart-detailed-totals.tpl) + - [themes/classic/templates/checkout/_partials/cart-detailed-totals.tpl](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/checkout/_partials/cart-detailed-totals.tpl) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/displayCheckoutSummaryTop.md b/modules/concepts/hooks/list-of-hooks/displayCheckoutSummaryTop.md index 6cf4ad1822..98595e6aca 100644 --- a/modules/concepts/hooks/list-of-hooks/displayCheckoutSummaryTop.md +++ b/modules/concepts/hooks/list-of-hooks/displayCheckoutSummaryTop.md @@ -27,7 +27,7 @@ Hook locations: Hook type: display Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/checkout/_partials/cart-summary-top.tpl](themes/classic/templates/checkout/_partials/cart-summary-top.tpl) + - [themes/classic/templates/checkout/_partials/cart-summary-top.tpl](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/checkout/_partials/cart-summary-top.tpl) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/displayCrossSellingShoppingCart.md b/modules/concepts/hooks/list-of-hooks/displayCrossSellingShoppingCart.md index 71dab2ae54..e8172150ef 100644 --- a/modules/concepts/hooks/list-of-hooks/displayCrossSellingShoppingCart.md +++ b/modules/concepts/hooks/list-of-hooks/displayCrossSellingShoppingCart.md @@ -21,7 +21,7 @@ Hook locations: Hook type: display Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/checkout/cart.tpl](themes/classic/templates/checkout/cart.tpl) + - [themes/classic/templates/checkout/cart.tpl](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/checkout/cart.tpl) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/displayCustomerAccount.md b/modules/concepts/hooks/list-of-hooks/displayCustomerAccount.md index 785321c7f1..5779b369e1 100644 --- a/modules/concepts/hooks/list-of-hooks/displayCustomerAccount.md +++ b/modules/concepts/hooks/list-of-hooks/displayCustomerAccount.md @@ -33,7 +33,7 @@ Hook locations: Hook type: display Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/customer/my-account.tpl](themes/classic/templates/customer/my-account.tpl) + - [themes/classic/templates/customer/my-account.tpl](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/customer/my-account.tpl) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/displayCustomerAccountForm.md b/modules/concepts/hooks/list-of-hooks/displayCustomerAccountForm.md index 2da82c7939..bd30d212c8 100644 --- a/modules/concepts/hooks/list-of-hooks/displayCustomerAccountForm.md +++ b/modules/concepts/hooks/list-of-hooks/displayCustomerAccountForm.md @@ -33,7 +33,7 @@ Hook locations: Hook type: display Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/form/CustomerForm.php](classes/form/CustomerForm.php) + - [classes/form/CustomerForm.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/form/CustomerForm.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/displayCustomerAccountFormTop.md b/modules/concepts/hooks/list-of-hooks/displayCustomerAccountFormTop.md index f23104a364..5664925c37 100644 --- a/modules/concepts/hooks/list-of-hooks/displayCustomerAccountFormTop.md +++ b/modules/concepts/hooks/list-of-hooks/displayCustomerAccountFormTop.md @@ -33,7 +33,7 @@ Hook locations: Hook type: display Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/front/RegistrationController.php](controllers/front/RegistrationController.php) + - [controllers/front/RegistrationController.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/front/RegistrationController.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/displayCustomerLoginFormAfter.md b/modules/concepts/hooks/list-of-hooks/displayCustomerLoginFormAfter.md index 827f1f5eed..4bf8f05837 100644 --- a/modules/concepts/hooks/list-of-hooks/displayCustomerLoginFormAfter.md +++ b/modules/concepts/hooks/list-of-hooks/displayCustomerLoginFormAfter.md @@ -27,7 +27,7 @@ Hook locations: Hook type: display Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/customer/authentication.tpl](themes/classic/templates/customer/authentication.tpl) + - [themes/classic/templates/customer/authentication.tpl](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/customer/authentication.tpl) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/displayCustomization.md b/modules/concepts/hooks/list-of-hooks/displayCustomization.md index bab148e5e9..1c29cd9ffb 100644 --- a/modules/concepts/hooks/list-of-hooks/displayCustomization.md +++ b/modules/concepts/hooks/list-of-hooks/displayCustomization.md @@ -21,7 +21,7 @@ Hook locations: Hook type: display Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Product.php](classes/Product.php) + - [classes/Product.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Product.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/displayDashboardToolbarIcons.md b/modules/concepts/hooks/list-of-hooks/displayDashboardToolbarIcons.md index 3066cd3fcd..86c88c8fa5 100644 --- a/modules/concepts/hooks/list-of-hooks/displayDashboardToolbarIcons.md +++ b/modules/concepts/hooks/list-of-hooks/displayDashboardToolbarIcons.md @@ -27,7 +27,7 @@ Hook locations: Hook type: display Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Resources/views/Admin/Product/CatalogPage/Blocks/tools.html.twig](src/PrestaShopBundle/Resources/views/Admin/Product/CatalogPage/Blocks/tools.html.twig) + - [src/PrestaShopBundle/Resources/views/Admin/Product/CatalogPage/Blocks/tools.html.twig](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Resources/views/Admin/Product/CatalogPage/Blocks/tools.html.twig) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/displayDashboardToolbarTopMenu.md b/modules/concepts/hooks/list-of-hooks/displayDashboardToolbarTopMenu.md index 1110d9f13c..256d283129 100644 --- a/modules/concepts/hooks/list-of-hooks/displayDashboardToolbarTopMenu.md +++ b/modules/concepts/hooks/list-of-hooks/displayDashboardToolbarTopMenu.md @@ -27,7 +27,7 @@ Hook locations: Hook type: display Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/admin784x07v4swfhm9fgvc0/themes/new-theme/template/page_header_toolbar.tpl](admin784x07v4swfhm9fgvc0/themes/new-theme/template/page_header_toolbar.tpl) + - [admin784x07v4swfhm9fgvc0/themes/new-theme/template/page_header_toolbar.tpl](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/admin784x07v4swfhm9fgvc0/themes/new-theme/template/page_header_toolbar.tpl) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/displayDashboardTop.md b/modules/concepts/hooks/list-of-hooks/displayDashboardTop.md index 56c2bf8a41..e8284134ef 100644 --- a/modules/concepts/hooks/list-of-hooks/displayDashboardTop.md +++ b/modules/concepts/hooks/list-of-hooks/displayDashboardTop.md @@ -27,7 +27,7 @@ Hook locations: Hook type: display Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/admin784x07v4swfhm9fgvc0/themes/new-theme/template/page_header_toolbar.tpl](admin784x07v4swfhm9fgvc0/themes/new-theme/template/page_header_toolbar.tpl) + - [admin784x07v4swfhm9fgvc0/themes/new-theme/template/page_header_toolbar.tpl](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/admin784x07v4swfhm9fgvc0/themes/new-theme/template/page_header_toolbar.tpl) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/displayEmptyModuleCategoryExtraMessage.md b/modules/concepts/hooks/list-of-hooks/displayEmptyModuleCategoryExtraMessage.md index 2e27ef9eea..d6011da421 100644 --- a/modules/concepts/hooks/list-of-hooks/displayEmptyModuleCategoryExtraMessage.md +++ b/modules/concepts/hooks/list-of-hooks/displayEmptyModuleCategoryExtraMessage.md @@ -27,7 +27,7 @@ Hook locations: Hook type: display Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Resources/views/Admin/Module/Includes/grid_manage_empty.html.twig](src/PrestaShopBundle/Resources/views/Admin/Module/Includes/grid_manage_empty.html.twig) + - [src/PrestaShopBundle/Resources/views/Admin/Module/Includes/grid_manage_empty.html.twig](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Resources/views/Admin/Module/Includes/grid_manage_empty.html.twig) ## Parameters details diff --git a/modules/concepts/hooks/list-of-hooks/displayExpressCheckout.md b/modules/concepts/hooks/list-of-hooks/displayExpressCheckout.md index 58e6738605..841a673613 100644 --- a/modules/concepts/hooks/list-of-hooks/displayExpressCheckout.md +++ b/modules/concepts/hooks/list-of-hooks/displayExpressCheckout.md @@ -21,7 +21,7 @@ Hook locations: Hook type: display Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/checkout/_partials/cart-detailed-actions.tpl](themes/classic/templates/checkout/_partials/cart-detailed-actions.tpl) + - [themes/classic/templates/checkout/_partials/cart-detailed-actions.tpl](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/checkout/_partials/cart-detailed-actions.tpl) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/displayFeatureForm.md b/modules/concepts/hooks/list-of-hooks/displayFeatureForm.md index fdf0650085..9479f9d926 100644 --- a/modules/concepts/hooks/list-of-hooks/displayFeatureForm.md +++ b/modules/concepts/hooks/list-of-hooks/displayFeatureForm.md @@ -33,7 +33,7 @@ Hook locations: Hook type: display Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Features/Blocks/form.html.twig](src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Features/Blocks/form.html.twig) + - [src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Features/Blocks/form.html.twig](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Features/Blocks/form.html.twig) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/displayFeaturePostProcess.md b/modules/concepts/hooks/list-of-hooks/displayFeaturePostProcess.md index 67dcb4f448..7bf4a25acb 100644 --- a/modules/concepts/hooks/list-of-hooks/displayFeaturePostProcess.md +++ b/modules/concepts/hooks/list-of-hooks/displayFeaturePostProcess.md @@ -33,7 +33,7 @@ Hook locations: Hook type: display Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/admin/AdminFeaturesController.php](controllers/admin/AdminFeaturesController.php) + - [controllers/admin/AdminFeaturesController.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/admin/AdminFeaturesController.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/displayFeatureValuePostProcess.md b/modules/concepts/hooks/list-of-hooks/displayFeatureValuePostProcess.md index ddf4443fc1..26b41c3deb 100644 --- a/modules/concepts/hooks/list-of-hooks/displayFeatureValuePostProcess.md +++ b/modules/concepts/hooks/list-of-hooks/displayFeatureValuePostProcess.md @@ -33,7 +33,7 @@ Hook locations: Hook type: display Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/admin/AdminFeaturesController.php](controllers/admin/AdminFeaturesController.php) + - [controllers/admin/AdminFeaturesController.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/admin/AdminFeaturesController.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/displayFooter.md b/modules/concepts/hooks/list-of-hooks/displayFooter.md index e7bdc3fdbb..d005751984 100644 --- a/modules/concepts/hooks/list-of-hooks/displayFooter.md +++ b/modules/concepts/hooks/list-of-hooks/displayFooter.md @@ -33,7 +33,7 @@ Hook locations: Hook type: display Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/_partials/footer.tpl](themes/classic/templates/_partials/footer.tpl) + - [themes/classic/templates/_partials/footer.tpl](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/_partials/footer.tpl) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/displayFooterAfter.md b/modules/concepts/hooks/list-of-hooks/displayFooterAfter.md index 2befc497a9..fd15471554 100644 --- a/modules/concepts/hooks/list-of-hooks/displayFooterAfter.md +++ b/modules/concepts/hooks/list-of-hooks/displayFooterAfter.md @@ -21,7 +21,7 @@ Hook locations: Hook type: display Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/_partials/footer.tpl](themes/classic/templates/_partials/footer.tpl) + - [themes/classic/templates/_partials/footer.tpl](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/_partials/footer.tpl) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/displayFooterBefore.md b/modules/concepts/hooks/list-of-hooks/displayFooterBefore.md index 2104e95e9d..f49bcda2a7 100644 --- a/modules/concepts/hooks/list-of-hooks/displayFooterBefore.md +++ b/modules/concepts/hooks/list-of-hooks/displayFooterBefore.md @@ -21,7 +21,7 @@ Hook locations: Hook type: display Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/_partials/footer.tpl](themes/classic/templates/_partials/footer.tpl) + - [themes/classic/templates/_partials/footer.tpl](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/_partials/footer.tpl) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/displayFooterProduct.md b/modules/concepts/hooks/list-of-hooks/displayFooterProduct.md index a58298f2f0..b35648461c 100644 --- a/modules/concepts/hooks/list-of-hooks/displayFooterProduct.md +++ b/modules/concepts/hooks/list-of-hooks/displayFooterProduct.md @@ -33,7 +33,7 @@ Hook locations: Hook type: display Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/catalog/product.tpl](themes/classic/templates/catalog/product.tpl) + - [themes/classic/templates/catalog/product.tpl](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/catalog/product.tpl) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/displayGDPRConsent.md b/modules/concepts/hooks/list-of-hooks/displayGDPRConsent.md index a2e98017b5..8a40e748e6 100644 --- a/modules/concepts/hooks/list-of-hooks/displayGDPRConsent.md +++ b/modules/concepts/hooks/list-of-hooks/displayGDPRConsent.md @@ -21,7 +21,7 @@ Hook locations: Hook type: display Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/modules/ps_emailsubscription/views/templates/hook/ps_emailsubscription.tpl](themes/classic/modules/ps_emailsubscription/views/templates/hook/ps_emailsubscription.tpl) + - [themes/classic/modules/ps_emailsubscription/views/templates/hook/ps_emailsubscription.tpl](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/modules/ps_emailsubscription/views/templates/hook/ps_emailsubscription.tpl) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/displayHeader.md b/modules/concepts/hooks/list-of-hooks/displayHeader.md index 9b10f06487..63c5897282 100644 --- a/modules/concepts/hooks/list-of-hooks/displayHeader.md +++ b/modules/concepts/hooks/list-of-hooks/displayHeader.md @@ -33,7 +33,7 @@ Hook locations: Hook type: display Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/FrontController.php](classes/controller/FrontController.php) + - [classes/controller/FrontController.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/FrontController.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/displayHome.md b/modules/concepts/hooks/list-of-hooks/displayHome.md index 20f1ce3f64..34bc41eb66 100644 --- a/modules/concepts/hooks/list-of-hooks/displayHome.md +++ b/modules/concepts/hooks/list-of-hooks/displayHome.md @@ -33,7 +33,7 @@ Hook locations: Hook type: display Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/front/IndexController.php](controllers/front/IndexController.php) + - [controllers/front/IndexController.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/front/IndexController.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/displayInvoiceLegalFreeText.md b/modules/concepts/hooks/list-of-hooks/displayInvoiceLegalFreeText.md index 839acc2bf9..61cdbf0e41 100644 --- a/modules/concepts/hooks/list-of-hooks/displayInvoiceLegalFreeText.md +++ b/modules/concepts/hooks/list-of-hooks/displayInvoiceLegalFreeText.md @@ -27,7 +27,7 @@ Hook locations: Hook type: display Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/pdf/HTMLTemplateInvoice.php](classes/pdf/HTMLTemplateInvoice.php) + - [classes/pdf/HTMLTemplateInvoice.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/pdf/HTMLTemplateInvoice.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/displayLeftColumnProduct.md b/modules/concepts/hooks/list-of-hooks/displayLeftColumnProduct.md index 2a3f804915..008a43dc2b 100644 --- a/modules/concepts/hooks/list-of-hooks/displayLeftColumnProduct.md +++ b/modules/concepts/hooks/list-of-hooks/displayLeftColumnProduct.md @@ -33,7 +33,7 @@ Hook locations: Hook type: display Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/layouts/layout-both-columns.tpl](themes/classic/templates/layouts/layout-both-columns.tpl) + - [themes/classic/templates/layouts/layout-both-columns.tpl](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/layouts/layout-both-columns.tpl) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/displayMaintenance.md b/modules/concepts/hooks/list-of-hooks/displayMaintenance.md index d1633fbdf7..37d5cd7f04 100644 --- a/modules/concepts/hooks/list-of-hooks/displayMaintenance.md +++ b/modules/concepts/hooks/list-of-hooks/displayMaintenance.md @@ -27,7 +27,7 @@ Hook locations: Hook type: display Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/FrontController.php](classes/controller/FrontController.php) + - [classes/controller/FrontController.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/FrontController.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/displayMyAccountBlock.md b/modules/concepts/hooks/list-of-hooks/displayMyAccountBlock.md index 09120e0a67..ec683ebb03 100644 --- a/modules/concepts/hooks/list-of-hooks/displayMyAccountBlock.md +++ b/modules/concepts/hooks/list-of-hooks/displayMyAccountBlock.md @@ -33,7 +33,7 @@ Hook locations: Hook type: display Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/modules/ps_customeraccountlinks/ps_customeraccountlinks.tpl](themes/classic/modules/ps_customeraccountlinks/ps_customeraccountlinks.tpl) + - [themes/classic/modules/ps_customeraccountlinks/ps_customeraccountlinks.tpl](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/modules/ps_customeraccountlinks/ps_customeraccountlinks.tpl) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/displayNav1.md b/modules/concepts/hooks/list-of-hooks/displayNav1.md index 58897c9b94..4219dfba36 100644 --- a/modules/concepts/hooks/list-of-hooks/displayNav1.md +++ b/modules/concepts/hooks/list-of-hooks/displayNav1.md @@ -21,7 +21,7 @@ Hook locations: Hook type: display Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/checkout/_partials/header.tpl](themes/classic/templates/checkout/_partials/header.tpl) + - [themes/classic/templates/checkout/_partials/header.tpl](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/checkout/_partials/header.tpl) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/displayNav2.md b/modules/concepts/hooks/list-of-hooks/displayNav2.md index 9917356ff8..30488e8798 100644 --- a/modules/concepts/hooks/list-of-hooks/displayNav2.md +++ b/modules/concepts/hooks/list-of-hooks/displayNav2.md @@ -21,7 +21,7 @@ Hook locations: Hook type: display Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/checkout/_partials/header.tpl](themes/classic/templates/checkout/_partials/header.tpl) + - [themes/classic/templates/checkout/_partials/header.tpl](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/checkout/_partials/header.tpl) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/displayNavFullWidth.md b/modules/concepts/hooks/list-of-hooks/displayNavFullWidth.md index 019a87c851..7884f0a9bf 100644 --- a/modules/concepts/hooks/list-of-hooks/displayNavFullWidth.md +++ b/modules/concepts/hooks/list-of-hooks/displayNavFullWidth.md @@ -27,7 +27,7 @@ Hook locations: Hook type: display Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/checkout/_partials/header.tpl](themes/classic/templates/checkout/_partials/header.tpl) + - [themes/classic/templates/checkout/_partials/header.tpl](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/checkout/_partials/header.tpl) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/displayNewsletterRegistration.md b/modules/concepts/hooks/list-of-hooks/displayNewsletterRegistration.md index e53b5d5c90..7d4b8593cf 100644 --- a/modules/concepts/hooks/list-of-hooks/displayNewsletterRegistration.md +++ b/modules/concepts/hooks/list-of-hooks/displayNewsletterRegistration.md @@ -21,7 +21,7 @@ Hook locations: Hook type: display Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/modules/ps_emailsubscription/views/templates/hook/ps_emailsubscription.tpl](themes/classic/modules/ps_emailsubscription/views/templates/hook/ps_emailsubscription.tpl) + - [themes/classic/modules/ps_emailsubscription/views/templates/hook/ps_emailsubscription.tpl](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/modules/ps_emailsubscription/views/templates/hook/ps_emailsubscription.tpl) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/displayNotFound.md b/modules/concepts/hooks/list-of-hooks/displayNotFound.md index bd13857db3..591753e4e7 100644 --- a/modules/concepts/hooks/list-of-hooks/displayNotFound.md +++ b/modules/concepts/hooks/list-of-hooks/displayNotFound.md @@ -21,7 +21,7 @@ Hook locations: Hook type: display Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/errors/not-found.tpl](themes/classic/templates/errors/not-found.tpl) + - [themes/classic/templates/errors/not-found.tpl](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/errors/not-found.tpl) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/displayOrderConfirmation.md b/modules/concepts/hooks/list-of-hooks/displayOrderConfirmation.md index 1a4895f62e..985c0f4b4f 100644 --- a/modules/concepts/hooks/list-of-hooks/displayOrderConfirmation.md +++ b/modules/concepts/hooks/list-of-hooks/displayOrderConfirmation.md @@ -33,7 +33,7 @@ Hook locations: Hook type: display Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/front/OrderConfirmationController.php](controllers/front/OrderConfirmationController.php) + - [controllers/front/OrderConfirmationController.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/front/OrderConfirmationController.php) ## Parameters details diff --git a/modules/concepts/hooks/list-of-hooks/displayOrderConfirmation1.md b/modules/concepts/hooks/list-of-hooks/displayOrderConfirmation1.md index a23f16b94b..bc1e0217c2 100644 --- a/modules/concepts/hooks/list-of-hooks/displayOrderConfirmation1.md +++ b/modules/concepts/hooks/list-of-hooks/displayOrderConfirmation1.md @@ -21,7 +21,7 @@ Hook locations: Hook type: display Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/checkout/order-confirmation.tpl](themes/classic/templates/checkout/order-confirmation.tpl) + - [themes/classic/templates/checkout/order-confirmation.tpl](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/checkout/order-confirmation.tpl) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/displayOrderConfirmation2.md b/modules/concepts/hooks/list-of-hooks/displayOrderConfirmation2.md index 2ccf6053dc..79610b9a09 100644 --- a/modules/concepts/hooks/list-of-hooks/displayOrderConfirmation2.md +++ b/modules/concepts/hooks/list-of-hooks/displayOrderConfirmation2.md @@ -21,7 +21,7 @@ Hook locations: Hook type: display Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/checkout/order-confirmation.tpl](themes/classic/templates/checkout/order-confirmation.tpl) + - [themes/classic/templates/checkout/order-confirmation.tpl](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/checkout/order-confirmation.tpl) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/displayOrderDetail.md b/modules/concepts/hooks/list-of-hooks/displayOrderDetail.md index 29bd4319ef..190db20f93 100644 --- a/modules/concepts/hooks/list-of-hooks/displayOrderDetail.md +++ b/modules/concepts/hooks/list-of-hooks/displayOrderDetail.md @@ -33,7 +33,7 @@ Hook locations: Hook type: display Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/front/OrderDetailController.php](controllers/front/OrderDetailController.php) + - [controllers/front/OrderDetailController.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/front/OrderDetailController.php) ## Parameters details diff --git a/modules/concepts/hooks/list-of-hooks/displayOrderPreview.md b/modules/concepts/hooks/list-of-hooks/displayOrderPreview.md index 8fc2d09ce6..6d615fe4d4 100644 --- a/modules/concepts/hooks/list-of-hooks/displayOrderPreview.md +++ b/modules/concepts/hooks/list-of-hooks/displayOrderPreview.md @@ -21,7 +21,7 @@ Hook locations: Hook type: display Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/preview.html.twig](src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/preview.html.twig) + - [src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/preview.html.twig](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/preview.html.twig) ## Parameters details diff --git a/modules/concepts/hooks/list-of-hooks/displayOverrideTemplate.md b/modules/concepts/hooks/list-of-hooks/displayOverrideTemplate.md index 368766669b..65a33f9263 100644 --- a/modules/concepts/hooks/list-of-hooks/displayOverrideTemplate.md +++ b/modules/concepts/hooks/list-of-hooks/displayOverrideTemplate.md @@ -27,7 +27,7 @@ Hook locations: Hook type: display Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/FrontController.php](classes/controller/FrontController.php) + - [classes/controller/FrontController.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/FrontController.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/displayPaymentByBinaries.md b/modules/concepts/hooks/list-of-hooks/displayPaymentByBinaries.md index 5567ccfc39..08e7eeae3e 100644 --- a/modules/concepts/hooks/list-of-hooks/displayPaymentByBinaries.md +++ b/modules/concepts/hooks/list-of-hooks/displayPaymentByBinaries.md @@ -27,7 +27,7 @@ Hook locations: Hook type: display Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/checkout/_partials/steps/payment.tpl](themes/classic/templates/checkout/_partials/steps/payment.tpl) + - [themes/classic/templates/checkout/_partials/steps/payment.tpl](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/checkout/_partials/steps/payment.tpl) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/displayPaymentReturn.md b/modules/concepts/hooks/list-of-hooks/displayPaymentReturn.md index 77a39ea021..67e58612bd 100644 --- a/modules/concepts/hooks/list-of-hooks/displayPaymentReturn.md +++ b/modules/concepts/hooks/list-of-hooks/displayPaymentReturn.md @@ -33,7 +33,7 @@ Hook locations: Hook type: display Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/front/OrderConfirmationController.php](controllers/front/OrderConfirmationController.php) + - [controllers/front/OrderConfirmationController.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/front/OrderConfirmationController.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/displayPaymentTop.md b/modules/concepts/hooks/list-of-hooks/displayPaymentTop.md index 3cae4854d3..8d2602f44e 100644 --- a/modules/concepts/hooks/list-of-hooks/displayPaymentTop.md +++ b/modules/concepts/hooks/list-of-hooks/displayPaymentTop.md @@ -33,7 +33,7 @@ Hook locations: Hook type: display Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/checkout/_partials/steps/payment.tpl](themes/classic/templates/checkout/_partials/steps/payment.tpl) + - [themes/classic/templates/checkout/_partials/steps/payment.tpl](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/checkout/_partials/steps/payment.tpl) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/displayPersonalInformationTop.md b/modules/concepts/hooks/list-of-hooks/displayPersonalInformationTop.md index 2c4ae619e9..44274db65e 100644 --- a/modules/concepts/hooks/list-of-hooks/displayPersonalInformationTop.md +++ b/modules/concepts/hooks/list-of-hooks/displayPersonalInformationTop.md @@ -27,7 +27,7 @@ Hook locations: Hook type: display Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/checkout/_partials/steps/personal-information.tpl](themes/classic/templates/checkout/_partials/steps/personal-information.tpl) + - [themes/classic/templates/checkout/_partials/steps/personal-information.tpl](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/checkout/_partials/steps/personal-information.tpl) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/displayProductActions.md b/modules/concepts/hooks/list-of-hooks/displayProductActions.md index 175078a39f..031c206a62 100644 --- a/modules/concepts/hooks/list-of-hooks/displayProductActions.md +++ b/modules/concepts/hooks/list-of-hooks/displayProductActions.md @@ -27,7 +27,7 @@ Hook locations: Hook type: action Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/catalog/_partials/product-add-to-cart.tpl](themes/classic/templates/catalog/_partials/product-add-to-cart.tpl) + - [themes/classic/templates/catalog/_partials/product-add-to-cart.tpl](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/catalog/_partials/product-add-to-cart.tpl) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/displayProductAdditionalInfo.md b/modules/concepts/hooks/list-of-hooks/displayProductAdditionalInfo.md index 7917773cdd..cf901e5e54 100644 --- a/modules/concepts/hooks/list-of-hooks/displayProductAdditionalInfo.md +++ b/modules/concepts/hooks/list-of-hooks/displayProductAdditionalInfo.md @@ -35,7 +35,7 @@ Hook locations: Hook type: display Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/catalog/_partials/quickview.tpl](themes/classic/templates/catalog/_partials/quickview.tpl) + - [themes/classic/templates/catalog/_partials/quickview.tpl](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/catalog/_partials/quickview.tpl) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/displayProductListReviews.md b/modules/concepts/hooks/list-of-hooks/displayProductListReviews.md index 9f610f11b7..a02318522e 100644 --- a/modules/concepts/hooks/list-of-hooks/displayProductListReviews.md +++ b/modules/concepts/hooks/list-of-hooks/displayProductListReviews.md @@ -21,7 +21,7 @@ Hook locations: Hook type: display Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/catalog/_partials/miniatures/product.tpl](themes/classic/templates/catalog/_partials/miniatures/product.tpl) + - [themes/classic/templates/catalog/_partials/miniatures/product.tpl](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/catalog/_partials/miniatures/product.tpl) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/displayProductPriceBlock.md b/modules/concepts/hooks/list-of-hooks/displayProductPriceBlock.md index 0c4f27b156..903510d916 100644 --- a/modules/concepts/hooks/list-of-hooks/displayProductPriceBlock.md +++ b/modules/concepts/hooks/list-of-hooks/displayProductPriceBlock.md @@ -21,7 +21,7 @@ Hook locations: Hook type: display Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/checkout/_partials/order-confirmation-table.tpl](themes/classic/templates/checkout/_partials/order-confirmation-table.tpl) + - [themes/classic/templates/checkout/_partials/order-confirmation-table.tpl](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/checkout/_partials/order-confirmation-table.tpl) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/displayReassurance.md b/modules/concepts/hooks/list-of-hooks/displayReassurance.md index f342c67e18..d07073cbcf 100644 --- a/modules/concepts/hooks/list-of-hooks/displayReassurance.md +++ b/modules/concepts/hooks/list-of-hooks/displayReassurance.md @@ -21,7 +21,7 @@ Hook locations: Hook type: display Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/checkout/checkout.tpl](themes/classic/templates/checkout/checkout.tpl) + - [themes/classic/templates/checkout/checkout.tpl](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/checkout/checkout.tpl) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/displayRightColumnProduct.md b/modules/concepts/hooks/list-of-hooks/displayRightColumnProduct.md index acc3aa1a02..7b32b6a844 100644 --- a/modules/concepts/hooks/list-of-hooks/displayRightColumnProduct.md +++ b/modules/concepts/hooks/list-of-hooks/displayRightColumnProduct.md @@ -33,7 +33,7 @@ Hook locations: Hook type: display Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/layouts/layout-both-columns.tpl](themes/classic/templates/layouts/layout-both-columns.tpl) + - [themes/classic/templates/layouts/layout-both-columns.tpl](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/layouts/layout-both-columns.tpl) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/displaySearch.md b/modules/concepts/hooks/list-of-hooks/displaySearch.md index 8412443565..62f6150ab7 100644 --- a/modules/concepts/hooks/list-of-hooks/displaySearch.md +++ b/modules/concepts/hooks/list-of-hooks/displaySearch.md @@ -21,7 +21,7 @@ Hook locations: Hook type: display Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/errors/not-found.tpl](themes/classic/templates/errors/not-found.tpl) + - [themes/classic/templates/errors/not-found.tpl](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/errors/not-found.tpl) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/displayShoppingCart.md b/modules/concepts/hooks/list-of-hooks/displayShoppingCart.md index 56e60c8c54..f51e82d2cc 100644 --- a/modules/concepts/hooks/list-of-hooks/displayShoppingCart.md +++ b/modules/concepts/hooks/list-of-hooks/displayShoppingCart.md @@ -33,7 +33,7 @@ Hook locations: Hook type: display Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/checkout/cart.tpl](themes/classic/templates/checkout/cart.tpl) + - [themes/classic/templates/checkout/cart.tpl](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/checkout/cart.tpl) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/displayShoppingCartFooter.md b/modules/concepts/hooks/list-of-hooks/displayShoppingCartFooter.md index 782d8047d2..e2ee895797 100644 --- a/modules/concepts/hooks/list-of-hooks/displayShoppingCartFooter.md +++ b/modules/concepts/hooks/list-of-hooks/displayShoppingCartFooter.md @@ -33,7 +33,7 @@ Hook locations: Hook type: display Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/checkout/cart.tpl](themes/classic/templates/checkout/cart.tpl) + - [themes/classic/templates/checkout/cart.tpl](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/checkout/cart.tpl) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/displayTop.md b/modules/concepts/hooks/list-of-hooks/displayTop.md index 3706605073..0e0de3667a 100644 --- a/modules/concepts/hooks/list-of-hooks/displayTop.md +++ b/modules/concepts/hooks/list-of-hooks/displayTop.md @@ -33,7 +33,7 @@ Hook locations: Hook type: display Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/checkout/_partials/header.tpl](themes/classic/templates/checkout/_partials/header.tpl) + - [themes/classic/templates/checkout/_partials/header.tpl](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/themes/classic/templates/checkout/_partials/header.tpl) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/filterCategoryContent.md b/modules/concepts/hooks/list-of-hooks/filterCategoryContent.md index f988c96e35..6acdb501de 100644 --- a/modules/concepts/hooks/list-of-hooks/filterCategoryContent.md +++ b/modules/concepts/hooks/list-of-hooks/filterCategoryContent.md @@ -25,7 +25,7 @@ Hook locations: - front office Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/front/listing/CategoryController.php](controllers/front/listing/CategoryController.php) + - [controllers/front/listing/CategoryController.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/front/listing/CategoryController.php) This hook has a `$chain` parameter set to `true` (hook will chain the return of hook module, [see explaination here]({{< relref "/8/development/components/hook/dispatching-hook">}})). diff --git a/modules/concepts/hooks/list-of-hooks/filterCmsCategoryContent.md b/modules/concepts/hooks/list-of-hooks/filterCmsCategoryContent.md index e0f3e9adff..d7642652c5 100644 --- a/modules/concepts/hooks/list-of-hooks/filterCmsCategoryContent.md +++ b/modules/concepts/hooks/list-of-hooks/filterCmsCategoryContent.md @@ -25,7 +25,7 @@ Hook locations: - front office Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/front/CmsController.php](controllers/front/CmsController.php) + - [controllers/front/CmsController.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/front/CmsController.php) This hook has a `$chain` parameter set to `true` (hook will chain the return of hook module, [see explaination here]({{< relref "/8/development/components/hook/dispatching-hook">}})). diff --git a/modules/concepts/hooks/list-of-hooks/filterCmsContent.md b/modules/concepts/hooks/list-of-hooks/filterCmsContent.md index 21a9d6c5e6..6e828280e4 100644 --- a/modules/concepts/hooks/list-of-hooks/filterCmsContent.md +++ b/modules/concepts/hooks/list-of-hooks/filterCmsContent.md @@ -25,7 +25,7 @@ Hook locations: - front office Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/front/CmsController.php](controllers/front/CmsController.php) + - [controllers/front/CmsController.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/front/CmsController.php) This hook has a `$chain` parameter set to `true` (hook will chain the return of hook module, [see explaination here]({{< relref "/8/development/components/hook/dispatching-hook">}})). diff --git a/modules/concepts/hooks/list-of-hooks/filterHtmlContent.md b/modules/concepts/hooks/list-of-hooks/filterHtmlContent.md index 8031434949..7cc4de7a85 100644 --- a/modules/concepts/hooks/list-of-hooks/filterHtmlContent.md +++ b/modules/concepts/hooks/list-of-hooks/filterHtmlContent.md @@ -25,7 +25,7 @@ Hook locations: - front office Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Presenter/Object/ObjectPresenter.php](src/Adapter/Presenter/Object/ObjectPresenter.php) + - [src/Adapter/Presenter/Object/ObjectPresenter.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Presenter/Object/ObjectPresenter.php) This hook has a `$chain` parameter set to `true` (hook will chain the return of hook module, [see explaination here]({{< relref "/8/development/components/hook/dispatching-hook">}})). diff --git a/modules/concepts/hooks/list-of-hooks/filterManufacturerContent.md b/modules/concepts/hooks/list-of-hooks/filterManufacturerContent.md index b6cbb3cd80..2a0b69a204 100644 --- a/modules/concepts/hooks/list-of-hooks/filterManufacturerContent.md +++ b/modules/concepts/hooks/list-of-hooks/filterManufacturerContent.md @@ -25,7 +25,7 @@ Hook locations: - front office Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/front/listing/ManufacturerController.php](controllers/front/listing/ManufacturerController.php) + - [controllers/front/listing/ManufacturerController.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/front/listing/ManufacturerController.php) This hook has a `$chain` parameter set to `true` (hook will chain the return of hook module, [see explaination here]({{< relref "/8/development/components/hook/dispatching-hook">}})). diff --git a/modules/concepts/hooks/list-of-hooks/filterProductContent.md b/modules/concepts/hooks/list-of-hooks/filterProductContent.md index 3a7f7cedf7..c30962f4fa 100644 --- a/modules/concepts/hooks/list-of-hooks/filterProductContent.md +++ b/modules/concepts/hooks/list-of-hooks/filterProductContent.md @@ -25,7 +25,7 @@ Hook locations: - front office Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/front/ProductController.php](controllers/front/ProductController.php) + - [controllers/front/ProductController.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/front/ProductController.php) This hook has a `$chain` parameter set to `true` (hook will chain the return of hook module, [see explaination here]({{< relref "/8/development/components/hook/dispatching-hook">}})). diff --git a/modules/concepts/hooks/list-of-hooks/filterProductSearch.md b/modules/concepts/hooks/list-of-hooks/filterProductSearch.md index c9be8039ea..673d23bd87 100644 --- a/modules/concepts/hooks/list-of-hooks/filterProductSearch.md +++ b/modules/concepts/hooks/list-of-hooks/filterProductSearch.md @@ -25,7 +25,7 @@ Hook locations: - front office Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/modules/blockwishlist/controllers/front/view.php](modules/blockwishlist/controllers/front/view.php) + - [modules/blockwishlist/controllers/front/view.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/modules/blockwishlist/controllers/front/view.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/filterSupplierContent.md b/modules/concepts/hooks/list-of-hooks/filterSupplierContent.md index 8671ac09cb..f9ae9df63e 100644 --- a/modules/concepts/hooks/list-of-hooks/filterSupplierContent.md +++ b/modules/concepts/hooks/list-of-hooks/filterSupplierContent.md @@ -25,7 +25,7 @@ Hook locations: - front office Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/front/listing/SupplierController.php](controllers/front/listing/SupplierController.php) + - [controllers/front/listing/SupplierController.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/controllers/front/listing/SupplierController.php) This hook has a `$chain` parameter set to `true` (hook will chain the return of hook module, [see explaination here]({{< relref "/8/development/components/hook/dispatching-hook">}})). diff --git a/modules/concepts/hooks/list-of-hooks/gSitemapAppendUrls.md b/modules/concepts/hooks/list-of-hooks/gSitemapAppendUrls.md index 2d7a0c2198..b83fb08026 100644 --- a/modules/concepts/hooks/list-of-hooks/gSitemapAppendUrls.md +++ b/modules/concepts/hooks/list-of-hooks/gSitemapAppendUrls.md @@ -19,7 +19,7 @@ Hook locations: - front office Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/modules/gsitemap/gsitemap.php](modules/gsitemap/gsitemap.php) + - [modules/gsitemap/gsitemap.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/modules/gsitemap/gsitemap.php) This hook has an `$array_return` parameter set to `true` (module output will be set by name in an array, [see explaination here]({{< relref "/8/development/components/hook/dispatching-hook">}})). diff --git a/modules/concepts/hooks/list-of-hooks/legacyblockkpi.md b/modules/concepts/hooks/list-of-hooks/legacyblockkpi.md index cdb9f2fa48..6a7d0b120e 100644 --- a/modules/concepts/hooks/list-of-hooks/legacyblockkpi.md +++ b/modules/concepts/hooks/list-of-hooks/legacyblockkpi.md @@ -19,7 +19,7 @@ Hook locations: - back office Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Resources/views/Admin/Product/CatalogPage/catalog.html.twig](src/PrestaShopBundle/Resources/views/Admin/Product/CatalogPage/catalog.html.twig) + - [src/PrestaShopBundle/Resources/views/Admin/Product/CatalogPage/catalog.html.twig](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Resources/views/Admin/Product/CatalogPage/catalog.html.twig) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/moduleRoutes.md b/modules/concepts/hooks/list-of-hooks/moduleRoutes.md index 5ce5b3658f..66ee502cbc 100644 --- a/modules/concepts/hooks/list-of-hooks/moduleRoutes.md +++ b/modules/concepts/hooks/list-of-hooks/moduleRoutes.md @@ -19,7 +19,7 @@ Hook locations: - front office Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Dispatcher.php](classes/Dispatcher.php) + - [classes/Dispatcher.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Dispatcher.php) This hook has an `$array_return` parameter set to `true` (module output will be set by name in an array, [see explaination here]({{< relref "/8/development/components/hook/dispatching-hook">}})). diff --git a/modules/concepts/hooks/list-of-hooks/overrideLayoutTemplate.md b/modules/concepts/hooks/list-of-hooks/overrideLayoutTemplate.md index 86bf845798..97a6807462 100644 --- a/modules/concepts/hooks/list-of-hooks/overrideLayoutTemplate.md +++ b/modules/concepts/hooks/list-of-hooks/overrideLayoutTemplate.md @@ -19,7 +19,7 @@ Hook locations: - front office Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/FrontController.php](classes/controller/FrontController.php) + - [classes/controller/FrontController.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/FrontController.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/overrideMinimalPurchasePrice.md b/modules/concepts/hooks/list-of-hooks/overrideMinimalPurchasePrice.md index 69ec8e1a74..2c8e9c628a 100644 --- a/modules/concepts/hooks/list-of-hooks/overrideMinimalPurchasePrice.md +++ b/modules/concepts/hooks/list-of-hooks/overrideMinimalPurchasePrice.md @@ -19,7 +19,7 @@ Hook locations: - front office Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Presenter/Cart/CartPresenter.php](src/Adapter/Presenter/Cart/CartPresenter.php) + - [src/Adapter/Presenter/Cart/CartPresenter.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Adapter/Presenter/Cart/CartPresenter.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/productSearchProvider.md b/modules/concepts/hooks/list-of-hooks/productSearchProvider.md index a13ff7b12c..8ae75b0792 100644 --- a/modules/concepts/hooks/list-of-hooks/productSearchProvider.md +++ b/modules/concepts/hooks/list-of-hooks/productSearchProvider.md @@ -19,7 +19,7 @@ Hook locations: - front office Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/ProductListingFrontController.php](classes/controller/ProductListingFrontController.php) + - [classes/controller/ProductListingFrontController.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/controller/ProductListingFrontController.php) This hook has an `$array_return` parameter set to `true` (module output will be set by name in an array, [see explaination here]({{< relref "/8/development/components/hook/dispatching-hook">}})). diff --git a/modules/concepts/hooks/list-of-hooks/sendMailAlterTemplateVars.md b/modules/concepts/hooks/list-of-hooks/sendMailAlterTemplateVars.md index 1ac642f7c3..6f1059e0e8 100644 --- a/modules/concepts/hooks/list-of-hooks/sendMailAlterTemplateVars.md +++ b/modules/concepts/hooks/list-of-hooks/sendMailAlterTemplateVars.md @@ -25,7 +25,7 @@ Hook locations: - front office Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Mail.php](classes/Mail.php) + - [classes/Mail.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/Mail.php) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/termsAndConditions.md b/modules/concepts/hooks/list-of-hooks/termsAndConditions.md index 1aa07e7b19..8b06518ff7 100644 --- a/modules/concepts/hooks/list-of-hooks/termsAndConditions.md +++ b/modules/concepts/hooks/list-of-hooks/termsAndConditions.md @@ -19,7 +19,7 @@ Hook locations: - front office Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/checkout/ConditionsToApproveFinder.php](classes/checkout/ConditionsToApproveFinder.php) + - [classes/checkout/ConditionsToApproveFinder.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/checkout/ConditionsToApproveFinder.php) This hook has an `$array_return` parameter set to `true` (module output will be set by name in an array, [see explaination here]({{< relref "/8/development/components/hook/dispatching-hook">}})). diff --git a/modules/concepts/hooks/list-of-hooks/validateCustomerFormFields.md b/modules/concepts/hooks/list-of-hooks/validateCustomerFormFields.md index 568a85f302..6ebcc57a4f 100644 --- a/modules/concepts/hooks/list-of-hooks/validateCustomerFormFields.md +++ b/modules/concepts/hooks/list-of-hooks/validateCustomerFormFields.md @@ -25,7 +25,7 @@ Hook locations: - front office Located in: - - [https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/form/CustomerForm.php](classes/form/CustomerForm.php) + - [classes/form/CustomerForm.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/classes/form/CustomerForm.php) This hook has an `$array_return` parameter set to `true` (module output will be set by name in an array, [see explaination here]({{< relref "/8/development/components/hook/dispatching-hook">}})). From 91007e0d2dabae85e8bd8fe855b7a93fed7e58fd Mon Sep 17 00:00:00 2001 From: Thomas Nares Date: Thu, 15 Dec 2022 15:13:45 +0400 Subject: [PATCH 170/310] Fix admin-dev links --- .../concepts/hooks/list-of-hooks/displayAdminAfterHeader.md | 4 ++-- .../concepts/hooks/list-of-hooks/displayAdminEndContent.md | 4 ++-- modules/concepts/hooks/list-of-hooks/displayAdminForm.md | 4 ++-- modules/concepts/hooks/list-of-hooks/displayAdminListAfter.md | 4 ++-- .../concepts/hooks/list-of-hooks/displayAdminListBefore.md | 4 ++-- .../hooks/list-of-hooks/displayAdminNavBarBeforeEnd.md | 4 ++-- modules/concepts/hooks/list-of-hooks/displayAdminOptions.md | 4 ++-- modules/concepts/hooks/list-of-hooks/displayAdminView.md | 4 ++-- .../hooks/list-of-hooks/displayDashboardToolbarTopMenu.md | 4 ++-- modules/concepts/hooks/list-of-hooks/displayDashboardTop.md | 4 ++-- 10 files changed, 20 insertions(+), 20 deletions(-) diff --git a/modules/concepts/hooks/list-of-hooks/displayAdminAfterHeader.md b/modules/concepts/hooks/list-of-hooks/displayAdminAfterHeader.md index e5282797aa..9595fa829c 100644 --- a/modules/concepts/hooks/list-of-hooks/displayAdminAfterHeader.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminAfterHeader.md @@ -4,7 +4,7 @@ Title: displayAdminAfterHeader hidden: true hookTitle: files: - - admin784x07v4swfhm9fgvc0/themes/new-theme/template/light_display_layout.tpl + - admin-dev/themes/new-theme/template/light_display_layout.tpl locations: - back office type: display @@ -21,7 +21,7 @@ Hook locations: Hook type: display Located in: - - [admin784x07v4swfhm9fgvc0/themes/new-theme/template/light_display_layout.tpl](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/admin784x07v4swfhm9fgvc0/themes/new-theme/template/light_display_layout.tpl) + - [admin-dev/themes/new-theme/template/light_display_layout.tpl](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/admin-dev/themes/new-theme/template/light_display_layout.tpl) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/displayAdminEndContent.md b/modules/concepts/hooks/list-of-hooks/displayAdminEndContent.md index 2062a601bd..f18b5cf88f 100644 --- a/modules/concepts/hooks/list-of-hooks/displayAdminEndContent.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminEndContent.md @@ -4,7 +4,7 @@ Title: displayAdminEndContent hidden: true hookTitle: Administration end of content files: - - admin784x07v4swfhm9fgvc0/themes/new-theme/template/light_display_layout.tpl + - admin-dev/themes/new-theme/template/light_display_layout.tpl locations: - back office type: display @@ -27,7 +27,7 @@ Hook locations: Hook type: display Located in: - - [admin784x07v4swfhm9fgvc0/themes/new-theme/template/light_display_layout.tpl](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/admin784x07v4swfhm9fgvc0/themes/new-theme/template/light_display_layout.tpl) + - [admin-dev/themes/new-theme/template/light_display_layout.tpl](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/admin-dev/themes/new-theme/template/light_display_layout.tpl) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/displayAdminForm.md b/modules/concepts/hooks/list-of-hooks/displayAdminForm.md index 5e008d8f0a..89ae528a5e 100644 --- a/modules/concepts/hooks/list-of-hooks/displayAdminForm.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminForm.md @@ -4,7 +4,7 @@ Title: displayAdminForm hidden: true hookTitle: files: - - admin784x07v4swfhm9fgvc0/themes/default/template/helpers/form/form.tpl + - admin-dev/themes/default/template/helpers/form/form.tpl locations: - back office type: display @@ -21,7 +21,7 @@ Hook locations: Hook type: display Located in: - - [admin784x07v4swfhm9fgvc0/themes/default/template/helpers/form/form.tpl](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/admin784x07v4swfhm9fgvc0/themes/default/template/helpers/form/form.tpl) + - [admin-dev/themes/default/template/helpers/form/form.tpl](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/admin-dev/themes/default/template/helpers/form/form.tpl) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/displayAdminListAfter.md b/modules/concepts/hooks/list-of-hooks/displayAdminListAfter.md index c44f200749..496e14703a 100644 --- a/modules/concepts/hooks/list-of-hooks/displayAdminListAfter.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminListAfter.md @@ -4,7 +4,7 @@ Title: displayAdminListAfter hidden: true hookTitle: files: - - admin784x07v4swfhm9fgvc0/themes/default/template/helpers/list/list_footer.tpl + - admin-dev/themes/default/template/helpers/list/list_footer.tpl locations: - back office type: display @@ -21,7 +21,7 @@ Hook locations: Hook type: display Located in: - - [admin784x07v4swfhm9fgvc0/themes/default/template/helpers/list/list_footer.tpl](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/admin784x07v4swfhm9fgvc0/themes/default/template/helpers/list/list_footer.tpl) + - [admin-dev/themes/default/template/helpers/list/list_footer.tpl](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/admin-dev/themes/default/template/helpers/list/list_footer.tpl) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/displayAdminListBefore.md b/modules/concepts/hooks/list-of-hooks/displayAdminListBefore.md index 8359ec0a78..b2bc3f6601 100644 --- a/modules/concepts/hooks/list-of-hooks/displayAdminListBefore.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminListBefore.md @@ -4,7 +4,7 @@ Title: displayAdminListBefore hidden: true hookTitle: files: - - admin784x07v4swfhm9fgvc0/themes/default/template/helpers/list/list_header.tpl + - admin-dev/themes/default/template/helpers/list/list_header.tpl locations: - back office type: display @@ -21,7 +21,7 @@ Hook locations: Hook type: display Located in: - - [admin784x07v4swfhm9fgvc0/themes/default/template/helpers/list/list_header.tpl](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/admin784x07v4swfhm9fgvc0/themes/default/template/helpers/list/list_header.tpl) + - [admin-dev/themes/default/template/helpers/list/list_header.tpl](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/admin-dev/themes/default/template/helpers/list/list_header.tpl) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/displayAdminNavBarBeforeEnd.md b/modules/concepts/hooks/list-of-hooks/displayAdminNavBarBeforeEnd.md index 4f5781dc46..8fd834a722 100644 --- a/modules/concepts/hooks/list-of-hooks/displayAdminNavBarBeforeEnd.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminNavBarBeforeEnd.md @@ -4,7 +4,7 @@ Title: displayAdminNavBarBeforeEnd hidden: true hookTitle: files: - - admin784x07v4swfhm9fgvc0/themes/new-theme/template/components/layout/nav_bar.tpl + - admin-dev/themes/new-theme/template/components/layout/nav_bar.tpl locations: - back office type: display @@ -21,7 +21,7 @@ Hook locations: Hook type: display Located in: - - [admin784x07v4swfhm9fgvc0/themes/new-theme/template/components/layout/nav_bar.tpl](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/admin784x07v4swfhm9fgvc0/themes/new-theme/template/components/layout/nav_bar.tpl) + - [admin-dev/themes/new-theme/template/components/layout/nav_bar.tpl](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/admin-dev/themes/new-theme/template/components/layout/nav_bar.tpl) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/displayAdminOptions.md b/modules/concepts/hooks/list-of-hooks/displayAdminOptions.md index 9138b18255..2ad844010b 100644 --- a/modules/concepts/hooks/list-of-hooks/displayAdminOptions.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminOptions.md @@ -4,7 +4,7 @@ Title: displayAdminOptions hidden: true hookTitle: files: - - admin784x07v4swfhm9fgvc0/themes/default/template/helpers/options/options.tpl + - admin-dev/themes/default/template/helpers/options/options.tpl locations: - back office type: display @@ -21,7 +21,7 @@ Hook locations: Hook type: display Located in: - - [admin784x07v4swfhm9fgvc0/themes/default/template/helpers/options/options.tpl](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/admin784x07v4swfhm9fgvc0/themes/default/template/helpers/options/options.tpl) + - [admin-dev/themes/default/template/helpers/options/options.tpl](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/admin-dev/themes/default/template/helpers/options/options.tpl) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/displayAdminView.md b/modules/concepts/hooks/list-of-hooks/displayAdminView.md index e122bc142a..a6d896a787 100644 --- a/modules/concepts/hooks/list-of-hooks/displayAdminView.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminView.md @@ -4,7 +4,7 @@ Title: displayAdminView hidden: true hookTitle: files: - - admin784x07v4swfhm9fgvc0/themes/default/template/helpers/view/view.tpl + - admin-dev/themes/default/template/helpers/view/view.tpl locations: - back office type: display @@ -21,7 +21,7 @@ Hook locations: Hook type: display Located in: - - [admin784x07v4swfhm9fgvc0/themes/default/template/helpers/view/view.tpl](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/admin784x07v4swfhm9fgvc0/themes/default/template/helpers/view/view.tpl) + - [admin-dev/themes/default/template/helpers/view/view.tpl](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/admin-dev/themes/default/template/helpers/view/view.tpl) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/displayDashboardToolbarTopMenu.md b/modules/concepts/hooks/list-of-hooks/displayDashboardToolbarTopMenu.md index 256d283129..9a62809db4 100644 --- a/modules/concepts/hooks/list-of-hooks/displayDashboardToolbarTopMenu.md +++ b/modules/concepts/hooks/list-of-hooks/displayDashboardToolbarTopMenu.md @@ -4,7 +4,7 @@ Title: displayDashboardToolbarTopMenu hidden: true hookTitle: Display new elements in back office page with a dashboard, on top Menu files: - - admin784x07v4swfhm9fgvc0/themes/new-theme/template/page_header_toolbar.tpl + - admin-dev/themes/new-theme/template/page_header_toolbar.tpl locations: - front office type: display @@ -27,7 +27,7 @@ Hook locations: Hook type: display Located in: - - [admin784x07v4swfhm9fgvc0/themes/new-theme/template/page_header_toolbar.tpl](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/admin784x07v4swfhm9fgvc0/themes/new-theme/template/page_header_toolbar.tpl) + - [admin-dev/themes/new-theme/template/page_header_toolbar.tpl](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/admin-dev/themes/new-theme/template/page_header_toolbar.tpl) ## Call of the Hook in the origin file diff --git a/modules/concepts/hooks/list-of-hooks/displayDashboardTop.md b/modules/concepts/hooks/list-of-hooks/displayDashboardTop.md index e8284134ef..339b496a13 100644 --- a/modules/concepts/hooks/list-of-hooks/displayDashboardTop.md +++ b/modules/concepts/hooks/list-of-hooks/displayDashboardTop.md @@ -4,7 +4,7 @@ Title: displayDashboardTop hidden: true hookTitle: Dashboard Top files: - - admin784x07v4swfhm9fgvc0/themes/new-theme/template/page_header_toolbar.tpl + - admin-dev/themes/new-theme/template/page_header_toolbar.tpl locations: - front office type: display @@ -27,7 +27,7 @@ Hook locations: Hook type: display Located in: - - [admin784x07v4swfhm9fgvc0/themes/new-theme/template/page_header_toolbar.tpl](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/admin784x07v4swfhm9fgvc0/themes/new-theme/template/page_header_toolbar.tpl) + - [admin-dev/themes/new-theme/template/page_header_toolbar.tpl](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/admin-dev/themes/new-theme/template/page_header_toolbar.tpl) ## Call of the Hook in the origin file From 668827a4f49492d422ad163bc8bb697db94a16b5 Mon Sep 17 00:00:00 2001 From: Krystian Podemski Date: Thu, 15 Dec 2022 12:53:26 +0100 Subject: [PATCH 171/310] Key for git info --- .github/workflows/build.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 1589d30cc9..5efd0aa503 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -55,4 +55,6 @@ jobs: mv _current "src/content/$VERSION" - name: Build + env: + DEVDOCS_GITHUB_READ_TOKEN: ${{ secrets.DEVDOCS_GITHUB_READ_TOKEN }} run: cd src/ && hugo From 5db6ef3a9484502a4c9894cf7569a1fab6191e1d Mon Sep 17 00:00:00 2001 From: PululuK Date: Fri, 16 Dec 2022 10:33:22 +0400 Subject: [PATCH 172/310] Move example from PululuK --- .../concepts/hooks/list-of-hooks/_index.md | 2 + .../list-of-hooks/actionValidateOrder.md | 74 ++++++++++++++ .../sample-modules/example-hooks/_index.md | 12 --- .../example-hooks/actionValidateOrder.md | 97 ------------------- 4 files changed, 76 insertions(+), 109 deletions(-) delete mode 100644 modules/sample-modules/example-hooks/_index.md delete mode 100644 modules/sample-modules/example-hooks/actionValidateOrder.md diff --git a/modules/concepts/hooks/list-of-hooks/_index.md b/modules/concepts/hooks/list-of-hooks/_index.md index 1961975e54..cb00a983f8 100644 --- a/modules/concepts/hooks/list-of-hooks/_index.md +++ b/modules/concepts/hooks/list-of-hooks/_index.md @@ -3,6 +3,8 @@ menuTitle: List of hooks title: List of hooks type: chapter: false +aliases: + - /8/modules/sample-modules/example-hooks --- # List of hooks diff --git a/modules/concepts/hooks/list-of-hooks/actionValidateOrder.md b/modules/concepts/hooks/list-of-hooks/actionValidateOrder.md index 8c5a1b1798..d09fa89b72 100644 --- a/modules/concepts/hooks/list-of-hooks/actionValidateOrder.md +++ b/modules/concepts/hooks/list-of-hooks/actionValidateOrder.md @@ -10,6 +10,8 @@ locations: type: action hookAliases: - newOrder +aliases: + - /8/modules/sample-modules/example-hooks/actionValidateOrder --- # Hook actionValidateOrder @@ -58,4 +60,76 @@ Hook::exec('actionValidateOrder', [ 'currency' => $this->context->currency, 'orderStatus' => $order_status, ]) +``` + +## Example implementation + +A classic use case for this hook could be: + +_I want to reward my customers on their n-th order_ + +```php +registerHook('actionValidateOrder'); + } + + public function hookActionValidateOrder($params) + { + $orderObject = $params['order']; + $customerObject = $params['customer']; + $hasValidParams = Validate::isLoadedObject($orderObject) && Validate::isLoadedObject($orderObject); + if ($hasValidParams && !$this->customerAlreadyRewarded((int) $customerObject->id)) { + $hasConfiguredState = in_array((int) $orderObject->getCurrentState(), $this->getConfuredOrdersStatesIds()); + $hasCustomerRequiredNbrOfTheOrderToReward = $this->getCustomerValidOrdersNbr((int) $customerObject->id) == $this->getRequiredNbrOfTheOrderToReward(); + if ($hasConfiguredState && $hasCustomerRequiredNbrOfTheOrderToReward) { + $customerReward = $this->createCustomerReward($customerObject, $orderObject); + if (Validate::isLoadedObject($customerReward)) { + $this->setAlreadyRewarded($customerObject); + $this->notifyCustomer($customerObject, $customerReward); + + // of course don't forget to log if something fails here :) + } + } + } + } + + protected function customerAlreadyRewarded(int $idCustomer): bool + { + // check if customer already rewarded + } + + protected setAlreadyRewarded(): void + { + // set customer was rewarded + } + + protected function getConfuredOrdersStatesIds(): array + { + // return array with configured states ids in your module + } + + protected function getCustomerValidOrdersNbr(int $idCustomer): int + { + // return number of total order valid by customer + } + + protected function getRequiredNbrOfTheOrderToReward(): int + { + // return configured number of orders required to reward the customer + } + + protected function createCustomerReward(Customer $customer, Order $order): ?CartRule + { + // generate customer cart rule (according to the order amount for example) + } + + protected function notifyCustomer(Customer $customer, CartRule $cartRule): bool + { + // notify the customer + } +} ``` \ No newline at end of file diff --git a/modules/sample-modules/example-hooks/_index.md b/modules/sample-modules/example-hooks/_index.md deleted file mode 100644 index 2cf191db0b..0000000000 --- a/modules/sample-modules/example-hooks/_index.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -title: Hook examples -weight: 2 ---- - -# Hook implementation examples - -Hooks are one of the most powerful tools to extend or modify PrestaShop using modules. - -For a complete introduction to hooks, please read [Hooks]({{< relref "/8/modules/concepts/hooks/" >}}) - -{{% children %}} \ No newline at end of file diff --git a/modules/sample-modules/example-hooks/actionValidateOrder.md b/modules/sample-modules/example-hooks/actionValidateOrder.md deleted file mode 100644 index 1a2cba6b72..0000000000 --- a/modules/sample-modules/example-hooks/actionValidateOrder.md +++ /dev/null @@ -1,97 +0,0 @@ ---- -title: "actionValidateOrder" -weight: 3 ---- - -# Hook example: actionValidateOrder - -This hook is triggered when an `order` is validated. - -actionValidateOrder -: - After an order has been validated. - Doesn't necessarily have to be paid. - - Located in: /classes/PaymentModule.php - - Parameters: - ```php - (object) Cart, - 'order' => (object) Order, - 'customer' => (object) Customer, - 'currency' => (object) Currency, - 'orderStatus' => (object) OrderState - ); - ``` - -A classic use case for this hook could be: - -_I want to reward my customers on their n-th order_ - -```php -registerHook('actionValidateOrder'); - } - - public function hookActionValidateOrder($params) - { - $orderObject = $params['order']; - $customerObject = $params['customer']; - $hasValidParams = Validate::isLoadedObject($orderObject) && Validate::isLoadedObject($orderObject); - if ($hasValidParams && !$this->customerAlreadyRewarded((int) $customerObject->id)) { - $hasConfiguredState = in_array((int) $orderObject->getCurrentState(), $this->getConfuredOrdersStatesIds()); - $hasCustomerRequiredNbrOfTheOrderToReward = $this->getCustomerValidOrdersNbr((int) $customerObject->id) == $this->getRequiredNbrOfTheOrderToReward(); - if ($hasConfiguredState && $hasCustomerRequiredNbrOfTheOrderToReward) { - $customerReward = $this->createCustomerReward($customerObject, $orderObject); - if (Validate::isLoadedObject($customerReward)) { - $this->setAlreadyRewarded($customerObject); - $this->notifyCustomer($customerObject, $customerReward); - - // of course don't forget to log if something fails here :) - } - } - } - } - - protected function customerAlreadyRewarded(int $idCustomer): bool - { - // check if customer already rewarded - } - - protected setAlreadyRewarded(): void - { - // set customer was rewarded - } - - protected function getConfuredOrdersStatesIds(): array - { - // return array with configured states ids in your module - } - - protected function getCustomerValidOrdersNbr(int $idCustomer): int - { - // return number of total order valid by customer - } - - protected function getRequiredNbrOfTheOrderToReward(): int - { - // return configured number of orders required to reward the customer - } - - protected function createCustomerReward(Customer $customer, Order $order): ?CartRule - { - // generate customer cart rule (according to the order amount for example) - } - - protected function notifyCustomer(Customer $customer, CartRule $cartRule): bool - { - // notify the customer - } -} -``` \ No newline at end of file From ccdaf2e60dca9a5336105367bc72fa5a468d0105 Mon Sep 17 00:00:00 2001 From: Thomas Nares Date: Fri, 16 Dec 2022 16:27:57 +0400 Subject: [PATCH 173/310] Add example flag on ActionValidateOrder --- modules/concepts/hooks/list-of-hooks/actionValidateOrder.md | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/concepts/hooks/list-of-hooks/actionValidateOrder.md b/modules/concepts/hooks/list-of-hooks/actionValidateOrder.md index d09fa89b72..7f85c414a9 100644 --- a/modules/concepts/hooks/list-of-hooks/actionValidateOrder.md +++ b/modules/concepts/hooks/list-of-hooks/actionValidateOrder.md @@ -12,6 +12,7 @@ hookAliases: - newOrder aliases: - /8/modules/sample-modules/example-hooks/actionValidateOrder +hasExample: true --- # Hook actionValidateOrder From f7202313830bdb5a795562c35d40ecd684957eec Mon Sep 17 00:00:00 2001 From: leemyongpakvn Date: Sat, 17 Dec 2022 14:09:16 +0700 Subject: [PATCH 174/310] switch to SF4 --- .../doctrine/how-to-handle-multi-lang-doctrine-entity.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/concepts/doctrine/how-to-handle-multi-lang-doctrine-entity.md b/modules/concepts/doctrine/how-to-handle-multi-lang-doctrine-entity.md index 5688651dc7..dd8904b635 100644 --- a/modules/concepts/doctrine/how-to-handle-multi-lang-doctrine-entity.md +++ b/modules/concepts/doctrine/how-to-handle-multi-lang-doctrine-entity.md @@ -394,7 +394,7 @@ class QuoteLang If you need more info about how to setup and handle Doctrine relations, you can read the [Symfony documentation](https://symfony.com/doc/4.4/doctrine/associations.html) about it. Focus on the `Annotation` sections since PrestaShop only handles this kind of configuration from modules' Entities. Here are some additional link that might be useful: - [Doctrine Association mapping](https://www.doctrine-project.org/projects/doctrine-orm/en/2.7/reference/association-mapping.html) -- [Mastering Doctrine Relationships in Symfony 3 (video tutorial)](https://symfonycasts.com/screencast/symfony3-doctrine-relations) +- [Mastering Doctrine Relationships in Symfony 4 (video tutorial)](https://symfonycasts.com/screencast/symfony4-doctrine-relations) {{% /notice %}} ## Create a translated entity From 67f89c30ee726a3297e082ba29d37998606abab0 Mon Sep 17 00:00:00 2001 From: leemyongpakvn Date: Sat, 17 Dec 2022 14:11:42 +0700 Subject: [PATCH 175/310] switch to PS8 --- modules/concepts/overrides.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/concepts/overrides.md b/modules/concepts/overrides.md index 1372f043a7..43e9a8fde1 100644 --- a/modules/concepts/overrides.md +++ b/modules/concepts/overrides.md @@ -28,7 +28,7 @@ Before creating an override, check the existing features can help you: There are many events triggered on each controller of PrestaShop. They can be used for displaying additional content or executing module actions. -See [the hooks chapter]({{< ref "1.7/modules/concepts/hooks/" >}}) for more details. +See [the hooks chapter]({{< ref "8/modules/concepts/hooks/" >}}) for more details. ### Classes @@ -65,13 +65,13 @@ Core controllers can be reused in a module as well, without being erased, thanks This allows a controller to be maintained easily, with its own identity but with the parent features. -See [the controllers chapter]({{< ref "1.7/modules/concepts/controllers/" >}}) for more details. +See [the controllers chapter]({{< ref "8/modules/concepts/controllers/" >}}) for more details. ### Service overrides PrestaShop is migrating to Symfony, and the parts migrated rely on Symfony container which enables service overrides and decorations. This is similar to overrides but avoids class erasing. -See [the Symfony services chapter]({{< ref "1.7/modules/concepts/services/" >}}) for more details. +See [the Symfony services chapter]({{< ref "8/modules/concepts/services/" >}}) for more details. ### Contributing From 3c816c26a1c6293c46eb05d895e957923649f6a9 Mon Sep 17 00:00:00 2001 From: leemyongpakvn Date: Sat, 17 Dec 2022 14:14:26 +0700 Subject: [PATCH 176/310] switch to SF4 --- modules/concepts/commands.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/concepts/commands.md b/modules/concepts/commands.md index 34a03f7b5d..4c8ff74bde 100644 --- a/modules/concepts/commands.md +++ b/modules/concepts/commands.md @@ -81,7 +81,7 @@ The command should be now available using `./bin/console your-module:export`. We use the Symfony Console with nothing specific to PrestaShop. -You can learn everything about this component in [their documentation](https://symfony.com/doc/4.4/console.html) in version 3.4. +You can learn everything about this component in [their documentation](https://symfony.com/doc/4.4/console.html) in version 4.4. To sum up, there is a list of useful links: From 112ead28ff3e97e1f42b2a40316b611259abdd36 Mon Sep 17 00:00:00 2001 From: leemyongpakvn Date: Sat, 17 Dec 2022 14:17:56 +0700 Subject: [PATCH 177/310] typo --- modules/concepts/module-class/_index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/concepts/module-class/_index.md b/modules/concepts/module-class/_index.md index 18c62a3bb8..14e15aeda8 100644 --- a/modules/concepts/module-class/_index.md +++ b/modules/concepts/module-class/_index.md @@ -57,7 +57,7 @@ $this->dependencies = ['ps_googleanalytics', 'productcomments']; - **Default:** (empty) - **Required:** No -This attribute contains the module's dependencies that PrestaShop checks when installing the module. If one of the dependant modules is unavailable, the installation will fail, and PrestaShop will display a warning. +This attribute contains the module's dependencies that PrestaShop checks when installing the module. If one of the dependent modules is unavailable, the installation will fail, and PrestaShop will display a warning. ### description From 63a23a2f5cf0b1bb66870fab05bdf43e349f29a2 Mon Sep 17 00:00:00 2001 From: leemyongpakvn Date: Sat, 17 Dec 2022 14:32:19 +0700 Subject: [PATCH 178/310] switch to PS8 --- modules/concepts/hooks/_index.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/concepts/hooks/_index.md b/modules/concepts/hooks/_index.md index 943964fe7c..39995609f9 100644 --- a/modules/concepts/hooks/_index.md +++ b/modules/concepts/hooks/_index.md @@ -40,7 +40,7 @@ public function install() } ``` -If you do not know where you can register, [a list of available hooks]({{< ref "1.7/modules/concepts/hooks/list-of-hooks" >}}) is available. +If you do not know where you can register, [a list of available hooks]({{< ref "8/modules/concepts/hooks/list-of-hooks" >}}) is available. ### Execution @@ -131,7 +131,7 @@ $hook->add(); // return true on success You can check if hook exists before this with Hook::getIdByName('hook_name') ``` -...but PrestaShop enables you to do it the easy way: +... but PrestaShop enables you to do it the easy way: ```php $this->registerHook('displayAtSpecificPlace'); @@ -139,4 +139,4 @@ $this->registerHook('displayAtSpecificPlace'); If the hook "displayAtSpecificPlace" doesn't exist, PrestaShop will create it for you but be careful: this will also plug the current module to the hook. -[hooks-component]: {{< ref "/8/development/components/hook/" >}} \ No newline at end of file +[hooks-component]: {{< ref "/8/development/components/hook/" >}} From 719036e01ea789cc18a9a998ec7145b0d786fbd3 Mon Sep 17 00:00:00 2001 From: Thomas Nares Date: Tue, 3 Jan 2023 14:47:49 +0100 Subject: [PATCH 179/310] Update twig dependency to 3.4 - issue 30116 --- modules/core-updates/8.0.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/core-updates/8.0.md b/modules/core-updates/8.0.md index 885fb08fd0..b8a290b496 100644 --- a/modules/core-updates/8.0.md +++ b/modules/core-updates/8.0.md @@ -1060,6 +1060,7 @@ The Bootstrap version used in Symfony-based Back office pages has been updated f * `admin-dev/searchcron.php` deprecated in 1.7.6 #### Removed files + * `images.inc.php` deprecated in 1.5.0 * `admin-dev/themes/default/public/theme.rtlfix` @@ -1117,7 +1118,7 @@ The Bootstrap version used in Symfony-based Back office pages has been updated f | symfony/polyfill-apcu | 1.0 | _~ Removed ~_ | | symfony/polyfill-php73 | 1.10 | _~ Removed ~_ | | symfony/symfony | 3.4 | 4.4 | -| twig/twig | 1.38 | 3.0 | +| twig/twig | 1.38 | 3.4 | ### JS libraries From 302eca02e990faf378980d2791e655d6d41bf1b8 Mon Sep 17 00:00:00 2001 From: Thomas Nares Date: Tue, 3 Jan 2023 15:18:47 +0100 Subject: [PATCH 180/310] deprecate CharacterCleaner class and Customer::validateController (issues 29953 and 30418) --- modules/core-updates/8.1.md | 39 +++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 modules/core-updates/8.1.md diff --git a/modules/core-updates/8.1.md b/modules/core-updates/8.1.md new file mode 100644 index 0000000000..56dc1c82f2 --- /dev/null +++ b/modules/core-updates/8.1.md @@ -0,0 +1,39 @@ +--- +title: Changes in PrestaShop 8.1 +menuTitle: Changes in 8.1 +--- + + + +{{% notice note %}} +This page is being created, it will be completed while 8.1 is under creation. +{{% /notice %}} + +# Notable changes in PrestaShop 8.1 + +## PHP support + +## Notable changes + +## API Changes + +## Behavior changes + +## Deprecations + +### PHP + +* `PrestaShop\PrestaShop\Core\String\CharacterCleaner` → Its use is not required + +## Updated dependencies + +### PHP libraries + +| Library name | Old version | New version | +|------------------------------------|---------------------------------------------------------------|---------------| From be0fdfdb65b025769aa8f11c72600381b3ea8406 Mon Sep 17 00:00:00 2001 From: Thomas Nares Date: Tue, 3 Jan 2023 15:20:09 +0100 Subject: [PATCH 181/310] deprecate Customer::validateController (issue 29953) --- modules/core-updates/8.1.md | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/core-updates/8.1.md b/modules/core-updates/8.1.md index 56dc1c82f2..9b13314dc3 100644 --- a/modules/core-updates/8.1.md +++ b/modules/core-updates/8.1.md @@ -30,6 +30,7 @@ This page is being created, it will be completed while 8.1 is under creation. ### PHP * `PrestaShop\PrestaShop\Core\String\CharacterCleaner` → Its use is not required +* `Customer::validateController()` → The password check has been moved in controllers and this method is not called anywhere since 1.7.0 ## Updated dependencies From 50df906c4f2dcabf7c4057eadcc75e43fa9e7005 Mon Sep 17 00:00:00 2001 From: Thomas Nares Date: Tue, 3 Jan 2023 15:37:13 +0100 Subject: [PATCH 182/310] Create new hook page for displayAddressSelectorBottomHook --- .../displayAddressSelectorBottom.md | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 modules/concepts/hooks/list-of-hooks/displayAddressSelectorBottom.md diff --git a/modules/concepts/hooks/list-of-hooks/displayAddressSelectorBottom.md b/modules/concepts/hooks/list-of-hooks/displayAddressSelectorBottom.md new file mode 100644 index 0000000000..e381c933f0 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/displayAddressSelectorBottom.md @@ -0,0 +1,37 @@ +--- +menuTitle: displayAddressSelectorBottom +Title: displayAddressSelectorBottom +hidden: true +hookTitle: +files: + - themes/classic/templates/checkout/_partials/steps/addresses.tpl +locations: + - front office +type: display +hookAliases: +since: 8.1.0 +--- + +# Hook displayAddressSelectorBottom + +## Information + +{{% notice tip %}} +**Add a message (or other content) on address step of checkout** +{{% /notice %}} + +Available since : {{< minver v="8.1.0" >}} + +Hook locations: + - front office + +Hook type: display + +Located in: + - themes/classic/templates/checkout/_partials/steps/addresses.tpl + +## Call of the Hook in the origin file + +```php +{hook h='displayAddressSelectorBottom'} +``` \ No newline at end of file From cbdbaf38e07cc907c599832c559e2fcb5c985f03 Mon Sep 17 00:00:00 2001 From: Pablo Borowicz Date: Thu, 5 Jan 2023 11:43:36 +0100 Subject: [PATCH 183/310] Fix the path to the translations folder --- basics/installation/localhost.md | 3 +-- .../contribute_using_localhost.md | 1 - .../internationalization/translation/introduction.md | 8 ++++---- .../internationalization/translation/translation-tips.md | 2 +- 4 files changed, 6 insertions(+), 8 deletions(-) diff --git a/basics/installation/localhost.md b/basics/installation/localhost.md index 26e921da58..de0b0aa719 100644 --- a/basics/installation/localhost.md +++ b/basics/installation/localhost.md @@ -176,7 +176,6 @@ PrestaShop needs recursive write permissions on several directories: - ./admin-dev/autoupgrade - ./app/config - ./app/logs -- ./app/Resources/translations - ./cache - ./config - ./download @@ -193,7 +192,7 @@ PrestaShop needs recursive write permissions on several directories: You can set up the appropriate permissions using this command: ```bash -$ chmod -R +w admin-dev/autoupgrade app/config app/logs app/Resources/translations cache config download img log mails modules override themes translations upload var +$ chmod -R +w admin-dev/autoupgrade app/config app/logs cache config download img log mails modules override themes translations upload var ``` If you do not have some of the folders above, please create them before changing permissions. For example: diff --git a/contribute/contribute-pull-requests/contribute_using_localhost.md b/contribute/contribute-pull-requests/contribute_using_localhost.md index f083d57d0b..ce21cee27c 100644 --- a/contribute/contribute-pull-requests/contribute_using_localhost.md +++ b/contribute/contribute-pull-requests/contribute_using_localhost.md @@ -96,7 +96,6 @@ PrestaShop needs recursive write permissions on several directories: - /admin-dev/autoupgrade/ - /app/logs -- /app/Resources/translations - /cache - /config/themes - /download diff --git a/development/internationalization/translation/introduction.md b/development/internationalization/translation/introduction.md index 6aafe20746..71f2a08bea 100644 --- a/development/internationalization/translation/introduction.md +++ b/development/internationalization/translation/introduction.md @@ -43,10 +43,10 @@ PrestaShop uses Symfony's [Translator Component](https://symfony.com/doc/4.4/tra This component is initialized for the configured language by loading five Catalogue Resources: * **Customized translations database** - Located in the `ps_translations` table. -* **Active theme** – XLF files in `themes//translations`. -* **Core** – XLF files in `app/Resources/translations`. -* **Active modules** – XLF files in `modules//translations`. -* **Active modules (legacy)** – PHP files in `modules//translations`. +* **Active theme** – XLF files in `./themes//translations`. +* **Core** – XLF files in `./translations`. +* **Active modules** – XLF files in `./modules//translations`. +* **Active modules (legacy)** – PHP files in `./modules//translations`. {{% notice tip %}} **The catalogue resources above are listed by precedence.** diff --git a/development/internationalization/translation/translation-tips.md b/development/internationalization/translation/translation-tips.md index b57414e238..090b08afd6 100644 --- a/development/internationalization/translation/translation-tips.md +++ b/development/internationalization/translation/translation-tips.md @@ -9,7 +9,7 @@ weight: 50 Wordings for the Core and Native modules can only be translated if they are declared in PrestaShop's default translation catalogue. Therefore, whenever a new wording is added to the core or to a native module, it must be added to the default catalogue as well. -Normally you would have to manually add each wording the appropriate default catalogue files (located in the `app/Resources/translations/default` folder). Thankfully, this task has been automated by the Core team! +Normally you would have to manually add each wording the appropriate default catalogue files (located in the `./translations/default` folder). Thankfully, this task has been automated by the Core team! Before every minor release, the whole source code for PrestaShop and Native Modules is analyzed using [TranslationToolsBundle](https://github.com/PrestaShop/TranslationToolsBundle), and all newly discovered wordings are automatically added to the default catalogue. From 8f5f83675087373768e20cd1eb5806043f987876 Mon Sep 17 00:00:00 2001 From: Thomas Nares Date: Mon, 9 Jan 2023 10:05:30 +0100 Subject: [PATCH 184/310] Change visibility of 8.1 changes page --- modules/core-updates/8.1.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/modules/core-updates/8.1.md b/modules/core-updates/8.1.md index 9b13314dc3..63a673693c 100644 --- a/modules/core-updates/8.1.md +++ b/modules/core-updates/8.1.md @@ -1,6 +1,7 @@ --- title: Changes in PrestaShop 8.1 menuTitle: Changes in 8.1 +hidden: true --- {{% notice note %}} -This page is being created, it will be completed while 8.1 is under creation. +This page is being created, it will be completed while 8.1 is under creation. +Remove hidden: true param when ready to publish. {{% /notice %}} # Notable changes in PrestaShop 8.1 From 13b189213093bb3102bcbad3720711690a80cb90 Mon Sep 17 00:00:00 2001 From: Thomas Nares Date: Mon, 9 Jan 2023 15:04:03 +0100 Subject: [PATCH 185/310] Document prestashop/PR28127 and classic/PR21 --- modules/core-updates/8.0.md | 2 +- .../core-updates/img/password-policy-bo.png | Bin 0 -> 27882 bytes .../core-updates/img/password-policy-fo.png | Bin 0 -> 28407 bytes modules/core-updates/new-password-policy.md | 67 ++++++++++++++++++ 4 files changed, 68 insertions(+), 1 deletion(-) create mode 100644 modules/core-updates/img/password-policy-bo.png create mode 100644 modules/core-updates/img/password-policy-fo.png create mode 100644 modules/core-updates/new-password-policy.md diff --git a/modules/core-updates/8.0.md b/modules/core-updates/8.0.md index b8a290b496..3d73ae8d52 100644 --- a/modules/core-updates/8.0.md +++ b/modules/core-updates/8.0.md @@ -33,7 +33,7 @@ PrestaShop 8.0 adds supports for PHP 8.0 and PHP 8.1 and requires at least PHP 7 * Because of the [support for PHP 8.1](https://github.com/PrestaShop/PrestaShop/pull/28402) many methods have declared a return type now. * The logic for customers' login and registration [is now](https://github.com/PrestaShop/PrestaShop/pull/27755/) split between two controllers (`RegistrationController`, `AuthController`). This might impact third-party themes and modules as the URL to the registration has changed. * Before PrestaShop places an order [there is an additional request now](https://github.com/PrestaShop/PrestaShop/pull/26048/), to see if the number of products in the cart is still valid. This might require third-party payment modules to implement the checks in their solutions accordingly. -* Due to the new [password policy management features](https://github.com/PrestaShop/PrestaShop/pull/28127), third-party solutions that generate customer data might require to implement changes accordingly. +* Due to the new [password policy management features](/8/modules/core-updates/new-password-policy), third-party solutions that generate customer data might require to implement changes accordingly. * In some countries, loading fonts through Google Fonts' CDN service has been judged incompatible with [GDPR](https://en.wikipedia.org/wiki/General_Data_Protection_Regulation), so [these fonts are now built into the project](https://github.com/PrestaShop/PrestaShop/issues/27541). This should not affect your work, but spreading awareness around this topic is important. ### Symfony update diff --git a/modules/core-updates/img/password-policy-bo.png b/modules/core-updates/img/password-policy-bo.png new file mode 100644 index 0000000000000000000000000000000000000000..91d58cc58126da9453bdae23df49d0269f2c4dd3 GIT binary patch literal 27882 zcmdqJWmp_b6fFvbBoIO%5Q4iUxa%MRf;+)2xVsGw2|h4ch? z-#`rsgoA_EHxm|?mk<^vk+-)oHnTK>gL@Nc6#CM+V{{yCG9)}5-d z;QiwlXi{6}ElnTNCYx1xHTIl41bzvlS`h3}~S5u}ffNFjzx{fLjZ&`r#`U>5lp zJDnyS>p*HX7k@cEiQoQcYEhvnzp~SGGS8?>2H*B^P%L3G3IjS?g5xVYiPD8N%vOzP zM*Or`k&r9@+H|AwSI4Y&f)-=v979Gm(^IG`Zn`t#3}Xb@L|p_MFLS9$k#Y5;l^7L8 zVTS{3&iXx{4X~-IzmY#mt|rg6HH@Uv`2_DTff#6nm@iDWyNFv|>G3$h^J#rBy$mk` z!-a1~Kpcn0lbZ{lQ;Q!-J96be3T9`X_sU$nhaZk!Z48B95dNm)m=gYVbv%3z{ZL}&(KES zhyiS6`%nZ91m*#fRz{9`Bw#B`YX=@MAKC9Sc!2c7*NkK&zfW& zU|?ckBIAEXLP7$vH#Fu^6cPQqIPf1InW>|rEe|83i;D|`3oC<-y$K^TH#avU6AL2? z3q5cKy@RW@qaK*v+JXG9O8(R%V&q_8Z)WRgW@AnAP_Lf8jguoE8QDWa|NQ;cPb09| zzb#oi{C!!#1u{P5FfubRG5%9GP!#m=Eswkz*vL{{#LNm99-s|=7FHI}@ALm3Isdl! zpOR|-mgHn&{cp+tSK>rs#9HPujl50KkeXnMKQ^Y9AYe*@eKN$ z`|8RM-w@t^ZD?qSUpbKV5yT)_^ps67D&Mo_@QaYS;D)vh&DA-qdz-kVb2}VpBWFbl zKF3t6a1#4MT@x)oQ$*{!@ZMr96HF#cBEG<7c?n~48p!__{Zm*-% z28LHSn^9x^#mO5sRvO9+8#`sxsaxUdo>8kZa#u@#r^_|uc^3>*4W`_=vr@2q z7_Pc^SDOk`PP@Z`4y8cyB+}GoOGs}os^@RpW-YrqSwg1HC}|xp3k5_2JYkmtZuFT% zXD_EZeGa{zC0Bk7+JGm&#nD_}ni#9n8#bvjgZ*3$TWf{fVO<=Dw>xYq>TnF5+$GGVe6%T$5M%j7wl+y7wbDC0Y#|V8)d>?@Qtj#@<$ zDtALAX)}jV{`0eI14frs2+VADShv2Y*Lyetf70ftrrruty+51wgFNMz`%*;dB9%1i z?)lG6jTZ|JFnlbpPy!w=MFC7Z?M!Qv3h;ch=d2x4`t+4_Zln(*y7(J5j6gkviN3g~ z@wZAno9!@+)8(QnLOv&rf%xKAL&=)uCPO$muPJ0>#QR>or68x0i!Z`u6~AFK1Eq!E zFzO)3LbY=)*W%A_|~XdW7GeoU-b-}-}ac|-6upA`y0zT zuT_7<`Np>!QVQX9H^UyT7A!YkAY+>hbMgBc@)56kVujld{DQ7o&`;ml>Jq6Ue>qu; zlWA~HzR(%JC|;;12U0K$P6{)2KzhNZP)fvZGOm3T1@;n)Q!~U%5So!X=C2dXu2Fme|Q@u6&JFd zW1qibPrv1_V-YL)dJ2@bAeQz6RdpZN=0|wT?v&ADq=EfNBeoPaefIR%wSMy6L8s5F z?0sKq2CqF_R`rJiE(_|8N3)Z#`ph9==`R+=GL>Q0r(S$uX!fM{`i_$);KHuqRu zQN(P`As4?p`%mc8YTgUNQs-+)gzyx>6)_!h+A}Ex;-+!oWTsbJ3;b>=P_Mu}p*-z$&CrVpIDrK|(k<0!51S7{hEKv!b1r`Q0F+@Oy-TyUK*BBDL+RgpP=(gKDRQMfj1)9ypaTP?u_5XZ<*qXjzj%nQm* zkv?jVrTSB5qd{hhd@*F|ELd4xtocH?cfQ}~jc-)?17CZ*(?yqH z-p;M*ch|i$^>XzZW7T&Qims71Fwd1El`5HLJ})ggoRX`%gR|Q#=NxC>`AlqgM!ngr zkbs?&$eRA$Rb-D^0}pW{>@dIk@l>vBeWp6zhvKzbJ3sWc+bpdzGPmcP1hsGZT#n1v zdefB0KuzHwZTz8qU!(xs;q2y({zz?&#LEgJCtB5r>3&tIRXpXQY^0KduFkaWlL-r! zquiHChG}mTEZ#I#n#s>bKIViQI;WOMQL~j%OIN6E?fTXB+cY_-7R5?#P_<1rnn9do zlVaXB-9TH_7<3vG+`PEdscNrCQ=H!nJwm}eVxM?5*8A*ea3C5tQq z?qE|)8F!Zy-s5Fr_sxbBr&Hy}miD9bbc40-%bVS&g`8iOg&?M&`XizCTN6$X_3yHg zLKu|KVEX=3v=S>KJ5H4+q-djxcnZ6{2qoH_*BDYKhRX=U$~s_SYkx#BjkrRG5*@VB z^3=}UWn!8y+LzCLy&JViw^$#e#(OMV7>!Ow^h&gy6CLV5?GBQ>9y~M>SKkfG0 zR2XtE6Q@~hj@h93%b6v!ZbA#W&2O;$0e6yRZN1I6C4~lng^1L~zc^VUea;Fi!YAFu zv8J&#IPKhJ)Reev66Ijvg5Pia_#?-0qoT{LBq0KOo9_ta`e0x6oV7*yj;cfAlv-kC zhI7q)AT=>T9+`O=f#qs~pTTAUm^O!81slV3furxaEa?UcgtJfU!uIwbReU^kU4`nj zY~Hb--aC3hGWbD8rCpsmuWKZh6wtq2dA^EK?-nNaDSd<){bn%~j~YyH>zKTOR&4qD zl_$b#mt0K#m~mgT=WS=lu_#0^P7r|ty#$#gB-3_TX!N2?Wi;pXPOfjoX>+JghOvGapQrc)1}8p(ikN05UP=SBM02G z<6EympHy!)#5Z2Vs3wy_2**iqpyqV%W0}SSa$Yf@!BfNquTyq69|NL_#i^DFBIrE^ z2^>ZsKfE8$h`0};I7vO?l{$v@C(t53!Yjyvygm_7eK;cesuVdq28r($#*&GIBl3xd z4U#<6O*qIEC(DmVM&V|0r%$+tOVK=MIn}>`lm{Gj6f;i zT31I+%ZmT4QV`)M88CkI9-zd3s}v_;c=_!rR4S{pI!X{kCI7<`_j>CyytTVphKG7h zw-#ZbxtFRDQz+uxOVhD}FK0W`gY$adqv4RRnBc$a5)%<{gd(os`xfJ?1{Xr?vS2Za zlv3gqRH0hV+y?&7Pi}46vju&j4B@=gqU?~<>p5!Q9;ER?O-&6p8w_<0B5HVyqjv~F zo~1ID7|0QVAWHcvQ9g+Xri@CfG07Xqy|-e8wZZ;&v1U!S)Ml8qyXW%C`|Xo82m7NX z(i+#jr$o9y=OryIRu2NJp8+s;`l42HYqO5^-@y}rQJ%$$?UK&;U)~a>JsMRU?TIgd$ll* z@k7bwRT=quGUHR;Flwnd>B$lunoxXp+iX2@lQ04niyILmc%pP~4*Bq@AIiehEuWjc z&dZU)7Zj#cbv?dsbD0d}E#_Fn%a%K@>s!rkMUqz*zd^DROpa$v%iY%idB=U*%L(2v zP0ec%Io8*pzHe9i#y=kHP@r0v+1-M-{aN5zoTFGXWA&t8ZgH1+6E@OJ`klBZ{9-VX zS-sq_w`dv^+Pa#`+cWy5;yh)dA6sHEUdPdu@D;tH+U{^1ePP^moq_v2qvrRR15R^! zIrWd!Vqtrqj)i$g4u~Nz(f$tRQrxqj?lb&nH8Q)eKb8M{vX_PW7{%@K6~g*Y;EweG zZuJtI(5ITh2wpNIEl5MN0K!9Qy6sz`?9ZNc7%m`@h#>L($`Lq_ThGt%{uy>uZrVO+ z)6H3IuhRG4^W7gP&{u?T=hIqpdt3H zwxkz(rW3TIx7>K&ZMxp7K@glP9Vzs9dWU^C8#a5`d;X1tyt%!TaA>i4RTr1jD^oh1 zS##EXsRdqXbFq9Ra2JzWRy^y;IpM_89I38X;kwO2xr~souriy?OyheSe#v--eAkAA zW|G6%NBj}Wg;NDwvZ*|=OHW$LA!6at+zy+COd#+3Psef9l`r0dAAg2~{7L~C)%QXK zX<`~UBY)20ECs!rX33#6E6-*zorLRUohk;6mdXe@R;T~m2yN!V?%0CElCWN!g$#Lq_O7zKX^yso7j zsd&O|v2Y?Kx$@XjtJ@bAN}p_=6uzm!u%4@Zi&Rm%cXf<8`5jTGsUUMvveuq*~Th;E>#f^4)h+pb zaD|$p2EWsBS*_QfFn?<)!Z?${q(_E(w!Mik%r0cSWaghcyVBq|&DV?$#S!a&K?Jh2 z+K~~9qL470K2Z*_|$1qEy z5R>bn)FU3gP`)j=8PA1jWuMvpg?)06R_er%m2xu_5ctF!^Xz|gj6#AZQ2Bx2Xm}?=i#@#S`&QExjku9F4#aF{=jhGk|L>!oFH{WpR6SPhL7L!_T zteiSgA`@~;7vEPObS@v=Dq7ohZK=^+;bZQu=?=H(XA z#4M9qk93@OFzp(4)aZXf*c?HwJl~skz{9p$_k2~dm5vopIB`=tH!F@=!M73~xufmE z?sd=wx6LW@oVBsk*&%*0t$WPb4bvZ<5#(3P`9$tGe=L`n+r?()weHDBZf-o}4hjGl z8bmSlJEL=Xk$>1oe-Xo{Y9qNdk0a3i&N`yy5xOm93J7cUuMR#c#2{dyJf9y_-K?SlzKyMb<)0^Y%6aWy6{=e|#W@Mz%UVG%Q8X(vMGM zfo216JOYCeaW2rY#RhLVN_e~nL62X=Szl|*(OooWKOOF!ARt8*qnkjNir z=E0?dJlKnpV?&#NyqO0d3Gffk;Q|7Hq<)y7pdiK_JDVK)D;hOHZ?zWfG*#H4QNC_T zSVKE=QrHFTti2|RMtLr!2N!o1=Sz3nD#-Vj$6=={cu%kh6L4bANk2XkZ-F5#QTwPe z>Kb~r?xBRIGHT_0W8>IeuCIur2f{al^}P3`W4x8#0}6(Mf{OVHO$9F@b`C5ihL(hc zp(~<6E1lVn`B4g>-PUr0>Duk+Lzr^);I8WS@CO04d{93=LikP7rc81|0AeGh;PEc~ z+YMlNz@~^i)ixH5%|Rb(g^;=*w}&e=o^I^gW#pI5bk(3{O%^8!L~$%_79WfK_80Te z1MwGm6t-WU0z1nU$d|goIqrRMd_sC4YIJpYm3<}W`>$&(dVAv2<$AG}S`AuhTcgu< z&++$Xt0K<}<9Cj)D{>_iS3RAKC?#J-zdtoGZB0W|)T}z@ty0oyeD9JRKSp*| zn6B5&f`Z6ON01Y7_sA14R)sNhaM|Vn=@?ZgCP6oM#dkT!l+$~k8aAu;BqO{hdW0>* z2Sb31(BE2?HlIEwylkaL)8ytnb~+;4K(Eavmgc&HEYp`j`gx<3+!#lQe&oJDnZ`nM z#CfxtjF?LXhf~rY^-gvdcCbr|fvcHfqQ0-eZrB-h{pnmqfq2GzdQM%*kyt=EWc8!| zbi6QsEK81*WbTXo%6Vaa{5Qdy!{smfT^64!ghOJPj@n(E8p~kz>DZMFF?AltjR6}! z#oU<}CY@M~+HeTv#?6Rr#w|i=tsRYJlecQUyrB2^Vu3@Px-a4uy@(2|I=Hup!FqGH zgWsNmA$khE!O#O75$E|8Ew!4>v@i}Em#N&`%Y|>@3(@SfuPtEl3@P+g<|=45=rC${ z;)l7-dem+lDd<5NK`CY2n@k-J4d9#(9_%x9w3x<48jZ0mxBYF;^CAxwgt-XWUG^&OQ{hm{sF(3n9*tSoM$M_vAUp z5E7isQ;=D>wTF({mLBZb~N{#nNZ4>4rI-Gkq{O(o{zY&(`xomzeSPtzT*>RF%&Q1MDJ0`(on`)Mh~vnZA!xJZbyh*%$jv52XC{u zZpZ$1f;RluF$Xc{VIw+6?dSewJxT0^j)xaTuTlJC2jyhK@dYGqPv$QL%y>jx@f;R> zE(PKQ#KPjtm1zNbVEl^}_c$m(&7gp+x zhKb|FN}5dq-eFM9PoIU!z=rynI&l&RXvuJXW9zi4hKJ2}EGw6hC*4PSG}4UP^>j|= zQ!#^@)xC=bU1n9&6(-SuZ~SAn^Xu!M77*2RRSKq~0?S{u>PrevMsIf8ebWojTiu^} zhlYGhVYTr!hPj_{b<3eZ=5pgJ&E^#+ZGKS%8q5Js#>*UXHe$q6sU}^f%*!w>mP`h^ zy|5H+ca?B;%=x)knSa8r4l+fY5z@3ua14|r#`q$@$icPY^86GNp*$b8Ui3~bp1GNBZb7(z2&LK(80X>ghM*73j??F-j(OM2)o{t zcY`u?r4jJT#MxK512VKVYpmiKA@{PE^eQ+FhXMC{wW59Tw1pW2t6c%^(4UhJ9^U4X z+ZUX!^Cu{SHrW7X*eGVJ|6sF=QF*Zt#Hw;bk%g4E|HTv> z8-{H2!^q)vsg_*Q77;hB?}xUdqe#?GOhfxk(!D8*XPv^XrmB??8O1AUY^7h4xJ4CkY91FVxG*b1%}l=x5T&Oo z{Qdj@q%lfDr-i$t#%1HrU*Ao>D-wjUogV8FSr=LPTnM!dL#0#@p4{tj0s`K)KOZIA zYfY`ALCHj2(Dq~e7Jl_PfX!wB6sAuSs6Bm#TQQy-XdCQ7CD0*axyUq7?D&$>GLY8W1OTBH<@W{X#W;ceSzkJ>{%QDx|LXOt{ z75gZ27Bz**St_31g@POnv>it%;MF!0(^9B9p=m>@1rPzGuR3NM7np3Fiq+3GO3;F9 z?rzS`7I-~xLio?~lp5mbG}%;z`Bo$eAe|v4_hL);a-rZp67a7Y`_uU;3dfCC`^&|s z7Hb>ShrOXSx~@w^1{<6!J$v34S2a%=esu<2vAl1s0?dX-xU>vlCSFKQ5ak%-!wx8u&dGE`z^z-PIcRo!%|EyB*3Tu)QysvL+FLUR5ygner8v z)dbH{EJ-0kMWIwbTw-N+DuK}#}iPe0ua(>yOTI(+*6Nm{-2}3hi+M7E$dJs;&u^j)b<- z6@(RMcW3XRKq6}F^bK^(g9st#gxdCwAk5x|!?R1b_dYV3)z1(aSDYO-dNRr~8ZP%H z6fbd^LoY#X2xP3Fd$GOUV7>+m-KeBtWbp8aoXzv_64I5Cr#OwR;8)>CD1PoOpekin zuDi{kVm{g~#InH$@6_$vOKcRmyREX-{pmUDbOG;ol5w>zV=PuTbf^NoA6Ig_L+}|* zhSQWdwiY$W_w-IT7)N>JvHci#{7vV|PIX!HnFXma>Q}<>;X`^=jWY?U@?+_h`a&*~ z-5&Y6kyU6nI9m*G#uc@*e+h~rCC&K6|M3Lp2fP-FatL}Fr?;MA=lk7S>L&_sx#}CW zC)T%{0@RFb14#LKwz^OqDwH~unWf3$(@B>&S2z_WlA=1KTab9|K48S=ljv;@Nv_PC zQ`(KGpn-5QHiR)&#&0SXmsgpWH4hsZzo1~p*fitOnGME^)uc6@2RAGC8=w5VeIz|F z%Of_2gXfF0Ahhul&zK4_0b@@D86_2|VI5riU~dM#W$ggbbpkmmEQxeO*<+pr>hwSx>0h8RIx2K~ZBesUJ(cJiOSS z(rte`67N(P-xo3bL?Uh=@o;#H%m|=+Xny6&CTEBN)78HD)hKPoe7y|frf)GE0JiKn zon#L$D|>x9Yt#JQuJ580(cNovUm>fzfD@}w-f@4l7c4E;7mClx9@2)99eDZ0<+Tth zhsl9QBFL$}@w%%}!{pIvJ0%hw|2sp}w=`|ay$gB?ZVqTaWkFTbB#bci*GGX8jR~5Q)9__XY7M?g zg@Oe2HR8tGYU62uH$A_<@Z5fXngb2_-Wq)}R;ug764XRsfnQ-l>Lx&Vl_5)HHj`QW z5^<{cAv0Fe`qz6 zwaSLaEAWf3g$YN1S->ZXxsvpO#GwVPvw_G~KZf3KwGJk?8k5bkmwfG{K~4~K-Z?Wn zpL26ke8u8wURbCPDsvhNmq$cW0jFf?<7A~!$Osat+27%F*UgEf_=wD{0i{BpttYXAcHx(~Na(sMVQ`w#M1kslTttu<6$IjD)=mv{ zEH(Y2^~ii7E0YHD7!6Sl@%$tbMlj7*r~k!%QcoMVjbCq5^5Zu*!Hd0VY9xnW4K9#Z z%w_g$7)P84aRDRB5Yi4Z%w{gM@DlAHRaGON++`HduTax2^5Z<5HsT{}rH%aJA3J9q zliU!_l+@u?{;sWeevCs-ubahrO&bp)r$1L?t=Bh1+P!X%tXkG1bm?5ui{00f{jg(y zxgcE6X|Sfn2~b$oNLR5}G7+R%6hFoU)x}H_SuILOvt_b$)GQXS+3Q|T5BalGYvU3v zI`5st{0InQe|yZ?2|Dp}i5LBkcYkF2P>m;7kN)=<)MO46#G@^UD3Y;Cd-L_8d~Y1P z)WC-x#eXB2EojI<$kJfsSo}H4`Rt(UG{G&i+$_KzPqtrGWo1i5@90BsrKev(((;aR z{=_-qkVQg)=;=6^+n!oFVx&mDP7Ov7WNffHvmWLoj@i>>l(4s}qj9}&rZ$uBkb7}6 zmd2&?-BDuuQZgM0<$#iu=)5aXOPWiqsL!3?5!kT=L0C zLHNFUDq1l)T@Sr)K-0|U*{|S-81Mq-k~!M3S0H7z6FeV;-#Jvzl?wV0>-y&);)jP^ zM+OIkhfzK__RrvmQVd6l0#YXe=JhibNL;B7y8i;$U_jz+X8#qonR#Oon-&Bgtjnu0> zavF~(8(1v2TolWMT=&OrQ1RC~<8SKrbiaq-8cna%MRh?Vq~+x!(i(t>%3yFhmiI$F%|9UIt-6Zbnoz`*|_#PMj_!t}a0K7wYCfLv}hEw=x>1Q2dW~$74Hq%kZCGxJe z=caDZA^@0EYiR?7lI*8BsDR-CdVci+pyoVH=zd{f9HAgITpmON07)SYyyJ?MI?1NNs(uB5sTX;L2dc9UW zN(Wlk^P4Tt!T7gIqTBaSRu;EC@b>H>szf|Ps=DYAWg@dhm>@wqm#gCYgNGPf3FNL7 z%4U;rAaE^>#z)+SEx>*65x!u5GH!Ogb>}iyJ!RCMApZMi2g1r**XQ}m9}UDw?lG?{ z)=c*ehX}Y0cP|JPbL=~jQoa6ifV7h)8`TZ2Z7zu(n1BP_TChSrXhA{chX&>{!Cs32 z^k>U3+ui4Ifmi{5v}nWLD2eV1tH(sM00p#D2E@7xeVPHBhnSd-265Vrb91#j8eQ+l zc_TclJU)@7@Z3j7>Zlt$iGcbuHwo9+?a|=4fKCr)T?khGRG@njH#1V$LLhK80 zAv8w)G0n4OOvo=@*g3MWv5k{@L?X%Au5?Hkc9aNkpJdBKca>Q!);exS8MyRMTGeaU z$kMm!etq?pz-Y-uUr6X+VwOn-RIv6pv44O z)Hi!0rFs|}jm)$$MIG=Zl+5=^;+t9|S=ShTkzIA*ey1UeT(#?|3Tm+FT%Iq5bb>r}^D;=) zKVcCFi6e>F!lrKXndZwJatD(5dWC$BZlePk^<#j(VYm3; zka$=6vYfd2GOS3WTJZfz1S5of88w5&Xy$n$r+3DgYgz7(9VQ^Y<$92qTNwfXq!DE6 zT~)^D2bSYS(ytZafEWF1$OeY3Dcg9r!S*!DMI^x+!!eX7#{CU8moDl87^Ge=4FK%- zV2h5l5s(M4!*6Yf7OglnUk4yHR^9nMr;8PiqGD@}s{~7Y)1n+E(%O`5pLIKcx{`wq zxrpuS(%DD^OP?^R82fxXH%t%@@ECeBYr5?Fws*KKl>~CFtE0|{ufoEiIYTLpR)mx7+{->hZB&> zl#1AN7xr0H`$wzv44Yx?m<#Q}@cM89YNi!b%8eifpsg*8wQHbP4_d42-{Pa6R4v0% zrsRh3IuG(J*1Wf;0S=&z-`#E&2V zW6|=u-@m*aZIS?&nQ*$6siN7Gv!MOHqF}goqRcPh)PU{?=!+U6i4LiLmien@1}U0 zMf3;&G%AN7k2QrJ#`@S_&=APuTzJmTD}-Pd2Fy(gJ_|>}L%EeF@GcK|)*-~25(vk! zK%NJo`bF?Vo`;W51>EAec~r2PU7! z3zkRF#+kQ>5>+`x8P_A6eEdG>4xvy@Q1}*n8{p854Tqlx~ ze0T}WF_Dk*PwdC`9h{q>Fo`yS`v-|vknpdS0#l!Vhks77TAKfw7oZ35TfS;(x5CH$ z!I6Jo4KP6BEf2D|n?d=CtiRj+JvKn!o;>9KIiUW)Y%BtU|6d)P;BmjjpA-I1suEne z8XW^jMQ(sPa;DbH^os%l$P$SxMjqP>o_9F6!-(8~RO8HZyYn`T+4tX0h_|r&g2}zm z2zlsI8~E`v;wK7JBE3q^BK6+~i-?D#@d6xP6o7y_1AdgE{d+Y>JxCo5r2(!LxqV+L zPmQh^g(+o{#z%7x3+(}>UF=B=)_-y56@xE$^|}fjz_Ic`e1I~RMkRtSkyR@BBE0_x z%vmZwiqdemdY{FkL$}=G(t2>A+?92EzAzwLJW|Vgv6&tcdZnaNq(vWqMjQ!%A<06O z!5sByQTvTO_3PDPh|zk%1cu|Pf85>Nm|S0y)2XQ6VnqkK#*CuD__Peilu7o!j)v`%ZjQZo^rgS~uKYQJC*wgUwr@q-tZRGR2ZR`g~ zquyX&hKNWJD7@|BsR(Ec`qhC3RQ|D$;HBZE4M2giDAVWO_MRv3K&$6`7;yaW1lo04y69u5mqmoOdT0|qH z0zg2?`6AP%Od89)!c)$F?n@xiNRECu7vO%m9}jSQJ*}SujD9h;PdrLy6?>7RP$fy( znr>96QWCjNtAZzIA&mUIkw(43=pnY1zga829i_s-7e_9}!T02)CLl@UQz`S{_WWXk zo3;YTtfUHG4?ghQ_7{8Hy-}1EMd}T*JWiImMj`23?;k{|0jjmeq2`KJ#-3O;eD!>} zM(^OzzzvW}%by=Ej~5f{FtdZqRt>B)%<*6{&6U%zq$wsO=6fHCGS zZ)@-#o6F0Vj%ctFqiBi=$*vIjq z_4Q@3hKgK+M?OA)X!RQFtY^fAKBdo@+w#==t9Oj}oLttC2zICMxX*j4&8F1vaRnqu z~=S?|xxLsX9bZZa%2N?Q+oQ_Nnkg!JF>z^bv=?So*Az zD@L=?>`xM|PebHuG*f5T2^;kE^hA4zF{Dg2pGwBkSzFx4Ii2Bh za*4My_oJIDX2}Yh%{7Lqtp<)@?M)Sp^~@a=m6z|h4jGBAdx*W8`zv}4ya!?;uB2XR z1H4d?MzcIs2w{FE)^Q_~-|NcVD?fjVwccpWdgpDrz`80ri#R$K*EXEj3`TrTYdgPqI;~2P@CMqk+0!cYdqB1P+lo@4=OT6R9`AMQk5d z=+S((&Z6-k-mbv~pj+9xpE<|R)@hodTHy43)srrFDx9tE-+hEXQ0IEGRvvZW{yyQc z-*q)1FF66P8=KbFd-0HN-o%40-K^k?oL#_SSle=%EK+ym^}hGG`3ggiC%jM6)IHX{ zhh7iB$PW4j(go7F@vPH^YEF(~|5#m;1N1-_X2`+FCi{ZUuXhzhOpPTD8}t#Lw--{? z4WEz^UYBJj3^-q(U?DfUDM!s|E9f0SzjS43wyh1)Y!0AFX*D7C2|P+ zd%>zEec8Ys)G}$`F=rzJd1fokNxkpSYqI6yWp{C{s34?%nKHXaYC3$=o!7O0H;);b@7 z5bX$f_iTIAJcVNv(8e)9UfjMbB@_GX<`iLg(!lUPnJD7pWD-zO3!x_%h1bQLF%a2b zPYB-&&Y*wNR&MX7LHFA1p+C=xE1!YhT zZSwlWM}X#!^GDt3Jxi=`QfHH4gEet3$y~2hFs=dd(MdP?Nm%o>(8>I{tj2YUZn|qh zApx(K*23MA0Usji<%cPTFx^UrA!6Oj)6L<{qZtiPkvXSZXR9J@&o4;+n+w*+1LwYW z_SMkqLq=AbP2Tu!&%X!^;C+!QqNO9o|7q-vGcU2mu8_2c)mHJytuZtU!H<+g_SL6n zfI3YrZg1v%H;P&KiEqT$uneM@SPq$_H&~x3CyrQ$@)dKwj=GkmUTb6(M42zw|FV9v z3rNBLTBk?w2xY}6WHcaRIE*owmMm*%9SdFXmveV*Tu>vLMHKE%P{GmrWOSZoklv88 zX5xQ|sHG&IMQO0Zyyy472!_9m+!ZF^5PRcU0g&$>s}2RQcS*V~+#dfQ`~+CS{|}xQ zo_)JvlDIB9LZ1IM_FtRL1iuBp^+}EG>!O<9A)_+&4>e^W?178;gYxu$P>D5?;BRMz zGHkFe&AdbcA3L2H@iim33k z~@p?*igWdqFVr8{_mc7g<@0YpN92+ zxlD6}Gbq3LO3{BHkT}WYgX#&-O-1^TwFX)`$^)Fa|F<(?c~?7CyX97!*72$HRql`! zh;8qBS#1P(tH4e+&&t#xqi@3F2vScCiFl6CqWMxvq4yS(HnBcF z6pDF*L}EAlvo(*?^j)0q+#=>0arX{vE64aIya7DRML(W}8u0kdn3mC*pnEE+!ihuM3teHyp|{+vT*1S3iyG z>wcv3^KMWR7Mox3S~7q`CdYDHekOqr-rU`QsC%QSD~MM({tT#3IQqBEDX}MH{G3^mUsz~3iht<_ zPDMnZ=POh-I=gr7gq9z+=(%nLIgi3%ZsI%R`G)tIu`ei|q7g^0^+xp-GV(DFJ6ll$ z_AO?;kb^6%LfZ1JdF=8u_V1}2}MgXFl3 z8~yWig;Cr&evQTDBu?2gcnepv8cUemXs%Qi0xr?yTwOT|Rdg%4<#crFtZ5nm2qn&G z*4H3>PtUjz57ImXvh6!ZRa87>Vp+Zb5OHp8w&Xf2m5UOqKX%+c5 zk?zfmqEvdq?X^-_jk}=TAd|+g+rK}yDj{Lu$NMkK;)2Yy*Xq(urBhX8-dT?4Y|F|e zLJgTHQfd7O`Sy*Z&S=FmcTi_bTq=>JZm!l&>5@LuoKQp^CB7(bpZC&qj!A@NG^JSZ z9@LfPA#$?TmjOVO(48JC%zK~8M*(4ykwVvJufosqZJ66|8MI%-jEj~oA~#U?*s*kQ zHueH)r%xPX{}_6YWWdndgv&LW5w2L~CSGZGEbHs5SM{wEcuJ*#>L{dMlQcEBIAu?B zVo-j)@8`PcerX+) z7{v{)0j0a>5LM2e4t(#ALPY2#Ae*1hS`GOc&iBtNp%f?$n5%JBi{>Y5eTIu zjRY}qyFp_te>Ex%m)#2!FyEZ+Memp><`(+6&j#i8#wepEwkbp^lENgNQzHEk6Iu@;B%XR62u&v2Jge-$r zBOT=+A{UO|!Q7XAN|Ugn`fwO%LKot!jLYr(^*I5{hgpR>A+zb)PK=hznJ+=Mp*vF} zwjn~Ijt1%f?Bh%Bh!_b8olJ`suQk`g5pCZ-(P=UkB8iez#1zI)M7_RHeXCLHQ)xBv zro2dp@bZJeB#x}vsfxQY3F|*z_7%ZHWWib-TJ!GcNWZtd=Q)|v&rx>!cIeXk)hF!a z{RiiEa_34{ZlRI5e+Q;oavuonv!hbGA;eO}N0Z~7;WD7f%nSyTjg)}D`J9Knbtw#B zqvj&@>W49qIQnzyH0E1P@CW?=ZTk5G{f_&L!|y+P8_9QM+x&{(B-wxH437uOWBB=F z{NDuBA3#6$uoERQ_5Xv209@(sUs)pku~iR@kMx7=)vS#!{XZ?Wm^_dz1M;P$ z{{R6X!7KyNrQeY&JpQ&GzoAw-z?0dnSP|L8d@r-Egut zrtl3A|G4N&&SEtw1UMsu2Knp#F%cUwJCfzu@I&Eih$t}PEJC3B5oA92T+6PNH2jfb?!R1r#gqf<2(r@qn8I`>9l?XFeD zr$Y|aJY)scMl#5|DZLl8qUh8|#bzdUr#`O*=!*7^$yLUtOjn5J-HxscBG=oI3nf*3 zwxw)T)x&1ci5fE*l4^yz64l;Cn+(JQ7(!~(d9aw~;o*;mCrMip7EPB|dle{4ow~gh zUN<94Qv%Nwj)IpY#x^C=iL@ydGDWNl`Q7%iq3p(ep50QhZ&uE+x4hk7n9kYNSLPqm z1|TyFFST{{+h0q5>u)R3X&^EKhxB7w1=*QNAI{a0w~K~MSP)G;z!1v9|IyZ2M@7B- z|DTeM1*D{6Di429XAV1(9xnm0nsvK)R#^q(NG`B$iHLX#wH;=HC0c=l;(5 zowNV!?99Gr-m}d6HIL`>HTV#E66j2nzp2UxQ2YcdYm7|qsUhZpJ4l}Pb-%B*! zj;khvXt8=O=QlQ*yA+`=8RP^&FtN((d-F!bb^9}i@mIri!7^HV5$<&Ec@?U0v11ms zeN!GW-o-^Yk7wK)#|4!q{#pIqi+>vV3*VL3=H-|BggrWmMYiZZp`h^tMz%ya2H zONly@f>tk(KKp(^kS6R@;akjSt5`&;e**6>8GbZH4si>*xPrB@^{1a1eX^~KKA%`! z_cH#PvdU~On2uoy2Y@p^x-IeoyUeg*u7G04G%nI8<)~c$Tax&>$_JFEk4tBq;zb2Y z6^|9^(AfwSAER!L&fTU#j1toOJ@hJ!le-kuDb=;n{#rSC5_dKFG)_KKzzq7-v#lUQ zI0gO(uV0q>$~8fEqH&K-D7fr>i&y17IhD%q_IFm(2V5Iv2b6?lV-eX#^rgR;d)f0? z`|dE{TBYUWMFa&YtQILOt(riV5dKWKwM?W#C%sqK%;zmM17tS`14m=zm;`_k)^ zPm8{^%}JTj&qw~f?e1Xes@ArDdn^Oi$s<_1$(hW#;B9Y`##@+LL>DmR782~58o)Zt z>mG1@3z_a9;KskFE|`X5 z^}zPVZH0YE1=P3av_OI+nw`cEf&()qk2n_X4t(&hFx>Sqy{Z8#U9kPnk16XTX{vh- zcMx+PLOalYJrqz%=nj?`T%qm7n4TASW-r#UL{}KN zM>Dg08=|lnZFZC)ZWnLdO#Z3I638Q%ebImj>z$z4`x9+do+02G`jW%AX8zQv*>tP1 z-}9TPiAhLMklu6NkcPRh_0_SX2^Cp}gBTuJvS%l#YlkHSP?yJdHht&o%cU}UhneCR>qPAx_8w*6vD5V^@9^fS;|!+|7@lHk=MM83|f zBy%cX_N!1=NsLYge&hoY%XL{Mjs&HJlvw@|O``c*ne3r7-p@St8V%_*5I+?`N4Mul zqF^-TcBiHD9Nh3-oq=MM>ob^J9Le)!A#Vik9I(CO2czMceFm9QjTcRLbey#81OU5< zI!-8a7Ffm*Fs?vaFks~t84bTC{hj#U)j4iewEC_E_055pL7Y9&54Dl_@yFMnqvDPp z9CYn?@OE_r?#2&#^9{~wOCiJZ8IL0t9CldnaW~x1i3eBw{ATzI7V?I2r?O9!u)SsGZw$ z6$iB0Uzu3zq3@Be=UeUI`zM_zu(gM&x)myJ0KW$ri`_2n>GCryTX9mquqUm=R|Wt+ z@lW;#Zo|;B{bC3d2a(18y2ZNqW#NZaIlR|Ym)x_b52Uf}K?WOxDL<@0&yQ3Ng-jt; z^A@t0R~W>EFrk)mC6xO-hLbSzK~bFHa2-xEq#&I@M5Q^#3x@)9WY zao^xsJ#CzR0ApT#IacT-=7lG_S+R(9s*ec%4R})SAaN4XZtcXRyhvOZq(Vr*2OS3? zv6hu5`@f6k#aLk`e53;@mGd9ZR%x0Glrwsvm-Jdl!XS(gA-c8g0p3sQ)QGP#nfu36 z)J)cLm$D5-Vy_=nP=6s>ZINzD2u4cYaaKOBct4ajt^oQ$j9YuK0wnJ`8Ru7Ie__}Q zE%r#pbADtp*U5qqig#%lU)&%?(L2nATpuuSGG}@2ZFlDFNunlx%?1yB2AHiY>X0NllE_ zMKMQ8YgB@Lx!8?5&o%;O^3%i&eQk~DqUy`^m}AiIf|&Oli9O9Fe5CKQ9Mq*deQnBk zX%1btpR3!OIje4~gX#Gh`0_&AbSX96SJ$b6E;~{kt=TnJ-jCG)v;6rotO$Q~M#~43 z(R@Mof%{I#xJ{oC<4Blhy4z7btx56$+r05;sMjZ+Tp*RT*LMK^BZS)rD&aN}sIYtV zb=8fxB@{$CP03*04Frg&kFHi)=EH0INQ6j62B)R;jbA&tmYjZ2+}&&cT(+Q)EIP~0zb$h3G(0N(_YHi^dEaZdvUbJj*Zo^w*9@A9)Sts zUH)^b7y7z=)cIV8v`k02ozz0uOU$-qg{e<%DuW<~2vRDM0XGYsVleKU107fQV!u1Z zVzP5F z1A#$?M)nu3Fz$i(`+uT~FiTY-;NC|wpewqEZ}_COGApIjhpMC>4Ec9a=JFI}eXk&5 zZ*C=kR<78h@hTQd;Z`&b1f57X@j zNFp2GEFpzOiDtkAUGk(RhJDqt zTh0Fi7!MO z+sJx#<{4?F?$FbLW>0TFkYRk!>4Gz;s-jG`TKZ8sibcKmodxZ}ae?ypyaIwA8l*yio2m}Ksdn?+UR?BN18Yb>s7PM~HCzM6xP1G%*CFf_T3_3WyLh`4s<0xD zEA#@S!KS* zgIPYW@j6{Wl?2n<63#rJw@yM^4xl~=xVC~#uln-bz5D=}mUWM*@N=hhMV6B!)HPAN z4tIlU+r(3$C6{Zv7#%D#U`tGQ??Z{`OJMO~2vmpxiGhSJ^Qgt#3VnldsZlXeZz7_G z%bdThl=nNGQ<~}ZtP(rN%$Yd7SK>^uY25>dHB8M}*>6Pclff(*C%;NeD5buWzMb2| z8=XiMKQ=GdR_?yDgEUpCQ1NZ&FMb~g;VE}nHQSpmc`QLdpP%T^PKhZM&285GJivxk zwgWw^Z;2(EjNh#V%jSCI`J=;VZl|((@EGK4xB?}bL2GDJ*YgkG9enV|=u|$}ye+Nc zT?lwWBt#HF7!g6EAK{wK@~WJFOHb_mJNc^4cC;A^j)JHLd9y467~J9R~JpMae5ifEz094sH&4FHWplX$(B zM;zzQa#RvmOJ>OX`lt4ucBLs_y1r`+Eu?*#Aamo-skY?h+AYZ5vVzgBYk&|N%YLb` zB0OH0zTr?t*y?yAWOkllVNz_lVP@hPPe-TtNX0-*43#sDMe_yC5om&6)# zrEVlFCy8-w!tCTer-}j57E!EZw`6UEE(hM@plh62`sWdN<|>wAC3NOxcRS@ra{Y6| zj>q5kx2v_T!h*TUZY(y?T=27}QBEQhwvV<~D)W#i(t+k@7=DPgK`lGi6c5_&X5ErKm84|KuKDMP2 zQq%82Q>V-1EXUF5n3ZgNoP?P-aXcWl<=NoU zTdZuA&~8b^yyw&O6#{l$81kR2MEH#|FqFP?^@8w4V=z?gTcRwbfk_K9%uZkDBMT7M7rLIVdXR71;Ebg#gfKq1-0S3$ ziNd>8MAyH2nQ_GZ#|Qc;rbs33(dTofy;QKeKk?66!r(mXJVov_JGSVhoB++xDooR1 zF+aMLHl`EteR*N>2MaYtR0lT;2et4t)gjcO5@T2aICCuo@Rj)= z!`NjmAJ`tQ4blg|k#Uq(*r?u^;MKSXBORA9yzJtV57&q=i6^Q|2^N9)g++B6U6!{~ zgChjg9UJ>xoI(W>E0K-a-WAm!$bU8Hv}F3ZF)L7IT(!%}MfTy9;ebG=9d zW2Q(PZ$XY>tS&9oo4NA4yR$~_5!ze<&)2%sMMQ14#NwJ{_UB~u`!=&qX1* z4&*V^7|2Cf5O$G)*b+|{)T#$7=IQOqSl=@$sNu@4;qjYy`e*ZIF4Wa+1Ksv(n4oZQ zuN{u%oc;ZNNI6i#g{Ice;A<=js~zL7hl97X1mHYHQFp*whwVx+@+as{L6P!lN8`ZR zUGVu6*?QW!OQv(dp|Y$PYV2!IQiG;naaK1izpKf9u1m(qdlz$5b$MbE(^7|D5hsvL z9T6J`peiNEJ`%M$OcWY&jkSFF>E!L`V%@{JGmA?41>aV9_50noeN8mK0KN^qSC-!D z4*dpUo0E(%lZqaF3|IIZ|EC2Rl5*g%HP=&FSr>cox4E4msPP4Zm-E5eGtPRkd5kLY zvW7t{5j{-xhyF>7C3K8i?v3jI6V6uJ?!DK`)v&tkHR8vXvei}J8p8X|4-AF;SCYwF z%KK7}Ezn5)8#|(V&I; zyw4yC@SuDd*p_?-3TxW|xb0Jz4#rVpkKItEX8})badi?^ihS4p>zf<4e}xX~Z2-4IDS->nW6GsS{clM3-DA5K2%{`4nf`&$f5Bnk zTW?#CT_3;m(!o(!TMl|c8~C=?*Pp6E-lH>ZH z&nCJR^Qpgq#{7>7Gd#N=ne=-fdLSR+d(XchatkKmju4=+{kM}x=>UzM`3y%|5dRAx zdk|Z(X8-WV1&>NIqJ+U9y+yiFfKv>?YxSKMzj9_R2zY037ZTlXx&e0@QyAXnSxL#D z9-1ojyG8NK>KMJ>X-}O&aER3{QxiEXN0?JcC6ai0m=If$L};Zd`LAh`!Js^$mN7Rd zb3illzM-%|WVAm_W>IGSgBtT6pvc9p|JA*C)k#1xI4BEJFV^TfH6RJr2h4?a$Y{7E$h?+3S$ z6C3Th`8BRPukGin>IdD^g({e0_hu%oK=XWCT=5N8XGzRTovkL{R?mEEJgA#Iw&DiG z8()-Zl}0B$F$El`WHj`uVgZPRA%m)+{L9$>!ZmwT=NdqIVmmMrn!ad{w_>9aimP7y z2HzJO{7b!72d44)7@|7jh56Li;ob$Reb2PN5uk4c2W)HC)991hFp!31Fn&EC{Yq9+ z@)FlyDIwHs2@u3K-%G3(`0t%N{dO37DB^b-3UFn~XtJja00R18?LF86aKC6L>`*`( zeDM$XV?F#+ihj%IQ;$LE1{}M`BI17>vsr09Z~RqOvjeQMJqTyaniN2*cPzG?2M)6e z4G$mCf=RG`-s@YwO%WWX9=KP408l$@)-2D`VJ$J6;?!*2e_VGwUCO0ObWcLFNF?PcE>3{Q>fz9YCE z{8Agq|Jld{AgdK_vjF=`QZ@2^k6A5KvBrAfiHYc!B!2ss#SQN|Cq;bG(MQFcWxq-+_TMCV+L|D(=J(~? z4-7wK>$NCK*)JDHg$P|O44v9c%@4b;PEtL!cg6tKlT56g_AMtedzK`PS3B`3a2E~f ze?0RFD9kV96l`g5zEkgGlsmRg=nEy+er9IatCpGDhxHDb|Lq)z@^7sh@;^3HHw>%( zILv1q0F$Pp6#3_(`KT@%KEbj^PWIVsDq-y&I%S7j^QkNBdo38RRh1+UyckG&`i5GX zGQ7XAV%~fI^6A_?_H>+wHQr=&F!HX%E+uf-2b$^uO8%Gw-u2mQJ%P?|Eh$^W0)9L0 zAD8e~Fv%?x8pX|jpKOj_1pPV!Hr2q|gn{wvjx_)yxd!)+Ij~@;MZga6UKsHQ3%0!j z*znxvIbz9aLxh{nJLv%$&NB5ZH4(r){o$Ml(xa95KlYce?oT7*OrK14@7=@aKECNG zHP-c+id+CtYw;_miIyNq$g111OF(R@qXA#>tMCt*kayoOsKKaRB0xUgj8o*p$d0Fc z6pBGNKA%iVd(#QyZOTJ~GBCRx4ZZGdn_LE*2E2A3>N%;Y7^xW6iiW_!HU&vs29uFL zMW2z}rSUI_%7w+W;?qdRoO({EQ|=0ToVPeGHyQ2D6te=@4Ftt)yYdeWrOb`{w!v!& z1(bX)89knOVoQ3oCWoTwm&=j)Z+6B%AIbf0oSUsZ1P+%@H4>#l;9BH}0D8C6?#*@1 zP6CgVw3D|~mw8`BE3fl7M`mI8tr}cZkBiEMRn`>%8PGes&*pPW|Wc?Q|AHz89Tjy?-KZGg}{GL zZ;G}zju=!K3%dN#dw;h1C>(yTy+9TV%9k1$HlM$p9@=CrDsHv^dB2tb7zH#&OTIQ$ zjTXS_dbR(&Bbxi*OD{DxEWXx<y$?ac&s<6btEMO{63Aw|zsK)PP7wqjXp|6w@ z>U5!rrcxJRO*F{Xp$So-)&=}8?>sN)E2Q=eWtSD=vL4^vHmG<1WRUgZTutxD5qo>y zf4zcqa&iFMS0S?up5aLcL=NE!NeNhhu@YgOkF1l>uqu6>AQ3fF< zU5&_M!{V4Fn#U5^D;Vk2lGtzlO4$HBQh=vEp`L!`LA-;{b4Ezc_UudgzB^|+_AWe! zG@(ukA4FDkoW%~m@?~CTSsGuOLPtcMB1AVrl_y(!u)?IRqLfendZZE{y1H)RZ$kA~ zh+rO^Aw>kXVBn0ZN*|A{H~WUUxY@^B-@RO>@RZ9Q`*ra`cNnbmUh5hNbIV+PF$^bT zkFA!u`BLh|BCuo!?MF~8Id<~z!m9`%?pRxZ8tA|mO~DB@^8mavpU!6c@{i{=!gFGQx7La|YVt9eABFH6eV!U#-YtkV>lK$g2{h~Y{Y(&GU?*R?;8@PqeELHUZe9A% zm8$#R$*u$(;S{B>d$K#=_1C=>Jk#JfRr$j5A9E| z-`uUnobRf}EbRbTKCR)1o1LflQ3 zPMGmaM=_;f)f}dMB`>Dw=3keM&W**L)U7R~)g%#bkB-y}l!|^g0VnyRN>exzpP9&3eMek}bGCo#gDVgBdMndfrX_tz_J*%GYUd8h)wZDAH?>o3`T}$Bdcq0S51C(JLo8df2GApzg;@UC@)TLcDO(TMvI2&i47_kE2e+WW{Bio12fV zBE?0~VSlaXJZh?7YMb|dawBZEdx}x>mGY5V+sUs8yZOZRM7E2}IdFS~HDxkgLTv7v z0E@M>6TF4NQ}PB)IkfzZ0*x>wmrIZ7NQOG;lT`ZAHtk}1^3!|{EPJXNFd@rli~@a9gOhWeE(kAJacP*vGz zT{JjKgE({mdq*@aD=lscq`$Eux4Nt#=G8Ov=c0W7MdW+jPP1*XM{<~tes~UyqSvFgdno7&i=~9eBX1K{4M8Y_$XJ0B|Z|&$$LidU8HYdw=!0RoE zA0$mtDxn@RKf$b2h|5q+w9LYQiW8F%n7ynyuH#LC>d&JW`iX*f#DkIigS(1nsLi%E zVVT;s#e#XHHWgFXZuTV7re8%hu3+f%@R=4_uwL4!Sp7a_eXMVG9$Q1nNmUm7{278Z ze%84)Ks)pP7Ae1rlU)L{m0?O*jJ zNr7HveEdxK_uIhx(dvSZ7%9r(tXNO~sRWe%zyO{ytWQd0fNR`W0zUaj1~fGSs}jEa zPZpGenPxBMy+-(Tu4I!Tj)R}6J&khcLNq&Kk-^S7tg)GDC$I zoX=%%cl&spUv&op7$mC#fk5sMN!hmvu{Ot(^EL#6;EW42V7PE3N!=t?`LFY#EB9wq~ztn-xo&q#>UnTZ)_Z^III#uQ9sO7H61k-6$FiJtR5J? zws~dzz}3nYaS4*Jt04GjW$b83>uP0b?I7qXLjUIsLGT%In3JCN&nb=;BJ`Sy%Cu58 z_Qtfl58w~r^rBd_w6wzZuT2D>OUwRyIrvY6{*9xftsp0-i;K$x7w!i(_NJU%0s;b@ z@Q0iaA98>*I2_!p9SvPMtQ{EsDdcZC(#8%(_GY$@W;WKeh;j{I**H0h(9b1=4-vateHI*R_!$ozZp|Nipd3xzomE&pFV z@lQAZISTq&6ib-%zcCZV3La}0K|&Hol9!fHbw%Dz#i+j9F%nEcXd)wlECYi`-0i!M zF0Rs?0yo4vO=?(8A#^8l7(m7e#mdUcdPScI&&qkM91)6ncl7G|N5yG6mGkKq^?={c zGW~r@lkBfc6AilKYU88F^v{&;K~_=xs(yJ-KD&M#yQIR9%{L@kBVIFwOJo5e=qX7JkhdaQb?F5=d<2&{^jL@Ep~l0I&0TO z^_%>W`G>bI2j7{6T0iPKYhhFHS*K9&+h$B#mi0fht4ye%Fp426ajORHfDC4}Bl6i42K=0{(@Cy4^;H;)au?%e7C@GpE0Nc8T>p z?N0moepP#4U(^hWUKTu=c~G-_r)pG5sK$AFDu{jC{dcNMZN-n5y*&f&3pDl>>E6QI z<)b=n!MNPRxf97Yjq5kpyFPWVN*VV#o30iIgbx*5ej0zQks;Q)7fZu8-&u{+_B-8Y zj>_k1Uu)M)XnpP0{dlA1qn`WsMJBE&W^w`h&zFngoI1O64NENoyIoOKn@mb6YbP@f zg93A>+tU-E5Q($c)n0(mVkpCw%RB6RSH^6`ET?16WT zy9uNpwXFq`>l63hm$%<}TCG)P!Wgifh*LdShKX`d)!}rOa@ZSN}smG z3%1NSjMD`Yy9%oY^dH(o;}1YHS~r8G9?rDJ>rn8m>&zx$kv4YwE9e zx-+Y2pyfC$qo^72JCTwbilL$F6ld|HAkiqIpnT+sdNej?{m}cBHr6!LqRUs8>{{tM zZY%}%u=`ioIh2%RBQ@d~W~14ij#|f-_4}O;%RH~zp;bGzn**i(DGaaDkPhQ&R9H+1bKQ!OaPuo6op^*y#LB3T0A>d{|d zDUaP6s?^Q5b?+cNvnEMpD?w5dx+CTD?)9M-wce;@JxSuA$?bYGnN%dkF+mtzF z-;%<|n@@_^>?OV(Pfwn9vw0h{6NgiH#p07}1fsJ>F}7ln6HI-GZY32@kW7$i4v$VO zZoKH>Xu3K`T&DAeinqylTpq0x`dfMqByhE*wWJBZ*W?mq2`Rto=;Fi--!6OY^)PNo zQHFl6NncNfS2waq9-`dU+AbGKZkz-;FnR9|o_DLPt?_(~if|*ws$p4*8aW!TG199f ziy|#!z4j2yNHXru#n$^;9c6;y+_1j8G~Q>1>fUf)SJM0%^}?4mnNlGpQ^6T_+Z7W@ zSORQzTgbs9O+G#^(nBzl#~DqC%Q@^Mhcfg&`@y+zsD-Q7;<(Lf9oH9Ood%sSEAQ1r zQygyW?tT5Dli#87M5^qS_x!aClQMVx(NX+xVijrkf=cnpdF}^bx6Ttj6JDrw+9b|O z`~f`{=!4UgqR3AB{a}Uh8$1cc_78kV!gi!1U1RVz2B{R~tM?nU$J#_(CQ@YWE7WBW zV`BPFWG|YMtQn7;8s<-a5|f_?qJu1^ zx|C`n^l^Z4;oZwmm~AZaCNrXX5Y@?#ZWcU}J7DqWMel<6 zG$UhFgNIC1wW5bj6z|Mj$7R;3vd7q8-|KkX;etA_&%Q#ezSo6=csho90fy{1&XaFS zD$MKZiG$+D*?PATANr;p`KwZ@V9@=_DY<#6*(h3Hd{pzxdroUZEeUpe9O7%Wt4S7p z6ZhV54M}G*W^g(XEV+Tb!ESOT;HN>HntJICyGfklwezf#1_k%LjK?18&sX6b_Cy~s zKj9Bo>U!>XtXBE2`igdx!=MGEYz8v3Irw%t+=0IB2@MOu6qLpRsNO6cSJaYZI%Hy3 z=)ALzqbdAdOB;>W^vZ)zE7ii=oXWO|hFO^m)n8mq{#Mgy6HbJwtdO+zg|9=I+$f6^ zw)Twg2WdvW6J3vn9n4d)xvP5_9t;x6dh#GIhcpu|274apwor}pm>GK8l}SIuB}eax z%Ks8;m*>tT;tzFeS35Z$S+THaJlo&PD~aqf)-g~=s`FeziD=GKraX{1WBq^;mB?>N z54rc2h-=qyJ^_wJ;6+lxK4x=%Kr5m^?I&=ivm8!=FGma2T%j;64`}jibs2ij*jt!4 zcptw7#c*d_L;sP4Vk74MTyBa7Ce*3AScU7`9T~6WXn`LKtNCV<;!ssW z!7+92r;Kb;kbATr48Ib+Fy_H1&{5_J5A=n>P{t*Yny7gE)XZMy#a4}crt!;*tXa1S zFi${5?!yYIFLb!45(7??q{T)qkG2aLEcoc2a|nGbp7TjJVo;({WX`GlyLmh~<52`s zw*2ZH6=Ql@9kLftZl zvHunt7w!uQ?Ai9H(D{3f9%%P+kSyn)IuRZ70OkMrM%Yzr6g7IW>1n zc4~{9Hh)+jtqofPKrukl-*9!%YrWq=;<8y-r8mc4qo>NJTU39S2{Pi}Y!ofB3ZRRH zk6CW)1|8&pjuux^^fjyS)u7m|7V;p$Y!uGfBAPt6>6yqDj}2}0=Cx@deHzoyuSApqZuEQQswD*~*& z9?=2dXD3cW&yGab@!jT3O&J3CQEt~A4hV7Ewf2V+FwB4*^A0t)#)ikZnnq1w)!bAc zJcP!(+T(a!gL^l(E%$4hxzpNMZtVC%FK1I zY3n+z1_Y+#^SW?+Dm4vIETu~ak%nek-PX5okG&R*Z4u*G42=8r9f{oQBs8b@emuTkkvpTStyr}xllw8d{z~9!N^oWhHFwa}s<9OHScG?Oc zh97trW}xQ8BZKC%ti}fSWBUmmhe)#q*(l2O0g=-g1!3!E)9x6$M0gb699VW|w|hiKGz|6};Rk`?ND#C+BTnab}w8q`pj6 zIU7y>h;_;!05|J&&V%!ykM_VD{oSc?=+&~Y+}yb0Z!#0dAqfnbv7g){YhYZ%1Rd94 zUf0JHTE@zaB(&^GuKNI_%IU#Eg&o4cjEQ~&cBaq=^?R*rV2*@)pDl!}WhYxdqYqe7qj?k`XRp4B8r~V zQnShH_WE>qz9oQR(3OFc()ggjoKmyh=LWkP?3uJ+2B&A`zW6FDN9FV(@)N8$&wB9s zP*gWf)*vY%XZ@c4LNEW<6t?2}k+}foC2Y^;X>7-MzNP5><7QNRO|l~zuc17({O)8j zcB`5zjaUcynsTkVkkNuWr8PB%bCH29}L|~H7@ zKf8B6ZVCy&hQyw*JvCCNi`e`uAFI%O@bayz?GfNFKZTmUMb}p{Zc^cU2hr$ypRW){ z`N9%>LPHHu3GsOhTOow3t|mIJA;Wt;MeqSYx;WS(_&#-T_5=5kXooLnJ-|l;ecZ*kNY{R`EzWndLPOx_bWc~8K z?1#L@gld(n(RDz(G3fd?QXl3_BUrAwwpE3KB8jE}aut9ewbkUp^+z}pxKx5;V?DZc z&Q4&memR^%mrIgVeIj_P?GPH*ewg~EtDQn}uHnR;@w5qacsm8Qf4++^V= zJ9WFY#_?L6x&R(&ecu?*|6QMbk1#m*o;(Jnt#9sf+YVk6mQzjwiMC~FL5`k^j?f(0!dox%X1dnkm7(Ggl%2UHuf+c?h-%O6pmFAyaF92cMRUDfK?6 zEBKO0GhJ@B6c2dvnZ=7uqld^gIUnrAJry3>y?m1y)F+L$Qx2wTyKqbTM8azYMzAJp zFg;axkdO%XuxdPCwf>swY~SE6W+HNKZ^B#Z4ly*HozWpqXe0*@=WMB zJw-#2&zAdQ@W7jqPwpB9De<}-ueUn%M_#OhyB#bGEOw$kk#_;qz78yX6X!(Pm<(r7 z+R$bCD=aXvNKRWYXcA_t68_5}RF7TJFD>cJn6M?2M!^jli3( z*U)1AB+$g_9M1l&n{t7!Iay$)6`PY1>=p?uyJ3uhNzYk6v#4S?mt9?-{)%^ES@MO{ zOv#WYh^rklG-BwDF5(Go!4I(|keWX-z$D3cJ&x84y~2l99^svkBO}ux>7#nm?QvmB z224QtA-trbPRJoTPLZb)MO@-jI_vg9L4upCkda^jHOh}4Q{_A}cDndj$0bq{O) zALN}fl`v@oHiXw>1;1a7E_@CSZcWCe#4!Zy`I~2bo-kX}p16qCO4%`vsTdEI-%yzH z10|DvG4)s|v7dbfkso@wTbXkZ}Hn+(s`J71L~? zHlIU`H0j=nH-$dbWj@R#=%(T3VsjRkZ)W~M zd&7t`h%|JDdC=@a6k8i=THRv94^4=uahdDhUUvy?kTP$i=Fjf)*OH(B=!qhk#s`?bP)cP`B`AP&J^mRVc349q81W zrFCOfL$!W~J#!x^Aq>R7OxaZAlCW5~zLRq5XFGS!rKK=D=rUs`_d^LYP_U1-;0*Ld zAamu+D?O+`cAd!M!5%8)@KjomJV@-c@4k(HN0rT)$=G{a)c(L<*M(<4@hPaiu2dXqf_qe*{3XatE+>DdAN*OU)mGF%^iM`gp ze0&Kvgv*k8s7aqE&<`n;`1i}zAL3b6ibV0i;k)-tr*Y*`+XMj@oHhQaYqAO@rFN}& zGfb}^-x=|q6V*r|_)zDu_`HZDo|C^{mN$lm0#Zx%vy|uGh4^3A$^TBhwv_St<#n3) zlKPQnrnj_1bEV9NFELUiQX`6RaqUK)I?)w_Yw&l@n&tOQlxL|JiRM|1(4=hGW71Wo zz$|ftXryo&sin?H#W&Kvhj@i_PX^fb$wHv45q49dHfZGB?_l>yARFi34F^_aYsU1B z`@)fExLA)5JKebR7f1@0MQ^VhUNjh;a>j=#Vh|d~VK13J60Ewbdh=y0?%{6j<^zWh z3W9>GdH8GwSG)$!HBc*bwzJRNIz`nLM4ecvar_F^F=m;02V70GI`hn}{Nl9Ysp+5d zF5cy0>+CUP7RP$S&K}2zL988KnDP)7+^}Fslxs>(O9%#r>oj6@ta6JjeQ|q`m|m?a z`E!I;Rg&{-L8L;7Yv;!&V0gwuIqI@Qi41ZfM$JqEa(-cSvZq{F6GDx?` zs=a3M-zB2^_wCexe zDS_o0h8IWc&d>FV0s;=kQ@LSht-5rqOiGzY4wq3EK{m%B_59T=6Ds2iUb@vkcy~Pa zxl-OKlk7dG2o(Q<;AYP~8Uvm2$sV>hcIl7jhVQcrBm_S@B+h!Zc=w4|)h_=kpW7IZ zDYNb3Yu)UrPOoNP&kB2Cc~+7c^x)2w31)>|BBjOW=aUH-WL0yC66)T6c==D; zM*I;A?veD9O)jSmRXzYd0EfD)IoY1B`O<)n+C!>BVNS3M;rR4QCa z^!zmt>NKhb1UIYO@PzsR+2W{o_PRK-qokG6qI}#jT-O$YKUn`exGh?Q46(p|bK3G8 z$&lzS3%cxBP6oN?2s9=w#V$F5O;!+6DxR|j@U{(~$BAWE4PFA8`^lD>>mJ$fQlqZm zoE^aK>;Z;rq~NtoSfc$LMI}_Lq3<<5M>5Kn7;%N`=8NIxYjJyX&0UNgC-r%^>2_{p z&iiuvhxfq(zVJHt6hWv1E599=(vb$-h$v4^IC2LN=o}Hq5o5&Nbs$`)jQ_9YKy0TE{Xh=#Cx>(i+WyKe}DoGTAm1lg^_x^dsz#n-4xWhL>lcb!oQ=XdJ5aaKp%hn34{lT+zS0xR-!K= zuiiSpOYh@$yCia4CNo-1q!?6X@Cnmf*0?6tQ%EVmxr4tv3Ixb*3+}Cc^ZY_$x6X8; z%@l`$xAg|E4E0Du>)|oSX(4U+V!{VFaKfEO)Whv>3AqPn0Kyg>=IWx1B{~65kc?ie zfg!%gk@DD=rymPWh0o&b9S22DHTm6Kvqj}nTzyHN(;oz(<5N>!{}#J_%R6J+)@{Me z-p4)AUEIzvDE$e9N@TqKEBE%&CtNiXg-0iD+MD0>d|+9q(0$r5i>>;OB;(t`8Q^UU zw?Eg`z~k1Vt)z}}D?a<4)V+o703|@?SSe!|a6fW4Iu>`JOmkSyH~XFRNvR!|KrU?3 z=;kX7hx-z_UtIpKP&~v5f5LX(!|a9fhoRmlQuCwF#GDdHmCK|GAS&w~ohE}@*5Y1$ zPehc`GHcLr$?sAzr^S1y=cRrBgRKr^Mfyu?J`h32y;1-_jp3pzd2eEzdT;Q<3g8T;NurhC$?**20oMeU}ivUm9K)Ly=N%Q(ZF?)hpscBTFB zzT-3Pp*it{fXX>{i%V?My(s>UAD@)9+?jz^)lW-HDAhl&$?VXQf+QubNCg#oxG>qJ za@$6#vcSv|NJPk-M(iZS6oCj$^`TR`2Vx0AS?G3v*hy@?9VYI-ixT*j?t=~T?N!K> zi1kHiQ}{3DLp|r8#{DGoVBsrcGw}U22^ zr*nKfqca$IGnVs?%hQwNpaRW7ZZbQOy;yYyy92+P?lWUA%UI``kb(p(8zT_eQ?j0^ zdrHLO2m4`SbGhH3Od}W32Em}lDNxPEsKK6Ojz9fvkW2!plhPDRufZB6fR8Uh7TM%G zE6LYN@dD{mZK*d@d0~Vjb{&5BvVjdEF&Z`|0xZFMo*Kp0d_rCaB2%a~dEJmD3M7ZT zFau3L19N~RxWCrHI-N#7%UiF+X$(L*Mqi^C@j(d<0+>(=`?A6xn3D&B`7s;#5CRRY zoS*O;eWhcY$x)BWc3(>`w;C(}VLt|!fjYPOGVMxE%*e<3=eIBCkMH$Y^u?kDz!u?k{QGVF>f=8TR46f*bNxTM14xE znl-(N;$MV@FDVs2l-`m`(rp%YWzo=dY*a@ltc z+W9$)6wt!O1!MJ~MCa0m_`hA8*Tj0qmyNd@Ztz`szsv}^Fr;eYqj?+> z4H06qZag=c$dUk*6&X-8=6rX4QI0A>OE0qBVcGFWS?##FyjAJLJPEd6we7vTRo7GnR25w;4QInIvPe+x6s=kqv(PqwF&$jY}x}ZM!kwrW= zSs!K{-^S&uvETa&nsl*^fOPK9zpU#LLyZ&D7I46{KF4~1=5o+XLzkd1WUl&gh-pFW zU2jNMg0Mv%b;pM<{O1Jo$>f$EifpBf{0|(nE7DdpIWeItlNK^#ZhF{I8C7`|0MYLM zE4q&>#~HuMp`(q9{72Y^`qc&kEK@s{Y##pi2swf|;Uec+{)Kj9j6k^_`!c7h{ofH7 z;vs}SHfDhQb135hU5tm=OI>qAj`AQ*v`(>BLQem}pskf+j@q-u@KiDWE+yg55w|y| zO(*A5LOa!;J{Q_lsEMtx{ZoJwDnO6pYjQrd8D8{!8qXW8HIh+KJiG8V+t9nxRh$Wly=y_wxkC5v9nsRD97uGBC=e`o zrl*afFZpFVI*9vzA_sbPJ;C_7ZO<$SLVh@JJAy&Q&>Br# z$5iBMzQn)m;Q&;}xsT&Fg^v6B7iV?k*q^B`b7p<+jUA@;IE#cOsTTg zBhY)|$1t$MxL0ejQW7lj?T0=5iG#sRKcAi#f;3TXD@r(Eh~aZb4( zx{Jb0b`XVXKcr+Ui}V%$Ab0e8Ec3Jg#(upM=ilM41c(_<(rs@~_Z1I4EZu;#m46$5 zaVQy&N^p{^g027rESzBkl2WvI%L{iU%b_p6DmnSwURO0>0nXuSR;ve8c;~Psgtx+r z(lgKpy-ONnQJF!tmy%Ef$mLZao;LM1Fxm3kTN&hlrw?k{1L^SAkr|>Q@i6ENzqO1V z065Z`l50_qq?(Yb-9DC>O zm&1TU&8CbevnVa8o;yZF{|q7-rEf9;CI1Ytytem|aSB2(M{LzX*#d#1)CW_BAyn*8 zA^|z}PcnJ>O@ELwl~=@kH=P;?RD9hW{TkhYYaH9?b9>{Qa*Pl&n(^h-%AY5EP2#oM zH~~_-@@L(a)%wGMGFQsa9cIZX);|%Ab``d5=MysSjH0q=WoL%lFY}#Cj{PnlRVo{0 zmx~}>z!O}f9km_y`TS`%=lW;A0|*}QM~w~0l>h$lLaFrTvkkm!IDMhHV2C7zyeCuh z2yI`02l{m;zo@py3y8?pS7-ZCb|j&M)XcyS0<=O=xpa7T20%|!N;~)ZfdydeWY$HW z0>7RukYiUyGUFA&Jdd1;8MGc~GVjDH;0M|`hfMWgZ(|<-SS9A|60Lrv2H;;0!b|>r554O|$D3rymN2f&z zzX%g1j1UfZi`YZMX)e04Ip2w~3b=!48Hecc2@c~yt1Lp2&;M#V7Qfm~_$)&BQy3y3 z(!G24Edr&w1>bcG{_wpF$g=NFS>6hxMuLEY@L@##5P_RjbO+|GiVZwbz#$v$yfF8j zsXc)v+JOSwfn>OdyPDgwmlAy^_BMl0v2GZ`g5vSaqn_62_)|j~o%Y<^Ank#i)U;+M z&K?G8XB;25=F6V7>8j$2@7SrlmEF_R8&YZyH9Dse;>x+JiN%r)2=+zQXPDcOrhh(` z{5X!BLh5mpE=DYPAQ?M;iwJgDE*Xj3ZLL0Ntyt*s;5?GiyCim_W0rnP%Be^CR=6yB zjfT@wM(<5|wZXuaU0N{`}qKK8*EDK@}>7fKE97oTI!WQPPAMF}ve z{w(sYk{JVBx9(I9Lk_Oqbf+)u5b!FQ`osK#H+9>Uz3yEB`m=I?L)8Q^&_Y&e=vzM+ zEcyZKRt!Pf8bebUZt+&w(27QrmSH>HEHEjVI0d$JU`n88BGV7Xb7;$Y2c^GV)Tr&W zG)R!20s$%pTi=}DJ~xNy-4;j@rFWbW3O#_PLRFm#|4Q^NR|F3Yu0G(7${~dky6FLL z&VEMsx%MuA$ad9LnQBPMUJb%B5B2tDy$ZCzmp5%S;5?_NIsHPp*3_|E3#rOQC zLFgCWp34k%V?M|-v)T*0STXaBbNQRE@5;_z z^P6w-XI6Hp5Vn@yapKHd<~O|KYYmXvi@2^|cF~v^S(+>3!>!qlDIOiAJiB#Z4H zsuOmt1Rr?Dh`NTBdDR-t{E`IAN#bfu-zTyY{~KyBnM!h7u&J-?y1@T+_u`#hDR5s2 z7BkxF(SF-3?V`3|BI&_jjgP@FKW2>AY|Z2iiT_t_-)f9uk`nN!=^b@thd+wq{oIs-&>2o2;Yy{<01eC3>2kA* zTw>6MG7D{&$DXseZcC{R$OMmEw9W zN#6Pf|J*LUFZ%aq1A>v&y7wf~Q)jM>IKRjOS?>R2!XERH%xDG8R*ppWMUB^xCsA-i zgs^WG10A&9w{FDPGQpj>N;dpT(YxS{;jsI;D%C*JY0D>X%0hDmd^c6&)MTZf_bHQo zvGpKUv>2rGDJh#ZgoV^NrDf5xGc5JWP*1+~9IszW6f6JY?9#Pn-*(5LgE@s~4EcBS zYpPt-U4xSKUn9F|4R6*sFl?-%oB zEgG+U_jXV}>wxvW9lxJ;RM1J6K#tQq?bDx38BFl&Vb2p14yS++KdZ(gM$f_ocIY+KsE8 z)l&t!nf~hIN7Z(ISt7(}@bvO$s^qU#hFxq!Bko@wLD+sz#51bN8t=p?Q~Vb9RV#MM z;zkchrC1IA?ze4nZaL}j`rsK-o--sIsC!d+xY=8&N0ifR8G91<6Hv^pR4@2`d6roW zX9YD39_xcX(M9&VGNd2FM2~8MuqlvYvTbkNVRPCYw$X-5Q3sYX63CK5{jg=fpK`&) znr#U(t_FNzjKAZ~ph%W)0|inu5C zG{vW3rp^0j3)K4ffkJ(EEUN;c0muxLOm7A09O-y6C9)`YmlJ-zf9zRl`<&OyZx=dA zi__6XB{`0aL21wmnN}Pg+Rx-_9a4h-0Py4ip$QkA3OZ?KT+3}xz`y~)wAuH3)$|b0 za~2)w2L_bmt9!}Q*oBnZp9D=|^K4P@vm|;ZHT8@9cb7J! z<{nxqJUx#V*-#W&f4bwK&}-l>>`!%h;Yb)BM1obHYR_49-4M4ge385S(*DU@x!LFw zrLPbmF+lx%k-i2z{20ngh)nfEHRLii_P}H?%}Q>U*r8UBDp*pH5NIn9$dKr_<{bSd z?-quMr`^w0dSRfY#*=1WR1=q6zCKIe@xDIR_!`^rRHDdp>0v3K)l_*WWiLM&&$3oy zPR?ovz3(8h2^tRuWd}!|4rrvR^{@ODCsO2cIfbMCWWMx#b)_`npO9W+j+cFEqE7%C z5<{Xl>3F@FxBZjmh1k6Z$f z%gE*&g+TFIg8QH8WQH&-q1q_q zAmOf@e<6rVUih41mdvj3n|eyk%4bFz<J(!y&C!Ypy-mQrigB{TAJpbpjOWEo14R~Lkx0NS?&Sk^ z*pHXM1U>^yW-mV`=T?HJML8VGUOpsg?T1Ee3tV>|6;HHW7lL$w{VOlE@nsOJN+E;t z50utN6FN&bz)vP1zA;()$z$FRgAzqb7f8h*B|r^DQg`=F#WUy_3d&Q?hH|03X4F5K z8Cm!3N54LE0mj{?O91C|CW>@*K|E###Egis4$#@ zw1T=Hh1#a?9iB~%t7`-IkZYDBz48eP%7|$Q9@Ul&@PxS_2n%j2BJ=~3Yx8A!1%#6l zeuSFkaq`o&%sl{5w7H*|Zj&G=Hmk@t`+5ZaE+&tF_l$1e8w7Wp2LW;X;sb1hvk0qV zFg{J%_gxTSu>&!mXG|jRj{w47MUeCGLl6N-x;tCrU|O}`Nm0iTEj)sV7RIL0+}}UX zOm!TQF9HgRb<_1p*(pM=5jtOvodvf4#afr$od*p^&oAvv?`+BS0b8@6;QHQy?f;zhjV_5|+OL-8zBr!V{Yl0um-A?h0C>lgw+yZqcJ@ z9H+(}o!2vRc^)AC6B~MNfc>6x;~NNBC0bd|I!!nMt0)iVM+qD+06uqq-QHAPf^>k$ zpGM&U`)Mw7ZYMXuS8k`FV;7V=lEb>GO{0p6d!gNpBQJ}h?O9c&r`Sozw}2oQ)vcu=E)UVz*Wg~z18IR$9Q zuY$}odya42^jbd1eyjb-LY=zrJELiAB51hL*1;rk>#Fam@2Dr^fdV(6Eqj8b)_2b% z;adXDH#ZuFJLX76a{fUkeF+N&Nsn7W&PrJc!fAO=U40Rjgr>fHb{`h(j*T9Ujx2%P zg5u}ff?t{y5+$%o8a^0y+eu-=lO5@04IGg!oQ-E$n6wPC5%3TR(pwOs*yf!yK#lGE zsAWR-G@KkC-5w}F$zD<4tg9E$N8RV2*@2`YEv>5%D;P)Xx84U9hTu7Vm|Y2sok_9* z;`bbRD4ZfS<1$tQgK@}Su_}}d$b4y+scyZ&G^CJG?v?w}E&|d#6cZRY1EntnXox6C zeoqJB33emwnM}0s?^%y}zy%y=#X80;1=e)UuHq%e@BGE1I%8|lJ8?4$mpPTrgeBN@ zNO$F5y=xN+6~OXC`h`v`@#ZN3`I!jefQO1Z!F>;06x4!e>7pkt2zk_Qsq?1+NH%K2 zbrQZZL~l3y)#xRwOQXJ(b553%zyu&O)r(sjkfUS`d}Ad?kAJ|=08<}TKtb?10Z1?n zuAOOrk};cZIU2C0I*53j@Nh%K!T{DC4J7iuJHv37(zY4d1bx995iW+$b(r;XRP{kI z0zV}MEGnR=>Be+!8&jR{f;G9f970HN{V_U^;-ebgb$s;VdHfwd{?|mYHks8gvK6=% zXqR8Suv^;B!pupq=fZR*>}_NG7p>cxF$Sm(;q50i0U9?n!C5q z9SX8Knz0U5_Z}Gxbkg|QVnXGQMviq(P$aR7vs(k3Y4YvVcXU+3B??**No6mF8F==j ze6>Cq`%bR=CZ+pD`|crOyJP7B+lIKcpH@j!*eZarE2 zEPwuW9HPx}nsi~mweLTm{>49!F1gkRW&;>$&lQ$>Yue`e0C=+vj^y~DFgjPU8M+8nCCJ(g?^f?;X4)56-(AgklRMJEKg^JlmTQS&tVP;1t}ZsAf~ ze-IWxX5bO5iQCzfiu9su#@E+(9XXCnuR4JhEFr1Js;Mbm2wc-Cs ziz#+8X%x@Ngj9J$>#EG;{{(DNg_hp@S2=Kpl4+DyVF|CrzGl69H%pgzFkY#~Ly$;g z;uPss{D43^yLkmHT6|VGH{|CzAF30K;94c-Eo2p7sUX3(PElIl94bCPc)<7|Zw}#G zC~P>HvIgt;;KwgPBotM5>#>M)J{ki{5=kJ+Y8f&r`lN86f$v2Vt3Ek-bTJCKVhT~> zM_SKp`0PV{$>jif{~#O(n!pTShErf9Pk2N!{q*`HD`bP%R9-y%x)Ef4?SRqat|P}G z+Lla-$>PF=zX5F8N(^ty9`34M3d|;jTs~vAS22@Kmq6lwZE3k2)QJ>{s*pBLS-zf~ zJhg*PDyNxCZP!kqPJ9`lCGwp2j!-tbCj}NkHngW2c-s|G{mk)&1iVQsS@J9b+wPiV zz5?wAF8cVTVp3M#2iK(K(rPQ(PjosJ;ZACCHY|2eTk`Ylj~nX=3=G?Lw?I7fp&@c4 zlhOoxQ64?1SmTQ`H#%Dkt2U0RnMK=9+(7XGN+M#DzRa^9-Ssfolidm>Y^Xw~CDCgQ zlsXiH_5{kk7tplZf-|^;4!|g6%o3{lmXU#oKufIe@V&rP{DQT`s5fwo1iq;NaVV~( zPXsp}DZ;vLbW%T0E2nh}QYEdhjUOj(hLM*5xxI2X!72e3^#RIwCW!DZ!BD=?`xZ9? zt>3aP&zAl5KB1^+$f(o%(7}-RD5Wp_&aqoiM$Ps_pu07}x_bL1z*5~w z9c?J-4^+iR=v+;ot5;$XqYy=kZ{2MR>y(HrCIZAUhe$In_ir%=fZ0g8ou-@r7lTrV z<&e1L#ijgr4gf!uhzz$%-LGNTf13HnjRZ(Cb!Cs%e=SGY#VqTTi2kPXD0?7inTTav z+26XpA<}<-I;XNefc!(PGfoiv#$%Gz^uJ+1r2Bl^7F7E$-DjH)lzUR5Ht=8n5hMC< z+9?lVzC#@Jn*t*xxow!A^0&7>aDZOusoYex`&(`WqKl{6)CK-F;J!A5m~}cSe{o$R z!{hX5Oy*Id1*8*rqI7;|;sC-YodH4>hu^BhSe}vxhOL`F`a3Vg_Yq@5&DL@E?_hBu z+L=(KF7>ziy9j={So&PyZ|y{g$@Tx?Lc|-oU+fPPz4&*m!SF*MpCxhv_0%c;w)sOS zXyP5@7mk119OnxTJXtfYQ29GU-Xc1V050?21i?gf-2Yz+QRHDkLSp;#E&%Yr{NFUK zS(33+!;wz;4vLSQPaW5<`X$jDyKmQCi^W6cy*#Hr`PIC=<+iEnYxBf8%vu%q42b?b zTgtuAv2fvWd$OKJNrJOis}n`L)zdR)Wa-3UiUz3fe5k;8X5$>LHV|$AGm=&erOb5D z8Ig{yZJzsO2JA0MVz0>RGpUAv#ZMQ#qOeZw1CSIhof|9I?cY%due-Typ7~jy=r@t5 zMPFb)Sj01{OP)3x=g<|oEr$I`B?YNkJ!HlpN#7n3hFRWQjvL03B>u+5FNlGr@23~^516yJF zd!dCuLiQ_Ar9(R~?(J^X7`6pR{W{9aFESszu$iL=A)@+@I{GIb%Vi5You|8;xrNX> z6HQ{xBU|<6r~YP%NQP^=wT_7lb3h8yPD z=MipGi-OW%i`m)=Gn|)z_9?{g@eJR2%Dw=?PBncrP5R}06xP+5YKMSpIbV4rUWU-O zo8%FA1AsfXqGE1BEm+;TbagLrJLvWw?m8$JXwi+m$&VANixr~Y+DY0=*u33e+8ME{ zs>>Hj=hcV`M=l+RcF2DMTS2+QZ6?nBkAr&3rMtcvTll5q}qAqAmpYS2b z?@D6jpCe|nUj!4Yk*o$bz?74@jDitj zh?IxJ(Xd<{0OQ(12x83#65haDE>Nq0KJ!~A$OP+@Z!DSj+beX9i$c@EG%fRE$?M0z zo--d9j#G3tQ+sSJXx6;SdnH4SFc$De0I7z;e+FcI8yL=O=M=}xypLh zGJ@Nh%;U{A3OD}w$ZdpApQvIIPbnAioSM^@LTrxm7;M)piDsTVeBp5CHPj8-q*Exn zYtdIX{emY2;n0W+6Y#2!{q^@r#DSux$ zRWpLoLx7Ccr)~@6X*)ny(=i`PFmPK=!U@q0lHf+6&g>uylD7rOVN(f=t@ut^H*mT@ zG*Uk4beIkB)CZ&48CojbfS7+F*Zm7*KPd96nQA*c3Lbyi6qsvw_$l-bLV!C)mL!sV z8hQ)(7|E90Mc7qKEN=^p3>C@_6?9I0Xb9$3SX!nTwF7buzq3mC}gBU0dp8^Jy{6lz2GwI@~a%c|5 zzP~Th$&uH4m?X^AzTs)-xI;fZ$Zzgn)Ecf)JTrVQza5Q@ajHPNb%xEe&?RrZL^OdH z?Vyv`Y^ZD}*+Fhv%b!LCV*80|kNQr)>kFI_2JFHUEw0jwS0lLj%m)F(S0E`lp7;M~ z@5|z$eECsS!zhu_zKyQB`U@)MMVjT zAxg4VmeBvY`~ALW|HJ3tId~j-y^Jw)x$f(Jf8N_v-r$ANLYzXTS^uVZYb!%&uH>Uz zaVFcqeS^=E@uk80u2UO%l+@=XuzFS%5wuK&mPJLE1e_CQ9I$McGO)fDGOAv~z2^f* ztfAC)!-$BSFGG=8pII=sjn)*(BgqA0tPYMkKDSX(}&>KAI?`)HNKthPEB5gfnBl4?*-W zdfyBt`pIhE>Zx(wCiIan=H2ec^hk!AC_39`vEKF-Xc{&7A`S1EQlb>--sNR70}AE0 zb;wYp?2f>r!zmrpAcWvL7`<1VJQd625ch0v+xz#^y>Cu`Wckl5dm)*(#D@3PWYNC= zqkZP3SJ3+5yY44@L^+V`oxf*$WLCfUPjpnCmGAjO3t+%mP_n^vG6mxNT7VeQie_SKF!O~qO67<6y{*24+UG@lv$>Nk0KDCZc7PH~Uqc@V~J5CbT0qxh9 zBmkEr{zwvEq4bL8(!;IY1RO+(3|%#`tJ?xEt)Kax4#!E0i3KlBe5hxuWbhXG^TN1t zLsPadGiC*(y9s41;VD5W*MMvsjXx_uuF@+gez=7=Hw<8nS7d!X`<6xd zN1uymFTqa<{U^iV@rD~0pFSOb{xW5W(RjsIvNZW6y-;?V(!1JPx9`t7lTv@99>?m8 z%5QWxJQW0h#KYR^Nl#1?lvF42ANEVYS#~%`6P0vZH~fRSyRChk?zvL*GC`_4{1K~{ zGX^=vOyiRyPwH0g(JIfbcQC~@zEl}^#a<;o3rUa^t5GzVVlu}ZMb3P_%`f0sf)H*)iud;5FTyA1D<=Cc!pus3xG0LQ zl|HTKyEN3af>Mfk9i<+L(BiScy9w~cwyq_Q-)AB?BG#GcRx7L@{9eePL3c?70p@R4 z!E*6tH*yzHXfp=mI{EB#qD9zm?N?)0qjAO#96v*QB|ilY(C}5?wCP?|YP5hABzb~Z z;?|pWfqXowE%$j%PM=M)l^X14*zc_qjIZBz%#UNJRA*{bPGpLSf(ap^tdo`&7r)5UrBER1jUR^O90bi}Ahfbjk>;F=V*a!~w=r4C|Q&whbv z^>?BC*0!|MCu-QxcHyCdl;*f!6CpFnDna=9!{2VnCDXmwBh(G{#$=3|iA=CCE%l-B z8>%oZR$b#SV*&a$2|nmSxmmk|HdvS8315z18zGpD(d8|<+oY6A$|`G|w}=)X?j!AH z$MV=_xP!ukS1tZ@+k8YE!d*kWMVN(=VbUTMrk4hBnsHgaXe-i=CpQ}9b3y7PT&eRE za|Y6_*ixDY8#<})X)q)UA8BFT{(~s4YX2in?Wsnf)Rf;mlVUxmtC;ISI~>}BbT_dr z^RC^cd85)4z8Bx4IS&=+$hTf)feALj*J0CLnbrj1HQ8vi1^FE!$(NBGY?90sPIYJc zb4P8aOTCU??^|04r^}K1hfxC@yxe7oD&KXdIP)=}Grbb_UX6`=kMDdPI0>eD@+A5E z{AtFeXf<)M2@SHbp)pBLQhW2hzO&|;Ci6J~dPi1#+=#_mwd{8tW6`RRS{F8wfiPl3 zI_XgCDH=D5k1a+;EI&u}ezH?GQ+5FvhY;Usr}Z_WSG90PZ`u}31g+}ITJ2UlDB@v= z(MUn8BSu7z%^hL&811{ticoPPh%8#^=%W{6`e2%Lj{R)Cf^y9<@drxdB_&^Z>ar#; zWRDzi*wYI|7=>&W$8Zmf$fnO|4~Snl#bL-U?2VmC50{a+gW;M4Q;Ymr*rO8y99^Vmwpa-@*tj&(^^ zuT36(o|`!vGsmr6k|N&Le%j>8_|0)9dAY)Ji{N1`|(b2$1r3Acg--=>Z(^QJ(;-0ABext7gz>ik9N zt#&jEuVL5<(u!c$)rs87@^jM^6Rx%9S7O?n&e#_;-np*VLRWLY^tN%6Qgc1(s`kqH zBuhj-d-pV}pd)D$tTi_MRq?7OZ^KZ?tlx=KWra(_l6Hb?C~y=3grsG-hegE#{rektjzzVo7U0H>N2nNYpgT>Wd;2pGe`4}%mtbM zvW+AWKv9xKA|Dq0YwY>|J`EDFj$Sl9mM}Pd0Wj(hVkt_zT+$mH~Ob(&Y}>#m-UQm=ggQzdLmtuP zXTPh)uYG&?{ZeR33CLdiLctWx5u@p=HhyFLa$_Ly2dNeud%oi*R{^kd6{t7F zY7&532x>>1ya~JsOTbjou-5Rw{owoiCVVclU=Dm-rzUZyrg8Gxi#4d$LtZpRv@{$V zx{z?hQG`x?YH|AbV{eZwP$Aa~zYD>L0-Y9KDew(ccR3q0N@h=lieH{Uu)KeGwTbQC z9xy_QMFUbijcz8>C`)easjUuPo)o&Q1Lko@5Q0mtrOy_Ac;qqe_0%X;I4AeXI{rmkVdTY9x8}9S+^D|m=3T<7aPX^YqaMw>I8`TD%=92NH01*7 zVZ#0>e+U~pfXnnHF|}V5o4Tx%OKSC%NCkWP6M@I`5Dri37t@~H1y@QCmwiOYSosp( zyM|?EKxuG5D65s_@Hc}^P)q7Lmt`ap+6hWd&98v1f1Ixq{DNpYlt=^11BpDA?+<^r z5hu>$Hk}dfqSA2YFMz0F=4Y%=5Pe-c5) zoUpMu+U>j}GuNhS*rW25FIp1iZ0%;YM8nW^7v@6R3ej90z`~Hr%N_R%7;om|?j54e zh|VQ8`B1(}Zt}M^J&<;fQL7z~xQCu@VUK9%6NwAZl>Qb$WS;LzQ|U}~YA4P1-pUqR z8w1z-%MGU3Gq<4AO6(yxyNtaDGtWLHE!;a1sOX{HfYqZN^6BIp-%Ys4tpzVzXOZky zrnrzTS9-GqFMc?%1y+0)97=r+Bp4;#3#~z5C7neHEY^;a#50qifUCsmZ(P zr;p*CV9FeemQ%msUHiuOf4C6>BGEL{{1H_L#Kx!#&!cI<{@CS1C}Fjsdx7ul8oJU) zPPQP?I2fceWBI3WATO1Y8K0`-m_~}`S)aelo|&pI{#~EermW+r%(rOR){du{=&7&D zamUZ5-h}JHA_u^se93;Fu=2kroyB1F{XM5UIq&StFStc95$;&4jPG(htmHf%m!)xl zDG15${H%G66liu0(=3dnsJ0XzMY6I9B#zh~VzgUtr0mZy>j(g9&vvuKWY=fm+ ze_J|Y@dBI_M~vVL26_FpjB@{N-c1mtI}b`8K7s-+4q}5r;{Gatl&j7b8?w%PEdl?` z$5CyNpAQ&pzeDj58(`HMlR4FV8#-?Kt6scuBD=n_xe(g*7ZL!!ph7vQL~5-WhfHzc z-b(a|yatIVy|*Me=b8cUPBU}{#OD{CqZu-DpsO+vvF5pVDl3XYKxMsszg}6Q@bpLeb#TW%ExQcPMIX?a8dvfmZ2jeW zDKxo%1VR0*P;H+nox223;g*gBnJ?Wk&X_Yy!yi%=0Yx8{lt9|BOgavMNXdE#Bw+i)i*+w8oz!sqq{$X_4csWq{7a+Ndi*TZR2KgLtYk-7P}{l zX(5-&Xxn$-Fs4V3i7^#<@lv-Z!Ec~-8HFFV?Pn6yV03_7E3zVJ-(0l0O76wdfO8~qCJ#v5P z2bR2H986h<^!Q8fLEVtV7$9ggWgXme89|)$1UAzOvq|xMAJ#^Q8b6b**fmx+=2g)Q zbsEb*9<~%uaB)jmG0Fup%!w#SVIuo_@-4TsIH|AcRVor~EUeGP16yR8)g-I%TPm^GiwuKLHIj`|7cNNWb9b+6S|p!z-VeqVJj zYq0zexR?0(o)J)(3|l{QkR8Z`bs@7oqa@*@z@k@RTuZ8eJg`~@!Cv38Ti!lMy+n|AMekU2v7Ce4g^{ul-EZFyh;+s66P95@V zDkEcs{o=; zun83L+Sy}vK`(~OKz8eg#}WCR003O#TLF;Xn*e9yxzz(y05a-83?w}Ps{Dw{0?y`0 z9@})JGL8d#1ta7}&&7taTZA1m?s0u}ihJgiPQf8ueF3&1Y4;|N<_d)+7!w${#=S-L zetu&Yr9fjr9Y@I5i@L9ab!`GQh-2G`i5%sNj0-n+164siXa^!<4M0vD+rV|2MtF3a z!HvQ^1bT|TBuG1~2Vb`R`i40C3+F}S-5uai$8B2JRN=1E1Tmy}qs@Y&VJt+a@IaRn zkY1hLhfzh?{tzVlvKd`SV#Q!qzlhe5TF>%y1AGk7&B1fURh})Ra*~0zr49Uv8osnW zRtwJ4%^%6Sr~1&LQKdahNLAxH=d{h~KG0Nj zwQK`Y8^6gJ2Au@_G2HfR_jv&6zt4Ffg&D4yfE-krq1VVfyCpm`g=4T|i5``t>ztN|mXw=p^t^UlI^iBPP4UQ-)Ap9bLcisF^wxrbM zrslcS0IGiI9MT5}A!^V-lgBBjQ~)z?M`BL%T->$!2z}1AD#KffjJu zj6S~j7ApxC!|3dYY|do=lKOV$Q$F}a1G^lqIcB)*4V%hMajH5s3W&rY#kycQvP}6U zk-2i6i<+hrZtyr2z#)jlkP(*=gS+45r0CI^S2IFC_ZOGrl+nH~VfGxuE0t4X#H31h z3)YS#x+v;5n5UKJvMQ3=?uYht_H_!r52|sNPO^5=T9|0|e<#=P`o>jn(5P|&77bE- z!<<;y+oM@}H|}$8bj`l>y7i=3D>l2x)Wa3i>yF-F+3SoD3NIG5CLgp&{{e2LmIwc7?w?WRh%##Hu%hf=0H>$2{AuA0$BRgp zB&lf9_Q7N#np@Al{wTuqhh2f*bC&*p{&)uGwjEaIW-JFf`9p3ke_LXhS)~_@9NeYV zds}|-w{N+rn%EW1>X0$ZCI5$=B?KYzxh!IR1XFjV{7kUs!qnI7iBEEW2j8`|uAEr)0r0IfWG07Ky%{`X$z} zB8*P@HOqUXicK2DhxE05I9C)hw)tD_3ia(A#V*ds_KQ9v_V)GCtemi^pRkR>^I0A3^vG#7YCUJ9TT7$kI>dzD+B^06tpf#>YG{A;1b7*1$~Ur!VjrJd^{g2?J8ml zp0LdPOk&ff#togDP%<X^J{R|GfN}Tsx!I7;Fi&4VU%N&N@9R76n zf)C;I`NB`k-)B#9SDN$-+)gT-d;R*leFC`?pSV+OWScg%2l)>INBSnhB{u$@V|S}hzP#nql%u%Qp_lc02J zJ4W9-Fc+7~Z03avpj&A4#4GxAyA&B2+^e`ioff;p&%xMAQw?oTnxTqO*BKLv>1ww< zANQ)70o_SNiLYk1Ds_)c&Q18S`e2OkM$j$<^v&2wHjv-{Ot*cu<)g+w8W2NT4pJYoEv!Rd@9=}%vq=O7>8-yPeoq0SUR zp%kF0@Z3e34|2X5eRy4#zwybkkCh9(i$x2!kEo@_S*Ia}i(Q!0e*U($$m2Rj&cNzz zCC3M(&dp)|TG`UnEzV!phW8NI_E_eBUV#kiD=M6Zf(gCyn!YZi#!R1zXJNr|s|4km z;H?ED2!@-gX*QcT*xb2=#a_Dt%R*sT`L)<(ju|pg(A^DnL8;>NCK*)HGRTzhg~8rN zpM5hq^@(y7uEFW)B<}p4Nkcx;F3JPfEwo=YXtC&)bFjg&xs*1uKV>k(pM~z@Ej;h#XR$EJlK?BQ_2EVZ}J1&v0s z<>5Glg~+2gdAQCS^4)nJC7wOmq&pTiLD;kgSqTvsyF1rfWauMKm~^l6$aeG?VQaP{ zRDAf>GH!^QNWbKPvOmy$G*DM9qBe>v5|;m)+g$|CN}B{lR^;cLm-fi22CerNi%40h z(pi=pom{W-x>C;XaHIhFFXUbJ^)Vk{LU#yPc=APJ{EEpZingA^kwo}rW{p0Z6Auo1 zLyIGjr2;T2k}eX?vD_Mlrs6@RVy%*$6qW;sdgC`lbE2lE?<7AdWuQx0iBFF=(_h(4wxT@T23`AQ)B2vP zAlP1*3K$xy<8DdewQN5>dO}#*6U#HTRre6l{e@hfOl|l( zk|Gx$7>y>U^Y~-%H1QCAFX=g?vSQiTdh&}LOv{c6UY&AK@4_=*J-g06n>$iLN$lOM zyV(kZt~ri_Q)Zuv@bp;bh&12G=doq~HNz5JU*VX3RkmkfIV@BbtrzyjpY1(# zEcKyrmV-ISnPl1ao@Je_MSqj(Uv)K;KdVqeAQ?D2iwZ3}EqU7}C@iF7`P7gLo5E8} z*q6G(0w4cF=qrFJc1~e0@L51^;^>>`YiXB*$PO441I-VsJ9GN-T_;YCgtiUqK=i$i zDY*L6(o-ysgFpJ$(t95X$o$d=s#b#k()%(HnQwYRZ{+XK0rQcDh2pXQ_mKZp>oWC+ Z>GC^|rSm)vC?@b_VqkWvN{ + {form_field field=$field} +
+``` + +- make sure your modifications on your theme does not alter the requirement of `_partials/password-policy-template.tpl` in the Javascripts includes. + +- make sure your modifications on your theme does not alter the `templates/_partials/form-fields.tpl` file on the password field, [please refer here for requirements](https://github.com/PrestaShop/classic-theme/pull/21/files#diff-2b3eb6586609ac820d08cd566e45c06c2dd477060b2ffadeda1fb1d2941d69b7). \ No newline at end of file From a6fd6702553666f45eaed6d664c294a5a9c5440f Mon Sep 17 00:00:00 2001 From: Thomas Nares Date: Mon, 9 Jan 2023 15:21:17 +0100 Subject: [PATCH 186/310] Improve actionFilterDeliveryOptionList doc --- .../actionFilterDeliveryOptionList.md | 42 ++++++++++++++++--- 1 file changed, 37 insertions(+), 5 deletions(-) diff --git a/modules/concepts/hooks/list-of-hooks/actionFilterDeliveryOptionList.md b/modules/concepts/hooks/list-of-hooks/actionFilterDeliveryOptionList.md index 2f008aed6e..0466a1e913 100644 --- a/modules/concepts/hooks/list-of-hooks/actionFilterDeliveryOptionList.md +++ b/modules/concepts/hooks/list-of-hooks/actionFilterDeliveryOptionList.md @@ -9,6 +9,7 @@ locations: - front office type: action hookAliases: +hasExample: true --- # Hook actionFilterDeliveryOptionList @@ -42,9 +43,40 @@ Located in: ```php Hook::exec( - 'actionFilterDeliveryOptionList', - [ - 'delivery_option_list' => &$delivery_option_list, - ] - ) + 'actionFilterDeliveryOptionList', + [ + 'delivery_option_list' => &$delivery_option_list, + ] +) +``` + +## Example implementation + +For example : + +- a module can decide to display or not a certain carrier depending on the customer group +- a module can decide to block a means of delivery for a specific customer or group of customers +- a module can decide to display or not a carrier according to the date? + +In this example, we disable the express delivery carrier on saturdays and sundays because our delivery promise of 24 hours cannot be satisfied: + +```php +registerHook('actionFilterDeliveryOptionList'); + } + + public function hookActionCustomFilterDeliveryOptionList($params) + { + $deliveryOptionList = $params['delivery_option_list']; + + if(0 == date('w') || 6 == date('w')){ // sundays or saturdays + // find carrier in $deliveryOptionList, and remove it + } + } +} ``` \ No newline at end of file From 30387dca4bd75a5779088063e797cf9c610fe150 Mon Sep 17 00:00:00 2001 From: Thomas Nares Date: Wed, 11 Jan 2023 11:30:00 +0000 Subject: [PATCH 187/310] Add missing hooks from issue 1447 --- .../actionGridDataModifier.md | 34 ++++++++++++++ ...ionGridDefinitionModifier.md | 34 ++++++++++++++ ...ionGridFilterFormModifier.md | 34 ++++++++++++++ ...nGridQueryBuilderModifier.md | 36 +++++++++++++++ .../actionFormBuilderModifier.md | 44 +++++++++++++++++++ .../actionFormDataProviderData.md | 39 ++++++++++++++++ .../actionOrderStatusPostUpdate.md | 3 +- 7 files changed, 222 insertions(+), 2 deletions(-) create mode 100644 modules/concepts/hooks/list-of-hooks/actionGridDataModifier.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionGridDefinitionModifier.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionGridFilterFormModifier.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionGridQueryBuilderModifier.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionFormBuilderModifier.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionFormDataProviderData.md diff --git a/modules/concepts/hooks/list-of-hooks/actionGridDataModifier.md b/modules/concepts/hooks/list-of-hooks/actionGridDataModifier.md new file mode 100644 index 0000000000..e379973a5b --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionGridDataModifier.md @@ -0,0 +1,34 @@ +--- +menuTitle: actionGridDataModifier +Title: actionGridDataModifier +hidden: true +hookTitle: +files: + - src/Core/Grid/GridFactory.php +locations: + - front office + - back office +type: action +hookAliases: +--- + +# Hook action<DefinitionId>GridDataModifier + +## Information + +Hook locations: + - front office + - back office + +Hook type: action + +Located in: + - [src/Core/Grid/GridFactory.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Core/Grid/GridFactory.php) + +## Call of the Hook in the origin file + +```php +$this->hookDispatcher->dispatchWithParameters('action' . Container::camelize($definition->getId()) . 'GridDataModifier', [ + 'data' => &$data, +]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionGridDefinitionModifier.md b/modules/concepts/hooks/list-of-hooks/actionGridDefinitionModifier.md new file mode 100644 index 0000000000..798f4a1731 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionGridDefinitionModifier.md @@ -0,0 +1,34 @@ +--- +menuTitle: actionGridDefinitionModifier +Title: actionGridDefinitionModifier +hidden: true +hookTitle: +files: + - src/Core/Grid/Definition/Factory/AbstractGridDefinitionFactory.php +locations: + - front office + - back office +type: action +hookAliases: +--- + +# Hook action<DefinitionId>GridDefinitionModifier + +## Information + +Hook locations: + - front office + - back office + +Hook type: action + +Located in: + - [src/Core/Grid/Definition/Factory/AbstractGridDefinitionFactory.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Core/Grid/Definition/Factory/AbstractGridDefinitionFactory.php) + +## Call of the Hook in the origin file + +```php +$this->hookDispatcher->dispatchWithParameters('action' . Container::camelize($definition->getId()) . 'GridDefinitionModifier', [ + 'definition' => $definition, +]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionGridFilterFormModifier.md b/modules/concepts/hooks/list-of-hooks/actionGridFilterFormModifier.md new file mode 100644 index 0000000000..3ce4b5c6db --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionGridFilterFormModifier.md @@ -0,0 +1,34 @@ +--- +menuTitle: actionGridFilterFormModifier +Title: actionGridFilterFormModifier +hidden: true +hookTitle: +files: + - src/Core/Grid/Filter/GridFilterFormFactory.php +locations: + - front office + - back office +type: action +hookAliases: +--- + +# Hook action<DefinitionId>GridFilterFormModifier + +## Information + +Hook locations: + - front office + - back office + +Hook type: action + +Located in: + - [src/Core/Grid/Filter/GridFilterFormFactory.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Core/Grid/Filter/GridFilterFormFactory.php) + +## Call of the Hook in the origin file + +```php +$this->hookDispatcher->dispatchWithParameters('action' . Container::camelize($definition->getId()) . 'GridFilterFormModifier', [ + 'filter_form_builder' => $formBuilder, +]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionGridQueryBuilderModifier.md b/modules/concepts/hooks/list-of-hooks/actionGridQueryBuilderModifier.md new file mode 100644 index 0000000000..d42c619bf8 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionGridQueryBuilderModifier.md @@ -0,0 +1,36 @@ +--- +menuTitle: actionGridQueryBuilderModifier +Title: actionGridQueryBuilderModifier +hidden: true +hookTitle: +files: + - src/Core/Grid/Data/Factory/DoctrineGridDataFactory.php +locations: + - front office + - back office +type: action +hookAliases: +--- + +# Hook action<DefinitionId>GridQueryBuilderModifier + +## Information + +Hook locations: + - front office + - back office + +Hook type: action + +Located in: + - [src/Core/Grid/Data/Factory/DoctrineGridDataFactory.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Core/Grid/Data/Factory/DoctrineGridDataFactory.php) + +## Call of the Hook in the origin file + +```php +$this->hookDispatcher->dispatchWithParameters('action' . Container::camelize($this->gridId) . 'GridQueryBuilderModifier', [ + 'search_query_builder' => $searchQueryBuilder, + 'count_query_builder' => $countQueryBuilder, + 'search_criteria' => $searchCriteria, +]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionFormBuilderModifier.md b/modules/concepts/hooks/list-of-hooks/actionFormBuilderModifier.md new file mode 100644 index 0000000000..0f14196e32 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionFormBuilderModifier.md @@ -0,0 +1,44 @@ +--- +menuTitle: action<FormName>FormBuilderModifier +Title: actionFormBuilderModifier +hidden: true +hookTitle: +files: + - src/Core/Form/IdentifiableObject/Builder/FormBuilder.php +locations: + - front office + - back office +type: action +hookAliases: +--- + +# Hook action<Object>FormBuilderModifier + +## Information + +{{% notice tip %}} +**Modify an identifiable object form content:** + +This hook allows to modify an identifiable object forms content by modifying form builder data or FormBuilder itself. +Replace FormBuilderName by the identitiable object type. +{{% /notice %}} + +Hook locations: + - back office + - front office + +Hook type: action + +Located in: + - [src/Core/Form/IdentifiableObject/Builder/FormBuilder.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Core/Form/IdentifiableObject/Builder/FormBuilder.php) + +## Call of the Hook in the origin file + +```php +$this->hookDispatcher->dispatchWithParameters('action' . $this->camelize($formBuilder->getName()) . 'FormBuilderModifier', [ + 'form_builder' => $formBuilder, + 'data' => &$data, + 'options' => &$options, + 'id' => $id +]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionFormDataProviderData.md b/modules/concepts/hooks/list-of-hooks/actionFormDataProviderData.md new file mode 100644 index 0000000000..0211ece7c0 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionFormDataProviderData.md @@ -0,0 +1,39 @@ +--- +menuTitle: actionFormDataProviderData +Title: actionFormDataProviderData +hidden: true +hookTitle: +files: + - src/Core/Form/IdentifiableObject/Builder/FormBuilder.php +locations: + - front office + - back office +type: action +hookAliases: +--- + +# Hook action<FormName>FormDataProviderData + +## Information + +Hook locations: + - front office + - back office + +Hook type: action + +Located in: + - [src/Core/Form/IdentifiableObject/Builder/FormBuilder.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Core/Form/IdentifiableObject/Builder/FormBuilder.php) + +## Call of the Hook in the origin file + +```php +$this->hookDispatcher->dispatchWithParameters( + 'action' . $this->camelize($this->getFormName()) . 'FormDataProviderData', + [ + 'data' => &$data, + 'id' => $id, + 'options' => &$options, + ] +); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionOrderStatusPostUpdate.md b/modules/concepts/hooks/list-of-hooks/actionOrderStatusPostUpdate.md index f3932f1882..3237d989d9 100644 --- a/modules/concepts/hooks/list-of-hooks/actionOrderStatusPostUpdate.md +++ b/modules/concepts/hooks/list-of-hooks/actionOrderStatusPostUpdate.md @@ -23,8 +23,7 @@ Aliases: {{% notice tip %}} **Post update of order status:** - - +Allows to be notified after an order status is changed. {{% /notice %}} Hook locations: From 0fa6fb83c5a0a8f59cb6473dacb4c7452d2cbc8a Mon Sep 17 00:00:00 2001 From: Thomas Nares Date: Tue, 10 Jan 2023 12:44:00 +0100 Subject: [PATCH 188/310] Suggestions from code review --- modules/core-updates/8.0.md | 3 ++- modules/core-updates/new-password-policy.md | 12 +++++++++--- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/modules/core-updates/8.0.md b/modules/core-updates/8.0.md index 3d73ae8d52..b0e749d770 100644 --- a/modules/core-updates/8.0.md +++ b/modules/core-updates/8.0.md @@ -33,7 +33,7 @@ PrestaShop 8.0 adds supports for PHP 8.0 and PHP 8.1 and requires at least PHP 7 * Because of the [support for PHP 8.1](https://github.com/PrestaShop/PrestaShop/pull/28402) many methods have declared a return type now. * The logic for customers' login and registration [is now](https://github.com/PrestaShop/PrestaShop/pull/27755/) split between two controllers (`RegistrationController`, `AuthController`). This might impact third-party themes and modules as the URL to the registration has changed. * Before PrestaShop places an order [there is an additional request now](https://github.com/PrestaShop/PrestaShop/pull/26048/), to see if the number of products in the cart is still valid. This might require third-party payment modules to implement the checks in their solutions accordingly. -* Due to the new [password policy management features](/8/modules/core-updates/new-password-policy), third-party solutions that generate customer data might require to implement changes accordingly. +* Due to the new [password policy management features](new-password-policy), third-party solutions that generate customer data might require to implement changes accordingly. * In some countries, loading fonts through Google Fonts' CDN service has been judged incompatible with [GDPR](https://en.wikipedia.org/wiki/General_Data_Protection_Regulation), so [these fonts are now built into the project](https://github.com/PrestaShop/PrestaShop/issues/27541). This should not affect your work, but spreading awareness around this topic is important. ### Symfony update @@ -1134,3 +1134,4 @@ The Bootstrap version used in Symfony-based Back office pages has been updated f [legacy-translation]: {{< relref "8/modules/creation/module-translation/classic-system" >}} [new-translation]: {{< relref "8/modules/creation/module-translation/new-system" >}} +[new-password-policy]: {{< relref "8/modules/core-updates/new-password-policy" >}} \ No newline at end of file diff --git a/modules/core-updates/new-password-policy.md b/modules/core-updates/new-password-policy.md index b2251295a7..602d10bf07 100644 --- a/modules/core-updates/new-password-policy.md +++ b/modules/core-updates/new-password-policy.md @@ -23,7 +23,7 @@ When creating / updating a `Customer` account, or an `Employee` account, the `Zx ![Password policy in front office for Customers](../img/password-policy-fo.png) -## What impacts does this new policy have ? +## Changes introduced in PrestaShop by this new policy This new password policy introduced some backward compatibility breaks: @@ -44,11 +44,17 @@ And some deprecations: * `Validate::isPlaintextPassword` is deprecated * `Validate::isPasswdAdmin` is deprecated -## How to update your code for backend development +{{% notice note %}} +Please note that the library is loaded asyncronously in `core.js` because of its size. +{{% /notice %}} + +## Upgrade guide for your module / theme + +### How to update your code for backend development If your module is creating / updating `Customers` or `Employees`, make sure to update your code according to the BC breaks and deprecations indicated above. -## How to update your frontend theme +### How to update your frontend theme If your theme is creating / updating `Customers` or `Employees`, make sure to update your code according to the BC breaks related to themes (`jquery-passy.js` no longer available, and form field `change-password` no longer working). From 2c207bb71e43b987e56a27ee94ebb91f605e3e4f Mon Sep 17 00:00:00 2001 From: Thomas Nares Date: Mon, 16 Jan 2023 08:23:35 +0100 Subject: [PATCH 189/310] Document cache handling mechanism and improve patch method documentation --- webservice/getting-started.md | 30 ++++++++++++++++++++++++++++++ webservice/reference.md | 26 +++++++++++++------------- 2 files changed, 43 insertions(+), 13 deletions(-) diff --git a/webservice/getting-started.md b/webservice/getting-started.md index cf20c37f63..16bffa29fb 100644 --- a/webservice/getting-started.md +++ b/webservice/getting-started.md @@ -238,6 +238,22 @@ The `sendemail=1` parameter can be used if you need to change the state of an or The `sendemail=1` parameter can be used on the `order_carriers` endpoint to send the _in-transit_ email with the tracking number. Example: `http://example.com/api/order_carriers/12345?sendemail=1` 12345 is the order carrier id. +##### Cache handling + +A cache mechanism has been introduced and bug fixed in {{< minver v="8.0" >}}, it allows to detect if the content changed or not between your previous API call and the current one. + +To use it: + +1) in your first API call, retrieve the header `Content-Sha1` and store it on your side. +2) in your second API call, add a `Local-Content-Sha1` header, with the previously stored `Content-Sha1` value. + +If the content has not changed, the API will return a `304 Not Modified` response code. +If the content has changed, the API will return a `200 Ok` response code. + +{{% notice note %}} +It can be used to avoid un-necessary updates if the resource didn't changed since last API call. +{{% /notice %}} + ### Create a resource To create a resource, you simply need to **GET** the XML blank data for the resource (example `/api/addresses?schema=blank`), fill it with your changes, and send **POST HTTP request** with the whole XML as body content to the `/api/addresses/` URL. @@ -252,6 +268,20 @@ To edit an existing resource: **GET** the full XML file for the resource you wan To partially edit an existing resource: **GET** a part of the XML file for the resource you want to change (example `/api/addresses/1`), edit its content as needed, then send a **PATCH HTTP request** with the partial XML file as the body content to the same URL again. +When partially updating a resource, the only required parameter is the `id` of the resource. Then, add the changed `parameters`, and **PATCH** method will handle that partial update. + +Example: update the company name for the address of `id=1` : `PATCH /api/addresses/1` + +```xml + + +
+ + +
+
+``` + ### Using JSON instead of XML The Web services can also output JSON instead of XML. To enable JSON output you have two choices: diff --git a/webservice/reference.md b/webservice/reference.md index 2e7e93d271..94f674668c 100644 --- a/webservice/reference.md +++ b/webservice/reference.md @@ -11,19 +11,19 @@ All webservice APIs are accessible through the `/api/` gateway. For instance, `h Most resources can be accessed in a REST manner, with the 5 main HTTP request methods: GET, POST, PUT, DELETE, HEAD. The only exceptions are: -| Key | GET | POST | PUT | DELETE | HEAD | -|--------------------------------|:---:|:----:|:---:|:------:|:----:| -| search | ✅ | | | | ✅ | -| stock_availables | ✅ | | ✅ | | ✅ | -| stock_movements | ✅ | | | | ✅ | -| stocks | ✅ | | | | ✅ | -| supply_order_details | ✅ | | | | ✅ | -| supply_order_histories | ✅ | | | | ✅ | -| supply_order_receipt_histories | ✅ | | | | ✅ | -| supply_order_states | ✅ | | | | ✅ | -| supply_orders | ✅ | | | | ✅ | -| warehouse_product_locations | ✅ | | | | ✅ | -| warehouses | ✅ | ✅ | ✅ | | ✅ | +| Key | GET | POST | PUT | PATCH | DELETE | HEAD | +|--------------------------------|:---:|:----:|:---:|:-----:|:------:|:----:| +| search | ✅ | | | | | ✅ | +| stock_availables | ✅ | | ✅ | ✅ | | ✅ | +| stock_movements | ✅ | | | | | ✅ | +| stocks | ✅ | | | | | ✅ | +| supply_order_details | ✅ | | | | | ✅ | +| supply_order_histories | ✅ | | | | | ✅ | +| supply_order_receipt_histories | ✅ | | | | | ✅ | +| supply_order_states | ✅ | | | | | ✅ | +| supply_orders | ✅ | | | | | ✅ | +| warehouse_product_locations | ✅ | | | | | ✅ | +| warehouses | ✅ | ✅ | ✅ | ✅ | | ✅ | All resources have two schemas that are accessible via a parameter: From f972863d3c467c9ee7ce1c6179e56fc84ace8b56 Mon Sep 17 00:00:00 2001 From: Antonin CLAUZIER Date: Mon, 16 Jan 2023 15:07:09 +0400 Subject: [PATCH 190/310] Fix dead link --- development/components/grid/_index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/development/components/grid/_index.md b/development/components/grid/_index.md index b532e98d66..62f2824041 100644 --- a/development/components/grid/_index.md +++ b/development/components/grid/_index.md @@ -132,7 +132,7 @@ Search Criteria is immutable. This means that once a Search Criteria object is c ### Creating Search Criteria -Even though most of the time Search Criteria will be created using the [Filters component](#), you can still +Even though most of the time Search Criteria will be created using the [Filters component](/8/development/components/grid/tutorials/work-with-search-form/), you can still create it manually. Grid provides a simple implementation for it. ```php From d7218e6f751f7bc4ef3c71b37bcf4f38707ff0c4 Mon Sep 17 00:00:00 2001 From: Krystian Podemski Date: Mon, 16 Jan 2023 14:14:25 +0100 Subject: [PATCH 191/310] Update modules/concepts/hooks/list-of-hooks/actionOrderStatusPostUpdate.md --- .../concepts/hooks/list-of-hooks/actionOrderStatusPostUpdate.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/concepts/hooks/list-of-hooks/actionOrderStatusPostUpdate.md b/modules/concepts/hooks/list-of-hooks/actionOrderStatusPostUpdate.md index 3237d989d9..03b5680f95 100644 --- a/modules/concepts/hooks/list-of-hooks/actionOrderStatusPostUpdate.md +++ b/modules/concepts/hooks/list-of-hooks/actionOrderStatusPostUpdate.md @@ -23,7 +23,7 @@ Aliases: {{% notice tip %}} **Post update of order status:** -Allows to be notified after an order status is changed. +Allows to be notified after order status is changed. {{% /notice %}} Hook locations: From 54e67ffa1873808efa787d097012268b8d88847c Mon Sep 17 00:00:00 2001 From: Thomas Nares Date: Mon, 16 Jan 2023 15:15:11 +0100 Subject: [PATCH 192/310] Begin creating CsvComponent documentation --- .../services/CsvResponse-component.md | 57 +++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 modules/concepts/services/CsvResponse-component.md diff --git a/modules/concepts/services/CsvResponse-component.md b/modules/concepts/services/CsvResponse-component.md new file mode 100644 index 0000000000..a77d6f1450 --- /dev/null +++ b/modules/concepts/services/CsvResponse-component.md @@ -0,0 +1,57 @@ +--- +menuTitle: CsvResponse component +title: CsvResponse component +description: Learn how to use the CsvComponent to export data to CSV format + +weight: 1 +--- + +# CsvResponse component + +Introduced in {{< minver v="1.7.3" >}}, this component allows to export data to CSV Format. + +## Basic usage of CsvResponse component + +To use this component, add a `use` statement in your module: + +```php +use PrestaShopBundle\Component\CsvResponse; +``` + +Then, build your data as an `array` of lines, and each line is an `associative array`: + +```php +$lines = [ + ["name" => "My product A", "brand" => "Brand 1", "price" => 2204], + ["name" => "My product B", "brand" => "Brand 2", "price" => 1399], + ["name" => "My product C", "brand" => "Brand 3", "price" => 687] +]; +``` + +Finally, create and return your CsvResponse export: + +```php +return (new CsvResponse()) + ->setData($lines); +``` + +Since `CsvResponse` extends `Symfony\Component\HttpFoundation\StreamedResponse`, this will create and send to the browser a `Symfony\Component\HttpFoundation\StreamedResponse` (which is extended from `Symfony\Component\HttpFoundation\Response`). + +Without any parameter when creating the export, the filename of the export is export_*date*.csv : + +```php +'export_' . date('Y-m-d_His') . '.csv' +``` + +### Set the filename of the export + +When creating / returning the CsvResponse, use `setFilename()` method to set a specific filename for the export: + +```php +return (new CsvResponse()) + ->setData($lines) + ->setFilename("my_awesome_export.csv"); +``` + +## Class reference + From a412881e644b3a3d157031fb6e4131ac63562507 Mon Sep 17 00:00:00 2001 From: "tivuno.com" Date: Tue, 17 Jan 2023 08:56:13 +0200 Subject: [PATCH 193/310] Update create-custom-column-type.md --- .../tutorials/create-custom-column-type.md | 71 ++++++++++++++++++- 1 file changed, 68 insertions(+), 3 deletions(-) diff --git a/development/components/grid/tutorials/create-custom-column-type.md b/development/components/grid/tutorials/create-custom-column-type.md index d145b82aa5..526cb44d75 100644 --- a/development/components/grid/tutorials/create-custom-column-type.md +++ b/development/components/grid/tutorials/create-custom-column-type.md @@ -5,8 +5,73 @@ weight: 9 --- # How to create a custom Column Type +It is highly likely that you are struggling to develop a module based on the new standards. You want to display some kind of data in a way not already predicted by the core team. No worries. Let's have a look. -{{% notice tip %}} -Do you know how to do it? Please feel free to contribute to the docs! -{{% /notice %}} +## Step 1. Define the new column type +Let's assume that we need to make an html column to fire some js script. +Create the following file: +```/modules/your_cool_module/src/Core/Grid/Column/Type/HtmlColumn.php``` +``` +setRequired([ + 'field', + ]) + ->setDefaults([ + 'clickable' => false, + ]) + ->setAllowedTypes('field', 'string') + ->setAllowedTypes('clickable', 'bool'); + } +} +``` +## Step 2. Use & call the new type +Go to +```/modules/your_cool_module/src/Core/Grid/Definition/Factory/YourCoolGridDefinitionFactory.php```. + +In the space above "final class" add the line below: + +```use PrestaShop\Module\Yourcoolmodule\Core\Grid\Column\Type\HtmlColumn;``` + +Then inside the getColumns function among other columns, you are welcome to use the following code snippet: + +``` +->add( + (new HtmlColumn('some_column')) + ->setName($this->trans('Print voucher', [], 'Modules.Yourcoolmodule.Admin')) + ->setOptions([ + 'field' => 'identifier_column' + ]) +) +``` +## Step 3. Define the respective .html.twig +Let's assume that we need to make an html column to fire some js script. Create the following file: + +```/modules/your_cool_module/views/PrestaShop/Admin/Common/Grid/Columns/Content/html.html.twig``` + +```
{{ record[column.options.field] }}``` + +This (quite simplified) scenario above will produce a column with an empty `````` tag containing the object id as text. From afcf2ed9b43094a558a54feb5cf46731c581917a Mon Sep 17 00:00:00 2001 From: "tivuno.com" Date: Tue, 17 Jan 2023 09:21:14 +0200 Subject: [PATCH 194/310] Update development/components/grid/tutorials/create-custom-column-type.md Co-authored-by: Thomas NARES --- .../components/grid/tutorials/create-custom-column-type.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/development/components/grid/tutorials/create-custom-column-type.md b/development/components/grid/tutorials/create-custom-column-type.md index 526cb44d75..1e7f013f30 100644 --- a/development/components/grid/tutorials/create-custom-column-type.md +++ b/development/components/grid/tutorials/create-custom-column-type.md @@ -5,7 +5,8 @@ weight: 9 --- # How to create a custom Column Type -It is highly likely that you are struggling to develop a module based on the new standards. You want to display some kind of data in a way not already predicted by the core team. No worries. Let's have a look. + +You may need to display some kind of data in a specific format. This is how to do it: ## Step 1. Define the new column type Let's assume that we need to make an html column to fire some js script. From 017a8d9648bdc1b771e6a6ba5119b51feb558899 Mon Sep 17 00:00:00 2001 From: "tivuno.com" Date: Tue, 17 Jan 2023 09:21:28 +0200 Subject: [PATCH 195/310] Update development/components/grid/tutorials/create-custom-column-type.md Co-authored-by: Thomas NARES --- .../components/grid/tutorials/create-custom-column-type.md | 1 + 1 file changed, 1 insertion(+) diff --git a/development/components/grid/tutorials/create-custom-column-type.md b/development/components/grid/tutorials/create-custom-column-type.md index 1e7f013f30..27dd25c12b 100644 --- a/development/components/grid/tutorials/create-custom-column-type.md +++ b/development/components/grid/tutorials/create-custom-column-type.md @@ -68,6 +68,7 @@ Then inside the getColumns function among other columns, you are welcome to use ]) ) ``` + ## Step 3. Define the respective .html.twig Let's assume that we need to make an html column to fire some js script. Create the following file: From ac7a5b99fa87227ecfd4abba24043bb89125c97f Mon Sep 17 00:00:00 2001 From: "tivuno.com" Date: Tue, 17 Jan 2023 09:21:51 +0200 Subject: [PATCH 196/310] Update development/components/grid/tutorials/create-custom-column-type.md Co-authored-by: Thomas NARES --- .../components/grid/tutorials/create-custom-column-type.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/development/components/grid/tutorials/create-custom-column-type.md b/development/components/grid/tutorials/create-custom-column-type.md index 27dd25c12b..11f7f17e2f 100644 --- a/development/components/grid/tutorials/create-custom-column-type.md +++ b/development/components/grid/tutorials/create-custom-column-type.md @@ -9,7 +9,7 @@ weight: 9 You may need to display some kind of data in a specific format. This is how to do it: ## Step 1. Define the new column type -Let's assume that we need to make an html column to fire some js script. +Let's assume that we need to make an html column to display an object's ID within a `<a>` html tag: Create the following file: ```/modules/your_cool_module/src/Core/Grid/Column/Type/HtmlColumn.php``` ``` From 6c1289c7162c10e9e8f9a047599a2bf35d3d39b0 Mon Sep 17 00:00:00 2001 From: "tivuno.com" Date: Tue, 17 Jan 2023 09:22:11 +0200 Subject: [PATCH 197/310] Update development/components/grid/tutorials/create-custom-column-type.md Co-authored-by: Thomas NARES --- .../components/grid/tutorials/create-custom-column-type.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/development/components/grid/tutorials/create-custom-column-type.md b/development/components/grid/tutorials/create-custom-column-type.md index 11f7f17e2f..9214e5f7d5 100644 --- a/development/components/grid/tutorials/create-custom-column-type.md +++ b/development/components/grid/tutorials/create-custom-column-type.md @@ -49,7 +49,9 @@ final class HtmlColumn extends AbstractColumn } } ``` + ## Step 2. Use & call the new type + Go to ```/modules/your_cool_module/src/Core/Grid/Definition/Factory/YourCoolGridDefinitionFactory.php```. From b1a8651e9fc574a66b5e1fac89b6286ab56ec792 Mon Sep 17 00:00:00 2001 From: "tivuno.com" Date: Tue, 17 Jan 2023 09:22:26 +0200 Subject: [PATCH 198/310] Update development/components/grid/tutorials/create-custom-column-type.md Co-authored-by: Thomas NARES --- .../components/grid/tutorials/create-custom-column-type.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/development/components/grid/tutorials/create-custom-column-type.md b/development/components/grid/tutorials/create-custom-column-type.md index 9214e5f7d5..ef9912d98c 100644 --- a/development/components/grid/tutorials/create-custom-column-type.md +++ b/development/components/grid/tutorials/create-custom-column-type.md @@ -8,7 +8,9 @@ weight: 9 You may need to display some kind of data in a specific format. This is how to do it: + ## Step 1. Define the new column type + Let's assume that we need to make an html column to display an object's ID within a `<a>` html tag: Create the following file: ```/modules/your_cool_module/src/Core/Grid/Column/Type/HtmlColumn.php``` From 503e6894d3c37b3894d8960fd91ff9c790c8aee1 Mon Sep 17 00:00:00 2001 From: "tivuno.com" Date: Tue, 17 Jan 2023 09:22:35 +0200 Subject: [PATCH 199/310] Update development/components/grid/tutorials/create-custom-column-type.md Co-authored-by: Thomas NARES --- .../components/grid/tutorials/create-custom-column-type.md | 1 + 1 file changed, 1 insertion(+) diff --git a/development/components/grid/tutorials/create-custom-column-type.md b/development/components/grid/tutorials/create-custom-column-type.md index ef9912d98c..7f82948370 100644 --- a/development/components/grid/tutorials/create-custom-column-type.md +++ b/development/components/grid/tutorials/create-custom-column-type.md @@ -13,6 +13,7 @@ You may need to display some kind of data in a specific format. This is how to d Let's assume that we need to make an html column to display an object's ID within a `<a>` html tag: Create the following file: + ```/modules/your_cool_module/src/Core/Grid/Column/Type/HtmlColumn.php``` ``` Date: Tue, 17 Jan 2023 15:43:36 +0100 Subject: [PATCH 200/310] Apply suggestions from code review --- webservice/getting-started.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/webservice/getting-started.md b/webservice/getting-started.md index 16bffa29fb..587dfac12d 100644 --- a/webservice/getting-started.md +++ b/webservice/getting-started.md @@ -240,7 +240,7 @@ The `sendemail=1` parameter can be used on the `order_carriers` endpoint to send ##### Cache handling -A cache mechanism has been introduced and bug fixed in {{< minver v="8.0" >}}, it allows to detect if the content changed or not between your previous API call and the current one. +A cache mechanism has been introduced and bug fixed in {{< minver v="8.0" >}}, it allows you to detect if the content changed between your API calls. To use it: @@ -251,7 +251,7 @@ If the content has not changed, the API will return a `304 Not Modified` respons If the content has changed, the API will return a `200 Ok` response code. {{% notice note %}} -It can be used to avoid un-necessary updates if the resource didn't changed since last API call. +It can be used to avoid unnecessary updates if the resource didn't change since the last API call. {{% /notice %}} ### Create a resource From 12a8cc1e965097813999e861a63bfc8ddb63bd3f Mon Sep 17 00:00:00 2001 From: Krystian Podemski Date: Tue, 17 Jan 2023 15:44:31 +0100 Subject: [PATCH 201/310] Update development/components/grid/_index.md Co-authored-by: Thomas NARES --- development/components/grid/_index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/development/components/grid/_index.md b/development/components/grid/_index.md index 62f2824041..dfcf9aaf83 100644 --- a/development/components/grid/_index.md +++ b/development/components/grid/_index.md @@ -132,7 +132,7 @@ Search Criteria is immutable. This means that once a Search Criteria object is c ### Creating Search Criteria -Even though most of the time Search Criteria will be created using the [Filters component](/8/development/components/grid/tutorials/work-with-search-form/), you can still +Even though most of the time Search Criteria will be created using the [Filters component]({{ relref "/8/development/components/grid/tutorials/work-with-search-form/" }}), you can still create it manually. Grid provides a simple implementation for it. ```php From b6727e8678f09da8574bf8ce2ab89fe9b3019c6e Mon Sep 17 00:00:00 2001 From: Thomas Nares Date: Tue, 17 Jan 2023 19:44:05 +0100 Subject: [PATCH 202/310] CSvComponent doc --- development/components/export/_index.md | 8 + development/components/export/csv-response.md | 161 ++++++++++++++++++ .../services/CsvResponse-component.md | 57 ------- 3 files changed, 169 insertions(+), 57 deletions(-) create mode 100644 development/components/export/_index.md create mode 100644 development/components/export/csv-response.md delete mode 100644 modules/concepts/services/CsvResponse-component.md diff --git a/development/components/export/_index.md b/development/components/export/_index.md new file mode 100644 index 0000000000..9bc95eeb65 --- /dev/null +++ b/development/components/export/_index.md @@ -0,0 +1,8 @@ +--- +title: Export components +menuTitle: Export +--- + +# Export Components + +{{% children %}} \ No newline at end of file diff --git a/development/components/export/csv-response.md b/development/components/export/csv-response.md new file mode 100644 index 0000000000..ff0c2e4dc8 --- /dev/null +++ b/development/components/export/csv-response.md @@ -0,0 +1,161 @@ +--- +menuTitle: CsvResponse +title: CsvResponse component +description: Learn how to use the CsvComponent to export data to CSV format + +weight: 1 +--- + +# CsvResponse component + +Introduced in {{< minver v="1.7.3" >}}, this component allows to export data to CSV Format. + +## Usage of CsvResponse component + +To use this component, add a `use` statement in your module: + +```php +use PrestaShopBundle\Component\CsvResponse; +``` + +Build your data as an `array` of lines, and each line is an `associative array`: + +```php +$lines = [ + ["name" => "My product A", "brand" => "Brand 1", "price" => 2204, "ignored_data" => "abcd"], + ["name" => "My product B", "brand" => "Brand 2", "price" => 1399, "ignored_data" => "efgh"], + ["name" => "My product C", "brand" => "Brand 3", "price" => 687, "ignored_data" => "ijkl"] +]; +``` + +Create the headers for your columns: + +```php +$headersData = [ + "name" => "Product name", + "brand" => "Product brand", + "price" => "Product price" +]; +``` + +{{% notice note %}} +You can remove columns from your export by ignoring them in `$headersData`. +{{% /notice %}} + +Finally, create and return your `CsvResponse` export: + +```php +return (new CsvResponse()) + ->setHeadersData($headersData) + ->setData($lines); +``` + +Since `CsvResponse` extends `Symfony\Component\HttpFoundation\StreamedResponse`, this will create and send to the browser a `Symfony\Component\HttpFoundation\StreamedResponse` (which is extended from `Symfony\Component\HttpFoundation\Response`). + +Without any parameter when creating the export, the filename of the export is export_*date*.csv : + +```php +'export_' . date('Y-m-d_His') . '.csv' +``` + +### Set the filename of the export + +When creating / returning the `CsvResponse`, use `setFilename()` method to set a specific filename for the export: + +```php +return (new CsvResponse()) + ->setHeadersData($headersData) + ->setData($lines) + ->setFilename("my_awesome_export.csv"); +``` + +### Advanced usage with a callback function to export large amounts of data (chunking) + +Sometimes you will need to export large parts of data with a large memory usage, that can cause performance issues. +To achieve this, you can't just query your database and retrieve your large amount of data. +You need to chunk your data, and build your csv export chunk by chunk. + +Let's understand how to do this: + +1) Create a `callback function`, with two parameters: `$offset` and `$limit`. + +```php +$dataCallback = function ($offset, $limit){ + $data = $myRepository->getData($offset, $limit); + return $data; +} +``` + +This `callback function` returns a set of data from a repository (eg. a database), with `$offset` and `$limit` parameters (eg. a `LIMIT 0,5000` SQL query). + +2) Create your CsvResponse with your `callback function` as data: + +```php +return (new CsvResponse()) + ->setHeadersData($headersData) + ->setData($dataCallback); +``` + +The default `$limit` is set to `5000`. +You can modify this limit by calling `setLimit(int $limit)`: + +```php +return (new CsvResponse()) + ->setHeadersData($headersData) + ->setData($dataCallback) + ->setLimit(1000); +``` + +Since `$dataCallback` is a `callable`, `CsvResponse` will loop over your `callback function` when creating the Csv. + +There are two modes when retrieving data with a `callback function`: + +- `CsvResponse::MODE_OFFSET`: Your callback function is receiving `$offset` (index to start retrieving items at) and `$limit` (count of items to retrieve). This is the equivalent of MySql `LIMIT 0,100`, `LIMIT 100,100`, `LIMIT 200,100`. +- `CsvResponse::MODE_PAGINATION`: Your callback function is receiving `$offset` (page number) and `$limit` (count of items to retrieve), and will handle its pagination itself. + +The default mode is `MODE_PAGINATION`. + +When looping over your `callback function`, the `CsvResponse` is retrieving `$limit` items, while there are results. + +#### Mode pagination + +`$offset` is starting at `1`, and is increased by `1` at each loop. To use this mode, add: + +```php +->setModeType(CsvResponse::MODE_PAGINATION) +``` + +#### Mode offset + +`$offset` is starting at `0`, and is increased by `$limit` at each loop. To use this mode, add: + +```php +->setModeType(CsvResponse::MODE_OFFSET) +``` + +{{% notice note %}} +A good example implementation of `CsvResponse::MODE_OFFSET` can be seen in [ProductCsvExporter.php](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/Core/Product/ProductCsvExporter.php#L56-L97) +{{% /notice %}} + +#### Manually setting $start parameter + +`$start` parameter can be set manually by adding a `setStart(int $start)` call to your `CsvResponse`: + +```php +return (new CsvResponse()) + ->setHeadersData($headersData) + ->setData($dataCallback) + ->setStart($start) + ->setLimit($limit) +``` + +### Hide header line from export + +From {{< minver v="8.0" >}}, to disable header line from export, use the `setIncludeHeaderRow()` method. This method expects a boolean parameter indicating if the header line should be displayed or not. + +```php +return (new CsvResponse()) + ->setHeadersData($headersData) + ->setData($lines) + ->setIncludedHeaderRow(false); +``` \ No newline at end of file diff --git a/modules/concepts/services/CsvResponse-component.md b/modules/concepts/services/CsvResponse-component.md deleted file mode 100644 index a77d6f1450..0000000000 --- a/modules/concepts/services/CsvResponse-component.md +++ /dev/null @@ -1,57 +0,0 @@ ---- -menuTitle: CsvResponse component -title: CsvResponse component -description: Learn how to use the CsvComponent to export data to CSV format - -weight: 1 ---- - -# CsvResponse component - -Introduced in {{< minver v="1.7.3" >}}, this component allows to export data to CSV Format. - -## Basic usage of CsvResponse component - -To use this component, add a `use` statement in your module: - -```php -use PrestaShopBundle\Component\CsvResponse; -``` - -Then, build your data as an `array` of lines, and each line is an `associative array`: - -```php -$lines = [ - ["name" => "My product A", "brand" => "Brand 1", "price" => 2204], - ["name" => "My product B", "brand" => "Brand 2", "price" => 1399], - ["name" => "My product C", "brand" => "Brand 3", "price" => 687] -]; -``` - -Finally, create and return your CsvResponse export: - -```php -return (new CsvResponse()) - ->setData($lines); -``` - -Since `CsvResponse` extends `Symfony\Component\HttpFoundation\StreamedResponse`, this will create and send to the browser a `Symfony\Component\HttpFoundation\StreamedResponse` (which is extended from `Symfony\Component\HttpFoundation\Response`). - -Without any parameter when creating the export, the filename of the export is export_*date*.csv : - -```php -'export_' . date('Y-m-d_His') . '.csv' -``` - -### Set the filename of the export - -When creating / returning the CsvResponse, use `setFilename()` method to set a specific filename for the export: - -```php -return (new CsvResponse()) - ->setData($lines) - ->setFilename("my_awesome_export.csv"); -``` - -## Class reference - From 0bb4793fec08d57e1d265f0980a2fa9108b55f5c Mon Sep 17 00:00:00 2001 From: Krystian Podemski Date: Thu, 26 Jan 2023 14:34:47 +0100 Subject: [PATCH 203/310] Minor improvements for the docs fix paths to translations --- basics/installation/localhost.md | 24 +++-- development/components/hook/symfony-bridge.md | 4 +- .../translation/using-the-translator.md | 2 +- faq/i-need-help.md | 3 +- .../concepts/controllers/front-controllers.md | 2 +- .../asset-management/webpack.md | 93 +------------------ webservice/tutorials/creating-access.md | 2 +- 7 files changed, 27 insertions(+), 103 deletions(-) diff --git a/basics/installation/localhost.md b/basics/installation/localhost.md index de0b0aa719..27a630d778 100644 --- a/basics/installation/localhost.md +++ b/basics/installation/localhost.md @@ -16,14 +16,14 @@ Read [System Requirements][system-requirements]. Installing any web-application locally requires that you first install the adequate environment, namely the Apache web server, the PHP language interpreter, the MySQL database server, and ideally a MySQL admin tool such as phpMyAdmin tool. -This is called an *AMP package: Apache+MySQL+PHP and the operating system, giving WAMP (Windows+Apache+MySQL+PHP), MAMP (Mac OS X+…) and LAMP (Linux+…). Since all of the items packaged are open-source, these installers are most of the time free. +This is called an *AMP package: Apache+MySQL+PHP and the operating system, giving WAMP (Windows+Apache+MySQL+PHP), MAMP (macOS…) and LAMP (Linux+…). Since all of the items packaged are open-source, these installers are most of the time free. Here is a selection of free AMP installers: -* [XAMPP](https://www.apachefriends.org/download.html) (Windows, Mac OS X, Linux, Solaris) +* [XAMPP](https://www.apachefriends.org/download.html) (Windows, macOS, Linux, Solaris) * [WampServer](http://www.wampserver.com/) (Windows) * [EasyPHP](https://www.easyphp.org/) (Windows) -* [MAMP](https://www.mamp.info/en/mamp/) (Windows, Mac OS X) +* [MAMP](https://www.mamp.info/en/mamp/) (Windows, macOS) * [Laragon](https://laragon.org/) (Windows) To install LAMP on your computer follow these steps (tested on Debian Buster). @@ -127,7 +127,7 @@ As stated above, if you decide to work on PrestaShop itself, it's best to clone - **This is the right branch to contribute new features, refactors, small bug fixes, etc.** * The maintenance branches (_8.0.x, ..._) contains all patches made for each minor version. - For example, the _8.0.x_ branch contains all patches from 8.0.0 to 8.0.99. - - Whenever a new minor or major version is ready for release, a new maintenance branch is created. For example, _8.0.x_ for version 8.0.0, _8.1.x_ for 8.1.0, 8.2.x_ for 8.2.0, and so forth. + - Whenever a new minor or major version is ready for release, a new maintenance branch is created. For example, _8.0.x_ for version 8.0.0, _8.1.x_ for 8.1.0, and so forth. - **Only the most recent maintenance branch accepts new contributions** {{% /callout %}} @@ -166,6 +166,15 @@ cd /path/to/prestashop make assets ``` +You can also compile assets for the particular element of the system: + +- `make admin-default` - for the legacy back office theme +- `make admin-new-theme` - for the new back office theme +- `make front-core` - front office theme core assets +- `make front-classic` - front office default theme assets +- `make front` - all assets for the the front office +- `make admin` - all assets for the the back office + Alternatively, you can [compile assets][compile-assets] manually. @@ -175,7 +184,6 @@ PrestaShop needs recursive write permissions on several directories: - ./admin-dev/autoupgrade - ./app/config -- ./app/logs - ./cache - ./config - ./download @@ -192,13 +200,13 @@ PrestaShop needs recursive write permissions on several directories: You can set up the appropriate permissions using this command: ```bash -$ chmod -R +w admin-dev/autoupgrade app/config app/logs cache config download img log mails modules override themes translations upload var +$ chmod -R +w admin-dev/autoupgrade app/config var/logs cache config download img log mails modules override themes translations upload var ``` If you do not have some of the folders above, please create them before changing permissions. For example: ```bash -$ mkdir log app/logs +$ mkdir log var/logs ``` To ease up your life on a development environment, we suggest to make Apache run with your own user and group. @@ -226,7 +234,7 @@ You may find this error message the first time you open up the Back Office. This problem may arise in case-insensitive file systems like MacOS due to a misconfiguration. Check your Apache configuration and make sure that the root directory path to your PrestaShop matches the capitalization of the actual system path exactly. A typical error is for example having a folder named `/path/to/PrestaShop` (capital P, capital S) and then configuring it in Apache as `/path/to/Prestashop` (missing the capital S). -[getting-started-guide]: https://docs.prestashop-project.org/1.7-documentation/getting-started +[getting-started-guide]: https://docs.prestashop-project.org/v.8-documentation/v/english/getting-started [system-requirements]: {{< relref "system-requirements" >}} [clone-the-repository]: {{< relref "/8/themes/getting-started/setting-up-your-local-environment" >}} [compile-assets]: {{< relref "/8/development/compile-assets" >}} diff --git a/development/components/hook/symfony-bridge.md b/development/components/hook/symfony-bridge.md index f68d86114b..507b40baef 100644 --- a/development/components/hook/symfony-bridge.md +++ b/development/components/hook/symfony-bridge.md @@ -41,5 +41,5 @@ Using a dedicated magic method `__call()`, the `LegacyHookSubscriber` will parse When a hook is dispatched inside Symfony-powered controllers, `HookDispatcher` dispatches the hook similarly to a regular Symfony event; this event is being listened to by `LegacyHookSubscriber` who will then trigger the related `Hook::exec()` call. [sf-event-dispatcher]: https://symfony.com/doc/current/components/event_dispatcher.html -[sf-hook-dispatcher-class]: https://github.com/PrestaShop/PrestaShop/blob/1.7.6.0/src/Core/Hook/HookDispatcher.php -[legacy-hook-subscriber]: https://github.com/PrestaShop/PrestaShop/blob/1.7.6.0/src/Adapter/LegacyHookSubscriber.php +[sf-hook-dispatcher-class]: https://github.com/PrestaShop/PrestaShop/blob/develop/src/Core/Hook/HookDispatcher.php +[legacy-hook-subscriber]: https://github.com/PrestaShop/PrestaShop/blob/develop/src/Adapter/LegacyHookSubscriber.php diff --git a/development/internationalization/translation/using-the-translator.md b/development/internationalization/translation/using-the-translator.md index 1068b79e50..e07a437536 100644 --- a/development/internationalization/translation/using-the-translator.md +++ b/development/internationalization/translation/using-the-translator.md @@ -26,7 +26,7 @@ The `trans()` method takes three arguments: 3. `$domain` – The [translation domain][translation-domains] for that wording. {{% notice warning %}} -Be aware that in Symfony-based Admin controllers, the second and third arguments have been swapped in order to allow `$replacements` to be optional. For more, see [FrameworkBundleAdminController](https://github.com/PrestaShop/PrestaShop/blob/1.7.6.0/src/PrestaShopBundle/Controller/Admin/FrameworkBundleAdminController.php#L275). +Be aware that in Symfony-based Admin controllers, the second and third arguments have been swapped in order to allow `$replacements` to be optional. For more, see [FrameworkBundleAdminController](https://github.com/PrestaShop/PrestaShop/blob/8.0.0/src/PrestaShopBundle/Controller/Admin/FrameworkBundleAdminController.php#L299). {{% /notice %}} ### Inside controllers diff --git a/faq/i-need-help.md b/faq/i-need-help.md index 8f2a60ab7e..e61dcaad50 100644 --- a/faq/i-need-help.md +++ b/faq/i-need-help.md @@ -9,7 +9,7 @@ If you have questions or need help, please do not open a GitHub issue as we use The very best place to start looking for an answer is: - Here (the Developer documentation), if you are a developer -- The [User's guide](https://docs.prestashop-project.org/1.7-documentation/user-guide) if you are a user +- The [User's guide](https://docs.prestashop-project.org/v.8-documentation/v/english/) if you are a user {{% notice tip %}} If you are a developer and you think there is a missing item in the Developer documentation, consider [creating an issue on the Documentation Repository](https://github.com/PrestaShop/docs/issues). This will help us discuss what to do to improve it. @@ -18,5 +18,6 @@ If you are a developer and you think there is a missing item in the Developer do Finally, you can also ask for help from other PrestaShop users: - [on the Community chat]({{< param "projectUrls.slack" >}}) (Slack) +- [on the project's GitHub Discussions](https://github.com/PrestaShop/PrestaShop/discussions/categories/q-a) - [on the Community forums](https://www.prestashop.com/forums/) - [on Stack Overflow](https://stackoverflow.com/questions/tagged/prestashop) diff --git a/modules/concepts/controllers/front-controllers.md b/modules/concepts/controllers/front-controllers.md index 5576990d12..39ae17277d 100644 --- a/modules/concepts/controllers/front-controllers.md +++ b/modules/concepts/controllers/front-controllers.md @@ -41,7 +41,7 @@ automatically. ## Available properties -The controllers added in a module extend [`ModuleFrontController`](https://github.com/PrestaShop/PrestaShop/blob/1.7.8.0/classes/controller/ModuleFrontController.php), itself extending [`FrontController`](https://github.com/PrestaShop/PrestaShop/blob/1.7.8.0/classes/controller/FrontController.php) & [`Controller`](https://github.com/PrestaShop/PrestaShop/blob/1.7.8.0/classes/controller/Controller.php). +The controllers added in a module extend [`ModuleFrontController`](https://github.com/PrestaShop/PrestaShop/blob/8.0.0/classes/controller/ModuleFrontController.php), itself extending [`FrontController`](https://github.com/PrestaShop/PrestaShop/blob/8.0.0/classes/controller/FrontController.php) & [`Controller`](https://github.com/PrestaShop/PrestaShop/blob/8.0.0/classes/controller/Controller.php). They provide access to the environment in which they run. * `$this->module` is the instance of the module responsible of the controller. diff --git a/themes/getting-started/asset-management/webpack.md b/themes/getting-started/asset-management/webpack.md index 701c94bb02..fee90416f0 100644 --- a/themes/getting-started/asset-management/webpack.md +++ b/themes/getting-started/asset-management/webpack.md @@ -33,98 +33,13 @@ If you want to compile your assets using Webpack (and we advise you to), follow - To build your assets once, type `npm run build`. - To rebuild your assets every time you change a file in the _dev folder, type `npm run watch`. - ## Webpack configuration -The [Webpack configuration file for Classic Theme](https://github.com/PrestaShop/PrestaShop/blob/1.7.6.0/themes/classic/_dev/webpack.config.js) is thus: +The [Webpack configuration file for Classic Theme](https://github.com/PrestaShop/classic-theme/blob/develop/_dev/webpack.config.js) is thus: 1. All CSS rules go to the `assets/css/theme.css` file. 2. All JavaScript code go to the `assets/js/theme.js` file. -It provides proper configuration for compile your Sass, Less, Stylus or CSS files into a single CSS file. - -JavaScript code is written in ES6, and compiled to ES5 with Babel. - -If you want to use Stylus or Less, simply edit the command line under the "scripts" section. - -```js -var webpack = require('webpack'); -var ExtractTextPlugin = require("extract-text-webpack-plugin"); - -var plugins = []; - -plugins.push( - new ExtractTextPlugin('../css/theme.css') -); - -module.exports = [{ - // JavaScript - entry: [ - './js/theme.js' - ], - output: { - path: '../assets/js', - filename: 'theme.js' - }, - module: { - loaders: [{ - test: /\.js$/, - exclude: /node_modules/, - loaders: ['babel-loader'] - }] - }, - externals: { - prestashop: 'prestashop' - }, - plugins: plugins, - resolve: { - extensions: ['', '.js'] - } -}, { - // CSS - entry: [ - './css/normalize.css', - './css/example.less', - './css/st/dev.styl', - './css/theme.scss' - ], - output: { - path: '../assets/css', - filename: 'theme.css' - }, - module: { - loaders: [{ - test: /\.scss$/, - loader: ExtractTextPlugin.extract( - "style", - "css-loader?sourceMap!postcss!sass-loader?sourceMap" - ) - }, { - test: /\.styl$/, - loader: ExtractTextPlugin.extract( - "style", - "css-loader?sourceMap!postcss!stylus-loader?sourceMap" - ) - }, { - test: /\.less$/, - loader: ExtractTextPlugin.extract( - "style", - "css-loader?sourceMap!postcss!less-loader?sourceMap" - ) - }, { - test: /\.css$/, - loader: ExtractTextPlugin.extract( - 'style', - 'css-loader?sourceMap!postcss-loader' - ) - }, { - test: /.(png|woff(2)?|eot|ttf|svg)(\?[a-z0-9=\.]+)?$/, - loader: 'file-loader?name=../css/[hash].[ext]' - }] - }, - plugins: plugins, - resolve: { - extensions: ['', '.scss', '.styl', '.less', '.css'] - } -}]; -``` +It provides proper configuration for compile your Sass or CSS files into a single CSS file. + +JavaScript code is written in ES6, and compiled to ES5 with [esbuild](https://github.com/privatenumber/esbuild-loader). diff --git a/webservice/tutorials/creating-access.md b/webservice/tutorials/creating-access.md index 9ed3f6b4d8..df8aec91df 100644 --- a/webservice/tutorials/creating-access.md +++ b/webservice/tutorials/creating-access.md @@ -69,7 +69,7 @@ $apiAccess->save(); This first code allows you to pass the authentication layer. You also need access to the resources you expect to use. We need the Api account ID in order to grant it access, and an array having the resource name as key and the array of methods allowed as value. -The available resources can be found in [`WebserviceRequest::getResources()` (link to definition)](https://github.com/PrestaShop/PrestaShop/blob/1.7.6.0/classes/webservice/WebserviceRequest.php#L285]). +The available resources can be found in [`WebserviceRequest::getResources()` (link to definition)](https://github.com/PrestaShop/PrestaShop/blob/8.0.0/classes/webservice/WebserviceRequest.php#L282]). For instance is we want to give all permissions for customers and orders resources for the account we previously created: From 6d439161cbf179b14178e025427e9ff9d6c41877 Mon Sep 17 00:00:00 2001 From: Krystian Podemski Date: Thu, 26 Jan 2023 14:43:35 +0100 Subject: [PATCH 204/310] fix grid custom column php highlight --- .../components/grid/tutorials/create-custom-column-type.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/development/components/grid/tutorials/create-custom-column-type.md b/development/components/grid/tutorials/create-custom-column-type.md index 7f82948370..a18b73b8f9 100644 --- a/development/components/grid/tutorials/create-custom-column-type.md +++ b/development/components/grid/tutorials/create-custom-column-type.md @@ -15,9 +15,7 @@ Let's assume that we need to make an html column to display an object's ID withi Create the following file: ```/modules/your_cool_module/src/Core/Grid/Column/Type/HtmlColumn.php``` -``` -add( (new HtmlColumn('some_column')) ->setName($this->trans('Print voucher', [], 'Modules.Yourcoolmodule.Admin')) From 29373096deac2bffe35c87ce62e742e9c03cef56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20ALFAIATE?= Date: Fri, 27 Jan 2023 10:23:41 +0700 Subject: [PATCH 205/310] Minor wording improvement --- development/internationalization/translation/_index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/development/internationalization/translation/_index.md b/development/internationalization/translation/_index.md index 8a8ae39aaf..987da6d11c 100644 --- a/development/internationalization/translation/_index.md +++ b/development/internationalization/translation/_index.md @@ -6,7 +6,7 @@ weight: 10 # Translation -One of the main needs for localization is translating wordings to the another language. PrestaShop is capable of translating wordings to any language, as long as it has the appropriate translation dictionaries available. +One of the main needs for localization is translating wordings into another language. PrestaShop is capable of translating wordings to any language, as long as it has the appropriate translation dictionaries available. PrestaShop's translation system is based on the [Symfony Translation component](https://symfony.com/doc/4.4/translation.html). From a8b7d82d987f14dc57cf44c541faf4a7146cbcbe Mon Sep 17 00:00:00 2001 From: leemyongpakvn Date: Mon, 30 Jan 2023 09:57:52 +0700 Subject: [PATCH 206/310] switch to 8.x branch, fix minor typo --- modules/testing/basic-checks.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/testing/basic-checks.md b/modules/testing/basic-checks.md index c7b0faa710..e4da949cd5 100644 --- a/modules/testing/basic-checks.md +++ b/modules/testing/basic-checks.md @@ -48,7 +48,7 @@ If some errors are reported by this tool, this gives you the opportunity : ## Coding standards -Modules follows the same rules as the core. The [coding standards chapter]({{< ref "1.7/development/coding-standards" >}}) of this project provides more details about it. +Modules follows the same rules as the core. The [coding standards chapter]({{< ref "8/development/coding-standards" >}}) of this project provides more details about it. Following the same rules as the core requires the configuration file to be available in your project. These rules are distributed and maintained on a repository `prestashop/php-dev-tools` available on [Packagist](https://packagist.org/packages/prestashop/php-dev-tools) which can be required via composer. @@ -61,7 +61,7 @@ composer require --dev prestashop/php-dev-tools php vendor/bin/prestashop-coding-standards cs-fixer:init ``` -These commands install and prepare your projet for php-cs-fixer and the core standards. The commands have run successfully if a file `.php_cs.dist` exists in the root folder. +These commands install and prepare your project for php-cs-fixer and the core standards. The commands have run successfully if a file `.php_cs.dist` exists in the root folder. [PHP-CS-Fixer](https://packagist.org/packages/friendsofphp/php-cs-fixer) is used to check the code style, and is automatically included in your project if you required `prestashop/php-dev-tools` by following the commands above. From 4b2e0b24a04cadbf5681e475f70a1c3d71dbf1b4 Mon Sep 17 00:00:00 2001 From: Thomas Nares Date: Wed, 8 Feb 2023 09:46:54 +0100 Subject: [PATCH 207/310] Wip creation of 8.1 changes page --- .../components/smarty-extensions/_index.md | 2 +- ...actionAjaxDieBefore.md | 14 ++++- .../actionGenerateDocumentReference.md | 37 +++++++++++++ .../actionModifyFrontendSitemap.md | 45 ++++++++++++++++ .../list-of-hooks/displayContactContent.md | 39 ++++++++++++++ .../list-of-hooks/displayContactLeftColumn.md | 39 ++++++++++++++ .../displayContactRightColumn.md | 39 ++++++++++++++ modules/core-updates/8.1.md | 54 +++++++++++++++++-- 8 files changed, 264 insertions(+), 5 deletions(-) create mode 100644 modules/concepts/hooks/list-of-hooks/actionGenerateDocumentReference.md create mode 100644 modules/concepts/hooks/list-of-hooks/actionModifyFrontendSitemap.md create mode 100644 modules/concepts/hooks/list-of-hooks/displayContactContent.md create mode 100644 modules/concepts/hooks/list-of-hooks/displayContactLeftColumn.md create mode 100644 modules/concepts/hooks/list-of-hooks/displayContactRightColumn.md diff --git a/development/components/smarty-extensions/_index.md b/development/components/smarty-extensions/_index.md index 1e78996a44..86089b446a 100644 --- a/development/components/smarty-extensions/_index.md +++ b/development/components/smarty-extensions/_index.md @@ -193,7 +193,7 @@ The `classname` data modifier will ensure that your string is a valid class name It will: 1. Put it in lowercase. -2. Replace any non-ASCII characters (such as accented characters) with their ASCII equivalent ([see the code here ](https://github.com/PrestaShop/PrestaShop/blob/1.7.2.0/classes/Tools.php#L1248-L1350)). +2. Replace any non-ASCII characters (such as accented characters) [with their ASCII equivalent with Transliterator](https://github.com/PrestaShop/PrestaShop/blob/8.0.0/classes/Tools.php#L1431-L1440). 3. Replace all non-alphanumerical characters with a single dash. 4. Ensure only one consecutive dash is used. diff --git a/modules/concepts/hooks/list-of-hooks/actionAjaxDieBefore.md b/modules/concepts/hooks/list-of-hooks/actionAjaxDieBefore.md index 4f93919ea7..58c9cb4d4e 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAjaxDieBefore.md +++ b/modules/concepts/hooks/list-of-hooks/actionAjaxDieBefore.md @@ -25,6 +25,18 @@ Located in: ## Call of the Hook in the origin file +### Before {{< minver v="8.1" >}} + ```php Hook::exec('actionAjaxDie' . $controller . $method . 'Before', ['value' => $value]) -``` \ No newline at end of file +``` + +### From {{< minver v="8.1" >}} + +```php +Hook::exec('actionAjaxDie' . $controller . $method . 'Before', ['value' => &$value]) +``` + +{{% notice note %}} +Note that the `value` is now passed by reference +{{% /notice %}} \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionGenerateDocumentReference.md b/modules/concepts/hooks/list-of-hooks/actionGenerateDocumentReference.md new file mode 100644 index 0000000000..7dd3c11fcb --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionGenerateDocumentReference.md @@ -0,0 +1,37 @@ +--- +menuTitle: actionGenerateDocumentReference +Title: actionGenerateDocumentReference +hidden: true +hookTitle: Modify document reference for Order +files: + - classes/order/Order.php +locations: + - front office +type: action +hookAliases: +--- + +# Hook actionGenerateDocumentReference + +## Information + +{{% notice tip %}} +**Modify document reference for Order:** + +This hook allows modules to return custom document references for orders{{% /notice %}} + +Hook locations: + - front office + +Hook type: action + +Located in: + - [classes/order/Order.php](https://github.com/PrestaShop/PrestaShop/blob/8.1.x/classes/order/Order.php) + +## Call of the Hook in the origin file + +```php +$reference = Hook::exec('actionGenerateDocumentReference', [ + 'type' => 'order', +]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionModifyFrontendSitemap.md b/modules/concepts/hooks/list-of-hooks/actionModifyFrontendSitemap.md new file mode 100644 index 0000000000..867ab96d90 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionModifyFrontendSitemap.md @@ -0,0 +1,45 @@ +--- +menuTitle: actionModifyFrontendSitemap +Title: actionModifyFrontendSitemap +hidden: true +hookTitle: Allows modules to add own urls (even whole new groups) to frontend sitemap. +files: + - controllers/front/SitemapController.php +locations: + - front office +type: action +hookAliases: +--- + +# Hook actionModifyFrontendSitemap + +## Information + +{{% notice tip %}} +**Allows modules to add own urls (even whole new groups) to frontend sitemap:** + +For example landing pages, blog posts and others. +{{% /notice %}} + +Hook locations: + - front office + +Hook type: action + +Located in: + - [controllers/front/SitemapController.php](https://github.com/PrestaShop/PrestaShop/blob/8.1.x/controllers/front/SitemapController.php) + +## Call of the Hook in the origin file + +```php +Hook::exec( + 'actionModifyFrontendSitemap', + ['urls' => &$urls], + null, + false, + true, + false, + null, + true +); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/displayContactContent.md b/modules/concepts/hooks/list-of-hooks/displayContactContent.md new file mode 100644 index 0000000000..83969a06ea --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/displayContactContent.md @@ -0,0 +1,39 @@ +--- +menuTitle: displayContactContent +Title: displayContactContent +hidden: true +hookTitle: Content wrapper section of the contact page +files: + - themes/hummingbird/templates/contact.tpl + - themes/classic/templates/contact.tpl +locations: + - front office +type: display +hookAliases: +--- + +# Hook displayContactContent + +## Information + +{{% notice tip %}} +**Content wrapper section of the contact page:** + +This hook displays new elements in the content wrapper of the contact page. +This replaces widget `contactform`. +{{% /notice %}} + +Hook locations: + - front office + +Hook type: display + +Located in: + - [themes/hummingbird/templates/contact.tpl](https://github.com/PrestaShop/hummingbird/blob/develop/templates/contact.tpl) + - [themes/classic/templates/contact.tpl](https://github.com/PrestaShop/classic-theme/blob/develop/templates/contact.tpl) + +## Call of the Hook in the origin file + +```php +{hook h='displayContactContent'} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/displayContactLeftColumn.md b/modules/concepts/hooks/list-of-hooks/displayContactLeftColumn.md new file mode 100644 index 0000000000..18da2c83f4 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/displayContactLeftColumn.md @@ -0,0 +1,39 @@ +--- +menuTitle: displayContactLeftColumn +Title: displayContactLeftColumn +hidden: true +hookTitle: Left column blocks on the contact page +files: + - themes/hummingbird/templates/contact.tpl + - themes/classic/templates/contact.tpl +locations: + - front office +type: display +hookAliases: +--- + +# Hook displayContactLeftColumn + +## Information + +{{% notice tip %}} +**Left column blocks on the contact page:** + +This hook displays new elements in the left-hand column of the contact page. +This replaces widget `ps_contactinfo` on hook `displayLeftColumn`. +{{% /notice %}} + +Hook locations: + - front office + +Hook type: display + +Located in: + - [themes/hummingbird/templates/contact.tpl](https://github.com/PrestaShop/hummingbird/blob/develop/templates/contact.tpl) + - [themes/classic/templates/contact.tpl](https://github.com/PrestaShop/classic-theme/blob/develop/templates/contact.tpl) + +## Call of the Hook in the origin file + +```php +{hook h='displayContactLeftColumn'} +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/displayContactRightColumn.md b/modules/concepts/hooks/list-of-hooks/displayContactRightColumn.md new file mode 100644 index 0000000000..84e467c446 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/displayContactRightColumn.md @@ -0,0 +1,39 @@ +--- +menuTitle: displayContactRightColumn +Title: displayContactRightColumn +hidden: true +hookTitle: Right column blocks of the contact page +files: + - themes/hummingbird/templates/contact.tpl + - themes/classic/templates/contact.tpl +locations: + - front office +type: display +hookAliases: +--- + +# Hook displayContactRightColumn + +## Information + +{{% notice tip %}} +**Right column blocks of the contact page:** + +This hook displays new elements in the right-hand column of the contact page. +This replaces widget `ps_contactinfo` on hook `displayRightColumn`. +{{% /notice %}} + +Hook locations: + - front office + +Hook type: display + +Located in: + - [themes/hummingbird/templates/contact.tpl](https://github.com/PrestaShop/hummingbird/blob/develop/templates/contact.tpl) + - [themes/classic/templates/contact.tpl](https://github.com/PrestaShop/classic-theme/blob/develop/templates/contact.tpl) + +## Call of the Hook in the origin file + +```php +{hook h='displayContactRightColumn'} +``` \ No newline at end of file diff --git a/modules/core-updates/8.1.md b/modules/core-updates/8.1.md index 63a673693c..59f6b1c8c0 100644 --- a/modules/core-updates/8.1.md +++ b/modules/core-updates/8.1.md @@ -1,7 +1,6 @@ --- title: Changes in PrestaShop 8.1 menuTitle: Changes in 8.1 -hidden: true --- -{{% notice note %}} -This page is being created, it will be completed while 8.1 is under creation. -Remove hidden: true param when ready to publish. -{{% /notice %}} - # Notable changes in PrestaShop 8.1 ## PHP support @@ -40,12 +35,11 @@ PrestaShop 8.1 has same PHP requirement as Prestashop 8.0. * Introduced `actionGenerateDocumentReference` hook to allow overriding order reference [PR#29781](https://github.com/PrestaShop/PrestaShop/pull/29781) * Introduced 3 new hooks about Contact Page: `displayContactRightColumn`, `displayContactContent`, `displayContactLeftColumn` in `classic` and `hummingbird` themes, and removed related widget hooks [PR#29516](https://github.com/PrestaShop/PrestaShop/pull/29516) * Introduced `Tools::getCurrentUrl()` to retrieve the current URL in a hook [PR#28541](https://github.com/PrestaShop/PrestaShop/pull/28541) - -* BC Break in minor version [link to pr](https://github.com/PrestaShop/PrestaShop/pull/28469) -* worth mentioning [link to pr](https://github.com/PrestaShop/PrestaShop/pull/28463) -* new hook [link to pr](https://github.com/PrestaShop/PrestaShop/pull/27927) - on hold -* a notable change that this page is now multi-store compatible, it doesn't have bc breaks (constructor modifications are allowed) [link to pr](https://github.com/PrestaShop/PrestaShop/pull/27608) -* new class to generate passwords [link to pr](https://github.com/PrestaShop/PrestaShop/pull/31004) +* BC break: `Shop::getBaseURL()` use secure mode by default [PR#28469](https://github.com/PrestaShop/PrestaShop/pull/28469) +* Vue was upgraded from 2.6 to 3.2, see below [PR#28463](https://github.com/PrestaShop/PrestaShop/pull/28463) +* Customer Settings > Customer page is now multistore compatible [PR#27608](https://github.com/PrestaShop/PrestaShop/pull/27608) +* Introduced `PrestaShop\PrestaShop\Core\Security\PasswordGenerator` class to generate random passwords with multiples types/lengths [PR#31004](https://github.com/PrestaShop/PrestaShop/pull/31004) +* Introduced `PrestaShop\PrestaShop\Core\Security\Hashing` class to hash a password from a password and a salt with md5 [PR#31004](https://github.com/PrestaShop/PrestaShop/pull/31004) ## Deprecations @@ -78,8 +72,17 @@ PrestaShop 8.1 has same PHP requirement as Prestashop 8.0. | nyholm/psr7 | _~ Not present ~_ | ^1.5 | | symfony/psr-http-message-bridge | _~ Not present ~_ | ^2.1 | -[80-changes]: {{< relref "8/modules/core-updates/8.0.md" >}} +### JS libraries + +| Library name | Old version | New version | +|------------------------------------|---------------------------------------------------------------|---------------| +| vue | 2.6.x | 3.2.x | +{{% notice note %}} +As `Vue` 2.x [will reach EOL on December 31st, 2023](https://v2.vuejs.org/lts/), `Vue` dependency was bumped to 3.2. +Every linked dependencies were also bumped to higher version to keep 3.2 compatibility. +Please refer to: [PR#28463](https://github.com/PrestaShop/PrestaShop/pull/28463) for an exhaustive list. +{{% /notice %}} ## Left todo: @@ -87,4 +90,7 @@ PrestaShop 8.1 has same PHP requirement as Prestashop 8.0. * new variable available, to be checked if it should go to the Themes documentation [link to pr](https://github.com/PrestaShop/PrestaShop/pull/30383) * info + there's a documentation about `{url}` that could be improved [link to pr](https://github.com/PrestaShop/PrestaShop/pull/30342) + [link to pr](https://github.com/PrestaShop/PrestaShop/pull/30314) * info + theme docs update [link to pr](https://github.com/PrestaShop/PrestaShop/pull/29995) -* not sure if needed, this comment https://github.com/PrestaShop/PrestaShop/pull/29750#pullrequestreview-1125910115 [link to pr](https://github.com/PrestaShop/PrestaShop/pull/29750) \ No newline at end of file +* not sure if needed, this comment https://github.com/PrestaShop/PrestaShop/pull/29750#pullrequestreview-1125910115 [link to pr](https://github.com/PrestaShop/PrestaShop/pull/29750) +* new hook [link to pr](https://github.com/PrestaShop/PrestaShop/pull/27927) - on hold + +[80-changes]: {{< relref "8/modules/core-updates/8.0.md" >}} \ No newline at end of file From 733bc3a1c5b689d366175cdeb8729ecda7790c9d Mon Sep 17 00:00:00 2001 From: Thomas Nares Date: Wed, 8 Feb 2023 11:59:33 +0100 Subject: [PATCH 209/310] Add minver on new hooks, and actionGenerateDocumentReference hook --- .../actionGenerateDocumentReference.md | 2 +- .../actionProductPriceCalculation.md | 62 +++++++++++++++++++ .../list-of-hooks/displayContactContent.md | 2 +- .../list-of-hooks/displayContactLeftColumn.md | 2 +- .../displayContactRightColumn.md | 2 +- modules/core-updates/8.1.md | 4 +- 6 files changed, 68 insertions(+), 6 deletions(-) create mode 100644 modules/concepts/hooks/list-of-hooks/actionProductPriceCalculation.md diff --git a/modules/concepts/hooks/list-of-hooks/actionGenerateDocumentReference.md b/modules/concepts/hooks/list-of-hooks/actionGenerateDocumentReference.md index 7dd3c11fcb..6900a46b4e 100644 --- a/modules/concepts/hooks/list-of-hooks/actionGenerateDocumentReference.md +++ b/modules/concepts/hooks/list-of-hooks/actionGenerateDocumentReference.md @@ -11,7 +11,7 @@ type: action hookAliases: --- -# Hook actionGenerateDocumentReference +# Hook actionGenerateDocumentReference {{< minver v="8.1" >}} ## Information diff --git a/modules/concepts/hooks/list-of-hooks/actionProductPriceCalculation.md b/modules/concepts/hooks/list-of-hooks/actionProductPriceCalculation.md new file mode 100644 index 0000000000..0189aa41f9 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/actionProductPriceCalculation.md @@ -0,0 +1,62 @@ +--- +menuTitle: actionProductPriceCalculation +Title: actionProductPriceCalculation +hidden: true +hookTitle: Product Price Calculation +files: + - controllers/admin/AdminLoginController.php +locations: + - back office +type: action +hookAliases: +--- + +# Hook actionProductPriceCalculation {{< minver v="8.1" >}} + +## Information + +{{% notice tip %}} +**Product Price Calculation:** + +This hook is called into the priceCalculation method to be able to override the price calculation{{% /notice %}} + +Hook locations: + - back office + - front office + +Hook type: action + +Located in: + - [classes/Product.php](https://github.com/PrestaShop/PrestaShop/blob/8.1.x/classes/Product.php) + +## Call of the Hook in the origin file + +```php +Hook::exec('actionProductPriceCalculation', [ + 'id_shop' => $id_shop, + 'id_product' => $id_product, + 'id_product_attribute' => $id_product_attribute, + 'id_customization' => $id_customization, + 'id_country' => $id_country, + 'id_state' => $id_state, + 'zip_code' => $zipcode, + 'id_currency' => $id_currency, + 'id_group' => $id_group, + 'id_cart' => $id_cart, + 'id_customer' => $id_customer, + 'use_customer_price' => $use_customer_price, + 'quantity' => $quantity, + 'real_quantity' => $real_quantity, + 'use_tax' => $use_tax, + 'decimals' => $decimals, + 'only_reduc' => $only_reduc, + 'use_reduc' => $use_reduc, + 'with_ecotax' => $with_ecotax, + 'specific_price' => &$specific_price, + 'use_group_reduction' => $use_group_reduction, + 'address' => $address, + 'context' => $context, + 'specific_price_reduction' => &$specific_price_reduction, + 'price' => &$price, +]); +``` \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/displayContactContent.md b/modules/concepts/hooks/list-of-hooks/displayContactContent.md index 83969a06ea..4fc450ab31 100644 --- a/modules/concepts/hooks/list-of-hooks/displayContactContent.md +++ b/modules/concepts/hooks/list-of-hooks/displayContactContent.md @@ -12,7 +12,7 @@ type: display hookAliases: --- -# Hook displayContactContent +# Hook displayContactContent {{< minver v="8.1" >}} ## Information diff --git a/modules/concepts/hooks/list-of-hooks/displayContactLeftColumn.md b/modules/concepts/hooks/list-of-hooks/displayContactLeftColumn.md index 18da2c83f4..734c574e24 100644 --- a/modules/concepts/hooks/list-of-hooks/displayContactLeftColumn.md +++ b/modules/concepts/hooks/list-of-hooks/displayContactLeftColumn.md @@ -12,7 +12,7 @@ type: display hookAliases: --- -# Hook displayContactLeftColumn +# Hook displayContactLeftColumn {{< minver v="8.1" >}} ## Information diff --git a/modules/concepts/hooks/list-of-hooks/displayContactRightColumn.md b/modules/concepts/hooks/list-of-hooks/displayContactRightColumn.md index 84e467c446..0c6ad1f76e 100644 --- a/modules/concepts/hooks/list-of-hooks/displayContactRightColumn.md +++ b/modules/concepts/hooks/list-of-hooks/displayContactRightColumn.md @@ -12,7 +12,7 @@ type: display hookAliases: --- -# Hook displayContactRightColumn +# Hook displayContactRightColumn {{< minver v="8.1" >}} ## Information diff --git a/modules/core-updates/8.1.md b/modules/core-updates/8.1.md index a7d4a95a02..98f9eabdd3 100644 --- a/modules/core-updates/8.1.md +++ b/modules/core-updates/8.1.md @@ -40,6 +40,7 @@ PrestaShop 8.1 has same PHP requirement as Prestashop 8.0. * Customer Settings > Customer page is now multistore compatible [PR#27608](https://github.com/PrestaShop/PrestaShop/pull/27608) * Introduced `PrestaShop\PrestaShop\Core\Security\PasswordGenerator` class to generate random passwords with multiples types/lengths [PR#31004](https://github.com/PrestaShop/PrestaShop/pull/31004) * Introduced `PrestaShop\PrestaShop\Core\Security\Hashing` class to hash a password from a password and a salt with md5 [PR#31004](https://github.com/PrestaShop/PrestaShop/pull/31004) +* Introduced `actionProductPriceCalculation` hook [PR#27927](https://github.com/PrestaShop/PrestaShop/pull/27927) ## Deprecations @@ -58,7 +59,7 @@ PrestaShop 8.1 has same PHP requirement as Prestashop 8.0. * `Prestashop\PrestaShop\Core\Grid\Column\Type\PrivateColumn` → moved to `PrestaShop\PrestaShop\Core\Grid\Column\Type\Common\PrivateColumn` * `CmsController::$cms` → use now `CmsController::getCms()` * `CmsController::$cms_category` → use now `CmsController::getCmsCategory()` -* `Validate::isAnything()` → will be removed from 9.0 +* `Validate::isAnything()` → will be removed from 9.0 since returns always `true` ## Updated dependencies @@ -91,6 +92,5 @@ Please refer to: [PR#28463](https://github.com/PrestaShop/PrestaShop/pull/28463) * info + there's a documentation about `{url}` that could be improved [link to pr](https://github.com/PrestaShop/PrestaShop/pull/30342) + [link to pr](https://github.com/PrestaShop/PrestaShop/pull/30314) * info + theme docs update [link to pr](https://github.com/PrestaShop/PrestaShop/pull/29995) * not sure if needed, this comment https://github.com/PrestaShop/PrestaShop/pull/29750#pullrequestreview-1125910115 [link to pr](https://github.com/PrestaShop/PrestaShop/pull/29750) -* new hook [link to pr](https://github.com/PrestaShop/PrestaShop/pull/27927) - on hold [80-changes]: {{< relref "8/modules/core-updates/8.0.md" >}} \ No newline at end of file From f45980812592016ec8c855856997c6fb59706cda Mon Sep 17 00:00:00 2001 From: Thomas Nares Date: Wed, 8 Feb 2023 14:33:59 +0100 Subject: [PATCH 210/310] Document url smarty helper, and corejs disable --- .../components/smarty-extensions/_index.md | 42 +++++++++++++++++-- modules/core-updates/8.1.md | 14 +++---- themes/getting-started/theme-yml.md | 11 ++++- 3 files changed, 53 insertions(+), 14 deletions(-) diff --git a/development/components/smarty-extensions/_index.md b/development/components/smarty-extensions/_index.md index 86089b446a..1fba8c82fe 100644 --- a/development/components/smarty-extensions/_index.md +++ b/development/components/smarty-extensions/_index.md @@ -96,9 +96,9 @@ So far, it is only used for forms (customer information and checkout). ### {url} This helper is used to generate URLs. -This will take care of SSL, domain name, virtual and physical base URI, parameters concatenation, and of course URL rewriting. +This will take care of http scheme (`http` or `https`), domain name, virtual and physical base URI, parameters concatenation, and of course URL rewriting. -`{url}` uses the Link class internally. +[`{url}` uses the `Link` class internally](https://github.com/PrestaShop/PrestaShop/blob/8.1.x/classes/Link.php#L1446-L1611). {{% notice note %}} Please see the `$urls` dataset to find already regenerated urls (such as home, cart, login and so on). @@ -108,7 +108,41 @@ This will take care of SSL, domain name, virtual and physical base URI, paramete While an instance of the Link object is still present in templates for backward compatibility purposes, **it is strongly recommended not to use it**. Use `{url}` instead. {{% /notice %}} -Here is a few examples: +#### Availables helpers + +| Entity | Required parameters | Optional parameters | +|-------------------|---------------------------------|------------------------------------------------------| +| supplier | ['id' => int] | | +| language | ['id' => int] | | +| product | ['id' => int] | ['category' => int, 'ean13' => string, 'ipa' => int] | +| category | ['id' => int] | ['selected_filters' => array] | +| categoryImage | ['id' => int] | ['selected_filters' => array, 'type' => int] | +| manufacturer | ['id' => int] | | +| manufacturerImage | ['id' => int] | | +| supplierImage | ['id' => int] | | +| cms | ['id' => int] | | +| module | ['id' => int, 'name' => string] | ['controller' => string, 'params' => array] | +| sf | ['route' => string] | ['sf-params' => array] | + +and all other `ObjectModel` based entities (`address`, ...). + +`id` is almost always required to generate urls, except for the `sf` helper, where `route` is the required parameter. + +Other parameters have default values and can be overidden, eg.: + +```php +$default = [ + 'id_lang' => $context->language->id, + 'id_shop' => null, + 'alias' => null, + 'ssl' => null, + 'relative_protocol' => true, + 'with_id_in_anchor' => false, + 'extra_params' => [], + 'add_anchor' => true, +]; +``` +Examples: ```smarty {url entity=address id=$id_address} @@ -117,7 +151,7 @@ Here is a few examples: {url entity='sf' route='admin_module_manage' sf-params=['foo' => 'bar']} ``` -...will respectively output: +Will respectively output: ```html http://prestashop.ps/it/address?id_address=3 diff --git a/modules/core-updates/8.1.md b/modules/core-updates/8.1.md index 98f9eabdd3..be974b33ff 100644 --- a/modules/core-updates/8.1.md +++ b/modules/core-updates/8.1.md @@ -41,6 +41,9 @@ PrestaShop 8.1 has same PHP requirement as Prestashop 8.0. * Introduced `PrestaShop\PrestaShop\Core\Security\PasswordGenerator` class to generate random passwords with multiples types/lengths [PR#31004](https://github.com/PrestaShop/PrestaShop/pull/31004) * Introduced `PrestaShop\PrestaShop\Core\Security\Hashing` class to hash a password from a password and a salt with md5 [PR#31004](https://github.com/PrestaShop/PrestaShop/pull/31004) * Introduced `actionProductPriceCalculation` hook [PR#27927](https://github.com/PrestaShop/PrestaShop/pull/27927) +* Added a new Smarty variable `theme_dir` in front controllers [PR#30383](https://github.com/PrestaShop/PrestaShop/pull/30383) +* Added a feature to disable `core.js` loading on custom themes [PR#29995](https://github.com/PrestaShop/PrestaShop/pull/29995). [More informations][corejs-informations] +* Added supplier url and manufacturer url to Smarty `{url}` helper [PR#30242](https://github.com/PrestaShop/PrestaShop/pull/30342) and [PR#30314](https://github.com/PrestaShop/PrestaShop/pull/30314) ## Deprecations @@ -85,12 +88,5 @@ Every linked dependencies were also bumped to higher version to keep 3.2 compati Please refer to: [PR#28463](https://github.com/PrestaShop/PrestaShop/pull/28463) for an exhaustive list. {{% /notice %}} -## Left todo: - -* examples that should go to the https://devdocs.prestashop-project.org/8/modules/concepts/services/#symfony-services [link to pr](https://github.com/PrestaShop/PrestaShop/pull/30588) -* new variable available, to be checked if it should go to the Themes documentation [link to pr](https://github.com/PrestaShop/PrestaShop/pull/30383) -* info + there's a documentation about `{url}` that could be improved [link to pr](https://github.com/PrestaShop/PrestaShop/pull/30342) + [link to pr](https://github.com/PrestaShop/PrestaShop/pull/30314) -* info + theme docs update [link to pr](https://github.com/PrestaShop/PrestaShop/pull/29995) -* not sure if needed, this comment https://github.com/PrestaShop/PrestaShop/pull/29750#pullrequestreview-1125910115 [link to pr](https://github.com/PrestaShop/PrestaShop/pull/29750) - -[80-changes]: {{< relref "8/modules/core-updates/8.0.md" >}} \ No newline at end of file +[80-changes]: {{< relref "8/modules/core-updates/8.0.md" >}} +[corejs-informations]: {{< relref "8/themes/getting-started/theme-yml" >}} \ No newline at end of file diff --git a/themes/getting-started/theme-yml.md b/themes/getting-started/theme-yml.md index b9d8a67cc5..2e73e326e0 100644 --- a/themes/getting-started/theme-yml.md +++ b/themes/getting-started/theme-yml.md @@ -36,7 +36,6 @@ Users will be able to choose the layout for each page from the theme's settings ## Global settings - ### Configuration You can have the theme change the configuration of PrestaShop when the theme is enabled. @@ -179,6 +178,16 @@ When the configuration is changed through the back office interface, only the se order-confirmation: layout-left-side-column ``` +#### Disable `core.js` loading on custom theme + +It may be needed to disable `core.js` loading and provide a custom implementation of whole logic initally contained in `core.js`. +To do this, use the `core_scripts` option, set to false, in `theme_settings` like in this example: + +```yaml +theme_settings: + core_scripts: false +``` + ## Dependencies When making a theme you may want to add features with custom modules. It's important that these modules From 0f743659cebd028bff11eec4b09a9936cb1e5151 Mon Sep 17 00:00:00 2001 From: Thomas NARES Date: Mon, 13 Feb 2023 08:44:57 +0100 Subject: [PATCH 211/310] Update modules/concepts/hooks/list-of-hooks/actionModifyFrontendSitemap.md Co-authored-by: Krystian Podemski --- .../concepts/hooks/list-of-hooks/actionModifyFrontendSitemap.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/concepts/hooks/list-of-hooks/actionModifyFrontendSitemap.md b/modules/concepts/hooks/list-of-hooks/actionModifyFrontendSitemap.md index 867ab96d90..dfb53b92f2 100644 --- a/modules/concepts/hooks/list-of-hooks/actionModifyFrontendSitemap.md +++ b/modules/concepts/hooks/list-of-hooks/actionModifyFrontendSitemap.md @@ -11,7 +11,7 @@ type: action hookAliases: --- -# Hook actionModifyFrontendSitemap +# Hook actionModifyFrontendSitemap {{< minver v="8.1" >}} ## Information From 296a0bee40ae425728159ede0da311b8958c5592 Mon Sep 17 00:00:00 2001 From: Thomas NARES Date: Mon, 13 Feb 2023 08:45:20 +0100 Subject: [PATCH 212/310] Update modules/core-updates/8.1.md Co-authored-by: Krystian Podemski --- modules/core-updates/8.1.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/core-updates/8.1.md b/modules/core-updates/8.1.md index be974b33ff..71e4c2ec97 100644 --- a/modules/core-updates/8.1.md +++ b/modules/core-updates/8.1.md @@ -39,7 +39,7 @@ PrestaShop 8.1 has same PHP requirement as Prestashop 8.0. * Vue was upgraded from 2.6 to 3.2, see below [PR#28463](https://github.com/PrestaShop/PrestaShop/pull/28463) * Customer Settings > Customer page is now multistore compatible [PR#27608](https://github.com/PrestaShop/PrestaShop/pull/27608) * Introduced `PrestaShop\PrestaShop\Core\Security\PasswordGenerator` class to generate random passwords with multiples types/lengths [PR#31004](https://github.com/PrestaShop/PrestaShop/pull/31004) -* Introduced `PrestaShop\PrestaShop\Core\Security\Hashing` class to hash a password from a password and a salt with md5 [PR#31004](https://github.com/PrestaShop/PrestaShop/pull/31004) +* Introduced `PrestaShop\PrestaShop\Core\Security\Hashing` class to hash a password from a plain text and a salt with md5 [PR#31004](https://github.com/PrestaShop/PrestaShop/pull/31004) * Introduced `actionProductPriceCalculation` hook [PR#27927](https://github.com/PrestaShop/PrestaShop/pull/27927) * Added a new Smarty variable `theme_dir` in front controllers [PR#30383](https://github.com/PrestaShop/PrestaShop/pull/30383) * Added a feature to disable `core.js` loading on custom themes [PR#29995](https://github.com/PrestaShop/PrestaShop/pull/29995). [More informations][corejs-informations] From 11844846f793690df85fbc0de4bed1674ddf16f4 Mon Sep 17 00:00:00 2001 From: Thomas NARES Date: Mon, 13 Feb 2023 08:45:30 +0100 Subject: [PATCH 213/310] Update themes/getting-started/theme-yml.md Co-authored-by: Krystian Podemski --- themes/getting-started/theme-yml.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/themes/getting-started/theme-yml.md b/themes/getting-started/theme-yml.md index 2e73e326e0..d3944eeea7 100644 --- a/themes/getting-started/theme-yml.md +++ b/themes/getting-started/theme-yml.md @@ -180,7 +180,7 @@ When the configuration is changed through the back office interface, only the se #### Disable `core.js` loading on custom theme -It may be needed to disable `core.js` loading and provide a custom implementation of whole logic initally contained in `core.js`. +You can disable `core.js` loading and provide a custom implementation of the whole logic initially contained in `core.js`. To do this, use the `core_scripts` option, set to false, in `theme_settings` like in this example: ```yaml From 62f7c9c7f19c455aa10eb1e6f1c0fe7a457ae936 Mon Sep 17 00:00:00 2001 From: Thomas NARES Date: Mon, 13 Feb 2023 08:45:37 +0100 Subject: [PATCH 214/310] Update modules/core-updates/8.1.md Co-authored-by: Krystian Podemski --- modules/core-updates/8.1.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/core-updates/8.1.md b/modules/core-updates/8.1.md index 71e4c2ec97..7726cd94e3 100644 --- a/modules/core-updates/8.1.md +++ b/modules/core-updates/8.1.md @@ -61,7 +61,7 @@ PrestaShop 8.1 has same PHP requirement as Prestashop 8.0. * `Prestashop\PrestaShop\Core\Grid\Column\Type\PreviewColumn` → moved to `PrestaShop\PrestaShop\Core\Grid\Column\Type\Common\PreviewColumn` * `Prestashop\PrestaShop\Core\Grid\Column\Type\PrivateColumn` → moved to `PrestaShop\PrestaShop\Core\Grid\Column\Type\Common\PrivateColumn` * `CmsController::$cms` → use now `CmsController::getCms()` -* `CmsController::$cms_category` → use now `CmsController::getCmsCategory()` +* `CmsController::$cms_category` → use `$cmsControllerInstance->getCmsCategory()` instead * `Validate::isAnything()` → will be removed from 9.0 since returns always `true` ## Updated dependencies From 17ece53758325a24eb3ee80a0e3709dd0cd2e62d Mon Sep 17 00:00:00 2001 From: Thomas NARES Date: Mon, 13 Feb 2023 08:45:46 +0100 Subject: [PATCH 215/310] Update themes/getting-started/theme-yml.md Co-authored-by: Krystian Podemski --- themes/getting-started/theme-yml.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/themes/getting-started/theme-yml.md b/themes/getting-started/theme-yml.md index d3944eeea7..9d1d764730 100644 --- a/themes/getting-started/theme-yml.md +++ b/themes/getting-started/theme-yml.md @@ -178,7 +178,7 @@ When the configuration is changed through the back office interface, only the se order-confirmation: layout-left-side-column ``` -#### Disable `core.js` loading on custom theme +#### Disable loading of `core.js` file in your custom theme You can disable `core.js` loading and provide a custom implementation of the whole logic initially contained in `core.js`. To do this, use the `core_scripts` option, set to false, in `theme_settings` like in this example: From e3a59cb4e6d717a6e281edb8c3bd2e4e213729c0 Mon Sep 17 00:00:00 2001 From: Thomas NARES Date: Mon, 13 Feb 2023 08:45:55 +0100 Subject: [PATCH 216/310] Update modules/core-updates/8.1.md Co-authored-by: Krystian Podemski --- modules/core-updates/8.1.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/core-updates/8.1.md b/modules/core-updates/8.1.md index 7726cd94e3..369854731c 100644 --- a/modules/core-updates/8.1.md +++ b/modules/core-updates/8.1.md @@ -62,7 +62,7 @@ PrestaShop 8.1 has same PHP requirement as Prestashop 8.0. * `Prestashop\PrestaShop\Core\Grid\Column\Type\PrivateColumn` → moved to `PrestaShop\PrestaShop\Core\Grid\Column\Type\Common\PrivateColumn` * `CmsController::$cms` → use now `CmsController::getCms()` * `CmsController::$cms_category` → use `$cmsControllerInstance->getCmsCategory()` instead -* `Validate::isAnything()` → will be removed from 9.0 since returns always `true` +* `Validate::isAnything()` → will be removed in 9.0 since returns always `true` ## Updated dependencies From 808ff96edf419bba344b0f8e03a9ed2927ae8088 Mon Sep 17 00:00:00 2001 From: Thomas NARES Date: Mon, 13 Feb 2023 08:46:03 +0100 Subject: [PATCH 217/310] Update modules/core-updates/8.1.md Co-authored-by: Krystian Podemski --- modules/core-updates/8.1.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/core-updates/8.1.md b/modules/core-updates/8.1.md index 369854731c..0bad86c40e 100644 --- a/modules/core-updates/8.1.md +++ b/modules/core-updates/8.1.md @@ -60,7 +60,7 @@ PrestaShop 8.1 has same PHP requirement as Prestashop 8.0. * `Prestashop\PrestaShop\Core\Grid\Column\Type\OrderPriceColumn` → moved to `PrestaShop\PrestaShop\Core\Grid\Column\Type\Order\OrderPriceColumn` * `Prestashop\PrestaShop\Core\Grid\Column\Type\PreviewColumn` → moved to `PrestaShop\PrestaShop\Core\Grid\Column\Type\Common\PreviewColumn` * `Prestashop\PrestaShop\Core\Grid\Column\Type\PrivateColumn` → moved to `PrestaShop\PrestaShop\Core\Grid\Column\Type\Common\PrivateColumn` -* `CmsController::$cms` → use now `CmsController::getCms()` +* `CmsController::$cms` → use `$cmsControllerInstance->getCms()` instead * `CmsController::$cms_category` → use `$cmsControllerInstance->getCmsCategory()` instead * `Validate::isAnything()` → will be removed in 9.0 since returns always `true` From 776a68e188e5f50a11f4a96dc16ef2d1bfed9d75 Mon Sep 17 00:00:00 2001 From: Thomas NARES Date: Mon, 13 Feb 2023 08:46:09 +0100 Subject: [PATCH 218/310] Update modules/core-updates/8.1.md Co-authored-by: Krystian Podemski --- modules/core-updates/8.1.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/core-updates/8.1.md b/modules/core-updates/8.1.md index 0bad86c40e..1019c34b17 100644 --- a/modules/core-updates/8.1.md +++ b/modules/core-updates/8.1.md @@ -15,7 +15,7 @@ menuTitle: Changes in 8.1 ## PHP support -PrestaShop 8.1 has same PHP requirement as Prestashop 8.0. +PrestaShop 8.1 has the same PHP requirement as Prestashop 8.0. [PrestaShop 8.0][80-changes] added support for PHP 8.0 and PHP 8.1 and required at least PHP 7.2.5. From 9ed9243cbcc1a9ec664454f13920aabd3d00e68d Mon Sep 17 00:00:00 2001 From: Thomas NARES Date: Mon, 13 Feb 2023 08:46:16 +0100 Subject: [PATCH 219/310] Update development/components/smarty-extensions/_index.md Co-authored-by: Krystian Podemski --- development/components/smarty-extensions/_index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/development/components/smarty-extensions/_index.md b/development/components/smarty-extensions/_index.md index 1fba8c82fe..7598dcd62e 100644 --- a/development/components/smarty-extensions/_index.md +++ b/development/components/smarty-extensions/_index.md @@ -126,7 +126,7 @@ This will take care of http scheme (`http` or `https`), domain name, virtual and and all other `ObjectModel` based entities (`address`, ...). -`id` is almost always required to generate urls, except for the `sf` helper, where `route` is the required parameter. +`id` is almost always required to generate URLs, except for the `sf` helper, where `route` is the required parameter. Other parameters have default values and can be overidden, eg.: From 3e03977c7d691fd5aa0089a819b3b26aa60fe37f Mon Sep 17 00:00:00 2001 From: Thomas NARES Date: Mon, 13 Feb 2023 08:46:22 +0100 Subject: [PATCH 220/310] Update development/components/smarty-extensions/_index.md Co-authored-by: Krystian Podemski --- development/components/smarty-extensions/_index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/development/components/smarty-extensions/_index.md b/development/components/smarty-extensions/_index.md index 7598dcd62e..c1624c3d98 100644 --- a/development/components/smarty-extensions/_index.md +++ b/development/components/smarty-extensions/_index.md @@ -128,7 +128,7 @@ and all other `ObjectModel` based entities (`address`, ...). `id` is almost always required to generate URLs, except for the `sf` helper, where `route` is the required parameter. -Other parameters have default values and can be overidden, eg.: +Other parameters have default values and can be overridden, e.g.: ```php $default = [ From 8277edda8915725c3d8e9c84a5652338c49bb1d6 Mon Sep 17 00:00:00 2001 From: Thomas NARES Date: Mon, 13 Feb 2023 08:46:27 +0100 Subject: [PATCH 221/310] Update development/components/smarty-extensions/_index.md Co-authored-by: Krystian Podemski --- development/components/smarty-extensions/_index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/development/components/smarty-extensions/_index.md b/development/components/smarty-extensions/_index.md index c1624c3d98..2e2408ed46 100644 --- a/development/components/smarty-extensions/_index.md +++ b/development/components/smarty-extensions/_index.md @@ -96,7 +96,7 @@ So far, it is only used for forms (customer information and checkout). ### {url} This helper is used to generate URLs. -This will take care of http scheme (`http` or `https`), domain name, virtual and physical base URI, parameters concatenation, and of course URL rewriting. +This will take care of the HTTP scheme (`http` or `https`), domain name, virtual and physical base URI, parameters concatenation, and URL rewriting. [`{url}` uses the `Link` class internally](https://github.com/PrestaShop/PrestaShop/blob/8.1.x/classes/Link.php#L1446-L1611). From a71c077bed8c1ac45b3bfb55b89774afbebbff65 Mon Sep 17 00:00:00 2001 From: Thomas NARES Date: Mon, 13 Feb 2023 15:51:48 +0100 Subject: [PATCH 222/310] Update themes/getting-started/theme-yml.md Co-authored-by: Krystian Podemski --- themes/getting-started/theme-yml.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/themes/getting-started/theme-yml.md b/themes/getting-started/theme-yml.md index 9d1d764730..73abdc399b 100644 --- a/themes/getting-started/theme-yml.md +++ b/themes/getting-started/theme-yml.md @@ -178,7 +178,7 @@ When the configuration is changed through the back office interface, only the se order-confirmation: layout-left-side-column ``` -#### Disable loading of `core.js` file in your custom theme +#### Disable loading of `core.js` file in your custom theme You can disable `core.js` loading and provide a custom implementation of the whole logic initially contained in `core.js`. To do this, use the `core_scripts` option, set to false, in `theme_settings` like in this example: From 92cc10225fc7b61f6ce55bc707cb847faa5893f2 Mon Sep 17 00:00:00 2001 From: Jonathan Danse Date: Fri, 17 Feb 2023 16:41:47 +0100 Subject: [PATCH 223/310] Set core.js as 8.1 min version --- themes/getting-started/theme-yml.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/themes/getting-started/theme-yml.md b/themes/getting-started/theme-yml.md index 73abdc399b..4af27e329c 100644 --- a/themes/getting-started/theme-yml.md +++ b/themes/getting-started/theme-yml.md @@ -178,7 +178,7 @@ When the configuration is changed through the back office interface, only the se order-confirmation: layout-left-side-column ``` -#### Disable loading of `core.js` file in your custom theme +#### Disable loading of `core.js` file in your custom theme {{< minver v="8.1.0" >}} You can disable `core.js` loading and provide a custom implementation of the whole logic initially contained in `core.js`. To do this, use the `core_scripts` option, set to false, in `theme_settings` like in this example: From b594de40b1f773921713c30fc06b8536a791c7bf Mon Sep 17 00:00:00 2001 From: Louis AUTHIE <65625876+LouisAUTHIE@users.noreply.github.com> Date: Mon, 20 Feb 2023 09:03:21 +0100 Subject: [PATCH 224/310] Update displayBackOfficeHeader.md --- .../hooks/list-of-hooks/displayBackOfficeHeader.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/modules/concepts/hooks/list-of-hooks/displayBackOfficeHeader.md b/modules/concepts/hooks/list-of-hooks/displayBackOfficeHeader.md index 579339c6c5..6b93ce552b 100644 --- a/modules/concepts/hooks/list-of-hooks/displayBackOfficeHeader.md +++ b/modules/concepts/hooks/list-of-hooks/displayBackOfficeHeader.md @@ -1,6 +1,6 @@ --- -menuTitle: displayback officeHeader -Title: displayback officeHeader +menuTitle: displaybackOfficeHeader +Title: displaybackOfficeHeader hidden: true hookTitle: Administration panel header files: @@ -9,13 +9,13 @@ locations: - back office type: display hookAliases: - - back officeHeader + - backOfficeHeader --- # Hook displayback officeHeader Aliases: - - back officeHeader + - backOfficeHeader @@ -38,5 +38,5 @@ Located in: ## Call of the Hook in the origin file ```php -Hook::exec('displayback officeHeader') -``` \ No newline at end of file +Hook::exec('displaybackOfficeHeader') +``` From 315cf4e239fbfcd984c13ba4a2193748a45bc07b Mon Sep 17 00:00:00 2001 From: Louis AUTHIE <65625876+LouisAUTHIE@users.noreply.github.com> Date: Mon, 20 Feb 2023 09:09:04 +0100 Subject: [PATCH 225/310] Update displayBackOfficeTop.md --- .../hooks/list-of-hooks/displayBackOfficeTop.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/modules/concepts/hooks/list-of-hooks/displayBackOfficeTop.md b/modules/concepts/hooks/list-of-hooks/displayBackOfficeTop.md index c9fdd4f84b..f4c9bcae8d 100644 --- a/modules/concepts/hooks/list-of-hooks/displayBackOfficeTop.md +++ b/modules/concepts/hooks/list-of-hooks/displayBackOfficeTop.md @@ -1,6 +1,6 @@ --- -menuTitle: displayback officeTop -Title: displayback officeTop +menuTitle: displaybackOfficeTop +Title: displaybackOfficeTop hidden: true hookTitle: Administration panel hover the tabs files: @@ -15,7 +15,7 @@ hookAliases: # Hook displayback officeTop Aliases: - - back officeTop + - backOfficeTop @@ -38,5 +38,5 @@ Located in: ## Call of the Hook in the origin file ```php -Hook::exec('displayback officeTop') -``` \ No newline at end of file +Hook::exec('displaybackOfficeTop') +``` From 90f737c2be55f902e0a137f567be2a0bdb3f6fea Mon Sep 17 00:00:00 2001 From: Louis AUTHIE <65625876+LouisAUTHIE@users.noreply.github.com> Date: Mon, 20 Feb 2023 09:11:26 +0100 Subject: [PATCH 226/310] Update displayBackOfficeCategory.md --- .../hooks/list-of-hooks/displayBackOfficeCategory.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/modules/concepts/hooks/list-of-hooks/displayBackOfficeCategory.md b/modules/concepts/hooks/list-of-hooks/displayBackOfficeCategory.md index aaab7938ea..e779841e2a 100644 --- a/modules/concepts/hooks/list-of-hooks/displayBackOfficeCategory.md +++ b/modules/concepts/hooks/list-of-hooks/displayBackOfficeCategory.md @@ -1,6 +1,6 @@ --- -menuTitle: displayback officeCategory -Title: displayback officeCategory +menuTitle: displaybackOfficeCategory +Title: displaybackOfficeCategory hidden: true hookTitle: Display new elements in the Back Office, tab AdminCategories files: @@ -11,7 +11,7 @@ type: display hookAliases: --- -# Hook displayback officeCategory +# Hook displaybackOfficeCategory ## Information @@ -32,5 +32,5 @@ Located in: ## Call of the Hook in the origin file ```php -{{ renderhook('displayback officeCategory') }} -``` \ No newline at end of file +{{ renderhook('displaybackOfficeCategory') }} +``` From 33a81eb1bd1655f78c323fb5f8c3c385ad32be1d Mon Sep 17 00:00:00 2001 From: Louis AUTHIE <65625876+LouisAUTHIE@users.noreply.github.com> Date: Mon, 20 Feb 2023 09:12:45 +0100 Subject: [PATCH 227/310] Update displayBackOfficeTop.md --- modules/concepts/hooks/list-of-hooks/displayBackOfficeTop.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/concepts/hooks/list-of-hooks/displayBackOfficeTop.md b/modules/concepts/hooks/list-of-hooks/displayBackOfficeTop.md index f4c9bcae8d..1f63d2adf5 100644 --- a/modules/concepts/hooks/list-of-hooks/displayBackOfficeTop.md +++ b/modules/concepts/hooks/list-of-hooks/displayBackOfficeTop.md @@ -9,10 +9,10 @@ locations: - back office type: display hookAliases: - - back officeTop + - backOfficeTop --- -# Hook displayback officeTop +# Hook displaybackOfficeTop Aliases: - backOfficeTop From 06f8032cdda84ec951478b42613348e45f26cbc8 Mon Sep 17 00:00:00 2001 From: Louis AUTHIE <65625876+LouisAUTHIE@users.noreply.github.com> Date: Mon, 20 Feb 2023 09:13:15 +0100 Subject: [PATCH 228/310] Update displayBackOfficeHeader.md --- modules/concepts/hooks/list-of-hooks/displayBackOfficeHeader.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/concepts/hooks/list-of-hooks/displayBackOfficeHeader.md b/modules/concepts/hooks/list-of-hooks/displayBackOfficeHeader.md index 6b93ce552b..d55d2c6fa5 100644 --- a/modules/concepts/hooks/list-of-hooks/displayBackOfficeHeader.md +++ b/modules/concepts/hooks/list-of-hooks/displayBackOfficeHeader.md @@ -12,7 +12,7 @@ hookAliases: - backOfficeHeader --- -# Hook displayback officeHeader +# Hook displaybackOfficeHeader Aliases: - backOfficeHeader From 607b66dd7cdc6cb0e68bf68932d378f81cba9f1f Mon Sep 17 00:00:00 2001 From: Louis AUTHIE <65625876+LouisAUTHIE@users.noreply.github.com> Date: Mon, 20 Feb 2023 09:15:37 +0100 Subject: [PATCH 229/310] Update displayBackOfficeEmployeeMenu.md --- .../list-of-hooks/displayBackOfficeEmployeeMenu.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/modules/concepts/hooks/list-of-hooks/displayBackOfficeEmployeeMenu.md b/modules/concepts/hooks/list-of-hooks/displayBackOfficeEmployeeMenu.md index bd66650125..1456b78919 100644 --- a/modules/concepts/hooks/list-of-hooks/displayBackOfficeEmployeeMenu.md +++ b/modules/concepts/hooks/list-of-hooks/displayBackOfficeEmployeeMenu.md @@ -1,6 +1,6 @@ --- -menuTitle: displayback officeEmployeeMenu -Title: displayback officeEmployeeMenu +menuTitle: displaybackOfficeEmployeeMenu +Title: displaybackOfficeEmployeeMenu hidden: true hookTitle: Administration Employee menu files: @@ -11,7 +11,7 @@ type: display hookAliases: --- -# Hook displayback officeEmployeeMenu +# Hook displaybackOfficeEmployeeMenu ## Information @@ -42,9 +42,9 @@ Located in: ```php dispatchWithParameters( - 'displayback officeEmployeeMenu', + 'displaybackOfficeEmployeeMenu', [ 'links' => $menuLinksCollections, ] ) -``` \ No newline at end of file +``` From 0433e79ad6bda87261d7b707ee2a2bd51971914f Mon Sep 17 00:00:00 2001 From: leemyongpakvn <3759923+leemyongpakvn@users.noreply.github.com> Date: Tue, 21 Feb 2023 20:51:34 +0700 Subject: [PATCH 230/310] correct NodeJs versions for PS 8 --- basics/installation/localhost.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/basics/installation/localhost.md b/basics/installation/localhost.md index 27a630d778..d3dd0334d5 100644 --- a/basics/installation/localhost.md +++ b/basics/installation/localhost.md @@ -159,7 +159,7 @@ make composer ### JavaScript and CSS dependencies PrestaShop uses NPM to manage dependencies and [Webpack][webpack] to compile them into static assets. -You only need NodeJS 8.x (14.x recommended [get it here][nodejs]), NPM will take care of it all. +You only need NodeJS 14.x (16.x recommended [get it here][nodejs]), NPM will take care of it all. ```bash cd /path/to/prestashop From 715e18304e55ce7d16492d10c48b2d7d4e4bcfab Mon Sep 17 00:00:00 2001 From: leemyongpakvn <3759923+leemyongpakvn@users.noreply.github.com> Date: Tue, 21 Feb 2023 20:55:41 +0700 Subject: [PATCH 231/310] PS 8 requires PHP 7.2 at least --- basics/installation/httpd.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/basics/installation/httpd.md b/basics/installation/httpd.md index 904a06cd92..e21ab89bca 100644 --- a/basics/installation/httpd.md +++ b/basics/installation/httpd.md @@ -44,7 +44,7 @@ It may be incomplete, and remember you must adapt it for your own server's needs ## With PHP-FPM You first have to ensure you have the `php-fpm` binary and Apache's FastCGI installed. -On a Debian based, packages are `libapache2-mod-fcgid` and `php7.1-fpm`. +On a Debian based, packages are `libapache2-mod-fcgid` and `php7.2-fpm`. After installing these packages, fpm service will automatically be started. PHP-FPM uses so-called pools to handle incoming FastCGI requests. @@ -58,7 +58,7 @@ user = www-data group = www-data ; use a unix domain socket -listen = /var/run/php/php7.1-fpm.sock +listen = /var/run/php/php7.2-fpm.sock ; or listen on a TCP socket ; listen = 127.0.0.1:9000 @@ -93,7 +93,7 @@ Don't forget to edit this configuration to make it works. # with mod_rewrite or mod_autoindex # SetHandler proxy:fcgi://127.0.0.1:9000 - SetHandler proxy:unix:/var/run/php/php7.1-fpm.sock|fcgi://dummy + SetHandler proxy:unix:/var/run/php/php7.2-fpm.sock|fcgi://dummy DocumentRoot /path/to/prestashop From 1cdac26d5e53b6372a53bfbdef3afbd180d089a3 Mon Sep 17 00:00:00 2001 From: leemyongpakvn <3759923+leemyongpakvn@users.noreply.github.com> Date: Tue, 21 Feb 2023 20:58:56 +0700 Subject: [PATCH 232/310] switch to 8.x branch --- basics/installation/nginx.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/basics/installation/nginx.md b/basics/installation/nginx.md index ef958cf3ce..99dcebf1d8 100644 --- a/basics/installation/nginx.md +++ b/basics/installation/nginx.md @@ -141,4 +141,4 @@ server { } ``` -[nginx-scale]: {{< ref "1.7/scale/webservers/nginx" >}} +[nginx-scale]: {{< ref "8/scale/webservers/nginx" >}} From 98d39c008e4a4a37009b34c0c63f5bc69b646098 Mon Sep 17 00:00:00 2001 From: leemyongpakvn <3759923+leemyongpakvn@users.noreply.github.com> Date: Tue, 21 Feb 2023 21:09:15 +0700 Subject: [PATCH 233/310] add some missing spaces --- basics/keeping-up-to-date/migration.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/basics/keeping-up-to-date/migration.md b/basics/keeping-up-to-date/migration.md index c9ffd3c39f..79e52d6210 100644 --- a/basics/keeping-up-to-date/migration.md +++ b/basics/keeping-up-to-date/migration.md @@ -125,7 +125,7 @@ If you used `mysqldump` for your backups, there is also an option for extracting Example for exporting the table ps_product: ```bash -mysqldump -h127.0.0.1 -P3307 -uroot -p -T/var/lib/mysql-files --fields-enclosed-by=\" --fields-terminated-by=\; prestashop16 ps_product +mysqldump -h 127.0.0.1 -P 3307 -u root -p -T /var/lib/mysql-files --fields-enclosed-by=\" --fields-terminated-by=\; prestashop16 ps_product ``` Several notes about `mysqldump` with CSV files: From 8039efc78afa1dbedf2996fc6a4f34686009a4f6 Mon Sep 17 00:00:00 2001 From: Thomas Nares Date: Thu, 23 Feb 2023 09:20:12 +0100 Subject: [PATCH 234/310] Add BC breaks --- modules/core-updates/8.1.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/modules/core-updates/8.1.md b/modules/core-updates/8.1.md index 1019c34b17..a96589ce6f 100644 --- a/modules/core-updates/8.1.md +++ b/modules/core-updates/8.1.md @@ -45,6 +45,12 @@ PrestaShop 8.1 has the same PHP requirement as Prestashop 8.0. * Added a feature to disable `core.js` loading on custom themes [PR#29995](https://github.com/PrestaShop/PrestaShop/pull/29995). [More informations][corejs-informations] * Added supplier url and manufacturer url to Smarty `{url}` helper [PR#30242](https://github.com/PrestaShop/PrestaShop/pull/30342) and [PR#30314](https://github.com/PrestaShop/PrestaShop/pull/30314) +## BC Breaks (Backward Compatibility Breaks) + +* `Shop::getBaseURL()` use secure mode by default [PR#28469](https://github.com/PrestaShop/PrestaShop/pull/28469) +* For the class `PrestaShop\PrestaShop\Core\Domain\TaxRulesGroup\QueryResult`, constructor parameters are now `TaxRulesGroupId $taxRulesGroupId, string $name, bool $active, array $shopAssociationIds` [PR#28812](https://github.com/PrestaShop/PrestaShop/pull/28812) +* Webservice does now respect the maximum image upload size set in back office (`PS_LIMIT_UPLOAD_IMAGE_VALUE`) [PR#29135](https://github.com/PrestaShop/PrestaShop/pull/29135) + ## Deprecations ### PHP From a21c4f865ef8097748d402ea944606480c342a79 Mon Sep 17 00:00:00 2001 From: Thomas Nares Date: Thu, 23 Feb 2023 12:09:53 +0100 Subject: [PATCH 235/310] Create missing hooks found in example modules, link examples on each hook page --- ...ionGridDefinitionModifier.md | 11 ++++- ...nGridQueryBuilderModifier.md | 9 +++- .../actionFormBuilderModifier.md | 13 +++++- .../actionAdminControllerSetMedia.md | 7 +++- .../actionAfterCreateFormHandler.md | 11 ++++- .../actionAfterUpdateFormHandler.md | 11 ++++- .../actionBuildMailLayoutVariables.md | 7 +++- .../actionGetAdminOrderButtons.md | 7 +++- .../actionGetMailLayoutTransformations.md | 7 +++- .../list-of-hooks/actionListMailThemes.md | 7 +++- .../hooks/list-of-hooks/displayAdminOrder.md | 9 ++-- .../list-of-hooks/displayAdminOrderMain.md | 7 +++- .../list-of-hooks/displayAdminOrderSide.md | 6 +-- .../displayAdminOrderSideBottom.md | 7 +++- .../displayAdminOrderTabContent.md | 39 ++++++++++++++++++ .../list-of-hooks/displayAdminOrderTabLink.md | 39 ++++++++++++++++++ .../list-of-hooks/displayAdminOrderTop.md | 41 +++++++++++++++++++ .../displayAdminProductsExtra.md | 41 +++++++++++++++++++ ...isplayAdminProductsQuantitiesStepBottom.md | 7 +++- .../list-of-hooks/displayFooterBefore.md | 7 +++- 20 files changed, 272 insertions(+), 21 deletions(-) create mode 100644 modules/concepts/hooks/list-of-hooks/displayAdminOrderTabContent.md create mode 100644 modules/concepts/hooks/list-of-hooks/displayAdminOrderTabLink.md create mode 100644 modules/concepts/hooks/list-of-hooks/displayAdminOrderTop.md create mode 100644 modules/concepts/hooks/list-of-hooks/displayAdminProductsExtra.md diff --git a/modules/concepts/hooks/list-of-hooks/actionGridDefinitionModifier.md b/modules/concepts/hooks/list-of-hooks/actionGridDefinitionModifier.md index 798f4a1731..1d1bb1dbc2 100644 --- a/modules/concepts/hooks/list-of-hooks/actionGridDefinitionModifier.md +++ b/modules/concepts/hooks/list-of-hooks/actionGridDefinitionModifier.md @@ -10,6 +10,7 @@ locations: - back office type: action hookAliases: +hasExample: true --- # Hook action<DefinitionId>GridDefinitionModifier @@ -31,4 +32,12 @@ Located in: $this->hookDispatcher->dispatchWithParameters('action' . Container::camelize($definition->getId()) . 'GridDefinitionModifier', [ 'definition' => $definition, ]); -``` \ No newline at end of file +``` + +## Example implementation + +This hook has been implemented as an example in our [modules examples repository - demoextendgrid](https://github.com/PrestaShop/example-modules/tree/master/demoextendgrid). + +This hook has been implemented as an example in our [modules examples repository - demoextendsymfonyform1](https://github.com/PrestaShop/example-modules/tree/master/demoextendsymfonyform1). + +This hook has been implemented as an example in our [modules examples repository - demoextendsymfonyform3](https://github.com/PrestaShop/example-modules/tree/master/demoextendsymfonyform3). \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionGridQueryBuilderModifier.md b/modules/concepts/hooks/list-of-hooks/actionGridQueryBuilderModifier.md index d42c619bf8..ae5ad04988 100644 --- a/modules/concepts/hooks/list-of-hooks/actionGridQueryBuilderModifier.md +++ b/modules/concepts/hooks/list-of-hooks/actionGridQueryBuilderModifier.md @@ -10,6 +10,7 @@ locations: - back office type: action hookAliases: +hasExample: true --- # Hook action<DefinitionId>GridQueryBuilderModifier @@ -33,4 +34,10 @@ $this->hookDispatcher->dispatchWithParameters('action' . Container::camelize($th 'count_query_builder' => $countQueryBuilder, 'search_criteria' => $searchCriteria, ]); -``` \ No newline at end of file +``` + +## Example implementation + +This hook has been implemented as an example in our [modules examples repository - demoextendsymfonyform1](https://github.com/PrestaShop/example-modules/tree/master/demoextendsymfonyform1). + +This hook has been implemented as an example in our [modules examples repository - demoextendsymfonyform3](https://github.com/PrestaShop/example-modules/tree/master/demoextendsymfonyform3). \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionFormBuilderModifier.md b/modules/concepts/hooks/list-of-hooks/actionFormBuilderModifier.md index 0f14196e32..6d33e56353 100644 --- a/modules/concepts/hooks/list-of-hooks/actionFormBuilderModifier.md +++ b/modules/concepts/hooks/list-of-hooks/actionFormBuilderModifier.md @@ -10,6 +10,7 @@ locations: - back office type: action hookAliases: +hasExample: true --- # Hook action<Object>FormBuilderModifier @@ -41,4 +42,14 @@ $this->hookDispatcher->dispatchWithParameters('action' . $this->camelize($formBu 'options' => &$options, 'id' => $id ]); -``` \ No newline at end of file +``` + +## Example implementation + +This hook has been implemented as an example in our [modules examples repository - demoextendsymfonyform1](https://github.com/PrestaShop/example-modules/tree/master/demoextendsymfonyform1). + +This hook has been implemented as an example in our [modules examples repository - demoextendsymfonyform2](https://github.com/PrestaShop/example-modules/tree/master/demoextendsymfonyform2). + +This hook has been implemented as an example in our [modules examples repository - demoextendsymfonyform3](https://github.com/PrestaShop/example-modules/tree/master/demoextendsymfonyform3). + +This hook has been implemented as an example in our [modules examples repository - demoproductform](https://github.com/PrestaShop/example-modules/tree/master/demoproductform). \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionAdminControllerSetMedia.md b/modules/concepts/hooks/list-of-hooks/actionAdminControllerSetMedia.md index 311f0e2406..8bd9a308a0 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAdminControllerSetMedia.md +++ b/modules/concepts/hooks/list-of-hooks/actionAdminControllerSetMedia.md @@ -9,6 +9,7 @@ locations: - back office type: action hookAliases: +hasExample: true --- # Hook actionAdminControllerSetMedia @@ -27,4 +28,8 @@ Located in: ```php dispatchWithParameters('actionAdminControllerSetMedia') -``` \ No newline at end of file +``` + +## Example implementation + +This hook has been implemented as an example in our [modules examples repository - demoextendgrid](https://github.com/PrestaShop/example-modules/tree/master/demoextendgrid). \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionAfterCreateFormHandler.md b/modules/concepts/hooks/list-of-hooks/actionAfterCreateFormHandler.md index fb4acf36ec..ca334db74d 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAfterCreateFormHandler.md +++ b/modules/concepts/hooks/list-of-hooks/actionAfterCreateFormHandler.md @@ -9,6 +9,7 @@ locations: - front office type: action hookAliases: +hasExample: true --- # Hook actionAfterCreate<FormName>FormHandler @@ -30,4 +31,12 @@ dispatchWithParameters('actionAfterCreate' . Container::camelize($form->getName( 'id' => $id, 'form_data' => &$data, ]) -``` \ No newline at end of file +``` + +## Example implementation + +This hook has been implemented as an example in our [modules examples repository - demoextendsymfonyform1](https://github.com/PrestaShop/example-modules/tree/master/demoextendsymfonyform1). + +This hook has been implemented as an example in our [modules examples repository - demoextendsymfonyform2](https://github.com/PrestaShop/example-modules/tree/master/demoextendsymfonyform2). + +This hook has been implemented as an example in our [modules examples repository - demoextendsymfonyform3](https://github.com/PrestaShop/example-modules/tree/master/demoextendsymfonyform3). \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionAfterUpdateFormHandler.md b/modules/concepts/hooks/list-of-hooks/actionAfterUpdateFormHandler.md index fb5864d4ae..86a8ac1fe1 100644 --- a/modules/concepts/hooks/list-of-hooks/actionAfterUpdateFormHandler.md +++ b/modules/concepts/hooks/list-of-hooks/actionAfterUpdateFormHandler.md @@ -9,6 +9,7 @@ locations: - front office type: action hookAliases: +hasExample: true --- # Hook actionAfterUpdate<FormName>FormHandler @@ -30,4 +31,12 @@ dispatchWithParameters('actionAfterUpdate' . Container::camelize($form->getName( 'id' => $id, 'form_data' => &$data, ]) -``` \ No newline at end of file +``` + +## Example implementation + +This hook has been implemented as an example in our [modules examples repository - demoextendsymfonyform1](https://github.com/PrestaShop/example-modules/tree/master/demoextendsymfonyform1). + +This hook has been implemented as an example in our [modules examples repository - demoextendsymfonyform2](https://github.com/PrestaShop/example-modules/tree/master/demoextendsymfonyform2). + +This hook has been implemented as an example in our [modules examples repository - demoextendsymfonyform3](https://github.com/PrestaShop/example-modules/tree/master/demoextendsymfonyform3). \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionBuildMailLayoutVariables.md b/modules/concepts/hooks/list-of-hooks/actionBuildMailLayoutVariables.md index 08a9527e98..b88733c1c7 100644 --- a/modules/concepts/hooks/list-of-hooks/actionBuildMailLayoutVariables.md +++ b/modules/concepts/hooks/list-of-hooks/actionBuildMailLayoutVariables.md @@ -9,6 +9,7 @@ locations: - front office type: action hookAliases: +hasExample: true --- # Hook actionBuildMailLayoutVariables @@ -39,4 +40,8 @@ dispatchWithParameters( 'mailLayoutVariables' => &$mailLayoutVariables, ] ) -``` \ No newline at end of file +``` + +## Example implementation + +This hook has been implemented as an example in our [modules examples repository - example_module_mailtheme](https://github.com/PrestaShop/example-modules/blob/master/example_module_mailtheme). \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionGetAdminOrderButtons.md b/modules/concepts/hooks/list-of-hooks/actionGetAdminOrderButtons.md index 88e3aeff10..d943e674f0 100644 --- a/modules/concepts/hooks/list-of-hooks/actionGetAdminOrderButtons.md +++ b/modules/concepts/hooks/list-of-hooks/actionGetAdminOrderButtons.md @@ -9,6 +9,7 @@ locations: - back office type: action hookAliases: +hasExample: true --- # Hook actionGetAdminOrderButtons @@ -51,4 +52,8 @@ dispatchHook( 'actions_bar_buttons_collection' => $back officeOrderButtons, ] ) -``` \ No newline at end of file +``` + +## Example implementation + +This hook has been implemented as an example in our [modules examples repository - demovieworderhooks](https://github.com/PrestaShop/example-modules/tree/master/demovieworderhooks). \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionGetMailLayoutTransformations.md b/modules/concepts/hooks/list-of-hooks/actionGetMailLayoutTransformations.md index cb67413824..8e16bb7222 100644 --- a/modules/concepts/hooks/list-of-hooks/actionGetMailLayoutTransformations.md +++ b/modules/concepts/hooks/list-of-hooks/actionGetMailLayoutTransformations.md @@ -9,6 +9,7 @@ locations: - front office type: action hookAliases: +hasExample: true --- # Hook actionGetMailLayoutTransformations @@ -40,4 +41,8 @@ dispatchWithParameters( 'layoutTransformations' => $templateTransformations, ] ) -``` \ No newline at end of file +``` + +## Example implementation + +This hook has been implemented as an example in our [modules examples repository - example_module_mailtheme](https://github.com/PrestaShop/example-modules/blob/master/example_module_mailtheme). \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/actionListMailThemes.md b/modules/concepts/hooks/list-of-hooks/actionListMailThemes.md index 5452f3f57e..0156635a08 100644 --- a/modules/concepts/hooks/list-of-hooks/actionListMailThemes.md +++ b/modules/concepts/hooks/list-of-hooks/actionListMailThemes.md @@ -9,6 +9,7 @@ locations: - front office type: action hookAliases: +hasExample: true --- # Hook actionListMailThemes @@ -36,4 +37,8 @@ dispatchWithParameters( ThemeCatalogInterface::LIST_MAIL_THEMES_HOOK, ['mailThemes' => $mailThemes] ) -``` \ No newline at end of file +``` + +## Example implementation + +This hook has been implemented as an example in our [modules examples repository - example_module_mailtheme](https://github.com/PrestaShop/example-modules/blob/master/example_module_mailtheme). \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/displayAdminOrder.md b/modules/concepts/hooks/list-of-hooks/displayAdminOrder.md index 35cbe481c7..05a4a6aa6a 100644 --- a/modules/concepts/hooks/list-of-hooks/displayAdminOrder.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminOrder.md @@ -10,6 +10,7 @@ locations: type: display hookAliases: - adminOrder +hasExample: true --- # Hook displayAdminOrder @@ -17,8 +18,6 @@ hookAliases: Aliases: - adminOrder - - ## Information {{% notice tip %}} @@ -48,4 +47,8 @@ Located in: ```php {{ renderhook('displayAdminOrder', {'id_order': orderForViewing.id}) }} -``` \ No newline at end of file +``` + +## Example implementation + +This hook has been implemented as an example in our [modules examples repository - demovieworderhooks](https://github.com/PrestaShop/example-modules/tree/master/demovieworderhooks). \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/displayAdminOrderMain.md b/modules/concepts/hooks/list-of-hooks/displayAdminOrderMain.md index 6826e5cee0..a540d51e3f 100644 --- a/modules/concepts/hooks/list-of-hooks/displayAdminOrderMain.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminOrderMain.md @@ -9,6 +9,7 @@ locations: - back office type: display hookAliases: +hasExample: true --- # Hook displayAdminOrderMain @@ -42,4 +43,8 @@ Located in: ```php {{ renderhook('displayAdminOrderMain', {'id_order': orderForViewing.id}) }} -``` \ No newline at end of file +``` + +## Example implementation + +This hook has been implemented as an example in our [modules examples repository - demovieworderhooks](https://github.com/PrestaShop/example-modules/tree/master/demovieworderhooks). \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/displayAdminOrderSide.md b/modules/concepts/hooks/list-of-hooks/displayAdminOrderSide.md index e897b6e562..691c77c8ea 100644 --- a/modules/concepts/hooks/list-of-hooks/displayAdminOrderSide.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminOrderSide.md @@ -9,15 +9,13 @@ locations: - back office type: display hookAliases: - - displayback officeOrderActions + - displayBackofficeOrderActions --- # Hook displayAdminOrderSide Aliases: - - displayback officeOrderActions - - + - displayBackofficeOrderActions ## Information diff --git a/modules/concepts/hooks/list-of-hooks/displayAdminOrderSideBottom.md b/modules/concepts/hooks/list-of-hooks/displayAdminOrderSideBottom.md index 4460182e5c..8e45ddbed1 100644 --- a/modules/concepts/hooks/list-of-hooks/displayAdminOrderSideBottom.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminOrderSideBottom.md @@ -9,6 +9,7 @@ locations: - back office type: display hookAliases: +hasExample: true --- # Hook displayAdminOrderSideBottom @@ -36,4 +37,8 @@ Located in: ```php {{ renderhook('displayAdminOrderSideBottom', {'id_order': orderForViewing.id}) }} -``` \ No newline at end of file +``` + +## Example implementation + +This hook has been implemented as an example in our [modules examples repository - demovieworderhooks](https://github.com/PrestaShop/example-modules/tree/master/demovieworderhooks). \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/displayAdminOrderTabContent.md b/modules/concepts/hooks/list-of-hooks/displayAdminOrderTabContent.md new file mode 100644 index 0000000000..8740e6cfa7 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/displayAdminOrderTabContent.md @@ -0,0 +1,39 @@ +--- +menuTitle: displayAdminOrderTabContent +Title: displayAdminOrderTabContent +hidden: true +hookTitle: Display new elements in the Back Office, tab contents on order +files: + - src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/details.html.twig +locations: + - back office +type: display +hookAliases: +hasExample: true +--- + +# Hook displayAdminOrderTabContent + +## Information + +{{% notice tip %}} +**Display new elements in the Back Office, tab contents on order** +{{% /notice %}} + +Hook locations: + - back office + +Hook type: display + +Located in: + - [src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/details.html.twig](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/details.html.twig) + +## Call of the Hook in the origin file + +```php +{% set displayAdminOrderTabContent = renderhook('displayAdminOrderTabContent', {'id_order': orderForViewing.id}) %} +``` + +## Example implementation + +This hook has been implemented as an example in our [modules examples repository - demovieworderhooks](https://github.com/PrestaShop/example-modules/tree/master/demovieworderhooks). \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/displayAdminOrderTabLink.md b/modules/concepts/hooks/list-of-hooks/displayAdminOrderTabLink.md new file mode 100644 index 0000000000..55af600c0b --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/displayAdminOrderTabLink.md @@ -0,0 +1,39 @@ +--- +menuTitle: displayAdminOrderTabLink +Title: displayAdminOrderTabLink +hidden: true +hookTitle: Display new elements in the Back Office, tab links on order +files: + - src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/details.html.twig +locations: + - back office +type: display +hookAliases: +hasExample: true +--- + +# Hook displayAdminOrderTabLink + +## Information + +{{% notice tip %}} +**Display new elements in the Back Office, tab contents on order** +{{% /notice %}} + +Hook locations: + - back office + +Hook type: display + +Located in: + - [src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/details.html.twig](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/details.html.twig) + +## Call of the Hook in the origin file + +```php +{% set displayAdminOrderTabLink = renderhook('displayAdminOrderTabLink', {'id_order': orderForViewing.id}) %} +``` + +## Example implementation + +This hook has been implemented as an example in our [modules examples repository - demovieworderhooks](https://github.com/PrestaShop/example-modules/tree/master/demovieworderhooks). \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/displayAdminOrderTop.md b/modules/concepts/hooks/list-of-hooks/displayAdminOrderTop.md new file mode 100644 index 0000000000..1bfff26b58 --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/displayAdminOrderTop.md @@ -0,0 +1,41 @@ +--- +menuTitle: displayAdminOrderTop +Title: displayAdminOrder +hidden: true +hookTitle: Display new elements in the Back Office, top of Order page +files: + - src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/view.html.twig +locations: + - back office +type: display +hookAliases: +hasExample: true +--- + +# Hook displayAdminOrder + +## Information + +{{% notice tip %}} +**Display new elements in the Back Office, top of Order page:** + +This hook launches modules when the Order is displayed in the Back Office +{{% /notice %}} + +Hook locations: + - back office + +Hook type: display + +Located in: + - [src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/view.html.twig](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/view.html.twig) + +## Call of the Hook in the origin file + +```php +{% set displayAdminOrderTopHookContent = renderhook('displayAdminOrderTop', {'id_order': orderForViewing.id}) %} +``` + +## Example implementation + +This hook has been implemented as an example in our [modules examples repository - demovieworderhooks](https://github.com/PrestaShop/example-modules/tree/master/demovieworderhooks). \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/displayAdminProductsExtra.md b/modules/concepts/hooks/list-of-hooks/displayAdminProductsExtra.md new file mode 100644 index 0000000000..4df09ede6a --- /dev/null +++ b/modules/concepts/hooks/list-of-hooks/displayAdminProductsExtra.md @@ -0,0 +1,41 @@ +--- +menuTitle: displayAdminProductsExtra +Title: displayAdminProductsExtra +hidden: true +hookTitle: Display new elements in back office product page, Extra tab +files: + - src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/product.html.twig +locations: + - back office +type: display +hookAliases: +hasExample: true +--- + +# Hook displayAdminProductsExtra + +## Information + +{{% notice tip %}} +**Display new elements in back office product page, Extra tab:** + +This hook launches modules when the back office product page is displayed +{{% /notice %}} + +Hook locations: + - back office + +Hook type: display + +Located in: + - [src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/product.html.twig](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/product.html.twig) + +## Call of the Hook in the origin file + +```php +{% set hooks = renderhooksarray('displayAdminProductsExtra', { 'id_product': id_product }) %} +``` + +## Example implementation + +This hook has been implemented as an example in our [modules examples repository - demoproductform](https://github.com/PrestaShop/example-modules/tree/master/demoproductform). \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/displayAdminProductsQuantitiesStepBottom.md b/modules/concepts/hooks/list-of-hooks/displayAdminProductsQuantitiesStepBottom.md index 5d14e5768b..3321b4fdee 100644 --- a/modules/concepts/hooks/list-of-hooks/displayAdminProductsQuantitiesStepBottom.md +++ b/modules/concepts/hooks/list-of-hooks/displayAdminProductsQuantitiesStepBottom.md @@ -9,6 +9,7 @@ locations: - back office type: display hookAliases: +hasExample: true --- # Hook displayAdminProductsQuantitiesStepBottom @@ -33,4 +34,8 @@ Located in: ```php {{ renderhook('displayAdminProductsQuantitiesStepBottom', { 'id_product': productId }) }} -``` \ No newline at end of file +``` + +## Example implementation + +This hook has been implemented as an example in our [modules examples repository - demovieworderhooks](https://github.com/PrestaShop/example-modules/tree/master/demovieworderhooks). \ No newline at end of file diff --git a/modules/concepts/hooks/list-of-hooks/displayFooterBefore.md b/modules/concepts/hooks/list-of-hooks/displayFooterBefore.md index f49bcda2a7..b33c37d5be 100644 --- a/modules/concepts/hooks/list-of-hooks/displayFooterBefore.md +++ b/modules/concepts/hooks/list-of-hooks/displayFooterBefore.md @@ -9,6 +9,7 @@ locations: - front office type: display hookAliases: +hasExample: true --- # Hook displayFooterBefore @@ -27,4 +28,8 @@ Located in: ```php {hook h='displayFooterBefore'} -``` \ No newline at end of file +``` + +## Example implementation + +This hook has been implemented as an example in our [modules examples repository - demomultistoreform](https://github.com/PrestaShop/example-modules/tree/master/demomultistoreform). \ No newline at end of file From 93e70d04b90132f0979bc56799e2fc3c118d8f58 Mon Sep 17 00:00:00 2001 From: Thomas Nares Date: Mon, 6 Mar 2023 07:37:06 +0100 Subject: [PATCH 236/310] Fix wrong doc about injecting translator in custom module class --- .../creation/module-translation/new-system.md | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/modules/creation/module-translation/new-system.md b/modules/creation/module-translation/new-system.md index 38304948fe..350d56a87b 100644 --- a/modules/creation/module-translation/new-system.md +++ b/modules/creation/module-translation/new-system.md @@ -172,27 +172,32 @@ class SomeAdminController extends FrameworkBundleAdminController #### Other classes -Other classes will need to retrieve the module's instance somehow. We recommend passing it as a parameter in the constructor and storing it for later use. +Other classes will need to retrieve the module's translator instance somehow. We recommend passing it as a parameter in the constructor and storing it for later use. ```php module = $module + $this->translator = $translator } public function foo() { - $this->text = $this->module->trans('My text to translate', [], 'Modules.Mymodule.Custommoduleclass'); + $this->text = $this->translator->trans('My text to translate', [], 'Modules.Mymodule.Custommoduleclass'); } } + +// from within the module: +$customModuleClass = new _NAMESPACE_\CustomModuleClass($this->getTranslator()); ``` -If you really need to, you can also retrieve a new instance of your module using `Module::getInstanceByName('mymodulename')`. This should be avoided though, as it's not a good practice. +{{% notice info %}} +If you really need to, you can also retrieve a new instance of your module using `$module = Module::getInstanceByName('mymodulename')`, and then access the `translator` with `$module->getTranslator()`. This should be avoided though, as it's not a good practice. +{{% /notice %}} ### Templates From c9b176e42c2e9fa1273ecda48f8a5329edb6e5d3 Mon Sep 17 00:00:00 2001 From: Thomas Nares Date: Mon, 6 Mar 2023 07:56:27 +0100 Subject: [PATCH 237/310] Add explaination about why undescore is not suitable in technical name #1608 --- modules/creation/tutorial.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/creation/tutorial.md b/modules/creation/tutorial.md index 498881cf47..0091c54aee 100644 --- a/modules/creation/tutorial.md +++ b/modules/creation/tutorial.md @@ -15,7 +15,7 @@ Let's create a first simple module, this will allow us to better describe its st First, create the module's folder, in PrestaShop's `/modules` folder. Let's call it `mymodule`. This will be the module's "technical" name. {{% notice tip %}} -Technical names can only accept lower case alphanumeric characters (`[a-z0-9]`). Although accepted, we strongly discourage using underscores because they don't work with translation domains. +Technical names can only accept lower case alphanumeric characters (`[a-z0-9]`). [Although accepted, we strongly discourage using underscores because they don't work with translation domains]({{< ref "/8/modules/creation/module-translation/new-system#translation-domain" >}}). {{% /notice %}} This folder must contain the main file, a PHP file of the same name as the folder, which will handle most of the processing: `mymodule.php`. From ee262d630149290356d28938f29ea9dc0cec3768 Mon Sep 17 00:00:00 2001 From: Thomas Nares Date: Mon, 6 Mar 2023 07:56:58 +0100 Subject: [PATCH 238/310] Fix module controller translator call as well --- modules/creation/module-translation/new-system.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/modules/creation/module-translation/new-system.md b/modules/creation/module-translation/new-system.md index 350d56a87b..d9fddb2ebe 100644 --- a/modules/creation/module-translation/new-system.md +++ b/modules/creation/module-translation/new-system.md @@ -52,7 +52,7 @@ To make your module translatable, you need to adapt your module's source code. F Don't worry if you don't translate everything to all languages right away. Any wording left untranslated will be shown in its original language. Because of this, we suggest writing all your wordings in English, and then translating them to other languages. {{% /notice %}} -### Translation domain +### Translation domain {#translation-domain} An important part of the new translation system is **Translation Domains**, which replaces the classic system's [contextualization][contextualization]. In the new translation system, all wordings must be linked to at least one translation domain. @@ -122,7 +122,7 @@ When translating wordings in the module's main class, since it extends the `Modu module` property. +`ModuleAdminController` and `ModuleFrontController` can access the module instance and translator via the `$this->module` property and `getTranslator()` public accessor. ```php title = $this->module->trans('My module title', [], 'Modules.Mymodule.Something'); + $this->title = $this->module->getTranslator()->trans('My module title', [], 'Modules.Mymodule.Something'); } } ``` -Symfony controllers work exactly the same as the Core's. Just use `$this->trans` method. +Symfony controllers work exactly the same as the Core's. Just use `$translator->trans()` method. {{% notice warning %}} -Be aware that in symfony controllers, the second and third arguments have been swapped to make `$replacements` optional. +Be aware that in Symfony controllers, the second and third arguments have been swapped to make `$replacements` optional. {{% /notice %}} ```php From a5bd82dba4916cc52260a163c81010d8f72815a9 Mon Sep 17 00:00:00 2001 From: Thomas Nares Date: Mon, 6 Mar 2023 07:58:10 +0100 Subject: [PATCH 239/310] Fix module controller translator call as well --- modules/creation/module-translation/new-system.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/creation/module-translation/new-system.md b/modules/creation/module-translation/new-system.md index d9fddb2ebe..12aec1246e 100644 --- a/modules/creation/module-translation/new-system.md +++ b/modules/creation/module-translation/new-system.md @@ -151,7 +151,7 @@ class MyModuleSomethingModuleFrontController extends ModuleFrontController } ``` -Symfony controllers work exactly the same as the Core's. Just use `$translator->trans()` method. +Symfony controllers work exactly the same as the Core's. Just use `$this->trans()` method. {{% notice warning %}} Be aware that in Symfony controllers, the second and third arguments have been swapped to make `$replacements` optional. From 6758debb20df882b73c2785ed3aeb4c017518b92 Mon Sep 17 00:00:00 2001 From: Thomas Nares Date: Tue, 7 Mar 2023 08:43:00 +0100 Subject: [PATCH 240/310] Document new product page features --- modules/sample-modules/extend-product-page.md | 112 ++++++++++++++++++ .../img/productform-backward.png | Bin 0 -> 40886 bytes .../img/productform-customfield.png | Bin 0 -> 18955 bytes .../img/productform-customtab.png | Bin 0 -> 15880 bytes 4 files changed, 112 insertions(+) create mode 100644 modules/sample-modules/extend-product-page.md create mode 100644 modules/sample-modules/img/productform-backward.png create mode 100644 modules/sample-modules/img/productform-customfield.png create mode 100644 modules/sample-modules/img/productform-customtab.png diff --git a/modules/sample-modules/extend-product-page.md b/modules/sample-modules/extend-product-page.md new file mode 100644 index 0000000000..8683897dd1 --- /dev/null +++ b/modules/sample-modules/extend-product-page.md @@ -0,0 +1,112 @@ +--- +title: Extending the new product page form +weight: 3 +--- + +# Extending the new product page form +{{< minver v="8.0" title="true" >}} + +To allow the new product page to be easily extendable by modules, a new feature was introduced in {{< minver v="8.1.0" title="true" >}} +This features allows to add new custom tabs with the `NavigationTabType`. + +The goal of this How-to is to show how to customize the new product page with all this new introduced features, and older ones. + +The example module we are going to create can be found [here](https://github.com/PrestaShop/example-modules/tree/master/demoproductform) in our [example modules repository](https://github.com/PrestaShop/example-modules). + +## What will be achieved with this how-to ? + +In this how-to, we will create a new module, and add a new custom field in the native description tab. + +![custom field in product form](../img/productform-customfield.png) + +Then, we will create a new empty tab, and we will add a new custom field in this module created tab. + +![custom tab in product form](../img/productform-customtab.png) + +Finally, we will experience how those features work in older versions of PrestaShop since they are backward compatible. + +![custom field and tabs in older versions of PrestaShop](../img/productform-backward.png) + +## Create the module + +To create the module, we use the [regular module creation method]({{< ref "8/modules/creation/tutorial" >}}). + +Our regular module skeleton: + +```php +name = 'demoproductform'; + $this->author = 'PrestaShop'; + $this->version = '1.0.0'; + $this->ps_versions_compliancy = ['min' => '8.1.0', 'max' => _PS_VERSION_]; + + parent::__construct(); + + $this->displayName = $this->trans('DemoProductForm', [], 'Modules.Demoproductform.Config'); + $this->description = $this->trans('DemoProductForm module description', [], 'Modules.Demoproductform.Config'); + } +} +``` + +In this example module, we use the [new translation system]({{< ref "/8/modules/creation/module-translation/new-system" >}}), so we need to add this method to enable the translation system: + +```php + public function isUsingNewTranslationSystem(): bool + { + return true; + } +``` + +This module is also PSR4 compliant, and namespaced, so we require the `autoload.php`, and our `composer.json` contains the following content: + +```json +{ + "name": "prestashop/demoproductform", + "authors": [ + { + "name": "Julius Zukauskas", + "email": "julius.zukauskas@invertus.eu" + }, + { + "name": "PrestaShop Core team" + } + ], + "autoload": { + "psr-4": { + "PrestaShop\\Module\\DemoProductForm\\": "src/" + }, + "config": { + "prepend-autoloader": false + }, + "type": "prestashop-module" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^3.14" + } +} +``` + + +## Create a custom field in description tab + +## Create a new tab + +## Create a custom field in the new tab + +## Backward compatibility of those features + + +## Next steps \ No newline at end of file diff --git a/modules/sample-modules/img/productform-backward.png b/modules/sample-modules/img/productform-backward.png new file mode 100644 index 0000000000000000000000000000000000000000..a89a6d67de105c6df981704c670fa554f8f818bd GIT binary patch literal 40886 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 literal 0 HcmV?d00001 diff --git a/modules/sample-modules/img/productform-customfield.png b/modules/sample-modules/img/productform-customfield.png new file mode 100644 index 0000000000000000000000000000000000000000..62bd03907e884d5fafd13280b56081b01a271542 GIT binary patch literal 18955 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 Date: Tue, 7 Mar 2023 16:02:11 +0000 Subject: [PATCH 241/310] Update link to "Get involved" page --- contribute/_index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contribute/_index.md b/contribute/_index.md index 1b8630fdb6..89a49ffed5 100644 --- a/contribute/_index.md +++ b/contribute/_index.md @@ -11,6 +11,6 @@ chapter: true PrestaShop is a community project, made by hundreds of people collaborating around the world. You can get involved too! -- [How to get involved in the project](https://prestashop-project.org/get-involved/) +- [How to get involved in the project](https://www.prestashop-project.org/get-involved/) {{% children %}} From da423c61985bb10bbbb74e7a622d302530acf46b Mon Sep 17 00:00:00 2001 From: Thomas Nares Date: Tue, 7 Mar 2023 17:20:03 +0100 Subject: [PATCH 242/310] Document PR30588 - services configurations priority MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Michał Kaleta --- modules/concepts/services/_index.md | 127 +++++++++++++++++++++++++++- modules/core-updates/8.1.md | 1 + 2 files changed, 127 insertions(+), 1 deletion(-) diff --git a/modules/concepts/services/_index.md b/modules/concepts/services/_index.md index 11e3dfa960..b554a70979 100644 --- a/modules/concepts/services/_index.md +++ b/modules/concepts/services/_index.md @@ -17,7 +17,7 @@ You have the ability to modify the Symfony container configuration from a module First we strongly advise you to use [**namespaces**](https://www.php.net/manual/en/language.namespaces.php) & autoloading in your module, which can be done thanks to composer. -[A dedicated chapter]({{< ref "1.7/modules/concepts/composer" >}}) is available to learn more about Composer and to set it up. +[A dedicated chapter]({{< ref "8/modules/concepts/composer" >}}) is available to learn more about Composer and to set it up. #### Define your service @@ -243,6 +243,131 @@ If however no interface was used here, you probably need to `extend` the previou As you can see, interfaces lay the ground for easy extension and customization, that is why we use them more and more in the Core codebase and we recommend you use them as well ! +#### Advanced services parameters (_instanceof or interface binding, manual tags) {{< minver v=8.1 >}} + +Since {{< minver v=8.1 >}}, [modules autoloaders and service configurations loading are now registered before compiler passes](https://github.com/PrestaShop/PrestaShop/pull/30588). That means that you can now use native Symfony service configuration features in your modules. + +Those features are : + +- [applying configuration based on the extended classes or implemented interfaces](https://symfony.com/blog/new-in-symfony-3-3-simpler-service-configuration#interface-based-service-configuration) +- [autoconfiguration](https://symfony.com/blog/new-in-symfony-3-3-simpler-service-configuration#interface-based-service-configuration) +- [an option to skip the class attribute](https://symfony.com/blog/new-in-symfony-3-3-optional-class-for-named-services) +- [automatically registering classes found in the specified directories as services](https://symfony.com/blog/new-in-symfony-3-3-psr-4-based-service-discovery) + +As an example, let's consider a module with the following structure: + +``` +config/ + services.yml +src/ + Collection/ + Collection.php + Element.php + ElementInterface.php +``` + +And this content: + +File: `src/Collection/Collection.php` + +```php +addElement($element); + } + } +``` + +File: `src/Collection/Element.php` + +```php +}} diff --git a/modules/core-updates/8.1.md b/modules/core-updates/8.1.md index a96589ce6f..f48989107c 100644 --- a/modules/core-updates/8.1.md +++ b/modules/core-updates/8.1.md @@ -44,6 +44,7 @@ PrestaShop 8.1 has the same PHP requirement as Prestashop 8.0. * Added a new Smarty variable `theme_dir` in front controllers [PR#30383](https://github.com/PrestaShop/PrestaShop/pull/30383) * Added a feature to disable `core.js` loading on custom themes [PR#29995](https://github.com/PrestaShop/PrestaShop/pull/29995). [More informations][corejs-informations] * Added supplier url and manufacturer url to Smarty `{url}` helper [PR#30242](https://github.com/PrestaShop/PrestaShop/pull/30342) and [PR#30314](https://github.com/PrestaShop/PrestaShop/pull/30314) +* Fixed modules autoloaders and service configurations registrations priority [PR#30588](https://github.com/PrestaShop/PrestaShop/pull/30588). [More informations]({{< relref "/8/modules/concepts/services/#advanced-services-parameters-_instanceof-or-interface-binding-manual-tags" >}}) ## BC Breaks (Backward Compatibility Breaks) From 99b8bd2b55d9452767bfda189939d76ce247cc46 Mon Sep 17 00:00:00 2001 From: Dimitri Mouillard Date: Wed, 8 Mar 2023 18:34:38 +0100 Subject: [PATCH 243/310] Security rules on payment modules In the documentation for 1.7, there was a chapter in a page related to the Addons marketplace about security on payment modules. This section is not dedicated to the marketplace, and should be available to everyone in the open source documentation. --- modules/payment/_index.md | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/modules/payment/_index.md b/modules/payment/_index.md index 2702a54195..077d27dbcd 100644 --- a/modules/payment/_index.md +++ b/modules/payment/_index.md @@ -76,11 +76,25 @@ We have identified four cases of payment module: The minimal variables to set are `$callToActionText` and `$form`. You can check the `getEmbeddedPaymentOption()` method of *[paymentexample](https://github.com/PrestaShop/paymentexample)* to have an example. -#### iFrame +#### iframe -: The payment form is displayed on the merchant's website, but inside an iFrame. +: The payment form is displayed on the merchant's website, but inside an iframe. The minimal variables to set are `$callToActionText` and `$additionalInformation`. You can check the `getIframePaymentOption()` method of *[paymentexample](https://github.com/PrestaShop/paymentexample)* to have an example. + +Payment modules rules +--------------------- + +We do have extra rules for Payment Modules as this type of modules require higher security. +Note that there are some modules which create the Order with a pending order status during the payment processing (1), while others wait for the payment system's approval to create it (2). But none of them create an order before the customer passed the payment service (bank, PayPal...). + +* Make sure you double check the id_cart before creating the order. + * The purpose is to make sure another customer cannot validate a cart which isn't his. + +* if (2), make sure the amount you use to validateOrder() comes from the external payment system. Do not use Cart->getOrderTotal(); + * For security reasons, always proceed as explained. + +* For (2), when receiving a call to process the payment, make sure you double check the source of the call using a signature or a token. Those values must not be known of all. Migrating from 1.6 to 1.7 ------------------------- From 22b7f43332632060bb8e9773df46be0a646664d6 Mon Sep 17 00:00:00 2001 From: Thomas Nares Date: Mon, 13 Mar 2023 12:21:40 +0100 Subject: [PATCH 244/310] Improve search results for the hook page in Algolia --- modules/concepts/hooks/list-of-hooks/_index.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/concepts/hooks/list-of-hooks/_index.md b/modules/concepts/hooks/list-of-hooks/_index.md index cb00a983f8..fa2657c3e3 100644 --- a/modules/concepts/hooks/list-of-hooks/_index.md +++ b/modules/concepts/hooks/list-of-hooks/_index.md @@ -16,8 +16,9 @@ For example, `actionAdminCustomersFormModifier` is documented as `action -

No hooks found