Skip to content
Snippets Groups Projects
Commit bd5c7d35 authored by Bram Driesen's avatar Bram Driesen Committed by Rodrigo Aguilera
Browse files

Issue #3427277: Implement hook_publishcontent_action_access

parent e0f34f63
Branches 8.x-1.x
Tags 8.x-1.7
1 merge request!5Issue #3427277: Implement hook_publishcontent_action_access
Pipeline #300909 failed
<?php
/**
* @file
* API Example for PublishContent module.
*/
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Session\AccountInterface;
use Drupal\node\NodeInterface;
/**
* Hook callback when publishing.
*
* @param \Drupal\node\NodeInterface $node
* The node we are trying to publish.
* @param \Drupal\Core\Session\AccountInterface $account
* The account that is trying to publish the node.
*
* @return \Drupal\Core\Access\AccessResult
* The access result.
*/
function hook_publishcontent_publish_access(NodeInterface $node, AccountInterface $account) {
// Very simple example.
if ($node->getType() === 'article') {
if ($node->hasField('field_test') && $node->field_test->value === 'dummy') {
return AccessResult::allowed();
}
return AccessResult::forbidden();
}
// Default neutral so other hooks can judge.
return AccessResult::neutral();
}
/**
* Hook callback when unpublishing.
*
* @param \Drupal\node\NodeInterface $node
* The node we are trying to unpublish.
* @param \Drupal\Core\Session\AccountInterface $account
* The account that is trying to unpublish the node.
*
* @return \Drupal\Core\Access\AccessResult
* The access result.
*/
function hook_publishcontent_unpublish_access(NodeInterface $node, AccountInterface $account) {
// Very simple example.
if ($node->getType() === 'article') {
if ($node->hasField('field_test') && $node->field_test->value === 'dummy') {
return AccessResult::allowed();
}
return AccessResult::forbidden();
}
// Default neutral so other hooks can judge.
return AccessResult::neutral();
}
......@@ -6,13 +6,12 @@
*/
use Drupal\Core\Form\FormStateInterface;
use Drupal\publishcontent\Access\PublishContentAccess;
/**
* Implements hook_form_BASE_FORM_ID_alter().
*/
function publishcontent_form_node_form_alter(&$form, FormStateInterface $form_state) {
$config = \Drupal::config('publishcontent.settings');
$config = Drupal::config('publishcontent.settings');
$form['status']['widget']['value']['#title'] = $config->get('publish_text_value');
if (!array_key_exists('#default_value', $form['status']['widget']['value'])) {
$form['status']['widget']['value']['#default_value'] = 0;
......@@ -27,10 +26,11 @@ function publishcontent_form_node_form_alter(&$form, FormStateInterface $form_st
if (!empty($form['status']) && empty($form['status']['#access'])) {
$user = Drupal::currentUser();
$node = $form_state->getFormObject()->getEntity();
$publishContentAccess = new PublishContentAccess();
/** @var \Drupal\publishcontent\Access\PublishContentAccess $publish_content_access */
$publish_content_access = Drupal::service('publishcontent.access');
$form['status']['#access'] = TRUE;
if (!$publishContentAccess->access($user, $node)->isAllowed()) {
if (!$publish_content_access->access($user, $node)->isAllowed()) {
$form['status']['#disabled'] = TRUE;
$form['status']['widget']['value']['#description'] = t('You can not change the @published status.', [
'@published' => $config->get('publish_text_value'),
......
services:
publishcontent.access:
class: Drupal\publishcontent\Access\PublishContentAccess
arguments: ['@module_handler']
tags:
- {name: access_check, applies_to: _publish_access_check}
......@@ -3,6 +3,7 @@
namespace Drupal\publishcontent\Access;
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Routing\Access\AccessInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\node\NodeInterface;
......@@ -13,6 +14,13 @@ use Drupal\publishcontent\PublishContentPermissions as Perm;
*/
class PublishContentAccess implements AccessInterface {
/**
* The module handler.
*
* @var \Drupal\Core\Extension\ModuleHandlerInterface
*/
private $moduleHandler;
/**
* The account performing the action.
*
......@@ -34,6 +42,16 @@ class PublishContentAccess implements AccessInterface {
*/
protected $arguments;
/**
* PublishContentAccess constructor.
*
* @param \Drupal\Core\Extension\ModuleHandlerInterface $moduleHandler
* The module handler interface.
*/
public function __construct(ModuleHandlerInterface $moduleHandler) {
$this->moduleHandler = $moduleHandler;
}
/**
* {@inheritdoc}
*/
......@@ -62,11 +80,52 @@ class PublishContentAccess implements AccessInterface {
|| $this->accessUnpublishAnyType()
|| $this->accessUnpublishOwnType()
|| $this->accessUnpublishEditableType()))) {
return AccessResult::allowed();
$hook = "publishcontent_{$action}_access";
$access = array_merge(
$this->moduleHandler->invokeAll($hook, [
$this->node,
$this->account,
]),
[AccessResult::allowed()]
);
return $this->processAccessHookResults($access);
}
return AccessResult::forbidden();
}
/**
* Process all acess hooks.
*
* We grant access if both of these conditions are met:
* - No modules say to deny access.
* - At least one module says to grant access.
*
* @param \Drupal\Core\Access\AccessResultInterface[] $access
* An array of access results of the fired access hook.
*
* @return \Drupal\Core\Access\AccessResultInterface
* The combined result of the various access check results.
*
* All their cacheability metadata is merged as well.
*
* @see \Drupal\Core\Access\AccessResultInterface::orIf()
*/
protected function processAccessHookResults(array $access) {
// No results means no opinion.
if (empty($access)) {
return AccessResult::neutral();
}
/** @var \Drupal\Core\Access\AccessResultInterface $result */
$result = array_shift($access);
foreach ($access as $other) {
$result = $result->orIf($other);
}
return $result;
}
/**
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment