Skip to content

Instantly share code, notes, and snippets.

@lucafregoso
Last active July 2, 2021 10:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lucafregoso/07cf78490c1ede79badf7172499a25ec to your computer and use it in GitHub Desktop.
Save lucafregoso/07cf78490c1ede79badf7172499a25ec to your computer and use it in GitHub Desktop.

Info:

  • area può essere frontend o adminhtml
  • router può essere standard o admin

Creazione modulo

  • creare cartella app/code/Vendor/Module

  • composer init

    {
        "name": "**vendor**/**module**",
        "description": "",
        "type": "magento2-module",
        "license": "proprietary",
        "authors": [{
            "email": "email@domain.test",
            "name": "Author Name"
        }],
        "minimum-stability": "dev",
        "require": {},
        "autoload": {
            "psr-4": {
                "**Vendor**\\**Module**\\": ""
            },
            "files": [
                "registration.php"
            ]
        }
    }
  • registrazione modulo

    registration.php

    \Magento\Framework\Component\ComponentRegistrar::register(
        \Magento\Framework\Component\ComponentRegistrar::**MODULE**,
        '**Vendor**_**Module**',
        __DIR__
    );

    etc/module.xml

    <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
        <module name="**Vendor**_**Module**" setup_version="0.0.1" />
    </config>
  • impostazione routes

    etc/area/routes.xml

    <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd">
        <router id="**router**">
            <route id="**route**" frontName="**route**">
                <module name="**Vendor**_**Module**" />
            </route>
        </router>
    </config>
  • controller

    namespace Vendor\Module\Controller\Index;
    
    use Magento\Framework\App\Action\Context;
    use Magento\Framework\View\Result\PageFactory;
    
    class Index extends \Magento\Framework\App\Action\Action
    {
        /**
        * @param Context $context
        * @param PageFactory $resultPageFactory
        */
        public function __construct(
            Context $context,
            PageFactory $resultPageFactory
        )
        {
            parent::__construct($context);
            $this->resultPageFactory = $resultPageFactory;
        }
    
        public function execute()
        {
            $resultPageFactory = $this->resultPageFactory->create();
    
            // Add page title
            $resultPageFactory->getConfig()->getTitle()->set(__('Example module'));
    
            // Add breadcrumb
            /** @var \Magento\Theme\Block\Html\Breadcrumbs */
            $breadcrumbs = $resultPageFactory->getLayout()->getBlock('breadcrumbs');
            $breadcrumbs->addCrumb('home',
                [
                    'label' => __('Home'),
                    'title' => __('Home'),
                    'link' => $this->_url->getUrl('')
                ]
            );
            $breadcrumbs->addCrumb('tutorial_example',
                [
                    'label' => __('Example'),
                    'title' => __('Example')
                ]
            );
    
            return $resultPageFactory;
        }
    }

    per admin il controller estende \Magento\Backend\App\Action ed utilizza il context di \Magento\Backend\App\Action\Context

  • layout

    <?xml version="1.0"?>
    <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
        <body>
            <referenceContainer name="content">
                <!-- SE HO BISOGNO DI BLOCK -->
                <block template="**templatename**.phtml" class="**Vendor**\**Module**\Block\**Area**\**BlockName**" name="vendor_module_block_**blockname**" />
                <!-- SE HO BISOGNO DI UI COMPONENT -->
                <uiComponent name="**ui_component_path**"/>
            </referenceContainer>
        </body>
    </page>
  • template

    view/area/templates/templatename.phtml

    <h1><?php echo __('This is an example module!') ?></h1>

Modelli

Ci sono due tipologie di modelli in Magento: simple e EAV (Entity Attribute Value) entrambe estendono Magento\Framework\Model\AbstractModel ma:

  • simple
    • la sua Resource estende Magento\Framework\Model\ResourceModel\Db\AbstractDb
    • la collection estende Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection
  • EAV
    • la sua Resource estende Magento\Eav\Model\Entity\VersionControl\AbstractEntity
    • la collection estende Magento\Eav\Model\Entity\Collection\VersionControl\AbstractCollection

la Resource è il vero collegamento al DB; nel caso dei modelli semplici i dati vengono salvati nella tabella di riferimento mentre per modelli EAV vengono utilizzate diverse tabelle eav_* (es. eav_attribute, eav_attribute_group, eav_attribute_label, eav_attribute_option, eav_attribute_option_swatch, eav_attribute_option_value, eav_attribute_set). I modelli EAV che usano effettivamente la logica di suddivisione dei dati sono visibili tramite query DB SELECT DISTINCT entity_type_id FROM eav_attribute; solitamente si utilizzano modelli semplici.

Model Model/ModelName.php

class **ModelName** extends \Magento\Framework\Model\AbstractModel {
    protected $_eventPrefix = 'vendor_module_event_prefix';
    protected $_eventObject = '**model_name**';

    protected function _construct() {
        $this->_init(\**Vendor**\**Module**\Model\ResourceModel\**ModelName**::class);
    }
}

L'uso di $_eventPrefix e $_eventObject non è obbligatorio, ma è altamente raccomandato. Questi valori sono usati dal dispatcher di eventi Magento\Framework\Model\AbstractModel e si aggiungono alla futura estensibilità del nostro modulo. Mentre Magento usa la convenzione <Module>_<ModelName> per la denominazione $_eventPrefix, potremmo essere più sicuri usando <Vendor>_<Module>_<ModelName>. $_eventObject, per convenzione, di solito porta il nome del modello stesso.

Resource

class **ModelName**  extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb {
    protected function _construct() {
        $this->_init('**model_table**', '**model_pk**');
    }
}

Il metodo _init accetta due argomenti: la tabella di riferimento e la colonna contenente la chiave primaria nel db.

Collection

class Collection extends \Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection {
    protected function _construct() {
        $this->_init(
            \**Vendor**\**Module**\Model\**ModelName**::class, 
            \**Vendor**\**Module**\Model\ResourceModel\**ModelName**::class
        );
    }
}

Il metodo _init della collection riceve due argomenti: i nomi di classe di modello e resource.

Metodi che vale la pena memorizzare

Sia EAV che i modelli semplici si estendono dalla classe Magento\Framework\Model\AbstractModel, che si estende ulteriormente da Magento\Framework\DataObject.

Il DataObject ha alcuni metodi che vale la pena memorizzare:

  • toArray: converte un array di dati oggetto in un array con chiavi richieste nell'array $keys
  • toXml: converte i dati dell'oggetto in una stringa XML
  • toJson: converte i dati dell'oggetto in JSON
  • toString: converte i dati dell'oggetto in una stringa con un formato predefinito
  • serialize: converte i dati dell'oggetto in una stringa con chiavi e valori definiti

Grazie all'utilizzo di __call, è possibile utilizzare la seguente sintassi per accedere agli attributi:

  • get<AttributeName>
  • set<AttributeName>
  • uns<AttributeName>
  • has<AttributeName>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment