Выбрать главу

function showCategories($rows, $option) { ?> <p><a href='<?=JRoute::_('index.php?option='.$option.'&task=showlist')?>'> <?=JText::_('COM_MYQUESTIONS_ALL_QUESTIONS')?></a></p> <p><a href='<?=JRoute::_('index.php?option='.$option.'&task=showform')?>'> <?=JText::_('COM_MYQUESTIONS_ADD_QUESTION')?></a></p> <table> <?php foreach($rows as $row) { $link = JRoute::_('index.php?option='.$option.'&id='.$row->id.'&task=showlist'); echo '<tr><td><p><a href="' . $link . '">'.$row->name. '</a></td><td>'.$row->desc.'</td></tr>'; } ?> </table> <?php }

Измените выделенный код в функции HTML_questions::showQuestions():

foreach($rows as $row) { $link = JRoute::_('index.php?option='.$option.'&id='.$row->id.'&task=showquestion'); $link_cat = JRoute::_('index.php?option='.$option.'&id_cat='.$row->id_cat.'&task=showlist'); ?>

Измените также выделенный код в функции HTML_questions::showQuestion():

function showQuestion($row, $option, $row_cat) { $link_cat = JRoute::_('index.php?option='.$option.'&id_cat='.$row->id_cat.'&task=showlist');

Теперь компонент будет генерировать SEF-ссылки по шаблону, установленному в функции MyQuestionsBuildRoute().

Декодирование SEF-ссылок

Если вы сейчас попытаетесь щелкнуть на одной из SEF-ссылок, то получите сообщение:

"Fatal error: Call to undefined function myquestionsParseRoute() in Y:\home\localhost\www\joomla\includes\router.php on line …".

Напишем функцию для декодирования SEF-ссылок.

Откройте файл /components/com_myquestions/router.phpи добавьте следующую функцию:

function MyQuestionsParseRoute ($segments) { $vars = array(); $vars['task'] = @$segments[0]; $vars['id'] = @$segments[1]; return $vars; }

Как видите, в функции MyQuestionsParseRoute() мы считали переменные task и id из массива $segments в том же порядке, в котором мы их записывали в одноименный массив в функции MyQuestionsBuildRoute().

Знаки "@" при получении элементов массива $segments используются для подавления вывода сообщений об обращении к несуществующим элементам массива, т.к. не все наши SEF-ссылки будут содержать id.

Теперь щелкните по какой-либо ссылке во фронтенде и обратите внимание на строку статуса в браузере. Вы должны увидеть URL вида: ссылка: http://localhost/joomla/component/myquestions/showlistили ссылка: http://localhost/joomla/component/myquestions/showquestion/1

Ключевые термины

JDocument - класс для работы с документом. JRoute - класс для создания SEF-ссылок. JUser - класс для работы с данными о пользователе.Документ Документ - буфер, использующийся для хранения содержимого веб-страницы, которая будет показана пользователю после выполнения запроса. Функция генерации SEF-ссылок - функция, которая принимает массив элементов HTTP-запроса и возвращает массив сегментов SEF-ссылки. Функция декодирования SEF-ссылок - функция, которая из массива сегментов SEF-ссылки создает массив переменных HTTP-запроса. Шаблон SEF-ссылок - последовательность сегментов.

Краткие итоги

SEF-ссылки в Joomla создаются с помощью метода JRoute::_(), который переводит внутреннюю ссылку, генерируемую Joomla, в SEF-ссылку. Чтобы компонент работал с SEF-ссылками, сгенерированными по собственному шаблону, необходимо создать в корневой папке его фронтенда файл router.php, в котором должны находиться функция для генерации SEF-ссылок и функция для их декодирования. Эти функции осуществляют взаимно обратные операции: первая из них из массива элементов HTTP-запроса создает массив сегментов SEF-ссылки, а вторая из массива сегментов SEF-ссылки создает массив переменных HTTP-запроса.

Так как SEF-ссылки не позволяют задать названия переменных запроса, то единственный способ определить, к какой переменной относится то или иное значение сегмента, - это использовать шаблон, который задает последовательность сегментов. Шаблон неявно задается в коде каждой из функций в файле router.php.

Для работы с документом и с данными пользователя в Joomla существуют соответственно классы JDocument и JUser.

Вопросы

Какой метод переводит внутреннюю ссылку, генерируемую Joomla, в SEF-ссылку?

Каким образом компоненты работают с SEF-ссылками?

Для чего служат функции генерации и декодирования SEF-ссылок?

Что такое шаблон SEF-ссылок и как он задается?

Какие классы используются для работы с документом и с данными пользователя?

Упражнения

Адаптируйте код из раздела " Практика" для своего варианта (см. список вариантов в дополнительных материалах).

Архитектура MVC в компонентах Joomla

Рассмотрены принципы реализации архитектуры MVC в компоненте и классы Joomla, использующиеся для этого.

Цель лекции:Ознакомиться с основами применения архитектуры MVC при разработке компонентов.

Взаимодействие элементов архитектуры MVC в Joomla

MVC("Model - View - Controller") - это набор паттернов проектирования, который предполагает разделение программного кода на три группы:

модели(model) используются для хранения данных. В Joomla модели реализуются с помощью абстрактного класса JModel;

представления(view) генерируют вывод для заданной информации с помощью шаблона. В Joomla реализуются с помощью абстрактного класса JView;

контроллеры(controller) получают команды от пользователя и управляют моделями и представлениями для выполнения этих команд. В Joomla реализуются с помощью абстрактного класса JController.

Приблизительно схема взаимодействия этих групп в коде Joomla представлена на следующей диаграмме последовательности (рис. 6.1 на основе иллюстрации из книги [4, p.246]).

Рис. 6.1.  Взаимодействие контроллера, модели и представления

В файле /components/com_<имя компонента>/<имя компонента>.phpнаходится код для создания контроллера, например:

$controller = new MyComponentController(); $controller->execute(JRequest::getVar('task')); $controller->redirect();

В HTTP-запросе задается задача, представление и, при необходимости, другие данные. Метод execute() вызывает метод вашего контроллера, который называется так же, как и заданная задача. Если задача не указана, то ей будет присвоено значение "display", следовательно, будет выполнен метод display(). Для этой и всех остальных задач, которые должен выполнять ваш компонент, необходимо создать в классе контроллера одноименные методы. Наконец, метод redirect() перенаправляет пользователя к другому URL, если такой URL был задан в каком-либо методе при выполнении контроллера.

В простейшем случае класс контроллера описан в файле /components/com_<имя компонента>/controller.php, в более сложных случаях этих классов может быть несколько. Каждый из них должен быть производным от JController:

class MyComponentController extends JController { … function display() { … parent::display(); … } … }

Вы можете переопределить метод JController::display() в своем классе контроллера. Метод display() базового класса вызывает методы getView(), getModel(), а также метод display() заданного представления. getView() возвращает объект-представитель заданного представления, getModel() - заданной модели. По умолчанию используются те представление и модель, название которых совпадает с именем контроллера.