Пишем модуль ограничения доступа к ноде drupal 7

В Drupal очень удобно сделано распределение доступов для материалов и действий на сайте. Для этого выделена целая страница admin/people/permissions, где галочками можно отмечать доступы ролям к сайту.

Но иногда требуется специфичное ограничение доступа к материалу. Например, только для пользователей, зарегистрированных больше недели назад. Такое уже не решить с помощью стандартных средств Drupal 7.

Здесь на помощь приходит hook_node_access (ссылка на документацию). Этот хук позволяет ограничивать или разрешать доступ к определённым нодам. Например:

function MODULE_NAME_node_access($node, $op, $account)
{
    if ($op == 'view' && $node->type == 'article') {
        if ($account->roles === 'Администратор') {
            return NODE_ACCESS_ALLOW;
        } else {
            return NODE_ACCESS_DENY
        }
    }
}

Код, приведённый выше, ограничивает доступ к нодам типа article для всех пользователей, кроме тех, у которых роль Администратор. Это простой пример, чтобы можно было понять смысл хука, тоже самое можно сделать и через стандарные правила Drupal 7 (admin/people/permissions).

Пишем свой модуль ограничения прав

Ссылка на репозиторий

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

Статья расчитана на новичков, так что описание процесса разработки я буду проводить как можно подробнее. Назовём модуль custom_access. В папке "\sites\all\modules\" (именно в этой папке должны лежать все сторонние модули Drupal) создадим новую папку "custom". В папке custom мы будем хранить все наши самописные модули.

Очень удобно хранить свои самописные модули в отдельной папке. Потому что когда проект разрастётся, и будет установлено много модулей, очень сложно искать свои модули, если нужно изменить их. А если они все будут лежать в папке custom, то поиск нужного своего модуля не займёт много времени.

Теперь, в папке custom создаём папку с названием custom_access для нового модуля. В созданной папке создаём 2 файла: custom_access.info и custom_access.module. Это 2 обязательных файла каждого модуля Drupal 7. В итоге структура файлов и папок должна получиться следующая:

folder_structure.png

Теперь открываем файл custom_access.info и напишем туда следующее:

custom_access.info

name = Custom node access
description = Модуль ограничивает доступ к нодам неавторизованным пользователям, и пользователям, которые которые зарегистрированны менее недели назад.
package = Custom
core = 7.x

Нужно сказать, что файл custom_access.info является описанием модуля для Drupal 7. Здесь прописывают название модуля, описание, раздел, в котором будет виден модуль в списке всех модулей "admin/modules", а так же другую информацию о модуле. На drupal.org есть хорошая статья о написании .info файлов модулей https://drupal.org/node/542202.

Теперь напишем сам код модуля. Открываем файл custom_access.module и пишем следующее:

<?php

/**
 * HOOK_node_access
 * @param $node
 * @param $op
 * @param $account
 * @return string
 */
function custom_access_node_access($node, $op, $account) {
    if ($op == 'view' && $node->type == 'article') {

        // Запрещаем доступ неавторизованным
        if ($account->uid === 0) {
            return NODE_ACCESS_DENY;
        }

        // Получаем данные тукещего авторизованного пользователя
        $user = user_load($account->uid);
        // Текущее время timestamp
        $current_time = time();

        // Проверка даты создания аккаунта
        if (($current_time - $user->created) <= 604800) {
            return NODE_ACCESS_DENY;
        } else {
            return NODE_ACCESS_ALLOW;
        }
    }
}

Поясню, что название хука выглядит так: hook_node_access, но вместо hook нужно подставлять название своего модуля, т.е. получается custom_access_node_access.

Здесь мы проверяем тип просматриваемой ноды, проверяем авторизован ли пользователь, загружаем объект с данными пользователя в переменную $user, затем проверяем дату создания аккаунта пользователя, который хочет просмотреть эту ноду. И если разница текущего времени и даты создания аккаунта больше недели, то разрешаем доступ к просмотру, иначе запрещаем. Всё просто.

В этом хуке есть несколько особенностей:

  • На пользователя с uid == 1 этот хук не действует. Т.е. ему доступно всё (это как раз главный администратор, который создаётся при установке Drupal 7).
  • В зависимости от значения переменной $op, $node может быть объектом, а может быть типа string. Это нужно учитывать при разработке.

Включаем наш модуль и проверяем работоспособность:

enable_module.png

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

access-denied.png