Текст книги "Разрботка расширений для CMS Joomla"
Автор книги: Яна Седова
Жанр:
Программирование
сообщить о нарушении
Текущая страница: 1 (всего у книги 10 страниц)
Разрботка расширений для CMS Joomla
Национальный Открытый Университет "ИНТУИТ"
2012
Разрботка расширений для CMS Joomla/ Я.А. Седова – М.: Национальный Открытый Университет «ИНТУИТ», 2012
Курс посвящен разработке расширений под систему управления контентом Joomla. Хотя под эту систему управления контентом разработано множество расширений, в ряде случаев программист может столкнуться с необходимостью написать собственный компонент или модуль. Несмотря на популярность Joomla в том числе в России, на русском языке в настоящее время отсутствуют подробные руководства для разработчиков расширений, поэтому курс для программистов под Joomla представляется актуальным.
Рассматривается ряд классов фреймворка Joomla, в том числе классы для работы с базой данных, электронной почтой, датами, URI, навигационной цепочкой, для генерации кода элементов HTML-форм, SEF-ссылок. Одна из лекций посвящена реализации архитектуры MVC в компонентах под Joomla. Каждая лекция сопровождается практическим примером пошаговой разработки программного кода, представляющего собой тот или иной фрагмент компонента или модуля. Таким образом, к концу курса учащийся получает два работоспособных расширения для Joomla – компонент и модуль. Код сопровождается комментариями и скриншотами. В конце первой лекции приведены задания для самостоятельной работы по вариантам на весь курс. В качестве лабораторных работ учащийся может адаптировать для своего варианта приведенный в практической части лекций программный код.
(c) ООО "ИНТУИТ.РУ", 2012
(c) Я.А. Седова, 2012
Архитектура Joomla. Базовые сведения
Коротко описана архитектура Joomla. Рассмотрены предопределенные константы, языковые файлы, реализация паттерна "фабрика", работа с HTTP-запросом, объектом JApplication, создание панелей инструментов.
Цель лекции:Изучить базовые сведения об архитектуре Joomla. Получить представление о функционировании такого типа расширений как компоненты.
Введение
Для системы управления контентом Joomla созданы тысячи расширений. Тем не менее, использовать готовое решение не всегда целесообразно. Стороннее расширение может быть слишком дорогим или перегружать сервер ненужными для конкретной задачи функциями. Для нестандартной задачи готового решения может вовсе не найтись.
Иногда достаточно воспользоваться одним из конструкторов контента (CCK) для Joomla, позволяющих создавать свои шаблоны для материалов. Однако и CCK – не панацея, и возможно, что и он окажется бессилен. В таком случае возникает необходимость написать собственное расширение.
Может случиться, что готовое решение начнет работать некорректно и придется искать в нем ошибку. Тогда, чтобы разобраться в его коде, программисту понадобится знание принципов построения расширений под Joomla.
Возможно, необходим какой-нибудь модуль для готового расширения, например, вывод списка последних комментариев к фотографиям, но такого модуля для этого расширения нет. Может быть, отдельные части существующего компонента являются платными и слишком дорогими. В этих случаях также стоит задуматься о разработке собственного расширения.
Архитектура Joomla
Фреймворк Joomla состоит из трех уровней (рис. 1.1):
уровень фреймворка;
уровень приложения;
уровень расширений.
Рис. 1.1. Фреймворк Joomla
Уровень фреймворкаобеспечивает базовую функциональность Joomla с помощью набора библиотек и плагинов и собственно фреймворка Joomla:
фреймворк Joomla(или «ядро») – набор классов, обеспечивающих базовую функциональность Joomla. Названия этих классов начинаются с буквы "J" и говорят сами за себя: JDatabase, JUser, JForm, JEditor и т.д.;
библиотекитребуются для работы фреймворка или сторонних расширений;
плагинырасширяют функциональность фреймворка.
Уровень приложениясостоит из приложений, которые расширяют абстрактный класс JApplication. Приложение– глобальный объект, использующийся для обработки запросов.
В этот уровень входят следующие приложения:
JInstallation запускается при установке Joomla. После завершения установки необходимо удалить директорию installation, которая как раз и содержит данное приложение. В дальнейшем установка расширений выполняется с помощью приложения JAdministrator;
JAdministrator управляет всеми функциями для администрирования Joomla;
JSite отвечает за компоновку и отображение фронтенда;
XML-RPC позволяет администрировать сайт Joomla удаленно.
Уровень расширенийсостоит из расширений фреймворка Joomla и приложений:
компоненты– основной тип расширений Joomla. При каждом обращении к Joomla происходит вызов соответствующего компонента. Например, при отображении какой-либо страницы сайта происходит вызов компонента com_content;
модулииспользуются для отображения небольших фрагментов контента, обычно в левой или правой колонке или верхней или нижней областях страницы;
плагиныпозволяют зарегистрировать функции и классы для обработки каких-либо событий, вызванных Joomla, например, поиск по сайту;
языковые файлыпозволяют представить контент Joomla на нескольких языках;
шаблоныотвечают за внешний вид сайта.
Фронтенд и бэкенд
Joomla делится на фронтенд– часть сайта, доступная пользователю, и бэкенд– систему администрирования сайта. Соответственно, в Joomla всего две точки входа – index.php для фронтенда и /administrator/index.php для бэкенда. Чтобы вызвать какой-либо установленный на сайте компонент, необходимо передать его имя (с префиксом «com_») скрипту index.php или /administrator/index.php в переменной option в строке URL. Например, переход по ссылке ссылка: http://localhost/joomla/index.php?option=com_bannersприведет к вызову компонента banners.
Большинство компонентов для Joomla делятся на фронтенд и бэкенд, и их код распределяется по двум папкам, каждая из которых называется по схеме com_<имя компонента>. В каждой из этих папок должен находиться файл, являющийся точкой входа, и называющийся так же, как компонент, т.е. <имя компонента>.php. Схематически это можно изобразить так:
administrator |– components ..|– com_mycomponent ....|– mycomponent.php components ..|– com_mycomponent ....|– mycomponent.php
Предопределенные константы
В Joomla определен ряд констант, хранящих значения путей: JPATH_BASE – путь к корневой директории текущего приложения; JPATH_ROOT – путь к корневой директории сайта, JPATH_COMPONENT – путь к директории компонента, JPATH_COMPONENT_SITE – путь к фронтенду компонента, JPATH_COMPONENT_ADMINISTRATOR – путь к бэкенду компонента и т.д. Полный их список можно найти в документации. Все эти константы возвращают значения абсолютных путей в файловой системе. Если вам необходимо получить путь для использования в URL, следует воспользоваться методом JURI::base().
В файле index.php, расположенном в корневой директории Joomla, определена константа _JEXEC. Большинство PHP-файлов, написанных под Joomla, начинаются с выражения
defined('_JEXEC') or die('Restricted access');
Данное выражение осуществляет проверку, был ли файл, в котором оно записано, вызван из Joomla. Таким путем запрещается доступ к файлу извне, чтобы предотвратить взлом сайта.
Еще одна популярная константа Joomla – DS, разделитель директорий, принятый в конкретной операционной системе (например, прямой или обратный слеш).
Языковые файлы
Joomla позволяет создать мультиязыковый сайт, задавая для каждого пользователя язык сайта и панели управления. Данная возможность реализована следующим образом: в кодах расширений при необходимости вывести на экран какой-либо заранее известный текст (например, сообщение об успешном выполнении запроса пользователя) вместо этого текста записывается его эквивалент ( ключ). Для каждого языка, поддерживающегося данным расширением, создаются языковые файлы, которые хранят переводыдля всех ключей, встретившихся в кодах расширения. Например, для ключа «COM_MYCOMPONENT_HELLO_WORLD» перевод на английский язык может задаваться как «Hello, world!», на русский – «Здравствуй, мир!», на французский – «Bonjour le monde!» и т.д.
Языковые файлы фронтенда хранятся в папке /language/
Языковые файлы бэкенда хранятся в папке /administrator/language/
Кроме файлов .ini, для расширения должен также быть создан файл *.sys.ini, в котором могут храниться переводы сообщений, выводящихся после установки расширения, переводы пунктов меню, создающихся для компонента в панели управления, переводы параметров компонента и переводы надписей, выводящихся в менеджере расширений. Например, путь к файлу .sys.ini компонента contact для русского языка выглядит так: /administrator/language/ru-RU/ru-RU.com_contact.sys.ini
Содержимое языкового файла состоит из пар "ключ-значение" и, при необходимости, комментариев. Пустые строки игнорируются. Комментарии начинаются с символа ";". Например:
; Это комментарий
Ключ – это строка для перевода, а значение – это перевод данной строки на заданный язык. Ключ отделяется от значения знаком равенства:
КЛЮЧ=Значение
Например:
COM_CONTACT="Контакты"
Ключ должен быть записан в верхнем регистре и не должен содержать пробелы. Все ключи во фронтенде должны начинаться со строки <префикс><имя расширения>_, например:
COM_CONTACT_CHANGE_CONTACT_BUTTON
Значение (перевод ключа) должно быть заключено в двойные кавычки. Если значение к тому же содержит двойные кавычки, то они должны быть записаны в виде HTML-сущности, например, ".
Для использования переводов применяются методы статического класса JText _(), sprint() и printf().
Простейший способ вывести перевод строки – использовать метод JText::_(), который просто переводит строку, переданную ему параметром. Например:
echo JText::_('COM_MYCOMPONENT_HELLO_WORLD');
Если перевод для заданной строки не будет найден в языковых файлах, то метод _() вернет саму эту строку. Перед поиском строка будет переведена в верхний регистр, поэтому не имеет значения, в каком регистре ее записать в коде.
Если в строку необходимо включить какие-либо значения, то используются методы JText sprintf() и printf(), аналогичные одноименным функциям в PHP. Их параметрами являются строка для перевода и любое количество аргументов для подстановки в переведенную строку. Сами параметры не будут переведены. Методы sprintf() и printf() различаются тем, что printf() выводит получившуюся строку на экран и возвращает ее длину, а sprintf() возвращает саму строку и ничего не выводит.
Например, если в языковом файле ru-RU.com_mycomponent.ini задано
COM_MYCOMPONENT_THANK_YOU="Спасибо за Ваше сообщение, %s!"
а в коде расширения имеется строка
echo JText::sprintf('COM_MYCOMPONENT_THANK_YOU', 'Вася');
то результатом будет вывод на экран строки "Спасибо за Ваше сообщение, Вася!".
Аргументы задаются так же, как в одноименных функциях PHP: %s означает строку, %d – целое число, %f – число с плавающей точкой и т.д.
Паттерн «фабрика» (класс JFactory)
В Joomla существует статический класс JFactory, реализующий паттерн "фабрика". Методы данного класса (getApplication(), getDate(), getDbo(), getDocument(), getLanguage(), getURI(), getUser(), getMailer(), getEditor() и др.) позволяют получить доступ к соответствующим глобальным объектам фреймворка (JApplication, JDate, JDatabase, JDocument, JLanguage, JURI, JUser, JMail, JEditor и др.), ряд которых будет рассмотрен далее.
Рассмотрим пример получения доступа к объекту JUser:
$user =& JFactory::getUser(); if ($user->guest) echo "Вы не вошли на сайт"; else echo "Вы вошли на сайт как ".$user->name;
Обратите внимание на знак амперсанда перед вызовом метода getUser(). Мы получаем ссылку на объект-представитель текущего пользователя. Если пропустить амперсанд, то будет создана копия этого объекта и изменения, которые мы будем в ней производить, не затронут оригинал.
HTTP-запрос (класс JRequest)
В Joomla вместо непосредственного использования глобальных массивов $_GET, $_POST, $_FILES, $_COOKIE, $_ENV, $_SERVER и $_REQUEST удобнее применять класс JRequest. Его методы пропускают данные, введенные пользователем, через фильтр во избежание инъекций.
Для получения переменных запроса GET/POST используется метод mixed getVar(string $name, string $default=null, string $hash='default', string $type='none', int $mask=0), где:
$name имя переменной; $default значение по умолчанию, которое вернет метод getVar(), если значение переменной не задано; $hash источник данных, по умолчанию они будут получены из массива $_REQUEST. Явное указание массива GET или POST повысит безопасность кода; $type тип ожидаемого значения: INT INTEGER FLOAT DOUBLE BOOL BOOL WORD ALNUM допускает только буквенно-цифровые значения; CMD BASE64 допускает только те символы, которые могут быть представлены в кодировке base64 (т.е. a-z, A-Z, 0-9, /, + и =); STRING ARRAY PATH исключает возможность атаки. Например, если исходное значение содержало /./ или /../, то вместо него метод вернет пустую строку; USERNAME удаляет управляющие символы (0x00 – 0x1F), 0x7F, <, >, ", ', % и &; $mask константа, задающая опции фильтрации: JREQUEST_NOTRIM не удалять пробелы в начале и конце строки; JREQUEST_ALLOWRAW без какой-либо фильтрации; JREQUEST_ALLOWHTML не удалять HTML-код, но пропустить значение через фильтр (в частности, удалить опасные теги – script, applet, iframe и др.).
Эти константы не заключаются в кавычки, т.к. это не строки, а статические переменные. Если ни одной опции не задано, то HTML-теги, а также пробелы в начале и конце строки будут удалены.
Пример:
$answer = JRequest::getVar('answer', 'no answer', 'post', 'string', JREQUEST_ALLOWRAW);
Если нужно получить весь массив переменных запроса в отфильтрованном виде, используется
mixed get(string $hash='default', int $mask=0)
Например, получим массив $_POST:
$arr = JRequest::get('post');
Для присвоения переменным запроса значений используется метод string setVar(string $name, string $value=null, string $hash='method', bool $overwrite=true)
Если $overwrite=false и в запросе уже задано значение переменной $name, то метод просто вернет само это значение. В противном случае переменной будет присвоено значение $value, а метод вернет старое значение $name.
Пример:
JRequest::setVar('var1', 'val1');
Класс JRequest содержит также методы, позволяющие получить значение определенного типа: getBool(), getCmd(), getFloat(), getInt(), getString(), getWord().
Приложение (класс JApplication)
Очередь сообщений
В Joomla существует очередь сообщений– массив строк, которые будут выведены на экран при следующей загрузке какой-либо страницы. Стандартными являются три типа сообщений (рис. 1.2): message (собственно сообщение), notice (предупреждение) и error (ошибка):
Рис. 1.2. Типы сообщений
Для добавления сообщений в очередь используется метод void enqueueMessage(string $msg, [string $type = 'message']), где:
$msg – текст сообщения; $type – тип сообщения.
Например:
global $app; $app->enqueueMessage('Message'); $app->enqueueMessage('Notice', 'notice'); $app->enqueueMessage('Error', 'error');
В данном примере $app – это глобальный объект JApplication.
Для получения копии очереди сообщений используется метод array getMessageQueue(). Например, для предыдущей очереди из трех сообщений он возвращает массив:
Array ( [0]=>Array ( [message]=>Message [type]=>message ) [1]=>Array ( [message]=>Notice [type]=>notice ) [2]=>Array ( [message]=>Error [type]=>error ) )
Перенаправление
Для перенаправления пользователя к другому URL используется метод void redirect(string $url, string $msg='', string $msgType='message', bool $moved=false), где:
$url – URL, к которому перенаправляется пользователь; $msg – сообщение, которое должно быть при этом выведено; $msgType – тип сообщения; $moved – при значении true браузер получит код состояния "301 Permanently Moved", в противном случае – "303 See Other".
Данный метод добавляет сообщение к очереди сообщений, перенаправляет браузер пользователя к заданному URL и завершает работу приложения Joomla. Например:
global $app; $app->redirect('index.php', JText::_('NOTICE'), 'notice');
Второй способ организации перенаправления – использовать метод JController::setRedirect(), который будет рассмотрен ниже вместе с другими методами класса JController.
Получение параметров конфигурации сайта
В число параметров конфигурации сайта входят настройки базы данных, почты, сервера, FTP, метаданных, SEO и другие. Для получения значений этих параметров используется метод
mixed getCfg(string $varname, string $default=null)
где $varname – название параметра.
Для примера получим название сайта:
global $app; echo $app->getCfg('sitename');
Определение типа запущенного приложения Joomla
Чтобы определить, откуда запущен код, можно использовать методы
int getClientId() bool isAdmin() bool isSite()
Метод getClientId() возвращает id запущенного приложения: 0 (сайт), 1 (панель управления), 2 (установщик).
Метод isAdmin() определяет, является ли запущенное приложение бэкендом, isSite() – фронтендом.
Панели инструментов (класс JToolBarHelper)
Joomla автоматически загружает в верхней правой части экрана бэкенда компонента файл, который называется toolbar.<имя компонента>.php. Таким образом можно отображать различные панели инструментов.
Класс JToolBarHelper содержит методы, которые генерируют HTML-код для построения кнопок панелей инструментов. Для отображения кнопок, которые часто используются в компонентах, – "Сохранить", "Отменить", "Удалить" – существуют готовые методы этого класса. Их список можно найти в документации Joomla: ссылка: http://docs.joomla.org/JToolBarHelper.
Для методов addNew(), publish(), publishList(), makeDefault(), unpublish(), editList(), save(), apply() заданы по умолчанию два параметра – задача (об ее значении будет сказано ниже) и подпись. Например, значения этих параметров по умолчанию для метода editList() выглядят так: $task = 'edit', $alt = 'Edit'. Можно задавать свои задачу и подпись, передавая их как, соответственно, первый и второй параметры.
Метод для удаления объектов имеет прототип
void deleteList(string $msg =, string $task = 'remove', string $alt = 'JTOOLBAR_DELETE')
где $msg – это текст сообщения с просьбой подтвердить удаление объектов. Если этот параметр задан, то при нажатии кнопки для удаления будет выводиться окно с заданным сообщением и объекты будут удалены только после нажатия кнопки " ОК" в этом окне. Если же параметр $msg не задан, то объекты будут удаляться без предупреждения.
В сложных случаях, когда требуется не просто изменить задачу и подпись, а создать собственную кнопку, используется метод
void custom(string $task = '', string $icon = '', string $iconOver = '', string $alt = '', bool $listSelect = true)
где:
$task – задача, которая будет выполнена; $icon – пиктограмма кнопки; $iconOver – пиктограмма при наведении курсора мыши; $alt – подпись под кнопкой; $listSelect – нужно ли работать только с выбранными элементами списка.
Как правило, в URL Joomla присутствует переменная task, определяющая задачу, которую должен выполнить компонент. В коде компонента в зависимости от полученного значения task вызывается некоторая функция. Например, если URL выглядит как ссылка: http://localhost/joomla/index.php?option=mycomponent&task=show, то компонент mycomponent будет обрабатывать задачу show.
Параметры $icon и $iconOver задают, как ни странно, не название файла изображения, а название класса CSS, для которого задано это изображение в качестве фонового. К названию класса автоматически добавится строка "icon-32-" и будет произведен поиск этого класса в подключенных файлах CSS. Например, если третий параметр функции JToolBarHelper::custom() задан как send.png, то будет найден класс .icon-32-send, а в результате картинка будет отображена с помощью кода:
Если данная панель инструментов создана для одной-единственной записи, а не для списка, то параметру $listSelect следует задавать значение false. Если этот параметр имеет значение true, то для события кнопки onclick задается следующий код на Javascript:
if (document.adminForm.boxchecked.value==0) { alert('Пожалуйста, выберите объект из списка'); } else { Joomla.submitbutton('myquestions_sendToExpert') }
Если же $listSelect имеет значение false, то проверка того, выбраны ли в списке какие-либо элементы, не осуществляется:
Joomla.submitbutton('myquestions_sendToExpert')
Для вывода названия панели инструментов и пиктограммы служит метод void title(string $title, string $icon), где:
$title – название панели инструментов; $icon – название класса CSS, для которого необходимое изображение задано в качестве фонового. К названию класса автоматически добавится строка "icon-48-".
Например, если вы хотите использовать в качестве пиктограммы файл /media/com_mycomponent/images/sample-48.png, то добавьте в CSS класс
.icon-48-sample { background: url('../images/sample-48.png') 0 0 no-repeat; }
Теперь для отображения названия необходимо добавить в код строку:
JToolBarHelper::title('Мой компонент','sample');
Для вывода между кнопками вертикальной черты-разделителя служит метод divider():
void divider();
Практика
Описание учебного примера
Для примера будем создавать компонент системы "вопрос – ответ". Назовем его myquestions. С помощью этого компонента посетители сайта смогут задавать свои вопросы, по желанию помечая их как предназначенные для публикации на сайте или как скрытые. Функциональность, доступная администратору системы:
отправить уведомление о вопросе эксперту по электронной почте;
задать дату снятия вопроса с публикации;
скрыть от посетителей сайта отдельные поля вопроса;
присвоить вопросу категорию;
редактировать список категорий;
ответить на вопрос;
отправить ответ автору вопроса по электронной почте;
удалить вопрос.
Уведомление о каждом присланном вопросе автоматически отправляется модератору по электронной почте. Модератор либо пересылает вопрос эксперту, либо удаляет (например, в случае спама), а также присваивает вопросу какую-либо категорию. Если посетитель пометил свой вопрос как скрытый, но по каким-то причинам его необходимо опубликовать (например, указан некорректный e-mail и отправить ответ невозможно), то модератор задает дату снятия вопроса с публикации. Таким образом, отображаться на сайте будут вопросы, удовлетворяющие следующим условиям:
есть ответ;
либо вопрос не помечен как скрытый, либо дата снятия вопроса с публикации указана и больше текущей даты
Для каждого вопроса будем хранить следующие данные:
id;
имя автора;
дата вопроса;
собственно текст вопроса;
город;
e-mail автора;
IP автора;
id категории;
отображать ли вопрос на сайте;
дата снятия вопроса с публикации;
отправлен ли вопрос эксперту;
ответ на вопрос;
отправлен ли ответ автору вопроса.
Регистрация компонента в базе данных
Зарегистрируем наш компонент в базе данных, добавив запись в таблицу, содержащую данные о расширениях. Перейдите в phpMyAdmin(если вы работаете с Denwer, то для этого вам нужно ввести в адресной строке браузера ссылка: http://localhost/tools/phpmyadmin), зайдите в базу данных, в которую вы установили Joomla, и откройте вкладку " SQL" (рис. 1.3).
(есть увеличенное изображение)
Рис. 1.3. Выполнение SQL-запроса
Теперь введите следующий SQL-запрос. Предполагается, что префикс таблиц вашей базы данных – "jos_". Если вы указали при установке Joomla другой префикс, замените "jos_" на него.
INSERT INTO `jos_extensions`(`name`, `type`, `element`, `folder`, `client_id`, `manifest_cache`, `params`, `custom_data`, `system_data`) VALUES('myquestions', 'component', 'com_myquestions', '', 1, '{"legacy":false, "name":"Моя система «вопрос – ответ»", "type":"component", "creationDate":"2012", "author":"me", "copyright":"(с) me", "authorEmail":"[email protected]", "authorUrl":"http:\/\/www.example.ru", "version":"1.0", "description":"Мой первый компонент для Joomla", "group":""}', '{}', '', '');
Как видите, мы задали название расширения – "myquestions", тип расширения – компонент и некоторую информацию о нем и его авторе.
Первые папки и файлы. Добавление пунктов меню
Создайте две папки под названием com_myquestions:
в папке /components;
в папке /administrator/components.
Создайте файл /components/com_myquestions/myquestions.phpследующего содержания:
Как видите, пока наш компонент просто будет выводить надпись "Моя система "вопрос – ответ"".
Не забудьте, что Joomla работает в кодировке UTF-8 и, следовательно, ваши PHP-файлы должны быть в той же кодировке. Например, в популярном текстовом редакторе Notepad++ кодировка изменяется с помощью пункта меню " Кодировка", из подпунктов которого нужно выбрать " Преобразовать в UTF-8 без BOM".
Теперь сохраните файл и обновите страницу ссылка: http://localhost/joomla/index.php?option=com_myquestionsв браузере. Страница примет следующий вид (рис. 1.4).
(есть увеличенное изображение)
Рис. 1.4. Первый результат во фронтенде
Создайте файл /administrator/components/com_myquestions/admin.myquestions.php:
Наберите в адресной строке браузера строку ссылка: http://localhost/joomla/administrator/index.php?option=com_myquestions. Результат должен выглядеть так, как на рис. 1.5.
(есть увеличенное изображение)
Рис. 1.5. Первый результат в бэкенде
Добавим эти ссылки в меню фронтенда и бэкенда. Для этого выясним, какой idбыл присвоен нашему компоненту в таблице jos_extensions. В phpMyAdminвойдите в эту таблицу и найдите расширение com_myquestions. Вероятно, оно находится в последней строке. Посмотрите, какое значение стоит в поле extension_id. Например, на рис. 1.6 видно, что в данном случае idравен 10006.
(есть увеличенное изображение)
Рис. 1.6. Определение id компонента
Теперь выполните SQL-запрос, не забыв заменить "10006" на найденный вами id:
INSERT INTO `jos_menu`(`menutype`, `title`, `alias`, `path`, `link`, `type`, `level`, `component_id`, `access`, `img`, `params`, `client_id`) VALUES('menu', 'com_myquestions_menu', 'My Questions', 'My Questions', 'index.php? option=com_myquestions', 'component', 1, 10006, 1, 'class:component', '', 1);
После выполнения данного запроса в меню " Компоненты" бэкенда появится новый подпункт со ссылкой на наш компонент. Однако он будет называться " myquestions", так как мы еще не задали перевод для строки com_myquestions_menu. Чтобы задать его, создайте языковой файл /administrator/language/ru-RU/ru-RU.com_myquestions.sys.iniследующего содержания:
COM_MYQUESTIONS_MENU="Моя система «вопрос – ответ»"
Зайдите в бэкенд. В меню " Компоненты" появился пункт " Моя система «вопрос – ответ»" (рис. 1.7).
Рис. 1.7. Пункт меню в бэкенде
Теперь создайте пункт меню фронтенда. Для этого зайдите в " Меню" – " Менеджер меню", нажмите на ссылку " Главное меню", а затем на кнопку " Создать". Выберите тип пункта меню " Внешний URL", в поле " Заголовок меню" введите " Моя система «вопрос – ответ»", а в поле " Ссылка" – ссылку на фронтенд нашего компонента: ссылка: http://localhost/joomla/index.php?option=com_myquestionsи нажмите " Сохранить". Обновите любую страницу фронтенда и убедитесь, что появился новый пункт меню (рис. 1.8).
(есть увеличенное изображение)
Рис. 1.8. Пункт меню во фронтенде
Создание панелей инструментов
Вспомните приведенное выше описание функционала, доступного администратору нашей системы. Соответственно, на панели инструментов для управления списком вопросов необходимы следующие кнопки:
отправить уведомление о вопросе эксперту по электронной почте;
присвоить вопросу категорию;
отправить ответ автору вопроса по электронной почте;
редактировать вопрос (в том числе: задать дату снятия вопроса с публикации; скрыть от посетителей сайта отдельные поля вопроса; ответить на вопрос);
удалить вопрос.
Для начала создайте файл /administrator/components/com_myquestions/toolbar.myquestions.html.php:
Каждая функция класса TOOLBAR_myquestions соответствует отдельной панели инструментов. Как видите, мы задали две такие панели – первая из них будет отображаться над формой для ответа на вопрос, а вторая – над списком вопросов.
В коде, приведенном выше для ряда кнопок вместо стандартных подписей задаются собственные, которые необходимо перевести в языковом файле вместе с другими надписями. Поэтому создадим языковой файл /administrator/language/ru-RU/ru-RU.com_myquestions.ini:
COM_MYQUESTIONS_TOOLBAR_SEND_TO_EXPERT="Отправить эксперту" COM_MYQUESTIONS_TOOLBAR_SEND_ANSWER="Отправить ответ" COM_MYQUESTIONS_TOOLBAR_TITLE="Моя система «вопрос – ответ»" COM_MYQUESTIONS_REPLY="Ответить / Редактировать" COM_MYQUESTIONS_TOOLBAR_REMOVE_QUESTIONS_CONFIRMATION="Вы действительно хотите удалить эти вопросы?"
Добавим код, который будет выбирать, какую из определенных нами панелей инструментов отображать. Создайте файл /administrator/components/com_myquestions/toolbar.myquestions.php:
Вызов функции getPath() класса JApplicationHelper позволяет обратиться к файлу toolbar.myquestions.html.phpбез указания имени компонента, что удобно, если впоследствии понадобится изменить это имя.
Выражение switch используется для выбора одной из панелей инструментов в зависимости от значений переменной $task.