четверг, 1 марта 2012 г.

Создание компонента для CMS Joomla. Часть 14. Добавление ACL(прав доступа)

Доброго времени суток. Сегодняшний пост - это продолжение серии статей по созданию компонента для CMS Joomla. В прошлой статье мы с Вами добавили к создаваемому нами компоненту файла конфигурации, добавили настройки компонента в админке. И логическим продолжением данной темы будет добавление прав доступа к компоненту. Что такое права доступа, так называемый ACL я описал в своем материале “ACL (Access Control List) в Joomla 1.6. Права доступа в Joomla 1.6.”. Тут хотел бы отметить, чтобы Вас не смущало, что статья написана для CMS Joomla 1.6, все в ней сказано справедливо и для Joomla 1.7, и для Joomla 2.5. Итак, мы знаем, что такое права доступа CMS Joomla, давайте приступим к добавлению этих прав доступа к создаваемому нами компоненту...

Прежде, чем приступить к добавлению прав доступа для создаваемого компонента скачайте компонент из предыдущего поста. Потому, что именно к этому компоненту мы и будем добавлять права доступа. Скачать данный компонент Вы можете по этой ссылке.
Файл с описанием прав доступа - access.xml
Каждый компонент CMS Joomla может иметь свой ACL. Файл, который отвечает за права доступа в компоненте называется access.xml. Этот файл должен находиться в папке admin. В данном уроке мы этот файл разобьем на две секции: первая будет относиться к самому компоненту, а вторая к сообщениям компонента. Давайте создадим файл /admin/access.xml и добавим в него следующий код:
<?xml version="1.0" encoding="utf-8" ?>
<access component="com_helloworld">
    <section name="component">
        <action name="core.admin" title="JACTION_ADMIN" description="JACTION_ADMIN_COMPONENT_DESC" />
        <action name="core.manage" title="JACTION_MANAGE" description="JACTION_MANAGE_COMPONENT_DESC" />
        <action name="core.create" title="JACTION_CREATE" description="JACTION_CREATE_COMPONENT_DESC" />
        <action name="core.delete" title="JACTION_DELETE" description="JACTION_DELETE_COMPONENT_DESC" />
        <action name="core.edit" title="JACTION_EDIT" description="JACTION_EDIT_COMPONENT_DESC" />
    </section>
    <section name="message">
        <action name="core.delete" title="JACTION_DELETE" description="COM_HELLOWORLD_ACCESS_DELETE_DESC" />
        <action name="core.edit" title="JACTION_EDIT" description="COM_HELLOWORLD_ACCESS_EDIT_DESC" />
    </section>
</access>

Ограничение доступа к компоненту.
Следующим шагом является ограничение доступа к компонету. Вообще, если просто сказать, то основная функция ACL - это ограничение доступа определенной группе пользователя. Давайте так и сделаем. Ограничим доступ доступ к компоненту. Для этого отредактируем файл admin/helloworld.php следующим образом:

<?php
// права доступа
defined('_JEXEC') or die('Restricted access');

// проверка доступа
if (!JFactory::getUser()->authorise('core.manage', 'com_helloworld'))
{
    return JError::raiseWarning(404, JText::_('JERROR_ALERTNOAUTHOR'));
}

// подключаем вспомогательный файл
JLoader::register('HelloWorldHelper', dirname(__FILE__) . DS . 'helpers' . DS . 'helloworld.php');

// импорт библиотеки контроллеров
jimport('joomla.application.component.controller');

// получаем экземпляр контроллера с префиксом HelloWorld
$controller = JController::getInstance('HelloWorld');

// выполнение запроса задачи  
$controller->execute(JRequest::getCmd('task'));

// перенаправление
$controller->redirect();

Показываем только нужные кнопки в панели инструментов
Следующим шагом будет ограничение доступа к управлению компонентов. Сделаем так, что бы кнопки на панели управления отображались в соответствии с ACL. Для этого изменим файл admin/views/helloworlds/view.html.php, так:

<?php
// права доступа
defined('_JEXEC') or die('Restricted access');

// импорт библиотеки view
jimport('joomla.application.component.view');

/**
* Создание подкласса HelloWorlds класса View
*/
class HelloWorldViewHelloWorlds extends JView
{
    /**
    * Создание метода display
    */
    function display($tpl = null)
    {
       // получаем данные из модели
       $items = $this->get('Items');
       $pagination = $this->get('Pagination');

       // проверяем на наличие ошибок
       if (count($errors = $this->get('Errors')))
       {
           JError::raiseError(500, implode('<br />', $errors));
           return false;
       }
       // назначаем данные
       $this->items = $items;
       $this->pagination = $pagination;

       // устанавливаем панель управления
       $this->addToolBar();

       // отображаем шаблон
       parent::display($tpl);

       // передаем данные
       $this->setDocument();
    }

    /**
    * свойства панели управления
    */
    protected function addToolBar()
    {
       $canDo = HelloWorldHelper::getActions();
       JToolBarHelper::title(JText::_('COM_HELLOWORLD_MANAGER_HELLOWORLDS'), 'helloworld');
       if ($canDo->get('core.create'))
       {
           JToolBarHelper::addNew('helloworld.add', 'JTOOLBAR_NEW');
       }
       if ($canDo->get('core.edit'))
       {
           JToolBarHelper::editList('helloworld.edit', 'JTOOLBAR_EDIT');
       }
       if ($canDo->get('core.delete'))
       {
           JToolBarHelper::deleteList('', 'helloworlds.delete', 'JTOOLBAR_DELETE');
       }
       if ($canDo->get('core.admin'))
       {
           JToolBarHelper::divider();
           JToolBarHelper::preferences('com_helloworld');
       }
    }
    /**
    * метод настройки свойств документа
    */
    protected function setDocument()
    {
       $document = JFactory::getDocument();
       $document->setTitle(JText::_('COM_HELLOWORLD_ADMINISTRATION'));
    }
}

И изменим файл admin/views/helloworld/view.html.php:

<?php
// права доступа
defined('_JEXEC') or die('Restricted access');

// импорт библиотеки view
jimport('joomla.application.component.view');

/**
* Подкласс HelloWorld класса View
*/
class HelloWorldViewHelloWorld extends JView
{
    /**
    * метод display
    */
    public function display($tpl = null)
    {
       // получаем данные
       $form = $this->get('Form');
       $item = $this->get('Item');
       $script = $this->get('Script');

       // проверяем на наличие ошибок
       if (count($errors = $this->get('Errors')))
       {
           JError::raiseError(500, implode('<br />', $errors));
           return false;
       }
       // назначаем данные
       $this->form = $form;
       $this->item = $item;
       $this->script = $script;

       // устанавливаем панель управления
       $this->addToolBar();

       // отображаем шаблон
       parent::display($tpl);

       // передаем данные
       $this->setDocument();
    }

    /**
    * свойства панели управления
    */
    protected function addToolBar()
    {
       JRequest::setVar('hidemainmenu', true);
       $user = JFactory::getUser();
       $userId = $user->id;
       $isNew = $this->item->id == 0;
       $canDo = HelloWorldHelper::getActions($this->item->id);
       JToolBarHelper::title($isNew ? JText::_('COM_HELLOWORLD_MANAGER_HELLOWORLD_NEW')
                                    : JText::_('COM_HELLOWORLD_MANAGER_HELLOWORLD_EDIT'), 'helloworld');
       // действия для новых и существующих записей.
       if ($isNew)
       {
           // для новых записей создаются разрешения
           if ($canDo->get('core.create'))
           {
               JToolBarHelper::apply('helloworld.apply', 'JTOOLBAR_APPLY');
               JToolBarHelper::save('helloworld.save', 'JTOOLBAR_SAVE');
               JToolBarHelper::custom('helloworld.save2new', 'save-new.png', 'save-new_f2.png',
                                      'JTOOLBAR_SAVE_AND_NEW', false);
           }
           JToolBarHelper::cancel('helloworld.cancel', 'JTOOLBAR_CANCEL');
       }
       else
       {
           if ($canDo->get('core.edit'))
           {
               // мы можем сохранить новую запись
               JToolBarHelper::apply('helloworld.apply', 'JTOOLBAR_APPLY');
               JToolBarHelper::save('helloworld.save', 'JTOOLBAR_SAVE');


               if ($canDo->get('core.create'))
               {
                   JToolBarHelper::custom('helloworld.save2new', 'save-new.png', 'save-new_f2.png',
                                          'JTOOLBAR_SAVE_AND_NEW', false);
               }
           }
           if ($canDo->get('core.create'))
           {
               JToolBarHelper::custom('helloworld.save2copy', 'save-copy.png', 'save-copy_f2.png',
                                      'JTOOLBAR_SAVE_AS_COPY', false);
           }
           JToolBarHelper::cancel('helloworld.cancel', 'JTOOLBAR_CLOSE');
       }
    }
    /**
    * метод установки свойств документа
    */
    protected function setDocument()
    {
       $isNew = $this->item->id == 0;
       $document = JFactory::getDocument();
       $document->setTitle($isNew ? JText::_('COM_HELLOWORLD_HELLOWORLD_CREATING')
                                  : JText::_('COM_HELLOWORLD_HELLOWORLD_EDITING'));
       $document->addScript(JURI::root() . $this->script);
       $document->addScript(JURI::root() . "/administrator/components/com_helloworld"
                                         . "/views/helloworld/submitbutton.js");
       JText::script('COM_HELLOWORLD_HELLOWORLD_ERROR_UNACCEPTABLE');
    }
}

Эти два файла использую метод getActions, который нам и нужно описать. Данный метод описывается в файле admin/helpers/helloworld.php. Изменим в нем код:

<?php
// права доступа
defined('_JEXEC') or die;

/**
* HelloWorld компонент helper.
*/
abstract class HelloWorldHelper
{
    /**
    * настройка Linkbar.
    */
    public static function addSubmenu($submenu)
    {
       JSubMenuHelper::addEntry(JText::_('COM_HELLOWORLD_SUBMENU_MESSAGES'),
                                'index.php?option=com_helloworld', $submenu == 'messages');
       JSubMenuHelper::addEntry(JText::_('COM_HELLOWORLD_SUBMENU_CATEGORIES'),
                                'index.php?option=com_categories&view=categories&extension=com_helloworld',
                                $submenu == 'categories');
       // устанавливаем глобальные свойства
       $document = JFactory::getDocument();
       $document->addStyleDeclaration('.icon-48-helloworld ' .
                                      '{background-image: url(../media/com_helloworld/images/tux-48x48.png);}');
       if ($submenu == 'categories')
       {
           $document->setTitle(JText::_('COM_HELLOWORLD_ADMINISTRATION_CATEGORIES'));
       }
    }
    /**
    * метод getActions
    */
    public static function getActions($messageId = 0)
    {    
       jimport('joomla.access.access');
       $user    = JFactory::getUser();
       $result    = new JObject;

       if (empty($messageId)) {
           $assetName = 'com_helloworld';
       }
       else {
           $assetName = 'com_helloworld.message.'.(int) $messageId;
       }

       $actions = JAccess::getActions('com_helloworld', 'component');

       foreach ($actions as $action) {
           $result->set($action->name, $user->authorise($action->name, $assetName));
       }

       return $result;
    }
}
Добавление прав доступа в настройки компонента.
Как мы знаем из предыдущей статьи настройки компонента описываются в файле admin/config.xml. Теперь нам необходимо добавить управление правами доступа компонента в его настройки. Для этого изменим файл admin/config.xml
<?xml version="1.0" encoding="utf-8"?>
<config>
    <fieldset
        name="greetings"
        label="COM_HELLOWORLD_CONFIG_GREETING_SETTINGS_LABEL"
        description="COM_HELLOWORLD_CONFIG_GREETING_SETTINGS_DESC"
    >
        <field
            name="show_category"
            type="radio"
            label="COM_HELLOWORLD_HELLOWORLD_FIELD_SHOW_CATEGORY_LABEL"
            description="COM_HELLOWORLD_HELLOWORLD_FIELD_SHOW_CATEGORY_DESC"
            default="0"
        >
            <option value="0">JHIDE</option>
            <option value="1">JSHOW</option>
        </field>
    </fieldset>
    <fieldset
        name="permissions"
        label="JCONFIG_PERMISSIONS_LABEL"
        description="JCONFIG_PERMISSIONS_DESC"
    >
        <field
            name="rules"
            type="rules"
            label="JCONFIG_PERMISSIONS_LABEL"
            class="inputbox"
            validate="rules"
            filter="rules"
            component="com_helloworld"
            section="component"
        />
    </fieldset>
</config>

Установка значений уровня доступа в таблице.
Для того, чтобы установить значения на уровень доступа в таблице мы должны сделать две вещи:
Во-первых изменить модель admin/models/helloworld.php:

<?php
// права доступа
defined('_JEXEC') or die('Restricted access');

// импорт библиотеки modelform
jimport('joomla.application.component.modeladmin');

/**
*  Подкласс HelloWorld класса Model
*/
class HelloWorldModelHelloWorld extends JModelAdmin
{

    protected function allowEdit($data = array(), $key = 'id')
    {
       // проверка разрешений на редактирование
       return JFactory::getUser()->authorise('core.edit', 'com_helloworld.message.'.
                                             ((int) isset($data[$key]) ? $data[$key] : 0))
              or parent::allowEdit($data, $key);
    }

    public function getTable($type = 'HelloWorld', $prefix = 'HelloWorldTable', $config = array())
    {
       return JTable::getInstance($type, $prefix, $config);
    }

    public function getForm($data = array(), $loadData = true)
    {
       // получение формы
       $form = $this->loadForm('com_helloworld.helloworld', 'helloworld',
                               array('control' => 'jform', 'load_data' => $loadData));
       if (empty($form))
       {
           return false;
       }
       return $form;
    }

    public function getScript()
    {
       return 'administrator/components/com_helloworld/models/forms/helloworld.js';
    }

    protected function loadFormData()
    {
       // проверка сессии раннее веденных данных
       $data = JFactory::getApplication()->getUserState('com_helloworld.edit.helloworld.data', array());
       if (empty($data))
       {
           $data = $this->getItem();
       }
       return $data;
    }
}

И во-вторых изменить таблицу admin/tables/helloworld.php:

<?php
// права доступа
defined('_JEXEC') or die('Restricted access');

// импорт библиотеки table
jimport('joomla.database.table');

/**
* Создаем подкласс Hello класса Table
*/
class HelloWorldTableHelloWorld extends JTable
{

    function __construct(&$db)
    {
       parent::__construct('#__helloworld', 'id', $db);
    }

    public function bind($array, $ignore = '')
    {
       if (isset($array['params']) && is_array($array['params']))
       {
           // Конвертируем данные поля в строку
           $parameter = new JRegistry;
           $parameter->loadArray($array['params']);
           $array['params'] = (string)$parameter;
       }
       return parent::bind($array, $ignore);
    }


    public function load($pk = null, $reset = true)
    {
       if (parent::load($pk, $reset))
       {
           // Изменяем регистр данных поля
           $params = new JRegistry;
           $params->loadJSON($this->params);
           $this->params = $params;
           return true;
       }
       else
       {
           return false;
       }
    }

    protected function _getAssetName()
    {
       $k = $this->_tbl_key;
       return 'com_helloworld.message.'.(int) $this->$k;
    }

    protected function _getAssetTitle()
    {
       return $this->greeting;
    }


    protected function _getAssetParentId()
    {
       $asset = JTable::getInstance('Asset');
       $asset->loadByName('com_helloworld');
       return $asset->id;
    }
}

На этом добавление ACL к нашему компоненту завершено. Осталось только изменить файл описания и можно приступать к тестированию.
Файл helloworld.xml:
<?xml version="1.0" encoding="utf-8"?>
<extension type="component" version="2.5.0" method="upgrade">

    <name>COM_HELLOWORLD</name>
    <!-- The following elements are optional and free of formatting constraints -->
    <creationDate>November 2009</creationDate>
    <author>John Doe</author>
    <authorEmail>john.doe@example.org</authorEmail>
    <authorUrl>http://www.example.org</authorUrl>
    <copyright>Copyright Info</copyright>
    <license>License Info</license>
    <!--  The version string is recorded in the components table -->
    <version>0.0.14</version>
    <!-- The description is optional and defaults to the name -->
    <description>COM_HELLOWORLD_DESCRIPTION</description>

    <install> <!-- Runs on install -->
        <sql>
            <file driver="mysql" charset="utf8">sql/install.mysql.utf8.sql</file>
        </sql>
    </install>
    <uninstall> <!-- Runs on uninstall -->
        <sql>
            <file driver="mysql" charset="utf8">sql/uninstall.mysql.utf8.sql</file>
        </sql>
    </uninstall>
    <update> <!-- Runs on update; New in 2.5 -->
        <schemas>
            <schemapath type="mysql">sql/updates/mysql</schemapath>
        </schemas>
    </update>

    <!-- Site Main File Copy Section -->
    <!-- Note the folder attribute: This attribute describes the folder
        to copy FROM in the package to install therefore files copied
        in this section are copied from /site/ in the package -->
    <files folder="site">
        <filename>index.html</filename>
        <filename>helloworld.php</filename>
        <filename>controller.php</filename>
        <folder>views</folder>
        <folder>models</folder>
        <folder>language</folder>
    </files>

    <media destination="com_helloworld" folder="media">
        <filename>index.html</filename>
        <folder>images</folder>
    </media>

    <administration>
        <!-- Administration Menu Section -->
        <menu img="../media/com_helloworld/images/tux-16x16.png">COM_HELLOWORLD_MENU</menu>
        <!-- Administration Main File Copy Section -->
        <!-- Note the folder attribute: This attribute describes the folder
            to copy FROM in the package to install therefore files copied
            in this section are copied from /admin/ in the package -->
        <files folder="admin">
            <!-- Admin Main File Copy Section -->
            <filename>index.html</filename>
            <filename>config.xml</filename>
            <filename>access.xml</filename>
            <filename>helloworld.php</filename>
            <filename>controller.php</filename>
            <!-- SQL files section -->
            <folder>sql</folder>
            <!-- tables files section -->
            <folder>tables</folder>
            <!-- models files section -->
            <folder>models</folder>
            <!-- views files section -->
            <folder>views</folder>
            <!-- controllers files section -->
            <folder>controllers</folder>
            <!-- helpers files section -->
            <folder>helpers</folder>
        </files>

        <languages folder="admin">
            <language tag="en-GB">language/en-GB/en-GB.com_helloworld.ini</language>
            <language tag="en-GB">language/en-GB/en-GB.com_helloworld.sys.ini</language>
        </languages>
    </administration>

</extension>


Скачать исходник данного материала Вы можете по следующей ссылке.
А на этом я с Вами прощаюсь. В следующей статье мы с Вами поговорим о добавлении скриптов install/uninstall/update и, наверно, это будет завершающая статья из цикла создание компонента для CMS Joomla. А в дальнейшем я планирую начать цикл статей по созданию модулей для CMS Joomla. И мы на примере создадим свой модуль, который можно будет использовать в действующем проекте. Так, что подписывайтесь на RSS-рассылку данного блога, чтобы не пропустить выхода новых статей.

Понравилась статья? Поблагодарить автора:

Введите e-mail адрес:



0 коммент.:

Отправить комментарий