- area può essere frontend o adminhtml
- router può essere standard o admin
-
creare cartella app/code/Vendor/Module
-
composer init
{ "name": "**vendor**/**module**", "description": "", "type": "magento2-module", "license": "proprietary", "authors": [{ "email": "[email protected]", "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>
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.
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>