Seguici su:

Magento 2 Setup Scripts Database

Magento 2 Script Database

Magento 2 Setup Scripts Database

Magento 2 Script per creare e aggiornare le tabelle del Database

Quando installiamo e abilitiamo un modulo in Magento 2 con il comando php bin/magento module:enable la shell ci indica di eseguire il comando php bin/magento setup:upgrade che aggiorna i moduli, i dati, il database e gli schemi creati all’interno dei moduli. Eseguito questo comando, Magento chiama la classe Magento/Setup/Model/Installer , contenuta in  setup/src/Magento/Setup/Model/Installer.php che esegue una serie di metodi tra cui anche il metodo getSchemaDataHandler($moduleName, $type) . In questo metodo sono dichiarati i tipi dei script di setup che magento mette a disposizione nella creazione di un modulo.

Tutti questi script vanno inseriti all’interno della cartella <VendorName>/<ModuleName>/Setup del modulo che stiamo creando. Dopo aver lanciato il comando setup:upgrade viene creato o aggiornato, in base a se il modulo è nuovo o era stato già installato, una riga nella tabella setup_module nel database di magento. Questa tabella ha tre campi:

  • module che ha come valore il nome dl modulo
  • schema_version che ha la versione dello schema
  • data_version che ha la versione dei dati

In fase di testing possiamo cancellare manualmente la riga del nostro modulo o modificare i valori solo di data_version per far rieseguire solo lo schema dei dati.

Come sempre utilizziamo il modulo base creato precedentemente e che potete scaricare qui

Script InstallSchema

Questo script è usato quando il nostro modulo, deve creare nuove tabelle o aggiungere nuove colonne a tabelle già esistenti. Come detto in precedenza, gli script, vengono eseguito solo quando il modulo è abilitato. Quindi dopo aver abilitato il modulo, verrà inserita una riga nella tabella setup_module, e nel campo schema_version, sarà aggiunta la versione dello script. Questo fa si che se eseguiamo nuovamente il comando setup:upgrade di Magento, non verrà rieseguito lo script. Creiamo il nostro primo script all’interno della cartella Tutorial4Dev/Easy/Setup/InstallSchema.php

<?php

namespace Tutorial4dev\Easy\Setup;

use Magento\Framework\Setup\InstallSchemaInterface;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\SchemaSetupInterface;

class InstallSchema implements InstallSchemaInterface
{
    protected $logger;

    public function __construct(\Psr\Log\LoggerInterface $loggerInterface)
    {
        $this->logger = $loggerInterface;
    }

    public function install(SchemaSetupInterface $setup, ModuleContextInterface $context)
    {
        $this->logger->info('Install Scheme Script Running!');

        $setup->startSetup();

        $table = $setup->getConnection()
            ->newTable($setup->getTable('tutorial4dev_easy_ticket'))
            ->addColumn(
                'entity_id',
                \Magento\Framework\Db\Ddl\Table::TYPE_INTEGER,
                null,
                ['identity' => true, 'unsigned' => true, 'nullable' => false, 'primary' => true],
                'Entity Id'
            )
            ->addColumn(
                'severity_level',
                \Magento\Framework\Db\Ddl\Table::TYPE_INTEGER,
                24,
                ['nullable' => false],
                'Severity Level'
            )
            ->addColumn(
                'note',
                \Magento\Framework\Db\Ddl\Table::TYPE_TEXT,
                null,
                ['nullable' => false],
                'Note'
            )
            ->addColumn(
                'created_at',
                \Magento\Framework\Db\Ddl\Table::TYPE_TEXT,
                null,
                ['nullable' =>false],
                'Created At'
            )
            ->setComment('Tutorial4Dev Easy Ticket Table');

        $setup->getConnection()->createTable($table);

        $setup->endSetup();
    }
}

La classe creata implementa l’interfaccia InstallSchemaInterface e questa ci obbliga ad implementare il metodo install che prende in input due parametri. All’interno di questo metodo utilizziamo l’interfaccia $setupper chiamare i metodi startSetup()e endSetup() e all’interno di queste due chiamate costruiamo la nostra tabella. L’uso di questi due metodi è una pratica comune della maggior parte degli script di installazione. Inoltre questi due metodi si occupano anche di eseguire dei passaggi di configurazione dell’ambiente del database come SQL_MODE o le FOREGIN_KEY_CHECK. Per creare la tabella si utilizza il metodo getConnection() dell’interfaccia $setup che ci restituisce un’istanza adapter. Dall’adaper possiamo usare tutti i metodi che ci occorrono per creare la tabella nel database. I metodi più comuni che possiamo utilizzare nella creazione della tabella in Magento sono:

  • newTable per ricevere un oggetto DDL per la nuova tabella
  • addColumn per aggiungere una colonna
  • addIndex per aggiungere un indice
  • addForeginKey per aggiungere una chiave esterna
  • setComment per settare un commento per la tabella
  • createTable per creare la tabella dall’oggetto DDL restituito da metodo newTable

La tabella appena creata è un modello semplice di Magento. Se avessimo voluto creare un modello EAV di magento, avremmo dovuto usare lo stesso script InstallSchema per creare le seguenti tabelle:

  • ticket_entity
  • ticket_entity_datetime
  • ticket_entity_decimal
  • ticket_entity_int
  • ticket_entity_text
  • ticket_entity_varchar

Per quanto riguarda gli attributi severity_leavel e note, in un modello EAV, gli attributi vanno creati all’interno dello scipt InstallData e UpgradeData.

Script UpgradeSchema

Lo script UpgradeSchema è usato quando dobbiamo creare delle nuove tabelle oppure modificare quelle già esistenti aggiungendo, per esempio, delle colonne. Principalmente si usa quando aggiorniamo un modulo e modifichiamo lo schema del database, quindi possiamo anche controllare, tramite il codice, la versione.

<?php
namespace Tutorial4dev\Easy\Setup;

use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\SchemaSetupInterface;
use Magento\Framework\Setup\UpgradeSchemaInterface;

class UpgradeSchema implements UpgradeSchemaInterface
{
    protected $logger;

    public function __construct(\Psr\Log\LoggerInterface $loggerInterface)
    {
        $this->logger = $loggerInterface;
    }

    public function upgrade(SchemaSetupInterface $setup, ModuleContextInterface $context)
    {
        $this->logger->info('Upgrade Schema Script Running!');

        $setup->startSetup();
        if (version_compare($context->getVersion(), '1.0.1', '<')) {
            $this->upgradeToVersionOneZeroOne($setup);
        }
        $setup->endSetup();
    }

    private function upgradeToVersionOneZeroOne(SchemaSetupInterface $setup)
    {
        $setup->getConnection()
            ->addColumn(
                $setup->getTable('tutorial4dev_easy_ticket'),
                'name',
                [
                    'type' => \Magento\Framework\Db\Ddl\Table::TYPE_TEXT,
                    'length'=> null,
                    'nullable' => false,
                    'comment' => 'Name',
                    'after' => 'entity_id'
                ]
            );
    }
}

In questo semplice esempio aggiungiamo un campo name alla tabella creata con lo script precedente. Eseguiamo un controllo di versione e se la versione precedente (1.0.0) è inferiore alla nuova versione (1.0.1) allora lo script verrà eseguito. La versione corrente è quella che si trova nella tabella setup_module. Al rilascio di una nuova versione del modulo, cambieremo il numero di versione nel file module.xml  in una versione superiore e lo script di update sarà lanciato correttamente aggiungendo il nuovo campo. Quando usiamo lo script UpgradeSchema ci possono servire alcuni metodi come:

  • dropColumn che cancella una colonna
  • dropForeginKey che cancella una chiave esterna
  • dropIndex che cancella un indice dalla tabella
  • dropTable che cancella una tabella
  • modifyColum che modifica la definizione di una colonna

Script Recurring

Questo script che come dice la parola è ricorrente, viene eseguito ogni volta che si esegue il comando setup:upgrade indipendentemente dal numero di versione registrata nella tabella setup_module

<?php
namespace Tutorial4dev\Easy\Setup;

use Magento\Framework\Setup\InstallSchemaInterface;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\SchemaSetupInterface;

class Recurring implements InstallSchemaInterface
{
    public function install(SchemaSetupInterface $setup, ModuleContextInterface $context)
    {
        $setup->startSetup();
        echo 'Recurring->install()' . PHP_EOL;
        $setup->endSetup();
    }
}

Questi script sono usati raramente in magento, principalmente per l’uso di chiavi esterne oppure quando si creano dei moduli multipli. Per esempio potremo creare Modulo 1 e Modulo 2 e usare uno script ricorrente in Modulo 1 dopo che Modulo 2 è stato installato.

Script InstallData

Questo script viene utilizzato quando si vogliono aggiungere dati a tabelle esistenti. Una volta abilitato il modulo verrà scritto un campo nella tabella setup_module, precisamente nella colonna data_version. Questo impedirà ad ogni esecuzione del comando setup:upgrade di eseguire lo script InstallData. Vediamo un esempio di come può essere utilizzato questo script. Creiamo un semplice attributo per un customer utilizzando una select che ci permette di scegliere un valore Yes/No

<?php

namespace Tutorial4dev\Easy\Setup;

use Magento\Customer\Setup\CustomerSetupFactory;
use Magento\Framework\Setup\InstallDataInterface;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\ModuleDataSetupInterface;

class InstallData implements InstallDataInterface
{
    const CUSTOMER_VIP = 'customer_vip';

    protected $customerSetupFactory;
    protected $logger;

    public function __construct(CustomerSetupFactory $customerSetupFactory, \Psr\Log\LoggerInterface $loggerInterface)
    {
        $this->customerSetupFactory = $customerSetupFactory;
        $this->logger = $loggerInterface;
    }

    public function install(ModuleDataSetupInterface $setup, ModuleContextInterface $context)
    {

        $this->logger->info('Install Data Script Running!');

        $setup->startSetup();

        $customerSetup = $this->customerSetupFactory->create(['setup' => $setup]);

        $customerSetup->addAttribute(\Magento\Customer\Model\Customer::ENTITY, self::CUSTOMER_VIP, [
            'type' => 'int',
            'label' => 'Customer Vip',
            'input' => 'select',
            'source' => \Magento\Eav\Model\Entity\Attribute\Source\Boolean::class,
            'default' => \Magento\Eav\Model\Entity\Attribute\Source\Boolean::VALUE_NO,
            'required' => false,
            'sort_order' => 1,
            'position' => 200,
            'system' => false,
            'visible' => true,
            'global' =>\Magento\Catalog\Model\ResourceModel\Eav\Attribute::SCOPE_GLOBAL,
            'is_used_in_grid' => true,
            'is_visible_in_grid' => false,
            'is_filterable_in_grid' => false,
            'is_searchable_in_grid' => false,
            'filterable' => false,
            'comparable' => false,
            'searchable' => true,

        ]);

        $customerVipAttr = $customerSetup
            ->getEavConfig()
            ->getAttribute(
                \Magento\Customer\Model\Customer::ENTITY,
                self:: CUSTOMER_VIP
            );

        $forms = [
            'adminhtml_customer',
            'checkout_register',
            'customer_account_create',
            'customer_account_edit',
            'adminhtml_checkout'
        ];

        $customerVipAttr->setData('used_in_forms', $forms);

        $customerVipAttr->save($customerVipAttr);

        $setup->endSetup();
    }
}

Questo semplice esempio crea un nuovo campo Customer Vip in customer, infatti dopo aver eseguito il comando setup:upgrade, indexer:reindex e cancellato la cache con il comando cache:flush possiamo vedere il nuovo campo all’interno dell’admin in Customers->All Customers. Se aggiungiamo un utente o ne selezioniamo uno già presente noteremo il campo Customer Vip. In questo caso usiamo una select per avere un campo Yes/No, che nel database viene inserito come un intero. Tutti le altre configurazioni le vedremo in seguito; le tabelle che vengono modificate utilizzando lo script InstallData sono, in questo caso, la tabella setup_module che modifica la riga aggiornando la versione nel campo data_version, aggiunge una riga nella tabella eav_attribute che rappresenta l’attributo appena creato e infine se aggiungiamo un utente o salviamo uno già esistente, il sistema aggiunge una riga nella tabella customer_entity_id.  All’interno di questa tabella, la riga, tiene traccia dell’indice dell’attributo appena creato, l’indice dell’utente a cui è stato associato il valore e il valore assegnato all’utente (Yes=1/No=1). In seguito vedremo in dettaglio come creare attributi per prodotti, customer, ordini etc..

Script UpgradeData

UpgradeData è utile quando vogliamo aggiornare i dati all’interno della tabella, come vedremo in seguito. Ora creiamo un semplice campo  all’interno della tabella sales_order. Sarebbe stato possibile anche crearlo con lo script InstallSchema, ma per questo esempio useremo UpgradeData.

<?php

namespace Tutorial4dev\Easy\Setup;

use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\ModuleDataSetupInterface;
use Magento\Framework\Setup\UpgradeDataInterface;
use Magento\Sales\Setup\SalesSetupFactory;

class UpgradeData implements UpgradeDataInterface
{
    protected $logger;
    protected $salesSetupFactory;

    public function __construct(
        SalesSetupFactory $salesSetupFactory,
        \Psr\Log\LoggerInterface $loggerInterface
    ) {
        $this->salesSetupFactory = $salesSetupFactory;
        $this->logger = $loggerInterface;
    }

    public function upgrade(ModuleDataSetupInterface $setup, ModuleContextInterface $context)
    {
        $this->logger->info('Upgrade Data Script Running!');
        $setup->startSetup();

        if (version_compare($context->getVersion(), '1.0.1', '<')) {
            $this->upgradeToVersionOneZeroOne($setup);
        }

        $setup->endSetup();
    }

    private function upgradeToVersionOneZeroOne(ModuleDataSetupInterface $setup)
    {
        $salesSetup = $this->salesSetupFactory->create(['setup' => $setup]);
        $salesSetup->addAttribute('order', 'customer_note', [
            'type' => \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
            'visible' => false,
            'required' => false
        ]);

    }
}

Come UpgradeSchema, utilizziamo una factory che ci permette permette di creare un oggetto SalesSetup tramite il la funzione create(). In questo caso la tabella e l’entity ordine è un po un mix: infatti anche se è registrata come tipo EAV, in realtà non usa la tabella eav_attribute_* ma usa la singola tabella sales_order per memorizzare i suoi attributi. (Avremmo potuto aggiungere la colonna nello script Install o Update ed usare la funzione addColum() per aggiungere la colonna). Quando viene eseguito lo script verrà creato il capo customer_note all’interno della tabella sales_order.

Script Recurring Data

Anche questo tipo di script, come lo script Recurring, viene utilizzato raramente in Magento. Anche questo viene eseguito ogni qual volta che si esegue il comando setup:upgrade indipendentemente dalla versione registrata nella tabella setup_module. Ecco un semplice esempio, che non fa nulla, di uno script RecurringData

<?php

namespace Tutorial4dev\Easy\Setup;

use Magento\Framework\Setup\InstallDataInterface;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\ModuleDataSetupInterface;

class RecurringData implements InstallDataInterface
{
    public function install(ModuleDataSetupInterface $setup, ModuleContextInterface $context)
    {
        $setup->startSetup();
        echo 'RecurringData->install()' . PHP_EOL;
        $setup->endSetup();
    }
}

Uninstall Script

Questo script serve per fare una pulizia nel database quando rimuoviamo un modulo installato in precedenza. Purtroppo, viene eseguito solo utilizzando composer e quindi non possiamo provarlo per ora. Vedremo poi come distribuire il proprio modulo tramite composer e vedremo anche come disinstallare un modulo

<?php
namespace Tutorial4dev\Easy\Setup;

use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\SchemaSetupInterface;
use Magento\Framework\Setup\UninstallInterface;

class Uninstall implements UninstallInterface
{
    public function uninstall(SchemaSetupInterface $setup, ModuleContextInterface $context)
    {
        $setup->startSetup();
        echo 'Uninstall->uninstall()' . PHP_EOL;
        $setup->endSetup();
    }
}

Questo esempio con tutti gli script è disponibile sul GitHub a questo indirizzo

[poet-badge]

Pasquale Guarino

pasquale.guarino80@gmail.com

WP2Social Auto Publish Powered By : XYZScripts.com