Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
2 changes: 1 addition & 1 deletion basics/installation/advanced/install-from-cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,5 +109,5 @@ 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
[activities]: https://github.com/PrestaShop/PrestaShop/blob/9.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
2 changes: 1 addition & 1 deletion contribute/contribution-guidelines/pull-requests.md
Original file line number Diff line number Diff line change
Expand Up @@ -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/8.0.x/docs/CHANGELOG.txt).
We use type & category to group changes in the [changelog](https://github.com/PrestaShop/PrestaShop/blob/9.0.x/docs/CHANGELOG.txt).
{{% /notice %}}

### BC breaks
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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/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.
You can take a look at [PerformanceController](https://github.com/PrestaShop/PrestaShop/blob/9.0.x/src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/PerformanceController.php) for an example of good implementation, and [ProductController](https://github.com/PrestaShop/PrestaShop/blob/9.0.x/src/PrestaShopBundle/Controller/Admin/ProductController.php) for something you should avoid at all costs.
{{% /notice %}}
Original file line number Diff line number Diff line change
Expand Up @@ -474,7 +474,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/8.0.x/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/9.0.x/src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/ContactsController.php).
{{% /notice %}}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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/8.0.x/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/9.0.x/src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/PerformanceController.php).

This is how we manage a form submit inside a Controller:

Expand Down Expand Up @@ -163,7 +163,7 @@ stateDiagram-v2

## 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/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.
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/9.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).

Expand Down
4 changes: 2 additions & 2 deletions development/architecture/migration-guide/hooks.md
Original file line number Diff line number Diff line change
Expand Up @@ -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#L735) and add the following code:
In ``classes/Hook``, find the [exec() function](https://github.com/PrestaShop/PrestaShop/blob/9.0.x/classes/Hook.php#L735) and add the following code:

```php
<?php
Expand Down Expand Up @@ -46,7 +46,7 @@ $this->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/8.0.x/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/9.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`.

Expand Down
10 changes: 5 additions & 5 deletions development/architecture/migration-guide/testing/behat.md
Original file line number Diff line number Diff line change
Expand Up @@ -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/8.0.x/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/9.0.x/tests/bin/create-test-db.php).
{{% /notice %}}

### Tables dump
Expand Down Expand Up @@ -90,10 +90,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/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).
When creating a new Context class, it should extend the [`AbstractDomainFeatureContext`](https://github.com/PrestaShop/PrestaShop/blob/9.0.x/tests/Integration/Behaviour/Features/Context/Domain/AbstractDomainFeatureContext.php).

{{% notice %}}
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.
The [`AbstractDomainFeatureContext`](https://github.com/PrestaShop/PrestaShop/blob/9.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:
Expand Down Expand Up @@ -135,7 +135,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:
The [SharedStorage](https://github.com/PrestaShop/PrestaShop/blob/9.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
Expand All @@ -150,7 +150,7 @@ The [SharedStorage](https://github.com/PrestaShop/PrestaShop/blob/8.0.x/tests/In

## 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/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)
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/9.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/9.0.x/tests/Integration/Behaviour/Features/Context/Domain/Product/AddProductFeatureContext.php)
):

```feature
Expand Down
4 changes: 2 additions & 2 deletions development/architecture/migration-guide/validation/_index.md
Original file line number Diff line number Diff line change
Expand Up @@ -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]({{<relref "../forms/crud-forms">}}) or [Settings]({{<relref "../forms/settings-forms">}})) - 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 "/9/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.
* [Value objects]({{< relref "/9/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/9.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/9.0.x/src/Core/Domain/Product/Command/UpdateProductOptionsCommand.php) and helps to maintain the command validity.
* [Domain services]({{<relref "../../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 "/9/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/8.0.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/9.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 %}}
2 changes: 1 addition & 1 deletion development/components/console/context-helper.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,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/8.0.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/9.0.x/src/Adapter/LegacyContextLoader.php).
Loading
Loading