воскресенье, 9 февраля 2014 г.

Пошаговое создание модуля в Magento — руководство начинающего разработчика

По логике Magento (и многих других ООП систем), обработка данных должна производиться на уровне объектов/моделей и коллекций, не учитывая способы получения и сохранения данных. Операции получения и сохранения данных оставляются для моделей-ресурсов, как более низкоуровневые — тогда, в случае изменения способа хранения данных (БД, файлы и т.д...), не требуется изменять логику обработки, а потребуется лишь изменить модель-ресурс, занимающейся получением и сохранением данных. Переделаем вывод новостей с использованием моделей, а также добавим вывод содержимого новости по айди:

  1. Добавить узел class в узел моделей в файле конфигурации:

    <?xml version="1.0" ?>
    <config>
    <modules>
    ...
    </modules>
    <frontend>
    ...
    </frontend>
    <global>
    <models>
    <dsnews>
    <class>DS_News_Model</class>
    <resourceModel>dsnews_resource</resourceModel>
    </dsnews>
    <dsnews_resource>
    <class>DS_News_Model_Resource</class>
    <entities>
    <table_news>
    <table>ds_news_entities</table>
    </table_news>
    </entities>
    </dsnews_resource>
    </models>
    <resources>
    ...
    </resources>
    </global>
    </config>




  2. Создать файл модели новостей Model/News.php

    <?php

    class DS_News_Model_News extends Mage_Core_Model_Abstract
    {

    public function _construct()
    {
    parent::_construct();
    $this->_init('dsnews/news');
    }

    }




  3. Создать файл ресурса модели новостей Model/Resource/News.php

    <?php

    class DS_News_Model_Resource_News extends Mage_Core_Model_Mysql4_Abstract
    {

    public function _construct()
    {
    $this->_init('dsnews/table_news', 'news_id');
    }

    }




  4. Создать файл ресурса коллекции Model/Resource/News/Collection.php

    <?php

    class DS_News_Model_Resource_News_Collection extends Mage_Core_Model_Mysql4_Collection_Abstract
    {

    public function _construct()
    {
    parent::_construct();
    $this->_init('dsnews/news');
    }

    }




  5. Изменить контроллер controllers/IndexController.php

    <?php

    class DS_News_IndexController extends Mage_Core_Controller_Front_Action
    {

    public function indexAction()
    {
    $news = Mage::getModel('dsnews/news')->getCollection()->setOrder('created', 'DESC');
    $viewUrl = Mage::getUrl('news/index/view');

    echo '<h1>News</h1>';
    foreach ($news as $item) {
    echo '<h2><a href="' . $viewUrl . '?id=' . $item->getId() . '">' . $item->getTitle() . '</a></h2>';
    }
    }

    public function viewAction()
    {
    $newsId = Mage::app()->getRequest()->getParam('id', 0);
    $news = Mage::getModel('dsnews/news')->load($newsId);

    if ($news->getId() > 0) {
    echo '<h1>' . $news->getTitle() . '</h1>';
    echo '<div class="content">' . $news->getContent() . '</div>';
    } else {
    $this->_forward('noRoute');
    }
    }

    }





Теперь по ссылке http://site.com/news откроется список новостей в виде ссылок, при клике на которые будет открываться страница с содержимым новости.


В пункте 1 в файл кофигурации добавляется узел class, в котором прописываются базовые префиксы классов для модели DS_News_Model и ресурса DS_News_Model_Resource.


При запросе модели в контроллере (пункт 5) Mage::getModel('dsnews/news'), функция getModel принимает строку типа [model]/[class], из которой формируется название класса модели, где [model] — это название узла config/global/models/[model], из которой берётся значение узла classDS_News_Model, и к этому префиксу класса добавляется значение [class] (первая буква в каждом слове [class] преобразуется в заглавную). К примеру, из строки dsnews/news получается класс DS_News_Model_News, а из строки dsnews/news_gallery получится класс DS_News_Model_News_Gallery.


В пункте 2 создаётся базовая модель новости DS_News_Model_News, в конструкторе которого происходит инициализация ресурса $this->_init('dsnews/news'): в качестве параметров функция принимает строку [model]/[class], где [model] — это название узла config/global/models/[model], а [class] — это название класса. Однако, в отличие от модели, инициализация класса ресурса в качестве префикса класса использует значение узла config/global/models/[resourceModel]/class ресурса, на который ссылается модель в узле resourceModel. В итоге при инициализации ресурса $this->_init('dsnews/news') будет инициализироваться класс DS_News_Model_Resource_News.


В пункте 3 создаётся класс ресурса DS_News_Model_Resource_News, в котором происходит инициализация таблицы $this->_init('dsnews/table_news', 'news_id'): первым параметром является путь к названию нужной таблицы, а вторым — поле, использующееся в качестве первичного ключа (PRIMARY KEY) таблицы.


В пункте 4 происходит инициализация класса коллекции объектов, в конструкторе которой происходит инициализация исходной модели DS_News_Model_News.


В пункте 5 происходит изменение получения данных из базы. На этот раз используются модели и коллекции. В действии indexAction происходит запрос всех новостей с помощью получения коллекции $news = Mage::getModel('dsnews/news')->getCollection(). Название класса коллекции вычисляется из названия класса ресурса модели DS_News_Model_Resource_News + _Collection.


В действии viewAction происходит загрузка новости по id, полученному в запросе. Если новость с данным айди существует, то выведется название новости и содержимое. В противном случае будет сгенерирована страница 404.


This entry passed through the Full-Text RSS service — if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.


Комментариев нет:

Отправить комментарий