Доступ к узлам через profile_taxonomy

Главные вкладки

Аватар пользователя vermix1 vermix1 8 апреля 2010 в 10:10

[#42674]Проблему[/#] с доступом к нодам без использования ролей решил. Хотя, возможно, не лучшем образом - с использованием [module=hook_node_grants] и [module=hook_node_access_records]. Минус - таблица node_access может очень сильно разрастись. Плюс - как оказалось, очень простая реализация). Полноценный модуль пока не дописан, поэтому выложу только реализацию упомянутых хуков.

function profile_taxonomy_access_node_grants($account, $op) {
  $grants = array();
  //Через api profile_taxonomy получаем словарь,
  //термины которого ассоциированы с профилем
  //и поле профиля к которому привязан словарь
  $pt_assignments = profile_taxonomy_get_assignments();
  //profile_taxonomy может работать с несколькими полями профиля,
  //к которым привязаны разные словари, но мне пока нужно только одно такое поле.
  //Поле назвал "profile_location", словарь "Регионы"(vid=1).
  //Как освобожусь сделаю по-нормальному.
  $field = $pt_assignments[0]->field;
  $vid = $pt_assignments[0]->vid;
  //Подгружаем в объект $account данные из профиля
  profile_load_profile(&$account);
  //Если в профиле есть данные о регионе пользователя
  //пытаемся получить tid термина по vid и name. Если
  //эти данные отсутствуют, этот модуль не предоставляет
  //никакого доступа
  if ($account->$field && $vid) {
    $tid = db_result(db_query("SELECT tid FROM {term_data} WHERE (name='%s' AND vid=%d)", $account->$field, $vid));
  } else {
    return $grants;
  }
  //Идентификатор сеанса управления ресурсами узла (gid) для рег.представителей
  if ($op == 'view' && $tid) {
    $grants['pta_view'] = array($tid);
  }
  //Тоже самое для для рег.модераторов. profile_location_moderator - поле-флажок в профиле. Если установлен,
  //то пользователь считается региональным модератором.
  if (($op == 'update' || $op == 'delete') && $tid && $account->profile_location_moderator) {
    $grants['pta_admin'] = array($tid);
  }

  return $grants;
}

function profile_taxonomy_access_node_access_records($node) {
  $grants = array();
  $pt_assignments = profile_taxonomy_get_assignments();
  //Поскольку $node приходит сюда с непонятно как оформленной таксономией,
  //приходится использовать такую штуку
  if ($node->taxonomy) {
    $terms = taxonomy_node_get_terms_by_vocabulary($node, $pt_assignments[0]->vid);
  } else {
    return $grants;
  }
  //Формируем список записей сеанса управления ресурсами для $node
  foreach ($terms as $term) {
    //Область доступа
    $grants[] = array(
      'realm' => 'pta_view',
      'gid' => $term->tid,
      'grant_view' => TRUE,
      'grant_update' => FALSE,
      'grant_delete' => FALSE,
      'priority' => 0,
    );
    //Область модерства
    $grants[] = array(
      'realm' => 'pta_admin',
      'gid' => $term->tid,
      'grant_view' => TRUE,
      'grant_update' => TRUE,
      'grant_delete' => TRUE,
      'priority' => 0,
    );
  }
  return $grants;
}

В принципе, если на время удалить запись по умолчанию в таблице node_access, то уже только с этими двумя хуками можно поиграться с этим механизмом доступа. Но "региональные" ноды пока может создавать только админ. До готового к употреблению модуля осталось только реализовать перестройку таблицы node_access и разобраться с добавлением нод региональными модераторами. Но это уже дело техники. Да, и еще: [module=profile_taxonomy] поддерживает добавление к профилю сразу нескольких словарей, так что если в модуле это учесть, может получиться интересный функционал. В общем, я пока занят, но постараюсь к понедельнику выложить полностью готовый модуль.

P.S. Пишу пост уже засыпая, так что прошу прощения за несколько сумбурное изложение.

P.P.S. Если обнаружите откровенный г*внокод, пожалуйста сообщите)