Часть 04 - использование базы данных и типов полей
Компоненты обычно управляют содержимым используя базу данных. Во время фаз установки/удаления/обновления компонента вы можете выполнять 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