Cоздание пользовательской части компонента.

Дата Автор 

Продолжаем обучение создания компонента для системы управления контентом Joomla.  В прошлых двух уроках, мы узнали, что создание компонента Joomla происходит по шаблону проектирования MVC, а так же создали основу компонента и установили его в систему. 

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

Сегодня мы будем программировать, а вернее создавать модель, вид и контролер.  Напомню для успешного понимания этого урока следует, прочесть два предыдущих. Ах да, забыл упомянуть, что создаваемый компонент подойдет как для версии Joomla 1.5, 1.6, 1.7, так и для версии 2.5. В основном я буду описывать создание компонента Joomla. Не буду говорить много слов и перейду к написанию компонента.

 

Пользовательская часть компонента состоит из модели, вида и контроллера, а так же из основного файла фронтэнда (пользовательской части компонента), с которого мы и начнем создание компонента

 

Создание главного файла фронтэнда

 

Заходим в нашу систему, а именно в папку components/com_название компонента (в моем случае components/com_lesson), создаем файл название компонента.php (lesson.php). и вносим в него следующий код:

 

<?php

defined( '_JEXEC' ) or die( 'Restricted access' );

require_once( JPATH_COMPONENT.DS.'controller.php' );

if($controller = JRequest::getVar( 'controller' )) {
require_once( JPATH_COMPONENT.DS.'controllers'.DS.$controller.'.php' );
}

$classname = 'NameController'.$controller;
$controller = new $classname( );

$controller->execute( JRequest::getVar( 'task' ) );

$controller->redirect();

 

Сейчас я подробно объясню, что значат все эти строчки. Ну самая первая строчка вам должна быть ясна, а если нет, то даже и не пробуйте начинать создавать компонент. Я начну рассказывать все со второй.

 

defined( '_JEXEC' ) or die( 'Restricted access' );

 

Защита от прямого обращения к файлу. То есть если ваш файл будут напрямую запрашивать через адресную строку (www.site.ru/ components/com_название компонента/название компонента.php) то выведеться сообщение "Restricted access" и код исполняться не будет. Эта строка обязательно должна быть во всех php файлах, в самом начале!!!

 

require_once( JPATH_COMPONENT.DS.'controller.php' );

 

Подключение к контроллеру, который мы в будующем создадим. О самом контроллере раскажу позже сейчас поясню все все команды:

require_once() - оператор php, который будет подключать файл который указан в круглых скобках. Файл будет подключаться всего один раз по ходу исполнения кода.

 JPATH_COMPONENT – путь в корень нашего компонента (components/com_название компонента).

. – склеивает значения в одну строку php команды

DS – выступает в роли слэша (\ или /), разделительной черты.  Фреймворк Joomla сам устанавливает нужный слэш в зависимости от ОС.

controller.php – название файла который будет подлючаться, в данном случае наш будующий контроллер.

 

if($controller = JRequest::getVar( 'controller' )) {

require_once( JPATH_COMPONENT.DS.'controllers'.DS.$controller.'.php' );

}

 

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

 

$controller = JRequest::getVar( 'controller' ); - тут, переменной $controller передаеться значение get переменной controller из адресной строки(ссылки).

 

JRequest::getVar() – это класс из фреймворка Joomla. Он определяет значения, находящееся в адресной строке(ссылке). Если на сайте не используеться ЧПУ, то в ссылке можете уидеть что-то типа «option» или «itemid».  JRequest::getVar() будет иметь значение указанное в этой переменной.

 

Следовательно JRequest::getVar( 'controller' ) будет иметь значение переменной “controller”.

 

Далее идет условие, переменная $controller проверяеться на пустоту, иначе говоря есть в ней значение или нет. Если в  адресной строке(ссылке) находиться get переменная controller, то и переменная $controller будет иметь такое же значение, следовательно должно выполняться подключение:

 

require_once( JPATH_COMPONENT.DS.'controllers'.DS.$controller.'.php' );

 

controllers – это папка где будут находиться контроллеры.

.$controller.'.php' – название файла контроллера к которому будем подключаться.

 

$classname = 'NameController'.$controller;

$controller = new $classname( );

 

Тут мы создаем, новую переменную $classname и в неё будем вносить название нашего класса, иначе говоря, наш класс должен иметь имя, в данном случае NameController, где Controller обязательная часть имени, а Name придумали мы, то есть тут что напишете, то и будет. ВАЖНО ЗАПОМНИТЬ ЭТО ПРАВИЛО!!!

 

Скажу пару слов о классах и контроллерах. Каждый контроллер имеет один класс, иначе говоря, один файл – один класс. И пока мы не укажем хотя бы один класс, компонент работать ни за что не будет,  даже если весь компонент будет написан правильно. Так же нужно понимать, что классы находиться не в файлах контроллера, а именно в этом главном файле фронтэнда.

 

Так же вам нужно знать, что любой компонент будет иметь как минимум одну страницу, в которой будет находиться пустая переменная $controller, для которой необходимо создать отдельный класс с функциями, которые нужно будет выполнить. Для того чтобы было понятно, что  и где будет выполняться разработчики Joomla сделали такую строку $classname = 'NameController'.$controller;  где к названию класса будет добавляться переменная $controller в которой содержится get значение. В итоге классы в контроллерах будут называться так:

 

На странице с пустой переменной $controller – class NameController {}

На остальных страницах – class NameControllerGetname  - где последнее является значением из переменной $controller

 

Тем самым все классы в компоненте получат свои уникальные имена, и теперь в переменную $controller можно записать не значение переменной get, а целый класс, который у нас записан в строке $controller = new $classname() где new означает, что это новый рабочий класс, а переменная $classname(), совокупность функций в этом классе.

 

Фууух…. Сложно, довольно таки запутанно, но за, то должно быть понятно и разжевано. Идем дальше.

 

$controller->execute( JRequest::getVar( 'task' ) );

 

Get переменная Task, позволяет выбрать нужную нам функцию из совокупности функций в классе. Она может, как быть, так и не быть, все зависит от  компонента и, как вы его будете создавать, но если она есть, то из всего класса выполниться только она одна.

 

Благодаря оператору execute, происходит выбор именно той функции, которую вы указали. Если функция не указанна, то выполниться функция по умолчанию display().

 

$controller->redirect();

 

Когда компонент отработал, а все классы выполнили все свои функции, остается вопрос, выполнять загрузку другой страницы или нет? Это ложиться на плечи самой Joomla. Просто необходимо присвоить значение redirect() переменной $controller.

 

Вы могли заметить, что в коде кое-чего не хватает, но это сделано намеренно.  В коде нахватает закрывающего php тега ?> Этого тега не должно быть не в одном файле компонента это тоже надо запомнить! Это нужно для того, чтобы весь файл был одним целым, и не оставалось свободного места в коде.

 

Вот собственно и все, основной файл фронтэнда, готов и полностью разжеван. Далее будет меньше текста, так как многие функции уже описаны, а, следовательно, мы с ними знакомы. Теперь начинаем создание контроллера.

 

Создание контроллера

 

Сейчас мы создадим контроллер который будет отвечать за первый старт, иначе начальную страницу компонента. Он будет находиться в корневой папке компонента. Название его мы уже писали в основном файле controller.php. Он будет подключаться только когда в строке адреса (ссылке) не определен любой другой контролер, при помощи get переменной controller.

<?php

defined( '_JEXEC' ) or die( 'Restricted access' );

jimport('joomla.application.component.controller');

class NameController extends JController

{

   function display()

   {

      parent::display();

   }

}

 

Собственно это весь код нашего контроллера. Как видите,в нем есть строчки которые я уже описал выше, следовательно их объяснение я буду пропускать.

 

jimport('joomla.application.component.controller');

 

С помощью класса jimport мы подключаем нужную нам библиотеку Joomla, которая содержит необходимые данные по работе с компонентом. Эту строку мы будем так же прописывать при создании Вида и Модели, только будет меняться последнее слово, то есть вместо controller будет model или view.

 

class NameController extends JController

   { 

      function display()

   {

      parent::display();

   }

Далее мы создаем класс с именем (NameController) которое мы написали в предидущем файле (lesson.php). Так же при создании класса мы прописываем ещё один оператор extends, он отнесет созданный нами класс к классу Jcontroller. Следует запомнить, что у всех созданных классов, в которых планируете использовать методы из классов Joomla, должен быть свой класс Joomla. Так же как и с библиотекой, в зависимости от типа файла будет меняться и класс Jview или Jmodel. Нужно указывать правильный класс Joomla, для создаваемого класса ЭТО ВАЖНО ЗАПОМНИТЬ!!!

 

Так, теперь объясню сам код. Как видите в созданном классе имеется только одна функция display, которая возвращает значение parent::display(). Теперь давайте вспомним, что мы объявили класс ontroller через оператор extends, следовательно, функция вернет значение классу JСontroller и получается что будет вызван метод  JController::display.

 

Собственно это весь код контролера, теперь осталось сделать модель и вид чем мы сейчас и займемся.

 

Создание модели

 

 

Наша модель должна находиться в папке models, следовательно, необходимо создать в корневой папке компонента, папку с таким названием. В ней создаем файл нашей модели, он должен называться название компонента.php (в моем случае lesson.php).  Код нашей модели будет выглядеть так:

 

<?php

defined( '_JEXEC' ) or die( 'Restricted access' );

jimport( 'joomla.application.component.model' );

class NameModelLesson extends JModel

{

   function getMtext()

      {

         $text = 'Если меня видно, значит компонент работает!!!';

         return $text;

      }

}

 

Собственно ничего сложного. Почти все абсолютно аналогично предыдущим файлам. Хочу обратить ваше внимание на подключаемую библиотеку jimport. Как и писал выше у каждого типа файла (модель, вид или контролер) будет подключаться своя библиотека. Так как это файл модели, то в последнее слово в подключении jimport – model. Далее создаем класс:

 

class NameModelLesson extends JModel

{

   function getMtext()

      {

         $text = 'Если меня видно, значит компонент работает!!!';

         return $text;

      }

}

 

Name – название класса созданного в основном файле lesson.php

Model – обязательное слово обозначающее, что это модель

Lesson - обязательно с большой буквы. Это слово определяет модель, установленную по умолчанию.

extends JModel – подключает к нашему классу, класс Joomla – JModel.

 

Далее создаем функцию getMtext, которая будет возвращать одну переменную $text  оператором return.  В переменной  $text  будет находиться сообщение, которое будет выводиться на сайте при обращении к компоненту.

 

Вот собственно и все, модель создана, теперь осталось создать вид и пользовательская часть компонента готова.

 

Создание вида

 

Файлы вида должны находиться в папке views/название компонента (в моем случае views/lesson). Вид, в отличие от модели и компонента, состоит из файла управления данными и файла вывода данных, иначе говоря, из двух файлов. Сначала мы создадим файл управления данными, который должен называться view.html.php. Его код будет выглядеть так:

 

<?php

defined( '_JEXEC' ) or die( 'Restricted access' );

jimport('joomla.application.component.view');

class NameViewLesson extends JView

{

   function display ($tpl = null)

      {

               $model = $this->getModel();

               $text = $model->getMtext();

               $this->assignRef( 'text', $text );

               parent:: display ($tpl);

      }

}

 

Тут все так же просто, и код мало чем отличается от предыдущих, но все же пару слов о нем. Опять же обращаю ваше внимание на подключение библиотеки, в конце стоит слово View, что означает подключение библиотеки для вида. Далее создаем класс, где все нам уже знакомо:

 

Name – название класса созданного в основном файле lesson.php

View – обязательное слово обозначающее, что это вид

Lesson - обязательно с большой буквы. Это слово определяет вид, установленный по умолчанию.

extends JView – подключает к нашему классу, класс Joomla – JView.

 

Далее создаем функцию display с параметром $tpl и обнуляем его.  Далее создаем новую переменную $model, которая будет обращаться к модели данного вида и загружать функции из неё. Ну а в переменную $text вносим значение из функции getMtext() из модели. Далее переменную $text передаем в шаблон командой assignRef из класса Joomla Jview. Это записывается таким способом:

 

$this->assignRef( 'переменная, вызываемая из шаблона', переменная с данными из этого файла );

 

ВНИМАНИЕ!!! Если вы создаете компонент для версии joomla 2.5, то для того чтобы у вас появился пункт меню вашего компонента, вам необходимо создать файл default.xml в папке view/название компонента/tmpl (view/lesson/tmpl) с кодом:

<?xml version="1.0" encoding="utf-8" ?>
<metadata>
<layout title="Вывод страницы Lesson">
<message>Тут будет всплывающая подсказка</message>
</layout>
<fields name="request">
<fieldset name="request">
<field
   id="id"
   name="id"
   type="list"
   label="Выберите значение"
   description="Здесь можно поместить описание"
   default="1"
>
</field>
</fieldset>
</fields>
</metadata>

 

Теперь код файла управления данными нам понятен, осталось только создать файл вывода данных, который будет находиться в папке view/название компонента/tmpl (view/lesson/tmpl) и называться он должен default.php. Код этого файла будет выглядеть так:

 

<?php

defined('_JEXEC') or die('Restricted access'); ?>

<div><?php echo $this->text; ?></div>

 

Вот и все! Ну если вам непонятен код <?php echo $this->text; ?> то в двух словах он выводит данные переменной текст из модели.

 

Теперь давайте проверим, работает ли наш компонент?  Для этого отправляемся в пункт меню в админке Joomla и выберите одно из созданных и опубликованных типов меню. В нем создайте новый пункт и выберите из списка наш компонент. Так как мы создали только одну страницу компонента под названием Lesson, то именно она у нас и будет выводиться. Выбираем её, заполняем строку заголовок и сохраняем новый пункт меню. Теперь осталось только проверить работает ли наш компонент. У меня все прекрасно выводиться, надеюсь у вас тоже =)

 

Получился очень большой пост, но надеюсь он того стоил. Я старался все максимально подробно описать и упомянуть, опять же надеюсь все доступно понятно, если нет всегда можно спросить, что не поняно в комментари.

 

P.S. Во вложении вы можете скачать файлы моего компонента com_lesson. Вложения находяться внизу страницы, сразу под тегами.

 

Спасибо за внимание!!! С уважением Остапенко Илья.

Оцените материал
(5 голосов)
 

Комментарии   

 
Алексей
0 # 26.09.2012 12:03
Илья, вопрос по первому файлу lesson.php:

Код файла в мануале для joomla 2.5 такой:

execute(JRequest::getCmd('task'));
// Redirect if set by the controller
$controller->redirect();

Помогите, пожалуйста, разобраться в этих строках... Я так понимаю, что это особенности 2.5? Они аналогичны Вашему коду или у Вас добавлен некий функционал, отраженный в разнице кодов?
Ответить | Ответить с цитатой | Цитировать
 
 
Алексей
0 # 26.09.2012 12:05
Код не прошел)
Илья, вопрос по первому файлу lesson.php:

Код файла в мануале для joomla 2.5 такой:
defined('_JEXEC') or die('Restricted access');
// import joomla controller library
jimport('joomla.application.component.controller');
// Get an instance of the controller prefixed by HelloWorld
$controller = JController::getInstance('HelloWorld');
// Perform the Request task
$controller->execute(JRequest::getCmd('task'));
// Redirect if set by the controller
$controller->redirect();

Помогите, пожалуйста, разобраться в этих строках... Я так понимаю, что это особенности 2.5? Они аналогичны Вашему коду или у Вас добавлен некий функционал, отраженный в разнице кодов?
Ответить | Ответить с цитатой | Цитировать
 
 
Алексей
0 # 26.09.2012 12:14
И еще вопрос по контроллеру...
строка обязательна?
parent::display();

Просто в меру моего понимания (только начинаю въезжать)), эта строка выводит display из класса Джумлы (JController)

Но ведь и без этой строки будет на выходе тот же display родителя?
Ответить | Ответить с цитатой | Цитировать
 
 
const
0 # const 25.07.2013 17:55
2Алексей
строка обязательна?
parent::display ();
Цитирую Алексей:
И еще вопрос по контроллеру...
строка обязательна?
parent::display ();

Просто в меру моего понимания (только начинаю въезжать)), эта строка выводит display из класса Джумлы (JController)

Но ведь и без этой строки будет на выходе тот же display родителя?


Можно я поясню? Эта строка вызывает родительский метод display, без него не будут выполнены некоторые стандартные функции. Если явно не указать вызов этого метода, то родительский метод вызван не будет, потому что он перекрыт текущим display. Можно конечно скопировать полностью метод parent::display () и не вызывать его, но тогда сводится на нет парадигма ООП - "наследственнос ть". Если методы display буду пустые, то их можно исключить из контроллера, модели или вида. Так как в этом случае они не будут перекрывать родительский метод и соответсвенно будет вызван родительский метод display. Советую вам поэксперементир овать, с пустыми методами.
Ответить | Ответить с цитатой | Цитировать
 
 
Остапенко Илья
0 # Остапенко Илья 26.09.2012 16:22
Алексей, я сам ещё новичок в этом деле, и пока что не так силен. Учился у другого человека, а не по мануалам, а так же изучал, как устроенны другие компоненты. Сравнивая код из мануала и свой код, то различие нашел тут:

jimport('joomla.application.component.controller');
$controller = JController::getInstance('HelloWorld');

Вот эти две строчки в мануале, равны этим двум строчкам в моем коде.

$classname = 'NameController '.$controller;
$controller = new $classname( );

Просто записанный по другому, принцип остается тот же. Далее в мануале, нету подключения с условием, но в принципе в моем компоненте, оно так же не пока что не понадобилось. Так же в мануале пишется getCmd, а у меня getVar, но смысл, опять же одинаковый.

По повод строки parent::display();
Честно говоря, сильно не вдавался в подробности данной строки, но рассмотрев многие компоненты, такая строка везде присутствует, а значит важна.

Да и что значит "код не прошел"?
Ответить | Ответить с цитатой | Цитировать
 
 
Алексей
0 # 26.09.2012 16:34
Спасибо за объяснение) Теперь все понятно)

Код не прошел значит, что когда я в первый комментарий вставил кусок кода, то первая строка была "скобка-вопрос- php" и Ваш компонент комментариев воспринял сие как тег HTML и обрезал до следующей скобки (вот этой ->))
Ответить | Ответить с цитатой | Цитировать
 
 
nemo
0 # nemo 02.01.2013 00:04
http://docs.joomla.org/JRequest - jRequest вроде бы уже не входит в Joomla. Последний был в платформе 11.1, а текущая версия 12.1
Ответить | Ответить с цитатой | Цитировать
 
Добавить комментарий


Защитный код
Обновить