Создание компонента для Joomla

Часть 9 - поддержка категорий

Joomla

Часть 9 - поддержка категорий

Добавление категорий для компонента на самом деле довольно простая задача.

Изменяем SQL файлы

Сначала необходимо изменить структуру таблиц базы данных, а именно добавить поле, где будет храниться id категории.

Вносим изменения в файл 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',
 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.9.sql для изменения структуры таблицы во время установки новой версии компонента:

ALTER TABLE `#__helloworld` ADD `catid` int(11) NOT NULL DEFAULT '0'

Изменяем форму

Теперь сообщение может принадлежать категории. Далее мы должны изменить форму редактирования. Откройте файл admin/models/forms/helloworld.xml и измените его:

<?xml version="1.0" encoding="utf-8"?>
<form
    addrulepath="/administrator/components/com_helloworld/models/rules"
>
    <fieldset>
        <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>
</form>

Мы добавили поле категории, в котором с помощью аттрибута extension указали, что оно принадлежит нашему компоненту com_helloworld. Обратите внимание на то, что id категории может быть 0, то есть без категории.

Изменяем пункт меню

Тип меню HelloWorld отображает выпадающий список всех сообщений. Если сообщение принадлежит категории, то неплохо было бы добавить название категории рядом с сообщением. Вносим изменения в файл admin/models/fields/helloworld.php:

<?php
// Запрет прямого доступа.
defined('_JEXEC') or die;
 
// Подключаем тип поля list.
jimport('joomla.form.helper');
JFormHelper::loadFieldClass('list');
 
/**
 * Класс поля формы HelloWorld компонента HelloWorld.
 */
class JFormFieldHelloWorld extends JFormFieldList
{
    /**
     * Тип поля.
     *
     * @var  string
     */
    protected $type = 'HelloWorld';
 
    /**
     * Метод для получения списка опций для поля списка.
     *
     * @return  array  Массив JHtml опций.
     */
    protected function getOptions()
    {
        // Получаем объект базы данных.
        $db = JFactory::getDbo();
 
        // Конструируем SQL запрос.
        $query = $db->getQuery(true);
        $query->select('h.id, h.greeting, h.catid')
            ->from('#__helloworld as h')
            ->select('c.title as category')
            ->leftJoin('#__categories AS c ON c.id = h.catid');
        $db->setQuery($query);
        $messages = $db->loadObjectList();
 
        // Массив JHtml опций.
        $options = array();
 
        if ($messages)
        {
            foreach ($messages as $message)
            {
                $options[] = JHtml::_('select.option', $message->id,
                    $message->greeting . ($message->catid ? ' (' . $message->category . ')' : '')
                );
            }
        }
 
        $options = array_merge(parent::getOptions(), $options);
 
        return $options;
    }
}

Теперь название категории будет находиться в скобках после сообщения.

Добавляем подменю (дочернее меню)

Мы можем добавить подменю используя хелпер класс для нашего компонента. Создайте файл admin/helpers/helloworld.php:

<?php
// Запрет прямого доступа.
defined('_JEXEC') or die;
 
/**
 * Хелпер HelloWorld компонента.
 */
abstract class HelloWorldHelper
{
    /**
     * Конфигурируем подменю.
     *
     * @param   string  $submenu  Активный пункт меню.
     *
     * @return  void
     */
    public static function addSubmenu($submenu)
    {
        // Добавляем пункты подменю.
        JSubMenuHelper::addEntry(
            JText::_('COM_HELLOWORLD_SUBMENU_MESSAGES'),
            'index.php?option=com_helloworld',
            $submenu == 'messages'
        );
 
        JSubMenuHelper::addEntry(
            JText::_('COM_HELLOWORLD_SUBMENU_CATEGORIES'),
            'index.php?option=com_categories&view=categories&extension=com_helloworld',
            $submenu == 'categories'
        );
 
        // Устанавливаем глобальные свойства.
        $document = JFactory::getDocument();
        $document->addStyleDeclaration('.icon-48-helloworld ' .
            '{background-image: url(../media/com_helloworld/images/hello-48x48.png);}');
 
        if ($submenu == 'categories')
        {
            $document->setTitle(JText::_('COM_HELLOWORLD_ADMINISTRATION_CATEGORIES'));
        }
    }
}

Метод addSubmenu() выполняет следующее:

  • добавляет элементы в подменю, используся метод addEntry() класса JSubMenuHelper (он находится в фале administrator/includes/toolbar.php)
  • изменяет некоторые css свойства (для отображения иконок)
  • меняет заголовок браузера, если выбраны категории

Обратите внимание, что в этом методе теперь находится css-класс .icon-48-helloworld. Для вызова этого метода нам необходимо изменить общий контроллер admin/controller.php и точку входа admin/helloworld.php

admin/controller.php

<?php
// Запрет прямого доступа.
defined('_JEXEC') or die;
 
// Подключаем библиотеку контроллера Joomla.
jimport('joomla.application.component.controller');
 
/**
 * Общий контроллер компонента Hello World.
 */
class HelloWorldController extends JControllerLegacy
{
    /**
     * Задача по отображению.
     *
     * @param   boolean  $cachable   Если true, то представление будет закешировано.
     * @param   array    $urlparams  Массив безопасных url-параметров и их валидных типов переменных.
     *
     * @return  void
     */
    public function display($cachable = false, $urlparams = array())
    {
        // Устанавливаем представление по умолчанию, если оно не было установлено.
        $input = JFactory::getApplication()->input;
        $input->set('view', $input->getCmd('view', 'HelloWorlds'));
 
        // Устанавливаем подменю.
        HelloWorldHelper::addSubmenu('messages');
 
        parent::display($cachable);
    }
}

admin/helloworld.php

<?php
// Запрет прямого доступа.
defined('_JEXEC') or die;
 
// Устанавливаем обработку ошибок в режим использования Exception.
JError::$legacy = false;
 
// Подключаем хелпер.
JLoader::register('HelloWorldHelper', dirname(__FILE__) . '/helpers/helloworld.php');
 
// Подключаем библиотеку контроллера Joomla.
jimport('joomla.application.component.controller');
 
// Получаем экземпляр контроллера с префиксом HelloWorld.
$controller = JControllerLegacy::getInstance('HelloWorld');
 
// Исполняем задачу task из Запроса.
$input = JFactory::getApplication()->input;
$controller->execute($input->getCmd('task', 'display'));
 
// Перенаправляем, если перенаправление установлено в контроллере.
$controller->redirect();

С помощью JLoader мы зарегистрировали наш хелпер класс HelloWorldHelper в автозагрузчике, указав имя класса и путь к файлу, в котором этот класс определен. Таким образом, в случае обращения к этому классу он будет подключен автоматически.

Добавляем языковые константы

Откройте файл admin/language/en-GB/en-GB.com_helloworld.ini и добавьте:

COM_HELLOWORLD_HELLOWORLD_FIELD_CATID_DESC="The category the messages belongs to"
COM_HELLOWORLD_HELLOWORLD_FIELD_CATID_LABEL="Category"
COM_HELLOWORLD_SUBMENU_MESSAGES="Messages"
COM_HELLOWORLD_SUBMENU_CATEGORIES="Categories"

Откройте файл admin/language/ru-RU/ru-RU.com_helloworld.ini и добавьте:

COM_HELLOWORLD_HELLOWORLD_FIELD_CATID_DESC="Категория, которой принадлежит сообщение."
COM_HELLOWORLD_HELLOWORLD_FIELD_CATID_LABEL="Категория"
COM_HELLOWORLD_SUBMENU_MESSAGES="Сообщения"
COM_HELLOWORLD_SUBMENU_CATEGORIES="Категории"
COM_HELLOWORLD_ADMINISTRATION_CATEGORIES="Администрирование категорий"

Собираем пакет установки компонента

Не забудьте поменять номер версии в файле helloworld.xml:

<version>0.0.9</version>

Добавляем подержку хелперов:

<folder>helpers</folder>

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.9</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>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/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/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 (контроль доступа) для нашего компонента.

В следующей части мы рассмотрим создание конфигурации компонента и параметров для сообщений.

Код для этой части

Скачать com_helloworld часть 9

Актуальный код части 9 на GitHub

Dmitry Rekun
Работаю в банковской сфере, а с веб-разработкой (непосредственно с Joomla) столкнулся в 2007 году. Теперь это моё хобби и время от времени вторая работа. Какое-то время вёл свой блог, но решил попробовать работать в команде. И вот c 2012 года я здесь :)