26 декабря 2016 в 05:34

Разработка → Пошаговая разработка модуля для Magento 2

PHP*

Вступление


Здравствуйте друзья и коллеги, не так давно вышла вторая версия мадженты и вопросов стало ещё больше — «Что?»,«Как?» и главное «Куда» собственно чему и будет посвящён данный пост. Я расскажу и покажу разработку модуля на magento 2 поэтапно.

Немного главных различий с первой веткой:


  • Magento стала фреймворком \Magento\Framework\
  • На место Mage::app() пришёл objectManager
  • Файлы модуля теперь находятся в одной директории
  • composer.json

Ближе к делу


И так, давайте приступим непосредственно к созданию нашего модуля. Первым делом необходимо создать директорию модуля, теперь она находится непосредственно в app/code без использования codepool (core/local/community) app/code/Vendor/Module/

Инициализация модуля в системе
app/code/Vendor/Module/registration.php
<?php
/**
 * @author Slava Yurthev
 */
\Magento\Framework\Component\ComponentRegistrar::register(
	\Magento\Framework\Component\ComponentRegistrar::MODULE,
	'Vendor_Module',
	__DIR__
);
?>

Регистрируем в системе текущую директорию в качестве Vendor_Module компонента после чего он появится в списке модулей в админ панели.

app/code/Vendor/Module/etc/module.xml
<?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="Vendor_Module" setup_version="0.0.1"></module>
</config>

Устанавливаем настройки нашего компонента

app/code/Vendor/Module/composer.json
{
    "name": "vendor/module",
    "description": "summary",
    "license": [
        "OSL-3.0"
    ],
    "type": "magento2-module",
    "version": "0.0.2",
    "authors": [
        {
            "name": "Slava Yurthev",
            "email": "support@slavayurthev.com",
            "homepage": "https://github.com/SlavaYurthev/",
            "role": "Developer"
        }
    ],
    "autoload": {
        "files": [ "registration.php" ],
        "psr-4": {
            "Vendor\\Module\\": ""
        }
    }
}



Инициализация в базе данных
Создадим `example_table` с 2 параметрами `id` и `text`
app/code/Vendor/Module/Setup/InstallSchema.php
<?php
/**
 * @author Slava Yurthev
 */
namespace Vendor\Module\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{
	public function install(SchemaSetupInterface $setup, ModuleContextInterface $context) {
		$installer = $setup;
		$installer->startSetup();
		$tableName = $installer->getTable('example_table');
		if ($installer->getConnection()->isTableExists($tableName) != true) {
			$table = $installer->getConnection()
				->newTable($tableName)
				->addColumn('id', Table::TYPE_INTEGER, null, [
						'identity' => true,
						'unsigned' => true,
						'nullable' => false,
						'primary' => true
					], 'ID')
				->addColumn('text', Table::TYPE_TEXT, null, [
						'length' => 255,
						'nullable' => false
					], 'TEXT')
				->setComment('Example Table');
			$installer->getConnection()->createTable($table);
		}
		$installer->endSetup();
	}
}
?>

InstallSchema.php будет запущен при установке модуля и будет инициализирован install method

Создаём модель
app/code/Vendor/Module/Model/Example.php
<?php
/**
 * @author Slava Yurthev
 */
namespace Vendor\Module\Model;
use Magento\Framework\Model\AbstractModel;
class Example extends AbstractModel {
	protected function _construct() {
		$this->_init('Vendor\Module\Model\Resource\Example');
	}
}
?>

С инициализацией ресурс модели

Ресурс модель
app/code/Vendor/Module/Model/Resource/Example.php
<?php
/**
 * @author Slava Yurthev
 */
namespace Vendor\Module\Model\Resource;
use Magento\Framework\Model\ResourceModel\Db\AbstractDb;
class Example extends AbstractDb {
	protected function _construct() {
		$this->_init('example_table', 'id');
	}
}
?>

С инициализацией таблицы

И конечно же коллекцию
app/code/Vendor/Module/Model/Resource/Example/Collection.php
<?php
/**
 * @author Slava Yurthev
 */
namespace Vendor\Module\Model\Resource\Example;
use Magento\Framework\Model\Resource\Db\Collection\AbstractCollection;
class Collection extends AbstractCollection {
	protected function _construct() {
		$this->_init(
			'Vendor\Module\Model\Example',
			'Vendor\Module\Model\Resource\Example'
		);
	}
}
?>

С инициализацией модели и ресурс модели


Создание Controller
app/code/Vendor/Module/etc/frontend/routes.xml
<?xml version="1.0"?>
<!--
/**
 * @author Slava Yurthev
 */
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd">
	<router id="standard">
		<route id="vendormodule" frontName="vendormodule">
			<module name="Vendor_Module" />
		</route>
	</router>
</config>

Где vendormodule имя нашего frontend контроллера

app/code/Vendor/Module/Controller/Index/Index.php
<?php
/**
 * @author Slava Yurthev
 */
namespace Vendor\Module\Controller\Index;
use Magento\Framework\App\Action\Context;
class Index extends \Magento\Framework\App\Action\Action {
	protected $_resultPageFactory;
	public function __construct(Context $context, \Magento\Framework\View\Result\PageFactory $resultPageFactory){
		$this->_resultPageFactory = $resultPageFactory;
		parent::__construct($context);
	}
	public function execute(){
		$resultPage = $this->_resultPageFactory->create();
		return $resultPage;
	}
}
?>

За вывод html отвечает execute метод. Вы можете вернуть в нём свой html либо сослатся на redirect


Создание Layout
app/code/Vendor/Module/view/frontend/layout/vendorhelloworld_index_index.xml
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/View/Layout/etc/page_configuration.xsd" layout="2columns-left">
	<body>
		<referenceContainer name="content">
			<block class="Vendor\Module\Block\Test" name="test" template="test.phtml" />
		</referenceContainer>
	</body>
</page>



Создание Block
app/code/Vendor/Module/Block/Test.php
<?php
/**
 * @author Slava Yurthev
 */
namespace Vendor\Module\Block;
use \Magento\Framework\View\Element\Template;
use \Magento\Framework\View\Element\Template\Context;
use \Vendor\Module\Helper\Data;
use \Vendor\Module\Model\Example;
class Test extends Template {
	public $helper;
	public $model;
	public function __construct(
		Context $context,
		Data $helper,
		Example $model,
		array $data = []
	){
		$this->helper = $helper;
		$this->model = $model;
        parent::__construct($context, $data);
	}
}
?>

Все необходимые классы для работы внутри данного блока можно передавать аргументом конструктора и записывать в protected переменные класса


Создание Template
app/code/Vendor/Module/view/frontend/templates/test.phtml
<?php
/**
 * @author Slava Yurthev
 */
echo __('Hello World');
?>

Для вывода информации в шаблоне от блока вы можете использовать $this а тест внутри конструкции __('');


Создание Helper
app/code/Vendor/Module/Helper/Data.php
<?php
/**
 * @author Slava Yurthev
 */
namespace Vendor\Module\Helper;
use \Magento\Framework\App\Helper\AbstractHelper;
class Data extends AbstractHelper {
	public function getModel($modelName){
		$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
		$model = $objectManager->create('\Vendor\Module\Model\\'.ucfirst($modelName));
		return $model;
	}
}
?>



P.S. Данная статья будет дополняться по мере работы с M2. Примеры модулей можете посмотреть у меня на github с пометкой M2.