Как предоставить доступ к редактированию для определенных узлов 1 или нескольким выбранным пользователям?
Я создаю школьный сайт на Drupal 8. Среди прочего, у меня есть два типа контента: один для учителей, другой для курсов. Учителя также имеют учетные записи пользователей и принадлежат к роли, скажем, "учитель".
Я хочу, чтобы учителя (аутентифицированные пользователи сайта, которые принадлежат к роли "учитель") могли редактировать страницы курсов, которые они преподают. Проблема в том, что есть курсы, которые преподаются более чем одним преподавателем, поэтому я не могу решить эту проблему, просто включив "редактировать собственный контент" и иметь их в качестве владельцев.
Итак, в целом, я хочу предоставить "доступ к редактированию" для определенных узлов конкретным, иногда нескольким пользователям.
Я провел исследование, прежде чем задать этот довольно простой вопрос.
Здесь есть очень похожий вопрос - однако ему четыре года, и модуль доступа к узлу , который предлагается в качестве решения, пока не подходит для Drupal 8.
Есть упоминание о другом модуле, flexi доступ, но он доступен только для Drupal 7.
Также есть ссылка на ACL, "API для других модулей для создания списков пользователей и предоставления им доступа к узлам", но это само по себе находится только в предварительном выпуске для Drupal 8, и модуль, который, похоже, использует его, Доступ к контенту имеет открытые проблемы безопасности (а также находится в состоянии предварительного выпуска).
Поискав вокруг, я также нашел Разрешения по термину модуль, кажется стабильным и очень хорошо документированным, однако, честно говоря, я не нашел это очень интуитивно понятным, а также, похоже, в основном предназначено для ограничения доступа к узлам (как предлагается здесь, но также из его видеоурока).
Я хочу чего-нибудь попроще. И я, очевидно, хочу, чтобы все узлы по-прежнему были общедоступны для просмотра кем угодно (даже анонимными пользователями, конечно). Поэтому, хотя разрешения по срокам казались возможным выбором, я не знаю, могу ли/должен ли я его использовать.
Существует также группа модуль, на который часто ссылаются, но это также кажется излишним и слишком сложным для простой задачи, которую я хочу выполнить.
Я немного запутался в этом вопросе.. Это кажется довольно простым, но я не могу найти способ сделать это. Любая помощь будет очень признательна...
5 answers
Модуль Группа - это то, на что вам следует обратить внимание... Это не °перебор° (как в вашем вопросе), вместо этого это единственный стабильный модуль D8, доступный сегодня, который также удовлетворит ваши потребности.
Для этого конкретного вопроса вы бы включили подмодуль gnode
, и для каждого типа группы вы бы определили соответствующие разрешения (просмотр, редактирование, удаление и т.д.) для различных типов контента. См. Мой ответ на " Как настроить доступ к курсам для учителей а студенты? "для примера конфигурации.
Примечание:
Позвольте мне также обратиться (частично) к вашему дополнительному комментарию под этим ответом, который выглядит следующим образом:
В моем случае мне понадобится довольно много групп - по одной на каждый курс, преподаваемый более чем 1 преподавателем.
Если бы я должен был настроить модуль группы для вашего случая, я бы использовал такой подход:
- Создайте Тип группы = Курсы.
- Создать Групповые роли = Учитель и ученик.
- Создайте ровно 1 группу для каждого возможного курса, помеченную (скажем) C1, C2, C3, ....
- Только предоставьте Групповое разрешение на "редактирование" узла типа контента "Курс" пользователям, которым была предоставлена "Роль преподавателя в группе". И в соответствии с вашим " Я хочу, чтобы все узлы по-прежнему были доступны для публичного просмотра любым (даже анонимным пользователям)", вы хотите предоставить "Просмотр" доступ "Посторонним" и "Анонимным", а также, возможно, также "Студенты".
- Если только учитель (пользователь) T1 преподает курс C1, то только T1 предоставляется групповая роль "Учитель" для (группы) C1.
- Если преподаватели (пользователи) T2 и T3 преподают курс C2, то только T2 и T3 получают групповую роль "Учитель" для (группы) C2.
- При создании узлов типа "Курс" назначьте их 1 (и только одной) группе (так что либо C1, либо C2, либо C3, либо...). И решите, какому преподавателю(преподавателям) (пользователю(пользователям)) вновь созданного курса будет предоставлена Группа роль "Учитель".
Готово...
Ресурсы
Если у вас есть тип контента course
с полем ссылки на сущность field_teachers
, вы можете включить редактирование для нескольких пользователей следующим образом:
mymodule.модуль:
use Drupal\node\NodeInterface;
use Drupal\Core\Access\AccessResult;
/**
* Implements hook_node_access().
*/
function mymodule_node_access(NodeInterface $node, $op, $account) {
$type = $node->bundle();
if ($type != 'course' || $op != 'update') {
return AccessResult::neutral();
}
$uids = array_column($node->field_teachers->getValue(), 'target_id');
return AccessResult::allowedIf(in_array($account->id(), $uids))->cachePerUser()->addCacheableDependency($node);
}
Если field_teachers ссылается не на пользователей, а на другой тип контента, то uid учителя, вероятно, хранится в указанном типе контента, и вам нужно извлечь оттуда uid каждого учителя. В этом случае добавьте все задействованные узлы в качестве кэшируемых зависимостей, чтобы при изменении узла учителя при использовании другого идентификатора uid результат доступа становится недействительным.
Вы можете заглянуть в модуль Доступ к рабочему столу . Это позволяет ограничить права на редактирование узлами на основе структуры меню или таксономии.
Вы можете создать словарь таксономии для различных групп редакторов. Примерами терминов могут быть Математика 4-го класса, естественные науки 5-го класса и т. Д. Или даже просто математика, естественные науки и т. Д. Добавьте справочное поле таксономии в узел "Курсы", оно используется для назначения вашего контента вашим группам. Затем вы можете назначить своим пользователям (преподавателям) правильные Группа (которые основаны только на вашем словаре таксономии), и все учителя в группе могут редактировать узел.
Вы могли бы реализовать ситуацию, когда каждый курс создает соответствующий термин таксономии автоматически при создании узла курса. Вы можете сделать это с помощью hook_entity_type_insert.
Что-то вроде следующего:
function hook_node_insert($node) {
if ($node->bundle() == 'course') {
// Check if a term with the $node->title() already exists. (See below [1])
// Or create a term (See below [2])
// Then set your taxonomy term reference field with the new tid, or existing tid
$node->field_my_tax_group_field[] = ['target_id' => $the_tid];
// Then save the node.
$node->save();
}
}
Если вы используете этот метод, единственное, что вам нужно будет сделать вручную после создания узла курса, это назначить правильный пользователей в Группу, чтобы разрешить им редактировать ее.
Еще один вариант, широко используемый в некоторых экземплярах D7 и, как и другие элементы, не полностью готовый для D8, - это Органические группы. Даже если вы готовы к прайм-тайму, у него есть небольшая кривая обучения, но он может быть довольно удобным. Вариант использования (хотя все еще в D7), аналогичный вашим потребностям, - это COD (Дистрибутив организатора конференций), который используется для проведения крупных мероприятий, таких как DrupalCon.
Возможно, вы захотите посмотреть, работает ли это для вас, но будьте предупреждены - некоторые архитекторы решений, с которыми я работаю были довольно разочарованы версией D8. Это связано со значительными архитектурными изменениями между D7 и D8, но в вашем случае это может сработать.
Прошло много времени, но я подумал о том, чтобы ответить на этот вопрос, чтобы, возможно, он был более полезен людям, оказавшимся здесь в поисках ответа.
Во-первых, я хотел бы поблагодарить всех тех, кто потратил время и усилия на написание ответов и комментариев - как новичок в Drupal, мне очень помогает такая обратная связь от более опытных пользователей (чего, на мой взгляд, немного не хватает Drupal..)
В любом случае, как я уже упоминал в своем вопросе, я нашел очень похожий вопрос, но я не хотел использовать ответ там, потому что он был довольно старым, и предложенный модуль казался нестабильным для Drupal 8 (все еще в бета-версии - и с этим примечанием, предлагающим: "У этого модуля есть предварительная версия для Drupal 8. ").
Тем не менее, я решил свою проблему, используя модуль Nodeaccess, упомянутый в этом (уже 5 лет) потоке - он работает нормально, хотя все еще находится в бета-версии для D8. Я протестировал на сайте разработки, а затем использовал его на производственный сайт, и он делает то, что я хочу (т. Е. Предоставляет доступ к редактированию определенным, иногда нескольким пользователям).
Поэтому я просто оставляю это здесь для дальнейшего использования.