Table of Contents

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 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.
  • 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 - 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 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.

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.

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).