Создание модуля для Magento — часть 1
Популярность Magento постоянно растет. Появляется множество новых интеренет-магазинов, написанных на этом замечательном движке.
К сожалению, информации для разработчиков маловато, поэтому, будем исправлять ситуацию :)
В мои планы входит написание нескольких статей о том, как создать модуль для Magento, на примере модуля блога.
Оригинал данной статьи находится на моем блоге.
Изначально ограничимся минимальным функционалом: напишем административную часть модуля, при помощи которой можно будет управлять статьями блога в админке.
Модуль создается в отдельном namespace. Обычно, namespace — это название компании разработчика модуля.
В данной статье я буду создавать модуль блога для Magento в своем неймспейсе Snowcore.
Название модуля не должно содержать символов подчеркивания. Все custom модули создаются в директории /app/code/local
Мой модуль будет называться Snowcore_Blog
Перейдем непосредственно к делу. Что же нужно для написания модуля для Magento?
Отключение кеша Magento
Первым делом отключаем cache в Magento, иначе не сможем увидеть своих изменений :) Отключить кеширование можно в админке: System — Cache Management — в первой вкладке Cache Controlизменяем параметр All Cache на Disable, жмем Save cache settings
Создание структуры директорий
В папке модуля создаем следующую структуру:
/app/code/local/Snowcore/Blog/
Block
controllers
etc
Helper
Model
sql
Добавляем директорию для шаблонов:
/app/design/frontend/default/default/template/blog
(здесь первый default — это интерфейс, второй default — тема)
Подключение модуля
Для подключения модуля нужно создать XML файл конфигурации:
/app/etc/modules/Snowcore_Blog.xml
<?xml version="1.0"?><config> <modules> <Snowcore_Blog> <active>true</active> <codePool>local</codePool> </Snowcore_Blog> </modules></config>На данном этапе Magento уже знает о нашем модуле. Включить или выключить его можно при помощи изменения параметра <active> конфигурационного файла.
Управлять модулем также можно через админку: System -> Configuration -> Advanced.
Значение local для узла <codePool> говорит о том, что наш модуль относится к custom модулям и размещается в папке /app/code/local
Создание XML конфигурации для модуля
Создаем новый xml файл: /app/code/local/Snowcore/Blog/etc/config.xml
<config> <modules> <Snowcore_Blog> <version>0.1.0</version> </Snowcore_Blog> </modules> <frontend> <routers> <blog> <use>standard</use> <args> <module>Snowcore_Blog</module> <frontName>blog</frontName> </args> </blog> </routers> </frontend> <admin> <routers> <blog> <use>admin</use> <args> <module>Snowcore_Blog</module> <frontName>blog</frontName> </args> </blog> </routers> </admin> <adminhtml> <menu> <blog module=“blog”> <title>Blog</title> <sort_order>77</sort_order> <children> <article module=“blog”> <title>Manage Articles</title> <sort_order>0</sort_order> <action>blog/adminhtml_article</action> </article> </children> </blog> </menu> <acl> <resources> <all> <title>Allow Everything</title> </all> <admin> <children> <blog> <title>Blog Module</title> <sort_order>200</sort_order> </blog> </children> </admin> </resources> </acl> <layout> <updates> <blog> <file>blog.xml</file> </blog> </updates> </layout> </adminhtml> <global> <models> <blog> <class>Snowcore_Blog_Model</class> <resourceModel>blog_mysql4</resourceModel> </blog> <blog_mysql4> <class>Snowcore_Blog_Model_Mysql4</class> <entities> <article> <table>blog_articles</table> </article> </entities> </blog_mysql4> </models> <resources> <blog_setup> <setup> <module>Snowcore_Blog</module> </setup> <connection> <use>core_setup</use> </connection> </blog_setup> <blog_write> <connection> <use>core_write</use> </connection> </blog_write> <blog_read> <connection> <use>core_read</use> </connection> </blog_read> </resources> <blocks> <blog> <class>Snowcore_Blog_Block</class> </blog> </blocks> <helpers> <blog> <class>Snowcore_Blog_Helper</class> </blog> </helpers> </global></config>В данном файле определяются основные настройки модуля.
Секция <adminhtml> отвечает за настройки меню и доступов к разным ресурсам в админ части приложения.
Часть <global> хранит информацию об используемых моделях и ресурсах, хелперах и блоках.
Создание Helper
Хелпер содержит всего пару строчек кода /app/code/local/Snowcore/Blog/Helper/Data.php
<?phpclass Snowcore_Blog_Helper_Data extends Mage_Core_Helper_Abstract{}Этот хелпер нужен для того, чтобы работала система переводов.
На данном этапе у нас должен появиться новый пункт в главном меню админки:

Сразу создадим хелпер для статей:
/app/code/local/Snowcore/Blog/Helper/Article.php
<?phpclass Snowcore_Blog_Helper_Article extends Mage_Core_Helper_Abstract{}Создание моделей
Magento использует «тонкие» модели. Есть два типа моделей:
- Обычная модель: отвечает за бизнес-логику
- Ресурс-модель, которая работает с базой
Для начала нам понадобятся модели для статей.
Создаем обычную модель:
/app/code/local/Snowcore/Blog/Model/Article.php
<?phpclass Snowcore_Blog_Model_Article extends Mage_Core_Model_Abstract{ public function _construct() { parent::_construct(); $this->_init(‘blog/article’); }}В ней мы указываем ресурс-модель, с которой будет работать данная модель.
Создаем ресурс-модель:
/app/code/local/Snowcore/Blog/Model/Mysql4/Article.php
<?phpclass Snowcore_Blog_Model_Mysql4_Article extends Mage_Core_Model_Mysql4_Abstract{ public function _construct() { $this->_init('blog/article', 'article_id'); }}Второй параметр метода _init это первичный ключ таблицы articles.
Создаем коллекцию для статей:
/app/code/local/Snowcore/Blog/Model/Mysql4/Article/Collection.php
С коллекциями работает grid, который показывает список сущностей (статей).
<?phpclass Snowcore_Blog_Model_Mysql4_Article_Collection extends Mage_Core_Model_Mysql4_Collection_Abstract{ public function _construct() { parent::_construct(); $this->_init('blog/article'); }}SQL установщик для модуля
Установка модуля (создание таблиц в базе) происходит автоматически.
Здесь главное правильно указать версию для модуля, она должна совпадать с версией, которая назначена в XML конфигурации.
/app/code/local/Snowcore/Blog/sql/blog_setup/mysql4-install-0.1.0.php
<?php$installer = $this;$installer->startSetup();$installer->run("– DROP TABLE IF EXISTS {$this->getTable('blog_articles')};CREATE TABLE {$this->getTable('blog_articles')} ( `article_id` int(10) unsigned NOT NULL AUTO_INCREMENT, `title` varchar(150) NOT NULL, `slug` varchar(150) NOT NULL, `content` text, `meta_keywords` varchar(255) NOT NULL DEFAULT '', `meta_description` varchar(160) NOT NULL DEFAULT '', `created_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`article_id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8 ");$installer->endSetup();Установка модуля (создание необходимых таблиц) происходит автоматически — при обращении к любой странице. Если возникают проблемы с установкой модуля (таблицы не создались) — посмотрите в базе таблицу core_resource, там должна быть запись со значением code = blog_setup. Удалите запись, модуль переустановится.
Создание Layout модуля
Создаем новый XML:
/app/design/adminhtml/default/default/layout/blog.xml
<?xml version="1.0"?><layout version="0.1.0"> <blog_adminhtml_article_index> <reference name="content"> <block type="blog/adminhtml_article" name="article" /> </reference> </blog_adminhtml_article_index></layout>Создание блоков
Блоки отвечают за отображение модуля. В рамках первой статьи создаем блоки для админки.
Изначально нам понадобится блок для отображения списка существующих записей — grid.
Создаем контейнер для grid:
/app/code/local/Snowcore/Blog/Block/Adminhtml/Article.php
<?phpclass Snowcore_Blog_Block_Adminhtml_Article extends Mage_Adminhtml_Block_Widget_Grid_Container{ public function __construct() { $this->_controller = 'adminhtml_article'; $this->_blockGroup = 'blog'; $this->_headerText = Mage::helper('blog/article')->__('Articles Manager'); $this->_addButtonLabel = Mage::helper('blog/article')->__('Add Article'); parent::__construct(); }}Далее создаем сам Grid:
/app/code/local/Snowcore/Blog/Block/Adminhtml/Article/Grid.php
<?phpclass Snowcore_Blog_Block_Adminhtml_Article_Grid extends Mage_Adminhtml_Block_Widget_Grid{ public function __construct() { parent::__construct(); $this->setId('blogArticleGrid'); $this->setDefaultSort('article_id'); $this->setDefaultDir('ASC'); $this->setSaveParametersInSession(true); } protected function _prepareCollection() { $collection = Mage::getModel('blog/article')->getCollection(); $this->setCollection($collection); return parent::_prepareCollection(); } protected function _prepareColumns() { $this->addColumn('article_id', array( 'header' => Mage::helper('blog/article')->__('ID'), 'align' => 'right', 'width' => '50px', 'index' => 'article_id', )); $this->addColumn('title', array( 'header' => Mage::helper('blog/article')->__('Title'), 'align' => 'left', 'index' => 'title', )); return parent::_prepareColumns(); } public function getRowUrl($row) { return $this->getUrl('*/*/edit', array('id' => $row->getId())); }}Кратко о гриде:
- В конструкторе мы задаем параметры сортировки
- В методе _prepareCollection указывается, с какой коллекцией будет работать grid
- Метод _prepareColumns позволяет определить, какие колонки будут отображаться в таблице сущностей
- Метод getRowUrl определяет формат ссылки для перехода на форму редактирования (при клике на определенную строку)
Cоздание контроллера
В рамках этой статьи у контроллера будет только index action (отображение таблицы со статьями)
/app/code/local/Snowcore/Blog/controllers/Adminhtml/ArticleController.php
<?phpclass Snowcore_Blog_Adminhtml_ArticleController extends Mage_Adminhtml_Controller_action{ protected function _initAction() { $this->loadLayout() ->_setActiveMenu('blog/article') ->_addBreadcrumb(Mage::helper('adminhtml')->__('Articles Manager'), Mage::helper('adminhtml')->__('Articles Manager')); return $this; } public function indexAction() { $this->_initAction() ->renderLayout(); }}Итог
Наш контроллер пока содержит index действие, в котором происходит инициализация layout и breadcrumbs. На данном этапе на странице Manage Articles отображается содержимое таблицы статей. Таблица пока пустая, но для проверки работоспособности грида, можете добавить вручную пару записей в базу.
Mage_Adminhtml_Block_Widget_Grid предоставляет возможность использования фильтра и сортировки списка по заданным полям.
В итоге мы получили рабочую таблицу с возможностью фильтрации и сортировки данных. В следующей статье мы сделаем возможность управления записями таблицы.