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 !
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 :
On a next lesson we will see how to add datas on our tables. But we have to create Magento 2 models before !
Thank you so much for the detailed explaination.!!