Formation Magento 2 : Chapitre 3 – Partie A

Présentation du module

Nous allons créer un nouveau module pour cette partie. Le but sera de créer un module d’offres d’emploi qui se compose de deux modèles :
– Un Department : Qui correspond à un pôle d’une entreprise (ex : Pôle marketing, Pôle Ressources Humaines etc…)
– Un Job : Qui correspond à l’offre d’emploi (ex : Directeur Technique, Chef de projet fonctionnel etc…)

Comme vous pouvez vous en douter, un job sera relié à un département, voici le schéma de nos tables :

Table ‘maxime_department’
entity_id int(10) unsigned Auto increment Department Id
name varchar(255) [] Department name
description text Department description

Table ‘maxime_job’
entity_id int(10) unsigned Auto increment Job Id
title varchar(255) [] Job Title
type varchar(255) [] Job Type (CDI, CDD...)
location varchar(255) [] Job Location
date date Job date begin
status tinyint(1) [0] Job status
description text Job description
department_id int(10) unsigned Department linked to the job

Nous allons donc créer ces tables et pas n’importe comment, grâce à un setup Magento !

Declaration du module

Comme pour le module précédent, nous allons créer un fichier XML :
app/code/Maxime/Jobs/etc/module.xml

Qui aura le contenu suivant :

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
    <module name="Maxime_Jobs" setup_version="0.1.0.0" />
</config>

Notez que le numéro de version va avoir son importance ici.

Créez également le fichier :
app/code/Maxime/Jobs/registration.php

Qui contiendra :

<?php
\Magento\Framework\Component\ComponentRegistrar::register(
    \Magento\Framework\Component\ComponentRegistrar::MODULE,
    'Maxime_Jobs',
    __DIR__
);

Ne lancez pas de suite la commande upgrade, nous allons déclarer un setup avant !

Creation du Setup d’installation

Créez le fichier suivant :
app/code/Maxime/Jobs/Setup/InstallSchema.php

Nous allons créer notre première table, la table des départements, que l’on appellera ici Department.
Voici le code que nous allons mettre, je le detaillerai juste après.

<?php namespace Maxime\Jobs\Setup;

use Magento\Framework\Setup\InstallSchemaInterface;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\SchemaSetupInterface;
use Magento\Framework\DB\Ddl\Table;

class InstallSchema implements InstallSchemaInterface
{
    /**
     * Installs DB schema for a module
     *
     * @param SchemaSetupInterface $setup
     * @param ModuleContextInterface $context
     * @return void
     */
    public function install(SchemaSetupInterface $setup, ModuleContextInterface $context)
    {
        $installer = $setup;
        $installer->startSetup();

        /**
         * Create table 'maxime_department'
         */

        $tableName = $installer->getTable('maxime_department');
        $tableComment = 'Department management for jobs module';
        $columns = array(
            'entity_id' => array(
                'type' => Table::TYPE_INTEGER,
                'size' => null,
                'options' => array('identity' => true, 'unsigned' => true, 'nullable' => false, 'primary' => true),
                'comment' => 'Department Id',
            ),
            'name' => array(
                'type' => Table::TYPE_TEXT,
                'size' => 255,
                'options' => array('nullable' => false, 'default' => ''),
                'comment' => 'Department name',
            ),
            'description' => array(
                'type' => Table::TYPE_TEXT,
                'size' => 2048,
                'options' => array('nullable' => false, 'default' => ''),
                'comment' => 'Department description',
            ),
        );

        $indexes =  array(
            // No index for this table
        );

        $foreignKeys = array(
            // No foreign keys for this table
        );

        /**
         *  We can use the parameters above to create our table
         */

        // Table creation
        $table = $installer->getConnection()->newTable($tableName);

        // Columns creation
        foreach($columns AS $name => $values){
            $table->addColumn(
                $name,
                $values['type'],
                $values['size'],
                $values['options'],
                $values['comment']
            );
        }

        // Indexes creation
        foreach($indexes AS $index){
            $table->addIndex(
                $installer->getIdxName($tableName, array($index)),
                array($index)
            );
        }

        // Foreign keys creation
        foreach($foreignKeys AS $column => $foreignKey){
            $table->addForeignKey(
                $installer->getFkName($tableName, $column, $foreignKey['ref_table'], $foreignKey['ref_column']),
                $column,
                $foreignKey['ref_table'],
                $foreignKey['ref_column'],
                $foreignKey['on_delete']
            );
        }

        // Table comment
        $table->setComment($tableComment);

        // Execute SQL to create the table
        $installer->getConnection()->createTable($table);

        // End Setup
        $installer->endSetup();
    }

}

Dans un premier temps je déclare ce dont j’aurai besoin pour ma table :
– Un nom : $tableName
– Un commentaire pour la table : $tableComment
– Les colonnes de ma table avec leur type, leur taille si nécessaire, certaines options, et un commentaire
– Des index si nécessaire (nous verrons celà par la suite) : $indexes
– Des clés étrangères si nécessaire (nous verrons celà par la suite) : $foreignKeys

Penchons nous quelques instants sur les options de colonnes :
– identity : permet de signaler que notre colonne sera en auto_increment
– unsigned : nous travaillons avec un entier non signé, cela nous permet d’utiliser les bytes réservés normalement à des valeurs négatives, pour des valeurs positives. Cela permet d’augmenter la valeur maximale de notre champ
– nullable : mis à false, cela permet d’ajouter l’action NOT NULL dans notre SQL
– primary : permet de signaler que notre colonne sera la clé primaire de notre table
– default : permet de choisir une valeur par défaut pour notre colonne

Dans un deuxième temps, je boucle sur mes paramètres définis précédemment et utilise les méthodes Magento pour mettre en place tout ce dont nous avons besoin. Je vous laisse regarder par vous même si vous le souhaitez le comportement et les méthodes utilisées 😉

Nous pouvons maintenant lancer l’upgrade en se mettant à la racine de notre Magento et regarder ce qu’il se passe.

./bin/magento setup:upgrade

Dans les lignes qui s’affichent, vous devriez avoir :

Schema creation/updates:
Module 'Maxime_Jobs':
Installing schema..

Et en BDD notre table est bien présente.

schema_table_department

Notez que le champ « name » est en VARCHAR alors que le champ « description » est en « TEXT ».
Pourtant dans le Setup, nous avons renseigné pour ces deux champs le type « Table::TYPE_TEXT »
C’est Magento qui choisit en fonction de la taille que nous définissons.

Creation du Setup d’upgrade

J’ai séparé la création des tables dans 2 setups afin de voir avec vous comment créer un setup d’upgrade.
Sachez que nous aurions pu faire la création de nos deux tables dans le fichier précédent.

Vous pouvez créer le fichier suivant :

app/code/Maxime/Jobs/Setup/UpgradeSchema.php

Avec ce contenu :

<?php namespace Maxime\Jobs\Setup;

use Magento\Framework\Setup\UpgradeSchemaInterface;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\SchemaSetupInterface;
use Magento\Framework\DB\Ddl\Table;

class UpgradeSchema implements UpgradeSchemaInterface
{
    /**
     * Upgrades DB schema for a module
     *
     * @param SchemaSetupInterface $setup
     * @param ModuleContextInterface $context
     * @return void
     */
    public function upgrade(SchemaSetupInterface $setup, ModuleContextInterface $context)
    {
        $installer = $setup;
        $installer->startSetup();

        // Action to do if module version is less than 1.0.0.0
        if (version_compare($context->getVersion(), '1.0.0.0') < 0) {

            /**
             * Create table 'maxime_jobs'
             */

            $tableName = $installer->getTable('maxime_job');
            $tableComment = 'Job management on Magento 2';
            $columns = array(
                'entity_id' => array(
                    'type' => Table::TYPE_INTEGER,
                    'size' => null,
                    'options' => array('identity' => true, 'unsigned' => true, 'nullable' => false, 'primary' => true),
                    'comment' => 'Job Id',
                ),
                'title' => array(
                    'type' => Table::TYPE_TEXT,
                    'size' => 255,
                    'options' => array('nullable' => false, 'default' => ''),
                    'comment' => 'Job Title',
                ),
                'type' => array(
                    'type' => Table::TYPE_TEXT,
                    'size' => 255,
                    'options' => array('nullable' => false, 'default' => ''),
                    'comment' => 'Job Type (CDI, CDD...)',
                ),
                'location' => array(
                    'type' => Table::TYPE_TEXT,
                    'size' => 255,
                    'options' => array('nullable' => false, 'default' => ''),
                    'comment' => 'Job Location',
                ),
                'date' => array(
                    'type' => Table::TYPE_DATE,
                    'size' => null,
                    'options' => array('nullable' => false),
                    'comment' => 'Job date begin',
                ),
                'status' => array(
                    'type' => Table::TYPE_BOOLEAN,
                    'size' => null,
                    'options' => array('nullable' => false, 'default' => 0),
                    'comment' => 'Job status',
                ),
                'description' => array(
                    'type' => Table::TYPE_TEXT,
                    'size' => 2048,
                    'options' => array('nullable' => false, 'default' => ''),
                    'comment' => 'Job description',
                ),
                'department_id' => array(
                    'type' => Table::TYPE_INTEGER,
                    'size' => null,
                    'options' => array('unsigned' => true, 'nullable' => false),
                    'comment' => 'Department linked to the job',
                ),
            );

            $indexes =  array(
                'title',
            );

            $foreignKeys = array(
                'department_id' => array(
                    'ref_table' => 'maxime_department',
                    'ref_column' => 'entity_id',
                    'on_delete' => Table::ACTION_CASCADE,
                )
            );

            /**
             *  We can use the parameters above to create our table
             */

            // Table creation
            $table = $installer->getConnection()->newTable($tableName);

            // Columns creation
            foreach($columns AS $name => $values){
                $table->addColumn(
                    $name,
                    $values['type'],
                    $values['size'],
                    $values['options'],
                    $values['comment']
                );
            }

            // Indexes creation
            foreach($indexes AS $index){
                $table->addIndex(
                    $installer->getIdxName($tableName, array($index)),
                    array($index)
                );
            }

            // Foreign keys creation
            foreach($foreignKeys AS $column => $foreignKey){
                $table->addForeignKey(
                    $installer->getFkName($tableName, $column, $foreignKey['ref_table'], $foreignKey['ref_column']),
                    $column,
                    $foreignKey['ref_table'],
                    $foreignKey['ref_column'],
                    $foreignKey['on_delete']
                );
            }

            // Table comment
            $table->setComment($tableComment);

            // Execute SQL to create the table
            $installer->getConnection()->createTable($table);
        }

        $installer->endSetup();
    }
}

Ce fichier ressemble beaucoup au précédent, mais je souhaite voir avec vous une notion particulière sur les versions de votre module.
Si nous regardons cette ligne :

if (version_compare($context->getVersion(), '1.0.0.0') < 0)

Nous remarquons l’utilisation de la méthode getVersion, qui permet de retourner la version actuelle de votre module.
Pour nous c’est la 0.1.0.0 .
version_compare retourne -1 si la version actuelle est inférieure à la version voulue
version_compare retourne 0 si la version actuelle est égale à la version voulue
version_compare retourne 1 si la version actuelle est supérieure à la version voulue

Chaque fois que vous allez upgrader un module, il faudra mettre cette condition dans ce même fichier.
Avec plusieurs update notre classe ressemblera donc à quelque chose de la sorte :

<?php namespace Maxime\Jobs\Setup;

use Magento\Framework\Setup\UpgradeSchemaInterface;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\SchemaSetupInterface;
use Magento\Framework\DB\Ddl\Table;

class UpgradeSchema implements UpgradeSchemaInterface
{
    /**
     * Upgrades DB schema for a module
     *
     * @param SchemaSetupInterface $setup
     * @param ModuleContextInterface $context
     * @return void
     */
    public function upgrade(SchemaSetupInterface $setup, ModuleContextInterface $context)
    {
        $installer = $setup;
        $installer->startSetup();

        if (version_compare($context->getVersion(), '1.0.0.0') < 0) {
            // Action to do if module version is less than 1.0.0.0
        }

        if (version_compare($context->getVersion(), '1.0.0.1') < 0) {
            // Action to do if module version is less than 1.0.0.1
        }

        if (version_compare($context->getVersion(), '1.1.0.0') < 0) {
            // Action to do if module version is less than 1.1.0.0
        }

        if (version_compare($context->getVersion(), '1.1.0.1') < 0) {
            // Action to do if module version is less than 1.1.0.1
        }

        if (version_compare($context->getVersion(), '2.0.0.0') < 0) {
            // Action to do if module version is less than 2.0.0.0
        }

        $installer->endSetup();
    }
}

Pas de elseif ni de switch car si nous ajoutons le module depuis github ou autre, il faut que l’upgrade passe dans toutes les conditions les une à la suite des autres
Et il faut les mettre de la version la plus ancienne à la plus récente pour ne pas avoir d’erreur et que les actions s’exécutent dans l’ordre.

Nous pouvons maintenant aller dans notre fichier app/code/Maxime/Jobs/etc/module.xml et passer l’attribut setup_version à 1.0.0.0

Et lancer la commande habituelle :

./bin/magento setup:upgrade

Vous devriez aperçevoir ce texte durant l’upgrade :

Schema creation/updates:
Module 'Maxime_Jobs':
Upgrading schema..

Et en BDD :

schema_table_job

Nous verrons prochainement comment ajouter des données à cette table automatiquement. Mais avant nous devons créer nos modèles.

Continuer la formation
Revenir à la partie précédente
Gestion des setups sous Magento 2
Taggé sur :            

2 thoughts on “Gestion des setups sous Magento 2

  • 03/02/2017 à 18:02
    Permalink

    Bonjour, j’ai testé la création de la table jobs via l’update de notre module, mais cela ne fonctionne pas, le module ne se met pas à jour… Je ne sais pas si c’est le test de la version qui ne passe pas bien
    (j’ai essayé la variante version_compare($context->getVersion(), ‘1.0.0’.0, ‘<') mais c'est sans effet) ou si c'est autre chose..
    Quelqu'un aurait-il des idées pour résoudre le problème ?^^

    Répondre
  • 03/05/2018 à 13:28
    Permalink

    Salut .

    Je te confirme que j’ai eu le même problème lors de la création. peut être parce que j’avais inititialisé le module avant ??

    J’ai réglé le problème en supprimant de la base de donnée la ligne du module :
    DELETE FROM `setup_module` WHERE `setup_module`.`module` = \’Maxime_Jobs\’;

    Chez moi ca a réglé le pb !

    Répondre

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Nous utilisons des cookies afin de nous assurer de vous proposer la meilleure expérience sur ce site.
Ok