Code compatibility
# Summary
This article describes the rules and guidelines that developers must follow when coding within Avantus. Please note that the objective of what is described here is to achieve a general standardization of the code within the project and not to dictate or force the programmer to change his coding style.
# Code style and formatting tool
The Avantus use the standard PSR-2: Coding Style Guide relying on the PHP-CS-Fixer tool(its be described in this documentation) For more information about PSR-2 and PHP-CS-Fixer you can check the links below:
- PSR-2: https://www.php-fig.org/psr/psr-2/
- PHP-CS-Fixer Project: https://github.com/FriendsOfPHP/PHP-CS-Fixer
- PHP-CS-Fixer Jetbrains Plugin: https://www.jetbrains.com/help/phpstorm/using-php-cs-fixer.html
Please note that PSR-2 is now marked as
deprecatedin favor of PSR-12. We are planning to migrate soon. Keep an eye into this documentation.
# Exceptions
PHP 7 changes how most errors are reported by PHP. Instead of reporting errors through the traditional error reporting mechanism used by PHP 5 now there is a new hierarchy of classes. Look at the following picture for a better understanding.

Due to the above, in Avantus Throwable is always used on top of the catch block. This is the class on top in the PHP 7 hierarchy.
Example of using try catch block as per below:

For standardization always use $thr as variable name when Throwable and $ex when is Exception.
Be aware that logger used in Avantus is not the normal Symfony Psr Logger. Check this class for better understanding of the available functions.
# Dependency injection
The Dependency Injection component implements a PSR-11 compatible service container that allows you to standardize and centralize the way objects are constructed in your application.
It is widely used within the Avantus. You only should use $this->get('SERVICE') or $this->container->get('SERVICE') when can not be used Dependency Injection.
# Repositories
Repositories are used by Dependency Injection, it means you can not attach the Entity and the Repository in the traditional Symfony way. As per below:
* @ORM\Entity (repositoryClass="App\Model\Repository\ActionRepository")
You must to use the below constructor into the Repositories classes with the proper Entity class:

# Entities
# Entity creation
Avantus database is actually a replication for a master database hosted in external service and application. So our DB is an slave. Because of this, we can not be free to add, remove o update fields to any table in our DB. Developers who wants to perform any of this operations, need to discuss with some expert in our DB before doing it.
# Entity getters and setters
The getter and setter of the entities need to be generated through the Symfony command instead of some IDEs generator.
Use make:entity App\Model\Entity\ENTITY_NAME --regenerate for our current Symfony version in Avantus
# Entity annotations
Like every Symfony+Doctrine entity, the ORM annotations are present into our Entitites. But there are some rules about annotations that developers should follow.
Despite of default values in ORM, developers should add them even specifing the default value. Eg...
nullable=false by default doctrine assume false value if the property is not declared on the ORM annotations. But developers must to specified even if is with the default value, like before.
name=email by default doctrine assume that the field name is the SNAKE version of the class attribute. Eg
In the above example doctrine will assume that the name of the field in the database is last_modification_date, because is the SNAKE version of lastModificationDate.The correct way to represent the previous example in the entity is like below:

This give to others developers clear vision of the field with just simple look to the property.
When the new or old field in the entity requires index, the value associated to the name property, must to remain empty. This will force Doctrine to create a name for such index.
The example below is complete WRONG because Doctrine will not generate a nme for the index and will respect the one present on the entity.

The correct way should be like in the pic below.

# Migrations
Doctrine Migrations is used to manage the changes on the database.
# Generate introspect migration
When you make some changes in the entities or you created new one, these changes need to be applied to DB. The command below generate a new migration file.
- doctrine:migrations:diff
Please note that despite of the quality and the fidelity of the changes on that field, developers MUST to manually check one by one the lines on the migration file, not only in the up() function but also in the down() function.
# Generate empty migration
Sometimes is needed to generate empty migration file without checking the database. While this is not the normal and proper behavior, sometimes developers can required it. The below command perform such action:
- doctrine:migrations:generate
# Apply migration
In order to apply the pending migrations you can execute the below command:
- doctrine:migrations:migrate
Note that this command will add one row in the doctrine_migrations table one per each applied migration file.
# Down migration
Sometimes also is needed to remove the last changes on the DB applied through migration, in such case Doctrine will remove the migration row from the doctrine_migrations table. You can down the file by executing the below command:
- doctrine:migrations:execute 20200825123614 --down
You can take the migration number (20200825123614 in previous example) by checking the name of the migration class that you want to down.
# Classes naming
In Avantus is strictly mandatory to name the classes with clear name, examples below.
- The list below are examples of completely WRONG names
- Action (when is into the Controller folder)
- Action (when is into the Handlers folder)
- Action (when is into the Services folder)
- Action (when is into the Repository folder)
- Action (when is into the Request folder)
- Action (when is into the Response folder)
- The list below are CORRECT example for each of previous examples
- ActionController (when is into the Controller folder)
- ActionHandler (when is into the Handlers folder)
- ActionService (when is into the Services folder)
- ActionRepository (when is into the Repository folder)
- ActionRequest (when is into the Request folder)
- ActionResponse (when is into the Response folder)
When you apply the wrong behavior, and you need to use into same php file a handler, services, repository and response for example, its very confuse what your are importing due all of them has identic name.
# Classes naming
Similar to classes naming are the variables naming.
Naming
You should provide proper name to the variable in order to allow others developers to easy know what is the target of the variable. Examples below.
- The list below are examples of completely WRONG names
- $action (when it refers to service object)
- $action (when it refers to handler object)
- $action (when it refers to repository object)
- $action (when it refers to request object)
- $action (when it refers to response object)
- The list below are CORRECT example for each of previous examples
- $actionSrv (when it refers to service object)
- $actionHandler(when it refers to handler object)
- $actionRepository or $actionRepo (when it refers to repository object)
- $actionRequest (when it refers to request object)
- $actionResponse (when it refers to response object)
# Comments
Its mandatory to add proper PHP doc comment when you declare attribues into any class or when you are using variable that contains object. Examples below.
- The next list contains examples of completely WRONG use .
Attributes without annotation about type

Loop without annotation for $project variable

Note the lack of php annotation.
2.The next list contains CORRECT examples for each of previous examples
Attributes with annotation about type

Loop with annotation for $project variable

Note the presence of php annotation.
# .ENV file
When adding new key in local ENV file(the one ignored by git) the developer is responsible to update the value also in the env.dist or env.test file.
Any new key in the ENV file need to be added in the proper section, because we would like to have definied by group the section keys for every mini app inside of Avantus. In the image below check the comments that delimite the group of keys.

Normally the ENV keys are connected to the parameters.yaml file into the config folder. Developers need to be careful when changing the name of any of existnig keys, because can cause parameters reference to previous name, fail. So, after update KEYS in ENV file, you must to check the reference on parameters.yaml and update it also there.

# Services.yaml
When adding new services in the file services.yaml the developer is responsible for adding them in the proper section, because we would like to have definied by section group in order to have better organization. In the image below check the comments that delimite the groups.

Into the **services.yaml file there is an important section for all cloud storage disk. For that we are using FlySystem dependency. Check the pic below in order to get familiar with the section we refer to.

When new storage need to be added, developers need to pay attention to few elements:
- The name for the client need to start with the service provider. "aws*" for Amazon,"gc*" for Google, "azu" or "azure" for Azure.
- The second word after underscore MUST to be the word client and the last part is the number of the client in Avants. Eg, in the above image you can see that there is already one client for Amazon, one for Google and one for Azure. In case we would like to add new client for each one, the name should be aws_client_2, gc_client_22 and azure_client_2. Please note the number 2 at the end. This is because is the second client. In case we would like to add another one only for amazon, we should use aws_client_3.
# Composer.json
Because Avantus is an unique Symfony Projehttps://drive.google.com/uc?export=view&id=1ZqNQA04I7FcvLXRa5S0z57lj7-gGT_otct, but has inside multiple mini-apps, developers need to be really careful when change the version of some dependencies or even when add new one.So developers need discuss with the team when adding new dependencies or update the versions, otherwise the operation of the system may be affected.
# General notes
# Testing code before submit
Its mandatory for developers to test the code before submitting to Gerrit, reviewers are not responsible for the malfunction on codes, only the developer which made the task is responsible for the result once on prod.
# Solve conflict
When developer push a code to Gerrit and is under review while there are others commit waiting or review, the developer is responsable for check the status of his commit on Gerrit and solve the conflict when another of awaiting commit is merged and cause conflict in the one that is waiting. Eg, Developer A push code to Gerrit, Developer B push code to Gerrit. Both are under review. After sometime the commit of the Developer A is approved and merged, and this action cause conflict in Developer B commit...so, the Developer B is responsible to fix the conflict in the awaiting commit and push another Patch Set.
# Commit
Developers MUST to specifcy message in the commit with the scope. The structure is like below:
** scope: verb + description** Example right description:
- avantus: add extra function in logger service.
- commands: add new command for sending notification.
- linkers: fix error in amazon services.
Note that the verb are not ending with ing like adding or fixing
Example wrong description:
- add extra function in logger service. (lack of scope)
- commands: adding new command (scope present but not correct ending for verb)
- some fixes(to general, no scope, and not clear description)
- avantus: add some classes for validating the entries on some classes, that before was not present. (TOO BIG)