Добавление конфигурационных параметров
Фреймворк Joomla позволяет использовать параметры, сохраненные для каждого компонента. Создайте конфигурационный файл admin/config.xml со следующим кодом:
<?xml version="1.0" encoding="utf-8"?>
<config>
<fieldset
name="greetings"
label="COM_HELLOWORLD_CONFIG_GREETING_SETTINGS_LABEL"
description="COM_HELLOWORLD_CONFIG_GREETING_SETTINGS_DESC"
>
<field
name="show_category"
type="radio"
label="COM_HELLOWORLD_HELLOWORLD_FIELD_SHOW_CATEGORY_LABEL"
description="COM_HELLOWORLD_HELLOWORLD_FIELD_SHOW_CATEGORY_DESC"
default="0"
>
<option value="0">JHIDE</option>
<option value="1">JSHOW</option>
</field>
</fieldset>
</config>
Этот файл будет прочитан встроенным в Joomla компонентом com_config. На данный момент мы определили всего один параметр show_category
- отображать или не отображать название категории в публичной части сайта.
Самым лучшим способом для установки параметров будет добавление кнопки "Настройки" на панель инструментов. Для этого необходимо внести изменения в метод addToolBar()
в файле admin/views/helloworlds/view.html.php:
/**
* Устанавливает панель инструментов.
*
* @return void
*/
protected function addToolBar()
{
JToolBarHelper::title(JText::_('COM_HELLOWORLD_MANAGER_HELLOWORLDS'), 'helloworld');
JToolBarHelper::addNew('helloworld.add');
JToolBarHelper::editList('helloworld.edit');
JToolBarHelper::divider();
JToolBarHelper::deleteList('', 'helloworlds.delete');
JToolBarHelper::divider();
JToolBarHelper::preferences('com_helloworld');
}
}
Кнопка выводится с помощью JToolBarHelper::preferences('com_helloworld')
.
Использование конфигурационных параметров в качестве значения по умолчанию
Теперь определим этот параметр индивидуально для каждого сообщения. Вносим изменения в файл admin/models/forms/helloworld.xml:
<?xml version="1.0" encoding="utf-8"?>
<form
addrulepath="/administrator/components/com_helloworld/models/rules"
>
<fieldset name="details">
<field
name="id"
type="hidden"
/>
<field
name="greeting"
type="text"
label="COM_HELLOWORLD_HELLOWORLD_FIELD_GREETING_LABEL"
description="COM_HELLOWORLD_HELLOWORLD_FIELD_GREETING_DESC"
size="40"
class="inputbox validate-greeting"
validate="greeting"
required="true"
default=""
/>
<field
name="catid"
type="category"
extension="com_helloworld"
class="inputbox"
default=""
label="COM_HELLOWORLD_HELLOWORLD_FIELD_CATID_LABEL"
description="COM_HELLOWORLD_HELLOWORLD_FIELD_CATID_DESC"
required="true"
>
<option value="0">JOPTION_SELECT_CATEGORY</option>
</field>
</fieldset>
<fields name="params">
<fieldset
name="params"
label="JGLOBAL_FIELDSET_DISPLAY_OPTIONS"
>
<field
name="show_category"
type="list"
label="COM_HELLOWORLD_HELLOWORLD_FIELD_SHOW_CATEGORY_LABEL"
description="COM_HELLOWORLD_HELLOWORLD_FIELD_SHOW_CATEGORY_DESC"
default=""
>
<option value="">JGLOBAL_USE_GLOBAL</option>
<option value="0">JHIDE</option>
<option value="1">JSHOW</option>
</field>
</fieldset>
</fields>
</form>
Мы определили одинаковый параметр show_category
для каждого сообщения с помощью дополнительного значения: По умолчанию. Это значение устанавливается в общем файле конфигурации config.xml.
Для хранения параметров необходимо добавить в таблицу базы данных еще одну колонку params
. Откройте файл admin/sql/install.mysql.utf8.sql и замените в нем код на следующий:
DROP TABLE IF EXISTS `#__helloworld`;
CREATE TABLE `#__helloworld` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`greeting` varchar(25) NOT NULL,
`catid` int(11) NOT NULL DEFAULT '0',
`params` TEXT NOT NULL DEFAULT '',
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=0 DEFAULT CHARSET=utf8;
INSERT INTO `#__helloworld` (`greeting`) VALUES
('Hello World!'),
('Good bye World!');
Не забываем про обновление компонента и изменяем файл admin/sql/updates/mysql/0.0.10.sql:
ALTER TABLE `#__helloworld` ADD `params` TEXT NOT NULL DEFAULT '';
Для поддержки параметров необходимо внести изменения и в класс таблицы HelloWorldTableHelloWorld
. В базе данных параметры будут храниться в формате JSON и загружаться в JRegistry. Нам необходимо переопределить JTable
методы bind и load и добавить их в admin/tables/helloworld.php:
<?php
// Запрет прямого доступа.
defined('_JEXEC') or die;
// Подключаем библиотеку таблиц Joomla.
jimport('joomla.database.table');
/**
* Класс таблицы HelloWorld.
*/
class HelloWorldTableHelloWorld extends JTable
{
/**
* Конструктор.
*
* @param JDatabase &$db Коннектор объекта базы данных.
*/
public function __construct(&$db)
{
parent::__construct('#__helloworld', 'id', $db);
}
/**
* Переопределяем bind метод JTable.
*
* @param array $array Массив значений.
* @param array $ignore Массив значений, которые должны быть игнорированы.
*
* @return boolean True если все прошло успешно, в противном случае false.
*/
public function bind($array, $ignore = array())
{
if (isset($array['params']) && is_array($array['params']))
{
// Конвертируем поле параметров в JSON строку.
$parameter = new JRegistry;
$parameter->loadArray($array['params']);
$array['params'] = (string) $parameter;
}
return parent::bind($array, $ignore);
}
/**
* Переопределяем load метод JTable.
*
* @param int $pk Первичный ключ.
* @param boolean $reset Сбрасывать данные перед загрузкой или нет.
*
* @return boolean True если все прошло успешно, в противном случае false.
*/
public function load($pk = null, $reset = true)
{
if (parent::load($pk, $reset))
{
// Конвертируем поле параметров в регистр.
$params = new JRegistry;
$params->loadString($this->params);
$this->params = $params;
return true;
}
else
{
return false;
}
}
}
Изменяем интерфейс администратора
Режим редактирования сообщения должен показывать выбор параметров администратору. Для этого отредактируем файл admin/views/helloworld/tmpl/edit.php:
<?php
// Запрет прямого доступа.
defined('_JEXEC') or die;
// Загружаем тултипы.
JHtml::_('behavior.tooltip');
// Загружаем проверку формы.
JHtml::_('behavior.formvalidation');
// Получаем параметры из формы.
$params = $this->form->getFieldsets('params');
?>
<form action="<?php echo JRoute::_('index.php?option=com_helloworld&layout=edit&id=' . (int) $this->item->id); ?>" method="post" name="adminForm" id="helloworld-form">
<div>
<fieldset>
<legend><?php echo JText::_('COM_HELLOWORLD_HELLOWORLD_DETAILS'); ?></legend>
<ul>
<?php foreach ($this->form->getFieldset('details') as $field) : ?>
<li><?php echo $field->label; echo $field->input; ?></li>
<?php endforeach; ?>
</ul>
</fieldset>
</div>
<div>
<?php echo JHtml::_('sliders.start', 'helloworld-slider');
foreach ($params as $name => $fieldset):
echo JHtml::_('sliders.panel', JText::_($fieldset->label), $name.'-params');
if (isset($fieldset->description) && trim($fieldset->description)) : ?>
<p><?php echo $this->escape(JText::_($fieldset->description));?></p>
<?php endif;?>
<fieldset >
<ul>
<?php foreach ($this->form->getFieldset($name) as $field) : ?>
<li><?php echo $field->label; ?><?php echo $field->input; ?></li>
<?php endforeach; ?>
</ul>
</fieldset>
<?php endforeach; ?>
<?php echo JHtml::_('sliders.end'); ?>
</div>
<div>
<input type="hidden" name="task" value="" />
<?php echo JHtml::_('form.token'); ?>
</div>
</form>
Здесь мы добавили слайдеры с помощью JHtml
и панель, в которой будут отображаться наши параметры.
Изменяем публичную часть
Необходимо также отредактировать публичную часть для того, чтобы был учтен новый параметр show_category
. Для этого изменим модель:
- она должна объединять глобальные параметры и индивидуальные параметры
- она должна предоставлять категорию
Откройте файл site/models/helloworld.php и замените код на следующий:
<?php
// Запрет прямого доступа.
defined('_JEXEC') or die;
// Подключаем библиотеку modelitem Joomla.
jimport('joomla.application.component.modelitem');
/**
* Модель сообщения компонента HelloWorld.
*/
class HelloWorldModelHelloWorld extends JModelItem
{
/**
* Получаем сообщение.
*
* @param int $id Id сообщения.
*
* @return object Объект сообщения, которое отображается пользователю.
*
* @throws Exception Если сообщение не найдено.
*
*/
public function getItem($id = null)
{
// Если id не установлено, то получаем его из состояния.
$id = (!empty($id)) ? $id : (int) $this->getState('message.id');
if ($this->_item === null)
{
$this->_item = array();
}
if (!isset($this->_item[$id]))
{
// Конструируем SQL запрос.
$query = $this->_db->getQuery(true);
$query->select('h.greeting, h.params')
->from('#__helloworld as h')
->select('c.title as category')
->leftJoin('#__categories as c ON c.id = h.catid')
->where('h.id = ' . (int) $id);
$this->_db->setQuery($query);
$data = $this->_db->loadObject();
// Генерируем исключение, если сообщение не найдено.
if (empty($data))
{
throw new Exception(JText::_('COM_HELLOWORLD_ERROR_MESSAGE_NOT_FOUND'), 404);
}
// Загружаем JSON строку параметров.
$params = new JRegistry;
$params->loadString($data->params);
$data->params = $params;
// Объединяем глобальные параметры с индивидуальными.
$params = clone $this->getState('params');
$params->merge($data->params);
$data->params = $params;
$this->_item[$id] = $data;
}
return $this->_item[$id];
}
/**
* Метод для авто-заполнения состояния модели.
*
* Заметка. Вызов метода getState в этом методе приведет к рекурсии.
*
* @return void
*/
protected function populateState()
{
$app = JFactory::getApplication();
// Получаем Id сообщения из Запроса.
$id = $app->input->getInt('id', 0);
// Добавляем Id сообщения в состояние модели.
$this->setState('message.id', $id);
// Загружаем глобальные параметры.
$params = $app->getParams();
// Добавляем параметры в состояние модели.
$this->setState('params', $params);
parent::populateState();
}
}
Класс был значительно изменен. Мы убрали метод getTable()
, так как JTable
мы больше не используем. Дело в том, что нам необходимо получить категорию, а информация о ней хранится в таблице #__categories
. А как известно, класс JTable
используется для работы с одной таблицей, поэтому вместо него в метод getItem()
был добавлен запрос для выборки сообщения вместе с категорией. Мы также генерируем исключение, если запрос в базу данных вернул пустой результат. Мы отмечаем это исключение кодом
404
, который потом мы обработаем в представлении.
Тут же присутствует обработка параметров. И снова мы применяем удобный объект JRegistry для преобразования JSON строки в объект. Обратите внимание, что при объединении глобальных параметров с индивидуальными мы предварительно делаем копию объекта параметров c помощью clone. Глобальные параметры мы получаем в методе populateState()
.
Теперь необходимо изменить представление и шаблон.
site/views/helloworld/view.html.php
<?php
// Запрет прямого доступа.
defined('_JEXEC') or die;
// Подключаем библиотеку представления Joomla.
jimport('joomla.application.component.view');
/**
* HTML представление сообщения компонента HelloWorld.
*/
class HelloWorldViewHelloWorld extends JViewLegacy
{
/**
* Сообщение.
*
* @var object
*/
protected $item;
/**
* Переопределяем метод display класса JViewLegacy.
*
* @param string $tpl Имя файла шаблона.
*
* @throws Exception Если сообщение не найдено.
*
* @return void
*/
public function display($tpl = null)
{
try
{
// Получаем сообщение.
$this->item = $this->get('Item');
// Подготавливаем документ.
$this->_prepareDocument();
// Отображаем представление.
parent::display($tpl);
}
catch (Exception $e)
{
if ($e->getCode() == 404)
{
// Сообщение не найдено.
throw new Exception($e->getMessage(), 404);
}
JFactory::getApplication()->enqueueMessage(JText::_('COM_HELLOWORLD_ERROR_OCCURRED'), 'error');
JLog::add($e->getMessage(), JLog::ERROR, 'com_helloworld');
}
}
/**
* Подготавливает документ.
*
* @return void
*/
protected function _prepareDocument()
{
$app = JFactory::getApplication();
$menus = $app->getMenu();
$title = null;
// Так как приложение устанавливает заголовок страницы по умолчанию,
// мы получаем его из пункта меню.
$menu = $menus->getActive();
if ($menu)
{
$this->item->params->def('page_heading', $this->item->params->get('page_title', $menu->title));
}
else
{
$this->item->params->def('page_heading', JText::_('COM_HELLOWORLD_DEFAULT_PAGE_TITLE'));
}
// Получаем заголовок страницы в браузере из параметров.
$title = $this->item->params->get('page_title', '');
if (empty($title))
{
$title = $app->getCfg('sitename');
}
elseif ($app->getCfg('sitename_pagetitles', 0) == 1)
{
$title = JText::sprintf('JPAGETITLE', $app->getCfg('sitename'), $title);
}
elseif ($app->getCfg('sitename_pagetitles', 0) == 2)
{
$title = JText::sprintf('JPAGETITLE', $title, $app->getCfg('sitename'));
}
if (empty($title))
{
$title = $this->item->greeting;
}
// Устанавливаем заголовок страницы в браузере.
$this->document->setTitle($title);
// Добавляем поддержку метаданных из пункта меню.
if ($this->item->params->get('menu-meta_description'))
{
$this->document->setDescription($this->item->params->get('menu-meta_description'));
}
if ($this->item->params->get('menu-meta_keywords'))
{
$this->document->setMetadata('keywords', $this->item->params->get('menu-meta_keywords'));
}
if ($this->item->params->get('robots'))
{
$this->document->setMetadata('robots', $this->item->params->get('robots'));
}
}
}
Помните, в модели мы генерировали исключение с кодом 404
? Теперь мы обрабатываем это исключение и генерируем новое исключение с кодом 404
. Далее Joomla перехватит это исключение, и в итоге для пустого результата мы получим стандартную страницу 404 с сообщением "Сообщение не найдено".
В методе _prepareDocument()
вместо $this->params
мы используем $this->item->params
, так как теперь параметры у нас хранятся в $this->item->params
.
site/views/helloworld/tmpl/default.php
<?php
// Запрет прямого доступа.
defined('_JEXEC') or die;
?>
<?php if ($this->item->params->get('show_page_heading')) : ?>
<h1>
<?php echo $this->escape($this->item->params->get('page_heading')); ?>
</h1>
<?php endif; ?>
<h2>
<?php echo $this->item->greeting .
(($this->item->category and $this->item->params->get('show_category')) ? (' (' . $this->item->category . ')') : ''); ?>
</h2>
В шаблоне мы получаем параметр show_category
и в зависимости от его значения (1
или 0
) отображаем или не отображаем категорию в скобках.
Добавляем языковые константы
Откройте файл admin/language/en-GB/en-GB.com_helloworld.ini и добавьте:
COM_HELLOWORLD_CONFIGURATION="HelloWorld! Configuration"
COM_HELLOWORLD_CONFIG_GREETING_SETTINGS_LABEL="Messages settings"
COM_HELLOWORLD_CONFIG_GREETING_SETTINGS_DESC="Settings that will be applied to all messages by default."
COM_HELLOWORLD_HELLOWORLD_FIELD_SHOW_CATEGORY_LABEL="Show category"
COM_HELLOWORLD_HELLOWORLD_FIELD_SHOW_CATEGORY_DESC="If set to Show, the title of the message's category will show."
Откройте файл admin/language/ru-RU/ru-RU.com_helloworld.ini и добавьте:
COM_HELLOWORLD_CONFIGURATION="Конфигурация"
COM_HELLOWORLD_CONFIG_GREETING_SETTINGS_LABEL="Параметры сообщения"
COM_HELLOWORLD_CONFIG_GREETING_SETTINGS_DESC="Параметры вступят в силу для всех сообщений."
COM_HELLOWORLD_HELLOWORLD_FIELD_SHOW_CATEGORY_LABEL="Выводить категорию"
COM_HELLOWORLD_HELLOWORLD_FIELD_SHOW_CATEGORY_DESC="Если показать, то будет показываться и категория."
Откройте файл site/language/en-GB/en-GB.com_helloworld.ini и добавьте:
COM_HELLOWORLD_ERROR_MESSAGE_NOT_FOUND="Message not found"
Откройте файл site/language/ru-RU/ru-RU.com_helloworld.ini и добавьте:
COM_HELLOWORLD_ERROR_MESSAGE_NOT_FOUND="Сообщение не найдено"
Собираем пакет установки компонента
Не забудьте поменять номер версии в файле helloworld.xml:
<version>0.0.10</version>
Добавляем поддержку конфигурацию:
<filename>config.xml</filename>
helloworld.xml
<?xml version="1.0" encoding="utf-8"?>
<extension type="component" version="2.5.0" method="upgrade">
<name>COM_HELLOWORLD</name>
<!-- Следующие элементы необязательны -->
<creationDate>Июль 2012</creationDate>
<author>Вася Пупкин</author>
<authorEmail>Ваш e-mail</authorEmail>
<authorUrl>Ваш сайт</authorUrl>
<copyright>Информация о копирайте</copyright>
<license>Информация о лицензии</license>
<!-- Версия записывается в таблицу компонентов -->
<version>0.0.10</version>
<!-- Описание необязательно -->
<description>COM_HELLOWORLD_DESCRIPTION</description>
<!-- Запускается при установке -->
<install>
<sql>
<file driver="mysql" charset="utf8">sql/install.mysql.utf8.sql</file>
</sql>
</install>
<!-- Запускается при удалении -->
<uninstall>
<sql>
<file driver="mysql" charset="utf8">sql/uninstall.mysql.utf8.sql</file>
</sql>
</uninstall>
<!-- Запускается при обновлении -->
<update>
<schemas>
<schemapath type="mysql">sql/updates/mysql</schemapath>
</schemas>
</update>
<!-- Раздел основных файлов сайта -->
<!-- Обратите внимание на значение аттрибута folder: Этот аттрибут описывает папку нашего пакета-установщика из которой должны копироваться файлы.
Поэтому указанные в этом разделе файлы будут скопированы из папки /site/ нашего пакета-установщика в соответствующую папку установки. -->
<files folder="site">
<filename>index.html</filename>
<filename>controller.php</filename>
<filename>helloworld.php</filename>
<folder>language</folder>
<folder>models</folder>
<folder>views</folder>
</files>
<media destination="com_helloworld" folder="media">
<filename>index.html</filename>
<folder>images</folder>
</media>
<!-- Администрирование -->
<administration>
<!-- Раздел Меню -->
<menu img="../media/com_helloworld/images/hello-16x16.png">COM_HELLOWORLD_MENU</menu>
<!-- Раздел основных файлов администрирования -->
<!-- Обратите внимание на значение аттрибута folder: Этот аттрибут описывает папку нашего пакета-установщика из которой должны копироваться файлы.
Поэтому указанные в этом разделе файлы будут скопированы из папки /admin/ нашего пакета-установщика в соответствующую папку установки. -->
<files folder="admin">
<filename>index.html</filename>
<filename>config.xml</filename>
<filename>controller.php</filename>
<filename>helloworld.php</filename>
<folder>controllers</folder>
<folder>helpers</folder>
<folder>models</folder>
<folder>sql</folder>
<folder>tables</folder>
<folder>views</folder>
</files>
<languages folder="admin">
<language tag="en-GB">language/en-GB/en-GB.com_helloworld.ini</language>
<language tag="en-GB">language/en-GB/en-GB.com_helloworld.sys.ini</language>
<language tag="ru-RU">language/ru-RU/ru-RU.com_helloworld.ini</language>
<language tag="ru-RU">language/ru-RU/ru-RU.com_helloworld.sys.ini</language>
</languages>
</administration>
</extension>
Содержимое директории с кодом:
helloworld.xml
site/index.html
site/helloworld.php
site/controller.php
site/language/index.html
site/language/en-GB/index.html
site/language/en-GB/en-GB.com_helloworld.ini
site/language/ru-RU/index.html
site/language/ru-RU/ru-RU.com_helloworld.ini
site/models/index.html
site/models/helloworld.php
site/views/index.html
site/views/helloworld/index.html
site/views/helloworld/view.html.php
site/views/helloworld/tmpl/index.html
site/views/helloworld/tmpl/default.xml
site/views/helloworld/tmpl/default.php
admin/index.html
admin/config.xml
admin/controller.php
admin/helloworld.php
admin/controllers/index.html
admin/controllers/helloworld.php
admin/controllers/helloworlds.php
admin/helpers/index.html
admin/helpers/helloworld.php
admin/language/index.html
admin/language/en-GB/index.html
admin/language/en-GB/en-GB.com_helloworld.ini
admin/language/en-GB/en-GB.com_helloworld.sys.ini
admin/language/ru-RU/index.html
admin/language/ru-RU/ru-RU.com_helloworld.ini
admin/language/ru-RU/ru-RU.com_helloworld.sys.ini
admin/models/index.html
admin/models/helloworld.php
admin/models/helloworlds.php
admin/models/fields/index.html
admin/models/fields/helloworld.php
admin/models/forms/index.html
admin/models/forms/helloworld.js
admin/models/forms/helloworld.xml
admin/models/rules/index.html
admin/models/rules/greeting.php
admin/sql/index.html
admin/sql/install.mysql.utf8.sql
admin/sql/uninstall.mysql.utf8.sql
admin/sql/updates/index.html
admin/sql/updates/mysql/index.html
admin/sql/updates/mysql/0.0.1.sql
admin/sql/updates/mysql/0.0.4.sql
admin/sql/updates/mysql/0.0.9.sql
admin/sql/updates/mysql/0.0.10.sql
admin/tables/index.html
admin/tables/helloworld.php
admin/views/index.html
admin/views/helloworld/index.html
admin/views/helloworld/view.html.php
admin/views/helloworld/submitbutton.js
admin/views/helloworld/tmpl/index.html
admin/views/helloworld/tmpl/edit.php
admin/views/helloworlds/index.html
admin/views/helloworlds/view.html.php
admin/views/helloworlds/tmpl/index.html
admin/views/helloworlds/tmpl/default.php
admin/views/helloworlds/tmpl/default_body.php
admin/views/helloworlds/tmpl/default_foot.php
admin/views/helloworlds/tmpl/default_head.php
language/index.html
language/en-GB/index.html
language/en-GB/en-GB.com_helloworld.sys.ini
language/ru-RU/index.html
language/ru-RU/ru-RU.com_helloworld.sys.ini
media/index.html
media/images/index.html
media/images/hello-16x16.png
media/images/hello-48x48.png
Запакуйте директорию в архивный файл (zip, tar, tar.gz, bz2) или скачайте его напрямую c GitHub. Далее установите его, используя менеджер расширений Joomla. Теперь мы можем конфигурировать общие параметры компонента и индивидуальные параметры сообщений.
В следующей части мы рассмотрим создание списков контроля доступов (ACL - Access Control List).