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

Часть 4 - использование базы данных и типов полей

Joomla
Добавление в избранное
Сохранить
1

Часть 4 - использование базы данных и типов полей

Компоненты обычно управляют содержимым используя базу данных. Во время фаз установки/удаления/обновления компонента вы можете выполнять SQL запросы, которые хранятся в текстовых файлах.

Использование базы данных

Создайте два файла admin/sql/install.mysql.utf8.sql и admin/sql/updates/mysql/0.0.4.sql с одинаковым содержимым:

DROP TABLE IF EXISTS `#__helloworld`;

CREATE TABLE `#__helloworld` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`greeting` varchar(25) NOT NULL,
PRIMARY KEY  (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=0 DEFAULT CHARSET=utf8;

INSERT INTO `#__helloworld` (`greeting`) VALUES
('Hello World!'),
('Good bye World!');

Файл admin/sql/install.mysql.utf8.sql будет выполнен во время установки. Файл admin/sql/updates/mysql/0.0.4.sql будет выполнен во время обновления. Чтобы они сработали, в helloworld.xml необходимо добавить следующие строки:

<!-- Запускается при установке -->
<install>
    <sql>
        <file driver="mysql" charset="utf8">sql/install.mysql.utf8.sql</file>
    </sql>
</install>
<!-- Запускается при обновлении -->
<update>
    <schemas>
        <schemapath type="mysql">sql/updates/mysql</schemapath>
    </schemas>
</update>

Когда компонент устанавливается, то читаются все файлы в папке обновления SQL (например, admin/sql/updates/mysql) и для внесения версии компонента в таблицу #__schemas используется имя последнего файла в алфавитном порядке. Это значение должно быть в таблице для того, чтобы автоматическое обновление могло выполнять SQL файлы обновления для будущих версий. Поэтому считается хорошей привычкой создавать SQL файл обновления для каждой версии (даже если он пустой или содержит только комментарии). Таким образом версия в таблице #__schemas всегда будет совпадать с версией компонента.

Теперь создайте файл admin/sql/uninstall.mysql.utf8.sql - он будет выполнен во время удаления:

DROP TABLE IF EXISTS `#__helloworld`;

Чтобы он сработал, в helloworld.xml необходимо добавить следующие строки:

<!-- Запускается при удалении -->
<uninstall>
 <sql>
 <file driver="mysql" charset="utf8">sql/uninstall.mysql.utf8.sql</file>
 </sql>
</uninstall>

Все эти строки необходимо добавить в определенном месте. Как обычно, в конце статьи будет приведено содержимое файла helloworld.xml, и вы сможете посмотреть где именно они расположены.

Добавление нового типа поля

На данном этапе наш тип поля для сообщений жестко зашит в код. Мы же должны использовать базу данных для выбора сообщения. Измените содержимое файла site/views/helloworld/tmpl/default.xml на следующий код:

<?xml version="1.0" encoding="utf-8"?>
<metadata>
    <layout title="COM_HELLOWORLD_HELLOWORLD_VIEW_DEFAULT_TITLE">
        <message>COM_HELLOWORLD_HELLOWORLD_VIEW_DEFAULT_DESC</message>
    </layout>
    <fields
        name="request"
        addfieldpath="/administrator/components/com_helloworld/models/fields"
    >
        <fieldset name="request">
            <field
                name="id"
                type="helloworld"
                label="COM_HELLOWORLD_HELLOWORLD_FIELD_GREETING_LABEL"
                description="COM_HELLOWORLD_HELLOWORLD_FIELD_GREETING_DESC"
            />
        </fieldset>
    </fields>
</metadata>

Мы добавили новый тип поля "helloworld" и с помощью атрибута addfieldpath сообщаем Joomla о том, что определение этого поля необходимо искать в папке /administrator/components/com_helloworld/models/fields.

Создайте файл 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('id, greeting')
                ->from('#__helloworld');
        $db->setQuery($query);
        $messages = $db->loadObjectList();
 
        // Массив JHtml опций.
        $options = array();

        if ($messages)
        {
            foreach($messages as $message) 
            {
                $options[] = JHtml::_('select.option', $message->id, $message->greeting);
            }
        }

        $options = array_merge(parent::getOptions(), $options);
 
        return $options;
    }
}

Мы создали новый тип поля HelloWorld, расширив класс JFormFieldList, который является дочерним для класса JFormField. Наш тип поля отображает выпадающий список сообщений, который мы получаем из базы данных и генерируем с помощью класса JHtml.

Отображение выбранного сообщения

Когда создается/обновляется пункт меню компонента, Joomla сохраняет идентификатор сообщения. Теперь модель HelloWorldModelHelloWorld должна позаботиться о том, чтобы выбирать сообщение в зависимости от идентификатора и данных в базе данных. Измените файл site/models/helloworld.php:

<?php
// Запрет прямого доступа.
defined('_JEXEC') or die;
 
// Подключаем библиотеку modelitem Joomla.
jimport('joomla.application.component.modelitem');
 
/**
 * Модель сообщения компонента HelloWorld.
 */
class HelloWorldModelHelloWorld extends JModelItem
{
    /**
     * Возвращает ссылку на объект таблицы.
     *
     * @param   string  $type    Тип таблицы.
     * @param   string  $prefix  Префикс имени класса таблицы. Необязателен.
     * @param   array   $config  Конифгурационный массив для таблицы. Необязателен.
     *
     * @return  JTable  Объект таблицы.
     */
    public function getTable($type = 'HelloWorld', $prefix = 'HelloWorldTable', $config = array()) 
    {
        return JTable::getInstance($type, $prefix, $config);
    }
 
   /**
     * Получаем сообщение.
     *
     * @param   int  $id  Id сообщения.
     *
     * @return  string  Сообщение, которое отображается пользователю.
     */
     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]))
        {
            // Получаем экземпляр класса TableHelloWorld.
            $table = $this->getTable();
 
            // Загружаем сообщение.
            $table->load($id);
 
            // Назначаем сообщение.
            $this->_item[$id] = $table->greeting;
        }
 
        return $this->_item[$id];
    }
}

Теперь модель получает данные о сообщении с помощью класса таблицы HelloWorldTableHelloWorld. Этот класс таблицы должен быть определен в файле admin/tables/helloworld.php:

<?php
// Запрет прямого доступа.
defined('_JEXEC') or die;
 
// Подключаем библиотеку таблиц Joomla.
jimport('joomla.database.table');

 
/**
 * Класс таблицы HelloWorld.
 */
class HelloWorldTableHelloWorld extends JTable
{
    /**
     * Конструктор.
     *
     * @param   JDatabase  &$db  Коннектор объекта базы данных.
     */
    function __construct(&$db) 
    {
        parent::__construct('#__helloworld', 'id', $db);
    }
}

Класс JTable (который мы расширяем) позволяет работать с таблицей и выполнять над ней CRUD операции. В нашем классе мы передали классу JTable в качестве аргументов имя таблицы #__helloworld и поле первичного ключа id.

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

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

<version>0.0.4</version>

Также мы добавили строки для поддержки sql файлов:

<!-- Запускается при установке -->
<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>models</folder>
<folder>tables</folder>

helloworld.xml


<?xml version="1.0" encoding="utf-8"?>
<extension type="component" version="2.5.0" method="upgrade">
 
    <name>Hello World!</name>
    <!-- Следующие элементы необязательны -->
    <creationDate>Июль 2012</creationDate>
    <author>Вася Пупкин</author>
    <authorEmail>Ваш e-mail</authorEmail>
    <authorUrl>Ваш сайт</authorUrl>
    <copyright>Информация о копирайте</copyright>
    <license>Информация о лицензии</license>
    <!--  Версия записывается в таблицу компонентов -->
    <version>0.0.4</version>
    <!-- Описание необязательно -->
    <description>Описание компонента Hello World! ...</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>models</folder>
        <folder>views</folder>
    </files>
 
    <!-- Администрирование -->
    <administration>
        <!-- Раздел Меню -->
        <menu>Hello World!</menu>
        <!-- Раздел основных файлов администрирования  -->
        <!-- Обратите внимание на значение аттрибута folder: Этот аттрибут описывает папку нашего пакета-установщика из которой должны копироваться файлы. 
        Поэтому указанные в этом разделе файлы будут скопированы из папки /admin/ нашего пакета-установщика в соответствующую папку установки. -->
        <files folder="admin">
            <filename>index.html</filename>
            <filename>helloworld.php</filename>
            <folder>models</folder>
            <folder>sql</folder>
            <folder>tables</folder>
        </files>
    </administration>
 
</extension>

Содержимое директории с кодом:

helloworld.xml
site/index.html
site/helloworld.php
site/controller.php
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/helloworld.php
admin/models/index.html
admin/models/fields/index.html
admin/models/fields/helloworld.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/tables/index.html
admin/tables/helloworld.php

Запакуйте директорию в архивный файл (zip, tar, tar.gz, bz2) или скачайте его напрямую с GitHub. Далее установите его, используя менеджер расширений Joomla. Вы не увидите изменений, но если вы зайдете в базу данных, то обнаружите там таблицу #__helloworld с двумя колонками: id и greeting. А в самой таблице будут две записи: "Hello World!" и "Good bye World!".

Записи в базе данных

В следущей части мы создадим интерфейс администратора.

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

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

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

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

Подпишитесь на рассылку новостей CMScafe