Web-программист занимается разработкой программ, поддерживающих функционирование интернет-сайтов. На основе концептуальных и дизайнерских задач, поставленных заказчиком или работодателем, web-программист создает технически адаптированные страницы, интерфейсы и т.д.
HomeJoomlaРуководство по созданию плагинов в Joomla 1.5
Руководство по созданию плагинов в Joomla 1.5
Плагины позволяют нам редактировать функциональность системы, без непосредственного редактирования существующего кода. Например, плагин можно использовать для обработки контента, перед выводом его на экран, расширить возможности поиска, или создать свой механизм авторизации. В этом уроке мы рассмотрим на примере, как заменить определенную стоку в статье с картинкой.
Введение
Когда мы начинаем создавать новый плагин, мы разбиваем создание на несколько частей. Так нам будет проще вникать в суть и удобнее тестировать плагин. В идеале, мы должны иметь более одного сервера, чтобы тестировать плагин (в частности его установку). Сначала мы создадим простейщий установщик. XML установщика опишит плагин, названный Foobar - My Extension.
Очень важно заметить параметр группы плагина. Вообще все плагины разделяются на логические группы. Вот список групп ядра Joomla: - authentication - content - editors - editors-xtd - search - system - user - xmlrpc Также как вы заметили, мы можем указать свою группу. Также в XMl-файле указывается очень важной информацией является параметр plugin. Этот параметр является уникальным в группе и идентифицирует наш плагин. Далее в таблице видны имена плагинов, которые уже заняты под ядро системы.
Группа
Зарезервированные имена
authentication
gmail
joomla
ldap
openid
content
emailcloak
geshi
loadmodule
pagebreak
pagenavigation
sef
vote
editors
none
tinymce
xstandard
editors-xtd
image
pagebreak
readmore
search
categories
contacts
content
newsfeeds
sections
weblinks
system
cache
debug
legacy
log
remember
user
joomla
xmlrpc
blogger
joomla
После того как вы создали XML файл myextension.xml, создайте файл myextension.php и положите их в каталог foobar. После чего заархивируйте в gz, .tar, .tar.gz, или zip (лучше все-так в zip). Заметьте, что файлы одного плагина не делятся на каталоги, потому что плагины состоят всего из двух файлов. После этого вы можете установить плагин. Но пока он не выполняет никаких действий.
События
Итак у нас должно быть создано событие, которое в дальнейшем будет обрабатываться плагином. Приложения Joomla используют глобальный объект, названный диспетчер событий (event dispatcher), для отправки событий зарегестрированным слушателям (listeners). Глобальный диспетчер событий - это объект JEventDispatcher, который является расширением абстрактного класса JObservable. В Joomla, слушателем может быть класс или функция. Когда мы используем класс слушателя, то этот класс должен быть расширением класса JPlugin. Именно расширением, для того чтобы наследовать основные методы класса. Итак, представьте что у нас есть компонент Foobar, отображающий некоторые записи из БД. Мы можем использовать событие onPrepareFoobar, которое происходит перед выводом записей. Чтобы добавить событие, мы записываем его с помощью метода triggerEvent() в диспетчер событий, который уже передает его слушателям. Метод triggerEvent() содержит два параметра: название события и массив аргументов переданных слушателям. Допустим мы добавляем событие onPrepareFoobar:
Заметьте, что мы передаем $foobarData в виде ссылки, а второй параметр функции обязательно должен быть массивом. Теперь мы можем написать плагины, которые будут обрабатывать $foobarData.
Слушатель
Это одно из важнейших понятий. Вообще слушателями являются плагины, которые обрабатывают события переданные из диспетчера событий.
Регестрирование слушателей
Когда мы создаем новый плагин, если мы используем функции, мы должны информировать приложение о каждой функции и событии. Для этого нужно использовать метод приложений registerEvent(). Метод содержит два параметра: имя события и имя обработчика. Технически имя обработчика может быть именем класса. Например, в ядре Joomla компонент поиска использует плагины для поиска результата. Этот плагин ищет в статьях с помощью функции plgSearchContent() которая обрабатывает событие onSearch:
Как уже говорилось ранее, мы можем использовать как функции, так и классы для обработки событий. Начнем мы наше изучение обработки событий с использования функций. Мы уже сделали заготовку плагина, названного My Plugin в группе Foobar и мы хотим обработать событие названное onPrepareFoobar. Перед тем как мы начнем создавать нашу функцию, мы должны дать ей название. Важно использовать следующее правило именований: слово plg, группа плагина, имя плагина, событие. Например, наша функция будет называться plgFoobarMyPluginPrepareFoobar. Например эту функцию мы можем использовать для обработки события:
$mainframe->registerEvent('onPrepareFoobar','plgFoobarMyPluginPrepareFoobar');
/**
* Переводит переданный параметр в верхний регистр.
*
* @param Foobar Reference to a Foobar object
*/
function plgFoobarMyPluginPrepareFoobar(&$foobar)
{
$foobar->name = strtoupper($foobar->name);
}
Самая важная часть в этой функции - это переданный параметр. Ранее мы передали параметр в виде массива. Каждый элемент массива обрабатывается плагином отдельно. Плагин состоящий из функции, так же может обрабатывать множественные события. Если мы хотим создать слушателя используя класс, для этого мы должны расширить класс JPlugin. Сначала мы должны разобраться как именовать класс слушателя. JPlugin требует специальное именование: слово plg, имя группы плагина, имя плагина. Например, плагин с именем myplugin в группе foobar должен называться plgFoobarMyplugin. Этот пример обрабатывает два события: onPrepareFoobar и onAfterDisplayFoobar.
// Импортируем класс JPlugin
jimport('joomla.event.plugin');
/**
* My Plugin event listener
*/
class plgFoobarMyplugin extends JPlugin
{
/**
* Обрабатываем событие onPrepareFoobar
*
* @param object Foobar to prepare
*/
function onPrepareFoobar(&$foobar)
{
$foobar->name = JString::strtoupper($foobar->name);
}
/**
* Обрабатываем событие onAfterDisplayFoobar
*
* @param object Foobar which is being displayed
* @return string XHTML to display after the Foobar
*/
function onAfterDisplayFoobar(&$foobar)
{
return '<p>'.JText::_('Foobar Name converted to upper case by
My Plugin').'<p>';
}
}
В этом примере, как видите, вам не приходится самим регестрировать события. За вас все сделает фрэймворк Joomla. Главное правильно назвать класс и события. Когда мы импортируем плагин в Joomla, глобальный диспетчер событий автоматически смотрит классы слушателей и регестрирует их. Метод onAfterDisplayFoobar() вернет значение. Вы должны помнить, что ранее мы передали на обработку плагину массив. В этом примере видно как получить обратно уже обработанный массив.
Это очень простой пример. Далее мы рассмотрим более сложные вещи.
Группы плагинов
Плагины делятся на различные группы. Каждая группа плагинов обрабатывает определенный набор событий. В ядре Joomla содержится 8 групп: authentication content editors editors-xtd search system user xmlrpc
Далее мы рассмотрим каждую группу подробнее.
Authentication
Joomla поддерживает 4 различных методов авторизации: GMail Joomla! LDAP OpenID
Также можно создать свои методы авторизации пользователя. В этой группе существует только один метод onAuthenticate. В плагине мы можем установить значение следующих свойств:
Свойство
Описание
birthdate
Дата рождения пользователя
country
Страна пользователя
email
E-mail адрес пользователя
error_message
Сообщение об ошибке или отмена авторизации
fullname
ФИО
gender
Пол
language
Язык
postcode
Почтовый индекс
status
Статус авторизации
timezone
Часовой пояс
username
Логин
Свойство status используется для определения результата авторизации. Таблица содержит три константы, которые может содержать свойство status:
Константа
Описание
JAUTHENTICATE_STATUS_CANCEL
Авторизация отменена
JAUTHENTICATE_STATUS_FAILURE
Ошибка авторизации
JAUTHENTICATE_STATUS_SUCCESS
Авторизация прошла успешно
По-умолчанию в Joomla опубликован только один плагин авторизации - Joomla!. Также вы можете опубликовать LDAP, GMAIL и OpenId.
onAuthenticate
Описание
Происходит, когда пользователь авторизируется на сайте
Параметры
username
Логин
password
Пароль
response
Ссылка на объект JAuthenticationResponse
Content
Плагины группы content, позволяют обрабатывать элементы контента, прежде чем вывести его на экран. Наиболее часто используемое событие - это onPrepareContent. Это событие запускается самым первым. Поставим такую задачу- заменить все символы ":)" на картинку улыбающегося смайлика. Вот решение этой задачи:
Заметьте, что итоговые значения не нужно возвращаться, и параметр $row передается по ссылке. Рассмотрим подробнее атрибуты контента:
Атрибут
Описание
created
дата создания в формате 0000-00-00 00:00:00.
modified
Дата последнего изменения в формате 0000-00-00 00:00:00
text
основной контент элемента
title
заголовок элемента контента
toc
таблица контента
Теперь рассмотрим происходящие события.
onAfterDisplayContent
Описание
Создается xhtml строка после обработки контента
Параметры
row
Ссылка на объект контента
params
ссылка на объект JParameter контента
page
Номер страницы
Возвращает
XHTML после отображения самого контента
onAfterDisplayTitle
Описание
Создается xhtml строка после отображения заголовка страницы
Параметры
row
Ссылка на объект контента
params
ссылка на объект JParameter контента
page
Номер страницы
Возвращает
XHTML после отображения заголовка страницы
onBeforeDisplayContent
Описание
Создается xhtml строка перед отображением элемента text. Например плагин - рейтинг записи
Параметры
row
Ссылка на объект контента
params
ссылка на объект JParameter контента
page
Номер страницы
Возвращает
XHTML перед выводом эелемента text
onPrepareContent
Описание
Обрабатывает один элемент контента. Если вы собираетесь внести изменения в текст элемента, то вы должны использовать это событие.
Параметры
row
Ссылка на объект контента
params
ссылка на объект JParameter контента
page
Номер страницы
Возвращает
Истина, если успешно
onPrepareContent
Описание
Обрабатывает один элемент контента. Если вы собираетесь внести изменения в текст элемента, то вы должны использовать это событие.
Параметры
row
Ссылка на объект контента
params
ссылка на объект JParameter контента
page
Номер страницы
Возвращает
Истина, если успешно
Editors
Пожалуй, самой сложный из всех основных плагинов - это редактор. Одним из основных редакторов является TinyMCE (http://tinymce.moxiecode.com/). TinyMCE это JavaScript редактор, который позволяет пользователю легко изменять данные в текстовом поле без знаний XHTML. Очень важно здесь отметить что кнопки под редактором создаются отдельными плагинами editors-xtd группы, о которых расскажу чуть позже. Приведу список самых популярных редактором за бугром: - ASBRU Web Content Editor - FCKeditor - wysiwygPro - XStandard - Yahoo Rich Text Editor Импортирование нового редактора задача не из легких. Зато если редактор уже встроен, то его очень просто подключать. Yahoo Rich Text Editor подает большие надежды. Это очень навороченный редактор, созданный на основе YUI (Yahoo User Interface). Про интерфейс Yahoo скоро начну вести отдельную серию статей. События плагинов:
onDisplay
Описание
Получить XHTML поле элемента формы
Параметры
name
Уникальное название редактора
content
Инициируемые контент
width
Ширина редактора в пикселях
height
Высота редактора в пикселях
col
Ширина редактора в символах
row
Высота редактора в строках
buttons
Булево значение, служит чтобы скрыть или показать дополнительные кнопки; смотрите событие onCustomEditorButton из раздела editors-xtd этой статьи.
Возвращает
XHTML форма редактора
onGetContent
Описание
Некоторый Javascript код, который возвращает контент
Параметры
editor
Уникальное имя редактора
Возвращает
Запускает Javascript на стороне клиента, который вернет контент редактора. Код должен заканчиваться точкой с запятой.
onGetInsertMethod
Описание
Запускаем javascript код, который определен функцией jInsertEditorText()
Параметры
name
Уникальное имя редактора
Возвращает
Вставляем в редактор заданный текст в позицию курсора
onInit
Описание
Инициализация запускается один раз независимо от колличества выхванных редакторов.
Возвращает
Необходимые функции по запуску редактора
onSave
Описание
Запускаем javascript код, который необходим для сохранения редактора
Параметры
name
Уникальное имя редактора
Возвращает
Javascript строку, которая запускается перед сохранением контента.
onSetContent
Описание
Запускаем javascript код, который установит заданный контент в редакторе
Параметры
name
Уникальное имя редактора
HTML
Новый контент редактора
Возвращает
Новый контент в редакторе
Editors-xtd
Эта группа плагинов используется для расширения функциональности редакторов, путем добавления к ним кнопок. К сожалению встроенный редактор xStandart не поддерживает эту группу плагинов. Существует только одно событие, связанные с этой группой, onCustomEditorButton. Поскольку существует только одно событие, связанное с этой группой, мы, будем использовать функции вместо работы с подклассами JPlugin. Этот пример показывает, каким образом мы можем добавить кнопку смайлика ":)" в редактор.
// no direct access
defined('_JEXEC') or die('Restricted access');
$mainframe->registerEvent('onCustomEditorButton',
'plgSmileyButton');
/**
* Кнопка смайликов
*
* @name string Name of the editor
* @return array Array of three elements: JavaScript action,
Button name, CSS class.
*/
function plgSmileyButton($name)
{
global $mainframe;
// get the image base URI
$doc =& JFactory::getDocument();
$url = $mainframe->isAdmin() ? $mainframe->getSiteURL() : JURI::base();
// get the JavaScript
$js = "
function insertSmiley()
{
jInsertEditorText(' :) ');
}
";
$css = " .button1-left .smiley { background:
url($url/plugins/editors-xtd/smiley1.gif)
100% 0 no-repeat; }";
$css .= "\n .button2-left .smiley { background:
url($url/plugins/editors-xtd/smiley2.gif)
100% 0 no-repeat; }";
$doc->addStyleDeclaration($css);
$doc->addScriptDeclaration($js);
$button = array("insertSmiley()", JText::_('Smiley'),
'smiley');
return $button;
}
В этом коде мы делаем два важных действия: мы определяем обработчик функции, и регистрируем ее в глобальном диспетчере событий. Переходя к функции plgSmileyButton() обратим внимание, что у нее есть параметр $name, который указывает на имя редактора. Он нужен для определения с каким редактором мы работает, так как их может быть несколько на одной странице. В самой функции мы этот параметр никак не используем.
Мы создаем JavaScript и CSS код. Клиент будет выполнять JavaScript при нажатии кнопки. Также мы определяем два стиля CSS, чтобы сделать кнопку в разных местах (в админке и во фронте).
В массиве $button мы возвращаем три элемента. Первый элемент - это JavaScript, который будет выполнен при нажатии кнопки. Вторым элементом является название кнопки. Третьим элементом является название класса CSS для кнопки.
Также в плагине мы используем картинки, которые должны быть добавлены в xml файле:
Перед тем как мы задействуем нашу кнопку в редакторе, обратим внимание на особо полезные методы редактора:
Метод>
Описание
getContent
JavaScript возвращает текст в редакторе
save
JavaScript сохраняет содержимое редактора (используется не во всех редакторах)
setContent
JavaScript устанавливает определенный контент
Все эти методы возвращают JavaScript строку. Мы можем использовать эти строки для создания скриптов, которые взаимодействуют с редактором. Покажу на примере, как пользоваться этими методами:
// получаем редактор
$editor =& JFactory::getEditor();
// вызываем javascript, который вызвращает контент
$getContent = $editor->getContent($name);
// строим javascript, который в окне отображает контент
$js = 'var content = '.$getContent."\n"
.'alert(content);';
onCustomEditorButton
Описание
Добавляет кнопку в редактор
Параметры
name
Уникальное имя редактора
Возвращает
Массив из трех элементов: javascript, имя кнопки и css стиль
Search
Плагины группы search использюется для расширения основного компонента поиска и получения результатов поиска. Есть два события, связанные с этой группой, onSearch и onSearchAreas. Цель onSearchAreas трудновато понять.
В рамках поиска, пользователь может выбрать, где он хочет искать. В данном случае можно выбрать "Статьи", "Ссылки", "Контакты", "Категории", "Разделы", и "Ленты'. Когда мы инициируем onSearchAreas, мы выбираем в каком компоненте будет произведен поиск. Важно: Один плагин может искать в нескольких компонентах. Событие onSearch более косвенно, и срабатывает только когда происходит поиск. В итоге должен вернуться массив результатов. Реалзиция поиска будет зависеть от того, что вы ищете.
onSearch
Описание
Выполняет поиск и возвращает результаты
Параметры
text
Искомая строка
phrase
Тип поиска 'any', 'all', или 'exact'.
ordering
Виды сортировки: 'newest', 'oldest', 'popular', 'alpha' (alphabetical), or 'category'.
areas
Раздел в котором ищем (основано на onSearchArea).
Возвращает
Ассоциативный массив со следующими полями: 'title', 'text', 'created', 'href', 'browsernav' (1 = открывать в новом окне), и 'section' (необязательное).
onSearchAreas
Описание
Получить массив различных областях, которые могли быть обнаружены с помощью этого плагина. Каждый поиск плагин должны обратиться по крайней мере к одной области.
Возвращает
Ассоциативный массив различных областей для поиска.
System Есть четыре важных системных события. Вот их порядок: - onAfterInitialize - onAfterRoute - onAfterDispatch - onAfterRender
onAfterDispatch
Описание
Происходит после того, как была отправлена заявка
onAfterRoute
Описание
Происходит после того как приложение инициализировано
onAfterDispatch
Описание
Происходит когда приложение отрендерено, но еще не отправлено пользователю
onAfterRender
Описание
Происходит после применения роутера
User
Плагины группы user позволяют выполнить дополнительную обработку в конкретных событиях связанных с пользователем. Это особенно полезно, когда эти плагины используются в сочетании с компонентом, который связан с таблицей # __users.
Рассмотрим на примере событие onAfterUserStore. Это событие срабатывает после того, пользователь соханяет свои данные (срабатывает для новых и уже существующих пользователей).
Этот пример показывает, как мы можем поддерживать другую таблицу, # __some_table, когда создан новый пользователь:
$mainframe->registerEvent('onAfterStoreUser',
'plgUserMaintainSomeTableStoreUser');
/**
* Add new rcord to #__some_table when a new user is created
*
* @param array User attributes
* @param boolean True if the user is new
* @param boolean True if the user was successfully stored
* @param string Error message
* @return array Array of three elements: JavaScript action, Button
name, CSS class.
*/
function plgUserMaintainSomeTableStoreUser($user, $isnew, $success,
$msg)
{
// if they are a new user and the store was successful
if ($isnew && $success)
{
// add a record to #__some_table
$db = JFactory::getDBO();
$query = 'INSERT INTO '.$db->nameQuote('#__some_table')
.' SET '.$db->nameQuote('userid').' = '.$user['id'];
$db->setQuery($query);
$db->query();
}
}
onBeforeStoreUser
Описание
Позволяет модифицировать данные пользователя перед сохранением
Параметры
user
Ассоциативный массив с данными пользователя
isnew
Истина если пользователь новый
onAfterStoreUser
Описание
Позволяет выполнять код, после того как данныен пользователя были сохранены
Параметры
user
Ассоциативный массив с данными пользователя
isnew
Истина если пользователь новый
success
Истина в случае успешного сохранения
msg
Сообщение об ошибке если она имеется
onBeforeDeleteUser
Описание
Позволяет нам выполнять дополнительную обработку до того, как пользователь будет удален. Это полезно для обновления неосновных таблиц, которые имеют отношение к ключевым таблицам #__users
Параметры
user
Ассоциативный массив с данными пользователя
onAfterDeleteUser
Описание
Позволяет выполнять код, после того как пользователь удален
Параметры
user
Ассоциативный массив с данными пользователя
success
Истина в случае успешного удаления
msg
Сообщение об ошибке если она имеется
onLoginFailure
Описание
Если логин или пароль введен неверно
Параметры
response
JAuthenticationResponse обьект
onLoginUser
Описание
Происходит при успешной авторизации пользователя
Параметры
user
JAuthenticationResponse обьект
remember
Истина если пользователь хочет быть "запомненным"
Возвращает
Булево знчение ложь, если неуспешно
onLogoutUser
Описание
Пользователь пытается выйти. В это время плагин "joomla" удаляет сессии.
Параметры
user
JAuthenticationResponse обьект
Возвращает
Булево знчение ложь, если неуспешно
XML-RPC
XML-RPC - стандарт/протокол вызова удалённых процедур, основанный на XML, является прародителем SOAP, отличается исключительной простотой применения. XML-RPC, как и любой другой интерфейс RPC, определяет набор стандартных типов данных и команд, которые программист может использовать для доступа к функциональности другой программы, находящейся на другом компьютере в сети. Joomla! включает в себя XML-RPC сервер, который, как мы можем расширить с помощью плагинов.
Плагины XML-RPC состоят из двух частей: обработчик события onGetWebServices, который возвращает массив поддерживающий веб-сервис вызовов, и статический класс или набор функций, которые управляют удаленным вызовом процедур. Если руки дойдут, расскажу об использовании XML-RPC в Joomla в отдельной статье.
onGetWebServices
Описание
Получить ассоциативный массив с описанием доступных методов веб-службы.
Возвращает
Ассоциативный массив в ассоциативном массиве, который определяет доступен ли сервис вызова.