|
С версии 5.12.0 в плагинах стало
доступно использование стандартных компонент модулей (пока что только для
интерфеса администратора), для этого в конфигурационный файл плагина нужно
добавить параметр
api_version = 6.00
В данной главе подразумевается,
что разработчик уже знаком с организацией кода плагина, поэтому пример
реализации модуля будет дан путем модификации плагина «sample». Инструкция по
созданию плагина: http://manual.amiro.ru/api/plugins/vvedenie.
Решаемая задача — создать
административный модуль управления списком людей и спецблок вывода списка на
общедоступной части сайта. Информация о человеке: ник, дата рождения, общая
информация, контактная информация(email, телефон). В
списке необходимо вывести ник, дату рождения и возраст пользователя. В списке
должны быть доступны действия «Редактировать», «Удалить», «Копировать»,
«Переименовать», «Опубликовать/распубликовать»; удаление должно быть запрещено
для элемента с id == 1. Должны быть следующие групповые операции:
«Опубликовать», «Распубликовать», «Переименовать» и «Удалить». В интерфейсе
администратора должна быть доступна фильтрация по имени пользователя и дате
рождения.
Далее, если идет речь о
модификации файла, указывается путь относительно папки плагина,
«_local/plugins_distr/my_sample» (в
свою очередь данный путь указан относительно корневой директории сайта).
Потребуются файлы, содержащие:
- SQL создания
таблицы;
- Точка входа модуля в панели управления;
- Контроллер модуля в панели управления;
- Модель таблиц БД;
- Компонента табличного списка;
- Компонента фильтра;
- Компонента формы;
- Точка входа модуля для публичной части сайта
(спецблок);
- Контроллер модуля для публичной части сайта;
- Отображение списка для публичной части сайта;
- Файлы шаблонов и локализаций.
- Файлы иконок действий.
Для простоты создания модуля,
несколько классов объединяются в один файл. В больших расширяемых проектах
классы рекомендуется размещать в отдельных файлах.
Исходя из задачи, делаем
следующие шаги до установки модуля:
- Копируем папку «_local/plugins_distr/sample» в «_local/plugins_distr/my_sample»
- Модифицируем
«_local/plugins_distr/my_sample/config.php»:
- Изменяем id плагина на «my_sample»;
- Изменяем версию плагина на 1.00;
- Указываем, что плагин работает с API 6.0, добавляя
параметр:
api_version
= 6.00 - Удаляем параметры «other», «config», «copy_allowed»;
- Модифицируем параметры «specblock», «admin»:
specblock = my_sample_specblock.php
admin = my_sample_mapping.php - В параметре «install_as» заменяем «sample» на «my_sample»:
install_as = plugins::my_sample,
modules::news::my_sample
Полученный
результирующий файл «config.php»:
;<? /* !!! DO NOT REMOVE THIS LINE !!! */ die(); ?>
; unique plugin ID (alphanumeric in lower case and underscore) id = my_sample
; current plugin version in format XX.YY version = 1.00
; new api usage api_version = 6.00
; specblock, admin file name (at least one of them should be specified) specblock = my_sample_specblock.php admin = my_sample_mapping.php
; sql install file sql_install = install.sql
; sql uninstall file sql_uninstall = uninstall.sql
; icon that will be displayed on start page (optional) icon = icon_sample.gif
; list of allowed modules where plugin will be installed to (it is required for now, later it will be optional) ; install_as module will be a real module later - system just checks for such module existence ; module links are considered as NOT installed for now install_as = plugins::my_sample, modules::news::my_sample
- Удаляем лишние файлы:
В папке «code»:
переименовываем файлы «my_admin.php» в «my_sample_mapping.php», «my_specblock.php» в «my_sample_specblock.php», удаляем php-файлы, кроме переименованных.
- Опциональный шаг. Удаляем папку «options», так как наш модуль не
будет иметь настроек.
- Создаем SQL-файл, исполняемый при
инсталляции плагина «databalse/install.sql»:
DROP TABLE IF EXISTS `my_sample_plugin`;
CREATE TABLE `my_sample_plugin` ( `id` int(11) NOT NULL auto_increment, `public` tinyint(3) unsigned NOT NULL DEFAULT '1', `nickname` varchar(255) NOT NULL, `birth` date NOT NULL DEFAULT '0000-00-00', `about` TEXT, `phone` varchar(16) NOT NULL DEFAULT '', `email` varchar(64) NOT NULL DEFAULT '', PRIMARY KEY (`id`) ) ENGINE=MyISAM;
- Создаем SQL-файл, исполняемый при деинсталляции плагина «databalse/uninstall.sql»:
DROP TABLE IF EXISTS `my_sample_plugin`; - Изменяем точку входа плагина
«code/my_sample_mapping.php» – создаем ресурсы модуля.
<?php
$modId = 'my_sample';
/* Добавление ресурсов модели данных: */ AMI::addModResources($modId, 'table');
/* Добавление ресурсов модели модуля и контроллера интерфейса администратора: */ AMI::addModResources($modId, 'module', array('model', 'controller/adm'));
/* Добавление ресурсов компоненты фильтра: */ AMI::addModResources($modId, 'filter/adm');
/* Добавление ресурсов компоненты списка: */ AMI::addModResources($modId, 'list/adm');
// Module admin list action controller AMI::addModResources($modId, 'list/adm', array('list_actions/controller/adm'));
// Module admin list group action controller AMI::addModResources($modId, 'list/adm', array('list_group_actions/controller/adm'));
/* Добавление ресурсов компоненты формы: */ AMI::addModResources($modId, 'form/adm');
- Содаем файл «code/ ami_sample_mapping_frn.php» с ресурсами модуля для
общедоступной части сайта.
<?php
$modId = 'my_sample';
/* Добавление ресурса контроллера модуля для общедоступной части сайта: */ AMI::addModResources($modId, 'module', array('controller/frn'));
/* Задание соответствия ресурса компоненты списка имени класса: */ AMI::addResourceMapping( array( $modId . '/list/view/frn' => AMI::getClassPrefix($modId) . '_ListViewFrn', ) );
- Создаем классы контроллера плагина и модели
плагина «code/MySample_Adm.php»:
<?php
class MySample_Adm extends AMI_Mod{ public function __construct(AMI_Request $oRequest, AMI_Response $oResponse){ parent::__construct($oRequest, $oResponse); /* Добавление компонент фильтра, списка и формы: */ $this->addComponents(array('filter', 'list', 'form')); } /* Указание файла локализации сообщений интерфейса администратора: */ public function getClientLocalePath(){ return '_local/plugins_distr/' . $this->getModId() . '/templates/client.lng'; } }
class MySample_State extends AMI_ModState{ }
- Создаем классы модели данных, элемента и
списка «code/MySample_Table.php»:
<?php
class MySample_Table extends AMI_ModTable{ /* Указание названия таблицы: */ protected $tableName = 'my_sample_plugin'; }
class MySample_TableItem extends AMI_ModTableItem{ public function __construct(AMI_ModTable $oTable, DB_Query $oQuery = null){ parent::__construct($oTable, $oQuery);
// Add field validators /* Добавление валидаторов (поля должны быть не пустыми, при ошибке производить остановку дальнейших проверок): */ $this->oTable->addValidators( array( 'nickname' => array('filled', 'stop_on_error'), 'birth' => array('filled', 'stop_on_error') ) );
/* Форматировать поле, как дату (стандартный форматтер): */ // Add field callback to process human-readable date from request $this->setFieldCallback('birth', array($this, 'fcbDate'));
/* Добавление собственного форматтера для виртуального поля: */ // Add virtual field callback $this->setFieldCallback('age', array($this, 'fcbAge')); } /* Метод-форматтер виртуального поля, возвращающий при получении значения поля вычисляемое значение и не позволяющий сохранить данное поле в базу при сохранении: */ protected function fcbAge(array $aData){ if($aData['action'] === 'get'){ // Sample age calculation list($y, $m, $d) = explode('-', $this->aData['birth']); $aData['value'] = date('Y') - $y - (int)(date('md') < ($m . $d)); }else{ $aData['_skip'] = true; } } }
class MySample_TableList extends AMI_ModTableList{ }
- Создаем класс модели модификатора элемента «code/MySample_ TableItemModifier.php»:
class AmiSample_TableItemModifier extends AMI_ModTableItemModifier{ }
- Создаем классы контроллера и отображения
табличного списка «code/MySample_ListAdm.php»:
<?php
class MySample_ListAdm extends AMI_ModListAdm{ // List actions controller resource id protected $listActionsResId = 'my_sample/list_actions/controller/adm'; public function init(){ /* Добавление вывода иконок стандартных действий редактирования и удаления, добавление действия «Копировать» в столбец действий в конце списка: */ // AMI_ModListAdm::addActions() must be called before parent::init()! // add actions to "actions" column $this->addActions(array('edit', 'delete', 'copy'));
/* Добавление действия публикации/распубликации в отдельный столбец, иконка, всплывающаяя подсказка и действие, передаваемое на сервер будут зависеть от значения поля элемента: */ // add separate column action $this->addColActions(array('public'), true);
/* Добавление действия переименования в отдельный столбец: */ // add separate column action $this->addColActions(array('rename'));
/* Добавление действия «Действие внутри содержимого ячейки» в существующий столбец «Имя»: */
// add action inside existing column $this->addActions(array('inner'), 'nickname');
// add group actions “public”, “unpublic”, “rename”, "delete" $this->addGroupActions( array( array(self::REQUIRE_FULL_ENV . 'public', 'public_section'), array(self::REQUIRE_FULL_ENV . 'unpublic', 'public_section'), array(self::REQUIRE_FULL_ENV . 'rename', 'rename_section'), array(self::REQUIRE_FULL_ENV . 'delete', 'delete_section')); parent::init(); return $this; } }
class MySample_ListViewAdm extends AMI_ModListView_JSON{ public function __construct(){ parent::__construct();
/* Добавление столбцов «id», «nickname», «birth», виртуального столбца «age» и указание растягиваемого столбца «nickname»: */ // Init colimns $this ->addColumn('id') ->addColumn('nickname') ->addColumn('birth') ->addColumnType('age', 'int') ->setColumnTensility('nickname') /* Задание столбцов, по которым можно сортировать список («Опубликованность», «Имя», «День рождения»), сортировка по виртуальным полям («age», «Возраст») недопустима: */ ->addSortColumns( array( 'public', 'nickname', 'birth' ) ); ; /* Поясним логику задания формата столбцов списка. Если в конструкторе класса-наследника AMI_ModListView_JSON в явном виде не вызван метод AMI_ModListView_JSON::addColumnType(), будут проанализированы поля, добавляемые во View формы вызовами AMI_ModFormView::addField(): • Поля, для которых отсутствует вызов AMI_ModFormView::addField() или у них указан тип «hidden», преобразуются в скрытые столбцы; • Поля с типами «date», «datetime» преобразуются в отцентрированные столбцы, содержащие текстовые данные (тип «text»); • Поля с типами «input», «checkbox», «textarea», «select» и «radio» преобразуются в столбцы, содержащие текстовые данные (тип «text»). Поля, для которых в наследнике AMI_ModListAdm::init() заданы действия вызовом AMI_ModListAdm:: addColActions() в виде
// AmiSample_ListAdm:: init() // add separate column action $this->addColActions(array('public'), true);
преобразуются в столбцы с типом «action». */
/* Указание места размещения с действием «Переименовать» перед столбцом «Имя»: */ // place 'rename' action column before 'nickname' column $this->putPlaceholder('rename', 'nickname.before');
/* Форматирование столбца «nickname» при помощи стандартного форматтера fmtTruncate: */ // Truncate 'header' column by 50 symbols $this->formatColumn( 'nickname', array($this, 'fmtTruncate'), array( 'length' => 50 ) );
/* Форматирование даты рождения при помощи собственного форматтера: */ // Use custom formatter on 'value' column $this->formatColumn( 'birth', array($this, 'fmtCustom') );
/* Добавление своего обработчика на действия списка «Редактировать», «Копировать». */ // Add custom script $this->addScriptFile('_local/plugins_distr/' . $this->getModId() . '/templates/list.adm.js'); }
/* Указание файла локализации компоненты списка: */ protected function getModLocalePath(){ return '_local/plugins_distr/' . $this->getModId() . '/templates/list.lng'; }
/* Собственный форматтер, демонстрирующий каким образом можно изменять данные: */ protected function fmtCustom($value, array $aArgs){
return '~ ' . $value . ' ~';
} }
- Создаем класс контроллера действий списка «code/MySample_ ListActionsAdm.php»:
<?php
class AmiSample_ListActionsAdm extends AMI_ModListActions{ /** * Dispatches 'delete' action. * * Overridden item deletion. Denies deletion of item having id == 1. */ public function dispatchDelete($name, array $aEvent, $handlerModId, $srcModId){ $oItem = $this->getItem($this->getRequestId())); if($oItem->getId() == 1){ $aEvent['oResponse']->addStatusMessage('status_del_firbidden', AMI_Response::STATUS_MESSAGE_ERROR, $handlerModId, 'list'); $this->refreshView(); }else{ parent::dispatchDelete($name, $aEvent, $handlerModId, $srcModId); } return $aEvent; }
/** * Dispatches 'inner' action. * * Displays three messages. */ public function dispatchInner($name, array $aEvent, $handlerModId, $srcModId){ // Метод dispatchInner() обрабатывает действие в столбце «Имя». // Обработка заключается в выдаче статусных сообщений трёх типов $aEvent['oResponse'] ->addStatusMessage('status_inner_note') ->addStatusMessage('status_inner_warning', AMI_Response::STATUS_MESSAGE_WARNING) ->addStatusMessage('status_inner_error', AMI_Response::STATUS_MESSAGE_ERROR); // и вызове для обновления View компоненты списка $this->refreshView(); return $aEvent; }
/** * Dispatches 'rename' action. * * Renames 'nickname' field to "[{$nickname}]". */ public function dispatchRename($name, array $aEvent, $handlerModId, $srcModId){ // Метод dispatchRename() обрабатывает действие «Переименовать»: // загружает модель элемента, обрамляет поле «Имя» квадратными скобками и сохраняет модель $oItem = $this->getItem($this->getRequestId())); $nickname = $oItem->nickname; $oItem->nickname = '[' . $nickname . ']'; $oItem->save(); // добавляет сатусное сообщение о переименовании $aEvent['oResponse']->addStatusMessage( 'status_renamed', array( 'source' => $nickname, 'destination' => $oItem->nickname ) ); // обновляет View компоненты списка $this->refreshView();
return $aEvent; }
/** * Dispatches 'copy' action. * * Copies item and prepends '- ' string to the new 'nickname' field. */ public function dispatchCopy($name, array $aEvent, $handlerModId, $srcModId){ // Метод dispatchCopy()обрабатывает действие «Копировать» // загружает модель элемента, дописывает вначало поля «Имя» строку “- “, сбрасывает id (primary key) модели элемента и сохраняет модель $oItem = $this->getItem($this->getRequestId())); $nickname = $oItem->nickname; $newNickname = '- ' . $nickname; $oItem->nickname = $newNickname; $oItem->resetId(); $oItem->save(); // добавляет сатусное сообщение о копировании $aEvent['oResponse']->addStatusMessage( 'status_copied', array( 'source' => $nickname, 'destination' => $newNickname ) ); // обновляет View компоненты списка $this->refreshView();
return $aEvent; }
/**#@-*/ }
Создаем класс контроллера групповых действий
списка «code/MySample_ ListGroupActionsAdm.php»:
class AmiSample_ListGroupActionsAdm extends AMI_ModListGroupActions{ /** * Dispatches 'delete' group action. * * Delete group items. */ public function dispatchGrpDelete($name, array $aEvent, $handlerModId, $srcModId){ // Метод dispatchGrpDelete() вызывает групповое удаление элементов, реализованное в родительском классе return parent::dispatchGrpDelete($name, $aEvent, $handlerModId, $srcModId); }
/** * Dispatches 'rename' action. * * Rename group items. */ public function dispatchGrpRename($name, array $aEvent, $handlerModId, $srcModId){ // Метод dispatchGrpRename () вызывает обработчик dispatchRename, реализованный в контроллере действий списка, для каждого элемента группы // Содаём объект контроллера действий списка $oListActionsAdm = AMI::getResource($handlerModId . '/list_actions/controller/adm');
$aRequestIds = $this->getRequestIds(); foreach($aRequestIds as $id){ $aEvent['oRequest']->set('mod_action_id', $id); $oListActionsAdm->setActionData($name, $aEvent, $handlerModId, $srcModId); $oListActionsAdm->dispatchRename($name, $aEvent, $handlerModId, $srcModId); }
// Удаляем статусные сообщения, возникшие при вызове $oListActionsAdm->dispatchRename() и выдаём общее сообщение $aEvent['oResponse']->resetStatusMessages(); $aEvent['oResponse']->addStatusMessage('status_grp_rename', array('num_items' => $itemsProcessed));
$this->refreshView();
return $aEvent; } }
Создаем классы контроллера, модели и
отображения фильтра «code/MySample_FilterAdm.php»:
<?php
// Контроллер компоненты фильтра class MySample_FilterAdm extends AMI_ModFilter{ }
// Модель компоненты фильтра, поля добавляются в модели, так как при фильтрации списка элементов View фильтра не используется и не может содержать описания полей class MySample_FilterModelAdm extends AMI_Filter{ public function __construct(){ // Добавление полей «Имя», «С даты», «По дату» в фильтр $this->addViewField( array( 'name' => 'nickname', 'type' => 'input', 'flt_type' => 'text', 'flt_default' => '', 'flt_condition' => 'like', 'flt_column' => 'nickname' ) ); $this->addViewField( array( 'name' => 'datefrom', 'type' => 'datefrom', 'flt_type' => 'date', 'flt_default' => AMI_Lib_Date::formatUnixTime(AMI_Lib_Date::UTIME_MIN), 'flt_condition' => '>=', 'flt_column' => 'birth' ) ); $this->addViewField( array( 'name' => 'dateto', 'type' => 'dateto', 'flt_type' => 'date', 'flt_default' => AMI_Lib_Date::formatUnixTime(AMI_Lib_Date::UTIME_MAX), 'flt_condition' => '<', 'flt_column' => 'birth' ) ); } }
class MySample_FilterViewAdm extends AMI_ModFilterView{ public function __construct(){ parent::__construct();
// Указание следования поля «Имя» перед полем «С даты» $this->putPlaceholder('nickname', 'datefrom.before'); }
// Указание файла локализации компоненты фильтра protected function getModLocalePath(){ return '_local/plugins_distr/' . $this->getModId() . '/templates/filter.lng'; } }
Создаем классы контроллера и отображения
формы «code/MySample_FormAdm.php»:
<?php
class MySample_FormAdm extends AMI_ModForm{ }
class MySample_FormViewAdm extends AMI_ModFormViewAdm{ public function __construct(){ parent::__construct();
// Добавление общих полей («id», кнопки сохранения) $this->addField(array('name' => 'id', 'type' => 'hidden')); // Form save action $this->addField(array('name' => 'mod_action', 'value' => 'form_save', 'type' => 'hidden'));
// Добавление полей « Публиковать», «Имя», «День рождения» $this->addField(array('name' => 'public', 'type' => 'checkbox', 'default_checked' => true)); $this->addField(array('name' => 'nickname')); $this->addField(array('name' => 'birth', 'type' => 'date'));
// Создание области вкладок «tabset», добавление вкладок «Информация» и «Контакты» $this->addTabContainer('tabset'); $this->addTab('info', 'tabset', 'active'); $this->addTab('contacts', 'tabset');
// Добавление поля на вкладку «Информация», полей «Телефон» и «Email» на вкладку «Контакты» $this->addField(array('name' => 'about', 'type' => 'htmleditor', 'cols' => 80, 'rows' => 10, 'position' => 'info.end')); $this->addField(array('name' => 'phone', 'position' => 'contacts.end')); $this->addField(array('name' => 'email', 'position' => 'contacts.end', 'validators' => 'email')); }
// Указание файла локализации компоненты формы protected function getModLocalePath(){ return '_local/plugins_distr/' . $this->getModId() . '/templates/form.lng'; } }
В папке «templates» удаляем старые и создаем новые файлы локализации панели управления плагина (в кодировке UTF-8):
Файл «templates/messages.lng»:
%%status_add%en%%
Record was added.
%%status_add%ru%%
Запись добавлена.
%%status_add_fail%en%%
Record was not added!
%%status_add_fail%ru%%
Запись не добавлена!
%%status_apply%en%%
Record was updated.
%%status_apply%ru%%
Запись изменена.
%%status_apply_fail%en%%
Record was not updated!
%%status_apply_fail%ru%%
Запись не изменена!
%%status_name_add%en%%
Record with name '_name_' was added.
%%status_name_add%ru%%
Запись с именем '_name_' добавлена.
%%status_renamed%en%%
Record "_source_" was renamed to "_destination_".
%%status_renamed%ru%%
Запись "_source_" переименована в "_destination_".
%%status_del%en%%
Record was deleted.
%%status_del%ru%%
Запись удалена.
%%status_del_fail%en%%
Record was not deleted.
%%status_del_fail%ru%%
Запись не удалена.
%%status_del_firbidden%en%%
Record deletion is firbidden.
%%status_del_firbidden%ru%%
Удаление записи запрещено.
%%status_grp_del%en%%
_num_items_ item was deleted.
%%status_grp_del%ru%%
Удалено элементов: _num_items_.
%%status_grp_rename%en%%
_num_items_ item was renamed.
%%status_grp_rename%ru%%
Переименовано элементов: _num_items_.
%%status_copied%en%%
Record "_source_" was copied to "_destination_".
%%status_copied%ru%%
Запись "_source_" скопирована в "_destination_".
%%status_inner_note%en%%
Inner cell action note.
%%status_inner_note%ru%%
Сообщение действия внутри содержимого ячейки.
%%status_inner_warning%en%%
Inner cell action warning.
%%status_inner_warning%ru%%
Предупреждение действия внутри содержимого ячейки.
%%status_inner_error%en%%
Inner cell action error.
%%status_inner_error%ru%%
Ошибка действия внутри содержимого ячейки Файл «templates/client.lng»:
%%list_edit_action_called%en%% Edit action is called... %%list_edit_action_called%ru%% Открытие элемента на редактирование...
%%list_confirm_copy%en%% Are you sure to copy record? %%list_confirm_copy%ru%% Скопировать запись?
%%list_action_grp_rename%en%% Rename %%list_action_grp_rename%ru%% Переименовать
Файл «templates/list.lng»: %%include_language "_local/plugins_distr/ami_sample/templates/common.lng"%%
%%list_col_rename%en%%
%%list_col_rename%ru%%
%%list_col_age%en%% Age %%list_col_age%ru%% Возраст
%%list_col_rename%en%% %%list_col_rename%ru%%
%%list_action_public%en%% Published on site, click to make unpublished %%list_action_public%ru%% Опубликовано на сайте
%%list_action_unpublic%en%% Not published on site, click to publish %%list_action_unpublic%ru%% Не опубликовано на сайте
%%list_action_edit%en%% Edit (Common image and title are overridden, click event handling is implemented on client side) %%list_action_edit%ru%% Редактировать (Стандартные изображение и название изменены, осуществлён перехват обработки события нажатия на стороне клиента)
%%list_action_delete%en%% Delete %%list_action_delete%ru%% Удалить
%%list_action_rename%en%% Rename %%list_action_rename%ru%% Переименовать
%%list_action_copy%en%% Copy %%list_action_copy%ru%% Копировать
%%list_action_inner%en%% ••» %%list_action_inner%ru%% ••»
%%list_action_title_inner%en%% Inner cell action %%list_action_title_inner%ru%% Действие внутри содержимого ячейки
Файл «templates/filter.lng»: %%filter_field_nickname%en%% Nickname: %%filter_field_nickname%ru%% Имя:
Файл «templates/form.lng»: %%include_language "_local/plugins_distr/ami_sample/templates/common.lng"%%
%%my_sample_add%en%% Add record %%my_sample_add%ru%% Добавить запись
%%my_sample_apply%en%% Edit record %%my_sample_apply%ru%% Редактировать запись
%%form_tab_info%en%% About %%form_tab_info%ru%% Информация
%%form_tab_contacts%en%% Contacts %%form_tab_contacts%ru%% Контакты
%%form_field_birth%en%% Birthday %%form_field_birth%ru%% День рождения
%%form_field_about%en%% About %%form_field_about%ru%% Описание
%%form_field_email%en%% Email %%form_field_email%ru%% Email
%%form_field_phone%en%% Phone %%form_field_phone%ru%% Телефон
- Размещаем в папке «img» gif/png-файлы с названиями «icon-{$action}.gif» или «icon-{$action}.png».
На время разработки, чтобы не проводить инсталляцию/деинсталляцию
модуля, файлы с иконками можно размещать в папке «_local/_admin/images/my_sample», куда
они попадают после инсталляции модуля.
- Модифицируем файл спецблока «code/my_sample_specblock.php»:
<?php
$modId = 'my_sample';
/** * Подключение описания ресурсов в случае несоответствия именования ресорсов/классов общей схемы ресурсов API Reference */ /* // Подключение описания ресурсов require_once $pluginParams['code_path'] . 'ami_sample_mapping.php'; // Подключение описания ресурсов общедоступной части сайта require_once $pluginParams['code_path'] . 'ami_sample_mapping_frn.php'; */
// Создание и инициализация контроллера спецблока модуля массивом параметров $pluginParams $plugin = AMI::getResource($modId . '/module/controller/frn', array($pluginParams));
// Получение результата и возврат его в качестве требуемой переменной $resultHtml для дальнейшего вывода результата в качестве спецблока $resultHtml = $plugin->getResponse();
- Создаем классы контроллера спецблока плагина
«code/MySample_Frn.php»
<?php
class MySample_Frn{
protected $oView;
public function __construct(array $aPluginParams){ // Получение объекта отображения $this->oView = AMI::getResource($this->getModId() . '/list/view/frn'); // Установка пространства переменных объекта отображения $this->oView->setScope( array( 'templates_path' => $aPluginParams['templates_path'] ) );
// Получение модели списка $oModelList = AMI::getResourceModel($this->getModId() . '/table')->getList();
// Задание модели списка столбцов, требуемых для получения из БД $oModelList->addColumns(array('id', 'nickname', 'birth'));
// Передача отображению инициализированной модели $this->oView->setModel($oModelList); }
// Метод получения результатов работы отображения public function getResponse(){ return $this->oView->get(); }
// Метод получения идентификатора текущего модуля (метод необходим, поскольку класс пока что не наследуется от другого класса, реализующего данный метод) protected function getModId(){ return AMI::getModId(get_class($this)); } }
- Создать класс отображения «code/MySample_ListViewFrn.php»:
<?php
class MySample_ListViewFrn extends AMI_View{
protected $tplBlockName = 'my_sample';
protected $oModel;
public function get(){ $res = ''; // Инициализация шаблонизатора $oTpl = $this->getTemplate();
// Добавление фильтрации по опубликованности и загрузка модели, инициализированной контроллером $this->oModel->addWhereDef('AND `public` = 1')->load(); if($this->oModel->count() > 0){ // Добавление блока шаблона $oTpl->addBlock($this->tplBlockName, $this->aScope['templates_path'] . 'front.tpl'); $rows = '';
// Итерирование по модели списка и формирование отображения моделей элементов foreach($this->oModel as $oModelItem){ $aRowData = array( 'id' => $oModelItem->id, 'nickname' => AMI_Lib_String::htmlChars($oModelItem->nickname), 'birth' => $oModelItem->birth ); $rows .= $oTpl->parse($this->tplBlockName . ':item_row', $aRowData); }
// Формирование полного отображения таблицы $res = $oTpl->parse($this->tplBlockName . ':items', array('rows' => $rows)); }else{ // No items found } return $res; }
// Метод предназначен для типизации передаваемой модели (отображение работает только с наследниками модели списка AMI_ModTableList) protected function _setModel(AMI_ModTableList $oModel){ return parent::_setModel($oModel); } }
- Создаем файлы шаблона и локализации спецблока
плагина
Файл шаблона «templates/front.tpl»: %%include_language "_local/plugins_distr/my_sample/templates/front.lng"%%
<!--#set var="items" value=" <table border="1" cellpadding=5 cellspacing=2> <tr><th>%%id%%</th><th>%%name%%</th><th>%%birth%%</th></tr> </table> "-->
<!--#set var="item_row" value=" <tr> <td></td> <td></td> <td></td> </tr> "--> Файл локализации «templates/front.lng»: %%id%en%% ID %%id%ru%% ID
%%name%en%% Name %%name%ru%% Имя
%%birth%en%% Birthday %%birth%ru%% - Установить плагин
Устанавливаем модуль через мастер надстроек. Обратите внимание, что
система кеширует файл конфигурации плагина, поэтому необходимо для
применения изменений в конфигурации, перед тем, как открывать модуль
плагинов, увеличить версию файла конфигурации. Подробнее о версии плагина. - Добавляем спецблок плагина на какую-либо
страницу. В процессе разработки рекомендуется временно отключить кеширование
на сайте, подробнее об отключении кеширования в режиме отладки.
- Добавляем данные в модуль в панели
управления.
- Готово. Можно смотреть результат работы плагина на
сайте.
|