Создание ctools access plugin для Panels

26.02.2014
Автор:

Не так давно мы рассматривали то, как при разработке сайтов создать ctools тип контента для модуля Panels. На этот раз пришел черед другого типа плагинов для Ctools, а именно -  access plugin. Плагины этого вида являются некими правилами, по которым Panels решают показывать либо не показывать pane (наименьшую структурную единицу панелей), выбрать тот или иной вариант отображения самой панельки.

Для примера рассмотрим такую задачу: у нас есть стандартная панель user_view, которая переопределяет стандартное отображение страницы пользователя в Drupal. Есть пользователь А, который смотрит профиль пользователя Б. Если пользователь А зарегистрирован на сайте раньше пользователя Б, то ему будем показываться один набор полей, если наоборот - другой. Задача немного надуманная (и присутствуют намеки на дедовщину), но для примера сойдет.

Первым делом, как и в случае с ctools типом контента, нужно с помощью hook_ctools_plugin_directory() объявить, что у нас есть плагины:

 /*
 * Implements hook_ctools_plugin_directory().
 */
function access_example_ctools_plugin_directory($owner, $plugin_type) {
  if ($owner == 'ctools' && !empty($plugin_type)) {
   return "plugins/{$plugin_type}";
  }
}

Далее в папке модуля создаем следующие папки: папку "plugins", в ней папку "access", и создаем в ней файл плагина - назовем его "access_example_plugin.inc". В файле плагина описываем правило доступа массивом:

 /**
 * Plugins are described by creating a $plugin array which will be used
 * by the system that includes this file.
 */
$plugin = array(
  // Plugin user-friendly name.
  'title' => t('Eldership rule'),
  // Plugin description.
  'description' => t('Controls access depends on eldership'),
  // Without required context plugin will now be shown in Panels UI.
  'required context' => array(new ctools_context_required(t('User'), 'user')),
  // Function which will allow or restrict access.
  'callback' => 'access_example_who_elder_access',
  // Plugin settings form.
  'settings form' => 'access_example_who_elder_access_settings_form',
  // Provides a summary descriptions depends on settings selected.
  'summary' => 'access_example_who_elder_access_summary',
);

Думаем, комментарии к коду достаточно красноречивы, дабы не описывать более подробно :). Нам остается написать три функции: 

Первая (ключ 'settings form' в массиве плагина) будет описывать форму настроек плагина. Здесь важно, чтобы элементы формы (которые по совместительству являются и настройками правил доступа) находились в контейнере "settings", иначе введенные данные не будут сохраняться. В нашем случае форма настроек будет состоять из одного чекбокса:

 /**
 * Settings form for our access plugin.
 *
function access_example_who_elder_access_settings_form(&$form, &$form_state, $conf) {
  $form['settings']['eldership'] = array(
    '#type' => 'checkbox',
    '#title' => t('Eldership'),
    '#description' => t('Will provide access if current user has been registered before user from context'),
    '#default_value' => !empty($conf['eldership']) ? TRUE : FALSE,
  );
  return $form;
}

Форма будет выглядеть примерно так:

Вторая функция (ключ "summary" в массиве плагина) является необязательной при создании плагина, но для удобства рекомендуем ее использовать, так как ее наличие позволяет, без открытия формы настроек правил доступа, понять текущее его состояние.

 /**
 * Provide a summary description based on selected settings.
 */
function access_example_who_elder_access_summary($conf, $context) {
  return !empty($conf['eldership']) ?
  t('Will grant access if current user has been registered earlier then context user') :
  t('Will grant access if current user has been registered later then context user');
}

Вот так будет выглядеть результат работы вышеописанной функции:

Ну и наиболее важная функция плагина (ключ "callback" в массиве плагина), собственно, управляет доступом. Если она возвращает TRUE, значит доступ разрешен, FALSE - запрещен.

 /**
 * Check for access.
 */
function access_example_who_elder_access($conf, $context) {
  global $user;
  // There should always be a context at this point, but this
  // is safe.
  if (empty($context[0]) || empty($context[0]->data)) {
    return FALSE;
  }
  // We should ignore this access rule in case user is viewing his own profile.
  if ($user->uid == $context[0]->data->uid) {
    return TRUE;
  }
  if ($user->created < $context[0]->data->created) {
    return TRUE;
  }
  return FALSE;
} 

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

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

1 vote, Rating: 5

Также по теме

1

Apps -  это модуль, который можно позиционировать как следующий шаг в развитии...

2

Задача импорта контента часто бывает нетривиальной. Писать импорт "с нуля" для каждого случая далеко не оптимальный вариант, поэтому мы рекомендуем использовать уже существующие решения, например...

3

В даной статье описан процесс развёртывания CMS Drupal с использованием Oracle DB на Debian сервере.

4

Иногда ситуация складывается так, что возникает потребность в использовании обоих интернет-протоколов  HTTP...

5

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

Need a quote? Let's discuss the project

Are you looking for someone to help you with your Drupal Web Development needs? Let’s get in touch and discuss the requirements of your project. We would love to hear from you.

Join the people who have already subscribed!

Want to be aware of important and interesting things happening? We will inform you about new blog posts on Drupal development, design, QA testing and more, as well news about Drupal events.

No charge. Unsubscribe anytime