В этом уроке мы рассмотрим, как правильно создавать новый «брендовый» модуль в Magento, которым можно управлять через панель администрирования. После прочтения этой статьи вы самостоятельно сможете создавать, обновлять и удалять бренды, которые имеют независимое представление в программах пользовательского интерфейса (клиентская часть системы). Таким же образом вы можете взаимодействовать с уже существующими логическими объектами, такими, как например «продукты» и «категории».
Кроме того, мы рассмотрим возможности взаимодействия нашего нового модуля с другими модулями Magento, такими как продукты. Сам процесс довольно длительный, потому что я буду подробно объяснять каждый шаг. Благодаря представленной информации вы с легкостью сможете выполнять все требуемые действия. Это отличный пример того, насколько мощной может быть платформа Magento при минимальном количестве приложенных усилий.
Мы рассмотрим следующие темы:
- Создание нового модуля бренда в Magento.
- Обзор, фильтрование и сортировка брендов в Magento с использованием панели администрирования.
- Создание, обновление и удаление брендов в панели администрирования.
- Создание списка брендов, а также просмотр страниц в программах пользовательского интерфейса.
- Создание связи между брендами и продуктами.
- Отображение связи продукт-бренд в программах пользовательского интерфейса.
- Использование изображений.
Этот урок относится к Magento Community Edition 1.8.0.0 – самая последняя версия, которая была доступна на момент написания этой статьи. Представленные в этой статье фрагменты кода и рассмотренные принципы могут быть применимы ко всем последним версиям Magento, как общественным, так и корпоративным.
Я постараюсь представить все свои объяснения в максимально понятной форме, однако в некоторых случаях документирование кода может быть лучшим способом пояснения определенных вещей. Но и в этом случае все фрагменты кода будут сопровождаться подробными комментариями. Представленные фрагменты кода имеют большее количество вариантов использования и элементов, чем описано в этом руководстве. Мы постараемся показать вам, как можно расширить все те возможности, о которых вы узнаете из данной статьи.
Создание модуля.
Начните с создания следующей папки и файловой структуры. В настоящее время, все файлы будут пустыми. Как правило, все эти файлы и папки создаются по одному экземпляру по мере необходимости, однако в рамках этого урока, мы сразу же расставим все по своим местам.
Я предполагаю начать с уже известных вам основ создания Magento модуля. Этот шаг довольно простой, поэтому не требует объяснений.
app
- code
- community
- SmashingMagazine
- BrandDirectory
- Block
- Adminhtml
- Brand
- Edit
- Form.php
- Edit.php
- Grid.php
- Brand.php
- Helper
- Data.php
- Model
- Resource
- Brand
- Collection.php
- Brand.php
- Brand.php
- controllers
- Adminhtml
- BrandController.php
- etc
- adminhtml.xml
- config.xml
- sql
- smashingmagazine_branddirectory_setup
- install-0.0.1.php
- etc
- modules
- SmashingMagazine_BrandDirectory.xml
Модуль установки скриптов.
Для того чтобы мы имели возможность использоваться модуль, необходимо где-то хранить наши данные. Таким образом, нам надо написать модуль установки скриптов, которые позволят создать таблицу базы данных для хранения информации о наших торговых марках. Установочные скрипты хранятся в двух местах внутри модуля, /sql
и /data
. Первый отвечает за физические изменения в вашем экземпляре Magento, такие, как например обновление схемы базы данных, а второй – за заполнение или удаление записей из существующей структуры.
В нашем случае мы добавляем новую таблицу. Вам необходимо отредактировать файл sql/smashingmagazine_branddirectory_setup/install-0.0.1.php
, поместив в него следующий код:
<?php
$this->startSetup();
/**
* Note: there are many ways in Magento to achieve the same result of
* creating a database table. For this tutorial, we have gone with the
* Varien_Db_Ddl_Table method, but feel free to explore what Magento
* does in CE 1.8.0.0 and earlier versions.
*/
$table = new Varien_Db_Ddl_Table();
/**
* This is an alias of the real name of our database table, which is
* configured in config.xml. By using an alias, we can refer to the same
* table throughout our code if we wish, and if the table name ever has
* to change, we can simply update a single location, config.xml
* - smashingmagazine_branddirectory is the model alias
* - brand is the table reference
*/
$table->setName($this->getTable('smashingmagazine_branddirectory/brand'));
/**
* Add the columns we need for now. If you need more later, you can
* always create a new setup script as an upgrade. We will introduce
* that later in this tutorial.
*/
$table->addColumn(
'entity_id',
Varien_Db_Ddl_Table::TYPE_INTEGER,
10,
array(
'auto_increment' => true,
'unsigned' => true,
'nullable'=> false,
'primary' => true
)
);
$table->addColumn(
'created_at',
Varien_Db_Ddl_Table::TYPE_DATETIME,
null,
array(
'nullable' => false,
)
);
$table->addColumn(
'updated_at',
Varien_Db_Ddl_Table::TYPE_DATETIME,
null,
array(
'nullable' => false,
)
);
$table->addColumn(
'name',
Varien_Db_Ddl_Table::TYPE_VARCHAR,
255,
array(
'nullable' => false,
)
);
$table->addColumn(
'url_key',
Varien_Db_Ddl_Table::TYPE_VARCHAR,
255,
array(
'nullable' => false,
)
);
$table->addColumn(
'description',
Varien_Db_Ddl_Table::TYPE_TEXT,
null,
array(
'nullable' => false,
)
);
$table->addColumn(
'visibility',
Varien_Db_Ddl_Table::TYPE_BOOLEAN,
null,
array(
'nullable' => false,
)
);
/**
* These two important lines are often missed.
*/
$table->setOption('type', 'InnoDB');
$table->setOption('charset', 'utf8');
/**
* Create the table!
*/
$this->getConnection()->createTable($table);
$this->endSetup();
Инициализация модуля.
На данном этапе у нас пока еще нет активного модуля Magento; мы просто обозначили требуемое количество папок, пустых файлов и установочных скриптов, которые на данный момент не выполняют никаких функций. Мы сделали это не случайно. Следующим шагом будем заполнение app/etc/modules
XML файла и настройка файла config.xml
. Эти действия необходимы для того, чтобы указать Magento, где необходимо искать установочный скрипт. При следующем посещении веб-сайта будет произведено переключение установочного скрипта в исполнительный.
Если бы мы выполняли эти действия в обратном порядке (то есть, сначала выполняли настройку модуля, а затем заполнили установочный скрипт), то существует вероятность того, что Magento будет воспринимать наш модуль как базовую версию 0.0.1. Поскольку наш установочный скрипт все еще пуст, то в целях большей эффективности будет пропущен. Чтобы ограничить количество неприятных для вас моментов, я по возможности старался как можно точнее сохранять порядок шагов.
Настройка модуля.
Следующим шагом станет редактирование файла app/etc/modules/SmashingMagazine_BrandDirectory.xml
путем добавления в него следующего фрагмента, который позволит активировать наш модуль:
<?xml version="1.0"?>
<config>
<modules>
<SmashingMagazine_BrandDirectory>
<active>true</active>
<codePool>community</codePool>
</SmashingMagazine_BrandDirectory>
</modules>
</config>
Обратите внимание, что мы используем community codepool. Этот BrandDirectory модуль не будет содержать клиентского кода или настроек. Вместо этого, он будет содержать стандартные блоки для нашего нового модуля, которые также могут быть использованы и в других модулях, в зависимости от назначения. Таким образом, этот модуль может быть удален в любом Magento экземпляре, а также может использоваться в исходной форме, без необходимости изменения кода. Если все же будет необходимо внести изменения кода для каждого использования, то более подходящим вариантом будет использование локального кодового пула.
Теперь мы должны сообщить Magento о том, что у нас есть модуль с номером версии, которая на самом деле будет определять запуск установочных скриптов и место поиска установочного скрипта. Необходимо редактировать файл etc/config.xml
, разместив в нем следующий фрагмент кода:
<?xml version="1.0"?>
<config>
<modules>
<SmashingMagazine_BrandDirectory>
<!--
This is the version number that our module is currently at. In
order for setup scripts to run, their version number must be less
than or equal to this value.
As we add upgrade scripts, we increment this value. The next time
your Magento instance is accessed, Magento will compare values in
the DB table 'core_resource' against this value. If the DB is
lower, it will attempt to run any setup scripts for the module
and then update the database table to match this value.
-->
<version>0.0.1</version>
</SmashingMagazine_BrandDirectory>
</modules>
<global>
<models>
<!--
This is the Model alias referred to in install-0.0.1.php.
-->
<smashingmagazine_branddirectory>
<!--
This tells Magento where to find
resource materials for this module.
-->
<resourceModel>smashingmagazine_branddirectory_resource</resourceModel>
</smashingmagazine_branddirectory>
<!--
This alias must match the above <resourceModel/> value.
-->
<smashingmagazine_branddirectory_resource>
<entities>
<!--
This is the table alias referred to in install-0.0.1.php.
-->
<brand>
<!--
This is the actual name of the database table.
-->
<table>smashingmagazine_branddirectory_brand</table>
</brand>
</entities>
</smashingmagazine_branddirectory_resource>
</models>
<resources>
<!--
This must match our folder name in the module sql folder.
-->
<smashingmagazine_branddirectory_setup>
<setup>
<!--
This defines which module the setup
scripts in this location belong to.
-->
<module>SmashingMagazine_BrandDirectory</module>
<!--
In each setup script, this
value determines the class of $this.
-->
<class>Mage_Eav_Model_Entity_Setup</class>
</setup>
<!--
This is only relevant if you have
multiple database connections.
-->
<connection>
<use>core_setup</use>
</connection>
</smashingmagazine_branddirectory_setup>
</resources>
</global>
</config>
Все ли работает в настоящий момент?
Двигаемся дальше. Домашняя страница позволяет получить доступ к любой странице вашего веб-сайта. Magento определит, что появился новый модуль в версии 0.0.1, но этот модуль пока еще не будет записан в core_resource
таблицы базы данных. Отсутствие записи заставит Magento выполнять поиск установочного скрипта и запускать его содержимое.
Если все пойдет хорошо…
Если все пойдет хорошо, то вам будет казаться, что абсолютно ничего не произошло. Странице Magento для загрузки может потребоваться на несколько минут больше. Это объясняется тем, что в это же самое время происходит запуск содержимого загрузочного скрипта (то есть пока создается новая таблица базы данных). Затем страница будет продолжать загружать как обычно. Теперь вам необходимо выполнить два действия, которые помогут проверить правильность процесса:
- Убедитесь, что Magento воспринимает ваш модуль и, что модуль активен. Для этого перейдите в
System → Configuration → Advanced → Advanced
. - Попробуйте получить доступ к базе данных через любой терминал или через что-то вроде PHPMyAdmin. Проверьте, создал ли Magento новую таблицу,
smashingmagazine_branddirectory_brand
.
Если что-то пошло не так…
Если что-то пошло не так, то вы можете этого и не заметить, только на этот раз действительно ничего не произошло! Причиной возникновения неисправностей может быть банальная опечатка в config.xml
файле, некорректно подобранное имя папки или файла (будьте осторожны с использованием регистра) или что-то в этом роде. Внимательно проанализируйте предыдущие этапы и выполните проверку на отсутствие ошибок.
С другой стороны, вы можете увидеть характерное сообщение об ошибке, например, «Фатальная ошибка PHP» или ошибка страницы отчета. Данное сообщение будет выведено в зависимости от серьезности ошибки. Используйте все свои навыки отладки для определения проблемы и ее исправления. И опять же, я вам советую несколько раз тщательно проверить правильность выполнения предыдущих шагов этого обучающего руководства.
«Что-то пошло не так. Что мне нужно сделать?»
Вы можете попробовать выполнить все перечисленные действия еще раз с нуля. Однако может потребоваться выполнение не всех действий в зависимости от поведения Magento до того момента, как что-то пошло не так. Вам нужно будет напрямую получить доступ к базе данных, потому что вы не сможете сделать это через Magento:
- В таблице
core
_
resource
необходимо исключить строкуsmashingmagazine
_
branddirectory
_
setup
. - Удалите таблицу
smashingmagazine_branddirectory_brand
.
Создание помощника.
В рамках этой статьи нам не нужно устанавливать какую-либо пользовательскую функциональность в помощник. Но нам необходимо будет добавить несколько пунктов меню в панель администрирования, которая будет использовать помощник с целью перевода. Мы можем просто создать помощник в файле Helper/Data.php
и забыть о нем.
<?php
class SmashingMagazine_BrandDirectory_Helper_Data
extends Mage_Core_Helper_Abstract
{
}
Создание моделей.
Далее, нам необходимо будет создать модели и модели ресурсов. Это необходимо для того, чтобы иметь возможность создавать и сохранять информацию бренда в базе данных, отображать информации о брендах в панели администрирования Magento, а также выводить список брендов перед пользователем в клиентской части.
Модель бренда.
Мы должны определить модель, которая позволит разработчикам взаимодействовать с модулями брендов. Я не буду вдаваться в подробности. Нет никаких сомнений, что большинство людей умнее меня, поэтому не стесняйтесь искать статьи обучающей направленности. На данный момент я буду просто стремиться обеспечить работоспособность нашей модели. Прежде всего необходимо ориентироваться на цели нашего учебного руководства. Необходимо отредактировать файл Model/Brand.php
:
<?php
class SmashingMagazine_BrandDirectory_Model_Brand
extends Mage_Core_Model_Abstract
{
const VISIBILITY_HIDDEN = '0';
const VISIBILITY_DIRECTORY = '1';
protected function _construct()
{
/**
* This tells Magento where the related resource model can be found.
*
* For a resource model, Magento will use the standard model alias -
* in this case 'smashingmagazine_branddirectory' - and look in
* config.xml for a child node <resourceModel/>. This will be the
* location that Magento will look for a model when
* Mage::getResourceModel() is called - in our case,
* SmashingMagazine_BrandDirectory_Model_Resource.
*/
$this->_init('smashingmagazine_branddirectory/brand');
}
/**
* This method is used in the grid and form for populating the dropdown.
*/
public function getAvailableVisibilies()
{
return array(
self::VISIBILITY_HIDDEN
=> Mage::helper('smashingmagazine_branddirectory')
->__('Hidden'),
self::VISIBILITY_DIRECTORY
=> Mage::helper('smashingmagazine_branddirectory')
->__('Visible in Directory'),
);
}
protected function _beforeSave()
{
parent::_beforeSave();
/**
* Perform some actions just before a brand is saved.
*/
$this->_updateTimestamps();
$this->_prepareUrlKey();
return $this;
}
protected function _updateTimestamps()
{
$timestamp = now();
/**
* Set the last updated timestamp.
*/
$this->setUpdatedAt($timestamp);
/**
* If we have a brand new object, set the created timestamp.
*/
if ($this->isObjectNew()) {
$this->setCreatedAt($timestamp);
}
return $this;
}
protected function _prepareUrlKey()
{
/**
* In this method, you might consider ensuring
* that the URL Key entered is unique and
* contains only alphanumeric characters.
*/
return $this;
}
}
Рабочая модель бренда.
Как и в описательной части указанной выше модели, я не буду вдаваться в подробности, а просто скажу, что основное назначение рабочей модели заключается в поддержке и извлечении информации из базы данных. Необходимо отредактировать файл Model/Resource/Brand.php
:
<?php
class SmashingMagazine_BrandDirectory_Model_Resource_Brand
extends Mage_Core_Model_Resource_Db_Abstract
{
protected function _construct()
{
/**
* Tell Magento the database name and primary key field to persist
* data to. Similar to the _construct() of our model, Magento finds
* this data from config.xml by finding the <resourceModel/> node
* and locating children of <entities/>.
*
* In this example:
* - smashingmagazine_branddirectory is the model alias
* - brand is the entity referenced in config.xml
* - entity_id is the name of the primary key column
*
* As a result, Magento will write data to the table
* 'smashingmagazine_branddirectory_brand' and any calls
* to $model->getId() will retrieve the data from the
* column named 'entity_id'.
*/
$this->_init('smashingmagazine_branddirectory/brand', 'entity_id');
}
}
Рабочая коллекция бренда.
Наконец, мы должны создать рабочую коллекцию, которая позволит выполнять итерацию брендов для таких вещей, как сетки панели администрирования и интерфейсный листинг страниц. Необходимо следующим образом отредактировать файл Model/Resource/Brand/Collection.php
:
<?php
class SmashingMagazine_BrandDirectory_Model_Resource_Brand_Collection
extends Mage_Core_Model_Resource_Db_Collection_Abstract
{
protected function _construct()
{
parent::_construct();
/**
* Tell Magento the model and resource model to use for
* this collection. Because both aliases are the same,
* we can omit the second paramater if we wish.
*/
$this->_init(
'smashingmagazine_branddirectory/brand',
'smashingmagazine_branddirectory/brand'
);
}
}
Создание блоков администрирования.
Мы уже выполнили основную массу тяжелой работы. База данных готова к заполнению, а модели и рабочие модели готовы ее заполнять. Теперь нам просто нужно создать интерфейс, который поможет это сделать. Мы начнем с создания и настройки блоков администрирования, которые будут отображать наши бренды как сетку в панели администрирования и позволят создавать новые элементы и обновлять уже существующие.
Сеточный контейнер блока.
Сеточный контейнер используется для размещения отдельных строк модуля бренда, которые будут отображаться в панели администрирования Magento. Сеточный контейнер напоминает оболочку и включает в себя кнопки, находящиеся в правом верхнем углу (например, «Добавить»). Необходимо отредактировать файл Block/Adminhtml/Brand.php
следующим образом:
<?php
class SmashingMagazine_BrandDirectory_Block_Adminhtml_Brand
extends Mage_Adminhtml_Block_Widget_Grid_Container
{ ...
Если вы хотите прочитать полностью статью, посетите сайт наших спонсоров