Magento 2 Training : Unit 3 – Lesson A

Module presentation

To begin this part of the formation, we will create a new module. It will be a job offer module with 2 models :
– A department : this is the department of the society
– A job : this is the job offer, linked to a department.

Here is the tables’ schemas

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

Let’s create our tables with Magento 2 setups !

Module declaration

Like dthe previous module, you can create this XML file :
app/code/Maxime/Jobs/etc/module.xml

With the content :

<?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>

In this file, the setup_version is very important.

Create the file :
app/code/Maxime/Jobs/registration.php

With the content :

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

Don’t launch the upgrade Magento command line, we must create a setup before !

Installation setup creation

Add the following file :
app/code/Maxime/Jobs/Setup/InstallSchema.php

The first table we will create is the “Department” table, I give you the content of the file, and I will explain it after.

<?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();
    }

}

Firstly I declare the elements I need to create my table :
– A name : $tableName
– A table comment : $tableComment
– Table columns with their type, their size, some options and a comment
– Some indexes if I need (we will see that on the next part of the lesson) : $indexes
– Some foreign keys if I nedd (we will see that on the next part of the lesson) : $foreignKeys

Let’s see available columns options :
– identity : we can declare an auto_increment column
– unsigned : we work with an unsigned number
– nullable : when it false, it add “NOT NULL” SQL to the column
– primary : we can declare our primary key
– default : we can declare a default value for our column

Secondly, I loop on each parameters to use the correct Magento 2 methods and setup all things we need. You can look more precisly the code if you want to analyze it’s behaviour 😉

Now, we can launch the upgrade. So you can go on your Magento root folder and launch :

./bin/magento setup:upgrade

You will see lines like :

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

Our table is created on database !

schema_table_department

You can see the “name” field has the VARCHAR type, whereas “description” has the TEXT type.
On the setup, we declared the same type : “Table::TYPE_TEXT”
Magento will choose one of both according to the field size.

Upgrade Setup Creation

I decided to split the creation of the to tables in order to explain how to create an upgrade setup.

You can create the file :

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

With the content :

<?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();
    }
}

The file has a lot of content identical to the previous file. But in an upgrade setup, we have to compare the old module version with the new module version :

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

The getVersion method give us the current module version. For us, it’s 0.1.0.0.

version_compare return -1 if current version is less than new version
version_compare retourne 0 if current version is equal new version
version_compare retourne 1 if current version is greater than new version

For each module upgrades, you have to put this condition on this file, like this :

<?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();
    }
}

I don’t put elseif condition, nor a switch because if someone download the module from github for example, the upgrade must do all the if conditions.
So you must put these conditions from the older to the newest in order to avoid errors during the upgrade process.

So you can go on the file :
app/code/Maxime/Jobs/etc/module.xml
And modify the setup_version attribute to 1.0.0.0

Launch the upgrade command :

./bin/magento setup:upgrade

You will see lines like these during the upgrade :

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

On database we have our table :

schema_table_job

On a next lesson we will see how to add datas on our tables. But we have to create Magento 2 models before !

Continue training
Return to previous lesson
Setup management on Magento 2
Tagged on:         

One thought on “Setup management on Magento 2

  • 03/06/2018 at 14:34
    Permalink

    Thank you so much for the detailed explaination.!!

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *

We use cookies to ensure that we give you the best experience on our website.
Ok