суббота, 8 октября 2011 г.

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

 Для CMS Joomla! существуют тысячи расширений и плагинов для самых разных нужд, но нередко случается так, что ни одно из них не подходит для решаемой задачи. К счастью, Joomla! предоставляет удобные инструменты для создания собственных расширений.


Расширения в Joomla делятся на три категории: компоненты, модули и плагины.
Комоненты — это расширения, которые могут иметь пункт в меню, а также свою панель управления в админиcтративной части, модули —  блоки с информацией, располагающиеся на сайте, их положение задано в шаблоне; а плагины —  это расширения, только  дополняющие функциональность каких-либо компонентов сайта.

Для примера создадим компонент, позволяющий выводить список определённой категории пользователей сайта, категория будет задаваться из административной панели.

Компоненты в Joomla! строятся на архитектуре MVC (Model-View-Controller - Модель-Представление-Контроллер) – схемы, с помощью которой модель данных, интерфейс пользователя и механизм взаимодействия с пользователем разделены на три отдельных составляющих так, что изменение одного из них минимально сказывается на двух других.

Все компоненты в Joomla  доступны по URL вида /index.php?option= com_<имя комонента> или /administrator/index.php?option=<имя комонента>, если речь идёт об админимтративной панели. Создадим в директории /components Joomla каталог с именем com_userlist – так будет называться наш компонент. В нём создадим файл userlist.php — точку входа в наш компонент.
<?php
// Защита от прямого обращения файлу
defined( '_JEXEC' ) or die( 'Restricted access' );
// Подключение файла контроллера
require_once( JPATH_COMPONENT.DS.'controller.php' );
echo "test";
// Создание контроллера
$controller = new UserlistController( );
// Даём инструкцию контроллеру
$controller->execute(JRequest::getVar('task'));
);
// Перенаправление, если это задано контроллером
$controller->redirect();
?>

JPATH_COMPONENT — абсолютный путь к компоненту, DS - автоматический выбор разделителя директорий '\' или '/', в зависимости от ОС.
Функция execute даёт указание контроллеру выполнить задачу, которая указана в URL: /index.php? option=com_userlist&task=Задача. Если определения задачи нет, то по умолчанию будет выполенеа задача ''display''.

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

Создим файл controller.php в той же директории:

<?php
defined( '_JEXEC' ) or die( 'Restricted access' );
jimport('joomla.application.component.controller');
class UserlistController extends JController
    function display() {
        parent::display();
    }
}
?> 
Поскольку никакагоко взаимодействия с пользователем здесь не потребуется, всё, что нужно от контроллера — загрузить представление. Эта функция уже предусмотрена в родительском классе JController, так что всё, что нужно сделать, это вызвать JController::display ()  из нашего метода display(). Как было сказано выше, если в URL не указана задача, то вызывается именно он.

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

Создадим файл userlist.php в субдиректории  com_userlist/models:
<?php
defined( '_JEXEC' ) or die( 'Restricted access' );
jimport( 'joomla.application.component.model' );
class UserlistModelUserlist extends JModel
{
    function getUserlist()
    {   
          //Создаём объект базы данных
       $db =& Jfactory::getDBO();
       //Пока нет выбора категории, выбирем всех пользователей
       $query = 'SELECT name FROM #__users';
       $db->setQuery($query);
       $userlist[] = $db->loadResultArray();
       return $userlist;
    }

Модель содержит данные и методы для их обработки. В нашем случае, в здесь булет единственная функция getUserlist(), которая возвращает массив имён пользователей.

Создание представления

Представеление (вид), отображает данные, полученные от модели.
Создадим ещё одну субдиректорию  com_userlist/views,  в ней директорию userlist — имя нашего представления (представлений может быть несколько), а в ней файл представления view.html.php:
<?php
defined( '_JEXEC' ) or die( 'Restricted access' );
jimport( 'joomla.application.component.view');

class UserlistViewUserlist extends JView
{
    function display($tpl = null)
    {
     // Получаем модель:
        $model =& $this->getModel();
     // Получаем данные из модели
        $userlist = $model->getUserlist();
      // И передаём их в шаблон
        $this->assignRef('userlist',$userlist);
        parent::display($tpl);
    }
} 
Файл шаблона должен находиться по адресу com_userlist/views/userlist/tmpl/default.php.
<?php
    defined('_JEXEC') or die('Restricted access');
    echo "

Users:

";     foreach ($this->userlist as $i) {         foreach ($i as $j) {             echo $j;         }     } ?>
В шаблоне выводим данные в нужном виде.
Итак, мы создали компонент, выводящий список всех пользователей. Теперь добавим возможность выводить пользователей только конкртеной категории, задав её в админиcтративной панели.
Создание административной части.
При создании админиcтративной части нашего компонента используется почти такие же имена файлов и директорий в каталоге administrator/components/com_userlist/.
Точка входа, файл userlist.php будeт таким же, как и в наружной части сайта.
В модели (models/usetlist.php) будет функция getUsertypes(), возвращающая массив имён  категорий пользователей, зарегистрированных на сайте, и функция store(), сохраняющаяя имя категории, пользователей которой будет отображать наш компонент.

 defined('_JEXEC') or die();
jimport( 'joomla.application.component.model' );

class UserlistModelUserlist extends JModel
{  
    function getData() {
             $db =& JFactory::getDBO();
        $query = 'SELECT DISTINCT usertype FROM #__users';
        $db->setQuery($query);
             $this->data = $db->loadRowList();
            return $this->data;
 }
    function store() {
        //Получаем данные от контроллера  
        $data = JRequest::get( 'post' );
        $db =& JFactory::getDBO();
        $ut = $data["usertype"];
        //О таблице userlist будет сказно позже
        $query = 'UPDATE #__userlist SET value="'.$ut.'" WHERE property = "usertype"';
        $db->setQuery($query);
        $db->query();
    }
}

Представеление (views/useslist/view.html.php) не сильно отличается от представления внешней части компонента:

defined('_JEXEC') or die();
jimport( 'joomla.application.component.view' );
class UserlistViewUserlist extends JView
{
    function display($tpl = null)
    {
      // Устанавливаем заголовок и значок для компонента админиcтративной части
        JToolBarHelper::title( JText::_( 'Userlist manager' ), 'generic.png' );
      //Добавляем кнопку «Сохранить».
        JToolBarHelper::save();

        $catlist =& $this->get('Data');
        $this->assignRef('catlist', $catlist );
        parent::display($tpl);
    }
}

Более подробную информацию об использовании стандартных элементов панели админиcтратора можно найти в официальной документации по Joomla на  http://api.joomla.org/ .

Создадим файл шаблона (views/userlist/tmpl/default.php) :
//Данный для POST-запроса: //Компонент //Задача, в нашем случае здесь будет 'save' //после нажатия кнопки “Сохранить” //И контроллер, обрабатывающий запрос

И, наконец, создадим контроллер (controller.php):

defined( '_JEXEC' ) or die( 'Restricted access' );
jimport('joomla.application.component.controller');
 class UserlistController extends JController
{
    function display()
    {
        parent::display();
    }

    function save()
    {
        //Опредеяем модель
            $model = $this->getModel('userlist');
        //Модель сохраненяет данные
            $model->store($post)
           $msg = JText::_( 'Сохранено' );
        $link = 'index.php?option=com_userlist';
        //Перенаправление
           $this->setRedirect($link, $msg);
    }

}

Тепрь можно модифицировать функцию  getUserlist() в модели внешней части для выбора пользователей определённой категории:
 function getUserlist()
    {  
       $db =& Jfactory::getDBO();
       $query = 'SELECT value FROM #__userlist WHERE property = "usertype"';
       $db->setQuery($query);
       $ut = $db->loadResult();
       $query = 'SELECT name FROM #__users WHERE usertype = "'.$ut.'"';
       $db->setQuery($query);
       $userlist[] = $db->loadResultArray();
       return $userlist;
    }
Стоит отметить, что один компонент может имметь несколько контроллеров, видов и моделей.
Мы создали две части компонента: внешнюю для отображения и админиcтративную для управления. Теперь нам нужно создать файл с инструкциями для установки. Данные об установке компонента в Joomla храняться в XML-файле, в нашем случае userlist.xml:




    Userlist
    Author
    author@example.org
    http://www.example.org
    Copyright Info
    License Info
    Component Version String
    Displays lis of users


    models/userlist.php
    models/index.html
    index.html
    userlist.php
    controller.php
    views/index.html
    views/userlist/index.html
    views/userlist/view.html.php
    views/userlist/tmpl/index.html
    views/userlist/tmpl/default.php




 
   install.sql
 

 

 
 
   uninstall.sql
 

 


 
 
 

List of users
 
 
    userlist.php
    models/userlist.php
    models/index.html
    controller.php
    views/index.html
    views/userlist/index.html
    views/userlist/view.html.php
    views/userlist/tmpl/index.html
    views/userlist/tmpl/default.php
      index.html
      install.sql
      uninstall.sql

В этом файле хранится список файлов компонента, а таже инфорация о нём.
Для корректной установки нужно, чтобы файлы и каталоги, предназначенные для админиcтративной части, то есть для (\admninidtrator\components\com_<имя компонента>)? а также файлы intstall.sql и uninstall.sql находилились в директории admin, а файлы, предназначенные для внешней части сайта (components\com_<имя компонента>)) — в директории site.  Файл userlist.xml должен быть на одном уровне с admin и site. Таким образом, получается следующаяя структура:
tree.png
Все файлы index.html содержат код , чтобы исключить получение списка файлов директорий.
В файле install.sql прописываются запросы к базе данных, которые нужно выполнить при установки:
DROP TABLE IF EXISTS `#__userlist`;

CREATE TABLE `#__userlist` (
  `property` varchar(25) NOT NULL,
  `value` varchar(25) NOT NULL,
  PRIMARY KEY  (`property`)
) ENGINE=MyISAM AUTO_INCREMENT=0 DEFAULT CHARSET=utf8;
INSERT INTO #__userlist VALUES ('usertype','Registered');

А в файле uninstall.sql  - запросы при удалении:
DROP TABLE IF EXISTS `#__userlist`;
Файл userlist.xml, директории admin и site запаковываем в архив и наш компонент можно устанавливать через менеджер расширени Joomla.
скриншоты
Теперь ссылка на панель усправления компонентом доступна из выпадающего меню «Компоненты» панели администратора, а ссылку на внешнюю часть компонента можно создать через меню.

Автор: Роман Сухов

1 комментарий:

  1. Очень сжато и по делу в одной статье. К сожалению подобных статей по Joomla! очень мало. Спасибо!

    ОтветитьУдалить