2015-08-17 17:00:26 -07:00
< ? php
namespace Drupal\node ;
use Drupal\Core\Access\AccessResult ;
use Drupal\Core\Entity\EntityHandlerInterface ;
use Drupal\Core\Entity\EntityTypeInterface ;
use Drupal\Core\Field\FieldDefinitionInterface ;
use Drupal\Core\Field\FieldItemListInterface ;
use Drupal\Core\Entity\EntityAccessControlHandler ;
use Drupal\Core\Entity\EntityInterface ;
use Drupal\Core\Session\AccountInterface ;
use Symfony\Component\DependencyInjection\ContainerInterface ;
/**
* Defines the access control handler for the node entity type .
*
* @ see \Drupal\node\Entity\Node
* @ ingroup node_access
*/
class NodeAccessControlHandler extends EntityAccessControlHandler implements NodeAccessControlHandlerInterface , EntityHandlerInterface {
/**
* The node grant storage .
*
* @ var \Drupal\node\NodeGrantDatabaseStorageInterface
*/
protected $grantStorage ;
/**
* Constructs a NodeAccessControlHandler object .
*
* @ param \Drupal\Core\Entity\EntityTypeInterface $entity_type
* The entity type definition .
* @ param \Drupal\node\NodeGrantDatabaseStorageInterface $grant_storage
* The node grant storage .
*/
public function __construct ( EntityTypeInterface $entity_type , NodeGrantDatabaseStorageInterface $grant_storage ) {
parent :: __construct ( $entity_type );
$this -> grantStorage = $grant_storage ;
}
/**
* { @ inheritdoc }
*/
public static function createInstance ( ContainerInterface $container , EntityTypeInterface $entity_type ) {
return new static (
$entity_type ,
$container -> get ( 'node.grant_storage' )
);
}
/**
* { @ inheritdoc }
*/
2015-10-08 11:40:12 -07:00
public function access ( EntityInterface $entity , $operation , AccountInterface $account = NULL , $return_as_object = FALSE ) {
2015-08-17 17:00:26 -07:00
$account = $this -> prepareUser ( $account );
if ( $account -> hasPermission ( 'bypass node access' )) {
$result = AccessResult :: allowed () -> cachePerPermissions ();
return $return_as_object ? $result : $result -> isAllowed ();
}
if ( ! $account -> hasPermission ( 'access content' )) {
$result = AccessResult :: forbidden () -> cachePerPermissions ();
return $return_as_object ? $result : $result -> isAllowed ();
}
2015-10-08 11:40:12 -07:00
$result = parent :: access ( $entity , $operation , $account , TRUE ) -> cachePerPermissions ();
2015-08-17 17:00:26 -07:00
return $return_as_object ? $result : $result -> isAllowed ();
}
/**
* { @ inheritdoc }
*/
public function createAccess ( $entity_bundle = NULL , AccountInterface $account = NULL , array $context = array (), $return_as_object = FALSE ) {
$account = $this -> prepareUser ( $account );
if ( $account -> hasPermission ( 'bypass node access' )) {
$result = AccessResult :: allowed () -> cachePerPermissions ();
return $return_as_object ? $result : $result -> isAllowed ();
}
if ( ! $account -> hasPermission ( 'access content' )) {
$result = AccessResult :: forbidden () -> cachePerPermissions ();
return $return_as_object ? $result : $result -> isAllowed ();
}
$result = parent :: createAccess ( $entity_bundle , $account , $context , TRUE ) -> cachePerPermissions ();
return $return_as_object ? $result : $result -> isAllowed ();
}
/**
* { @ inheritdoc }
*/
2015-10-08 11:40:12 -07:00
protected function checkAccess ( EntityInterface $node , $operation , AccountInterface $account ) {
2015-08-17 17:00:26 -07:00
/** @var \Drupal\node\NodeInterface $node */
2015-10-08 11:40:12 -07:00
2015-08-17 17:00:26 -07:00
// Fetch information from the node object if possible.
2015-10-08 11:40:12 -07:00
$status = $node -> isPublished ();
$uid = $node -> getOwnerId ();
2015-08-17 17:00:26 -07:00
// Check if authors can view their own unpublished nodes.
if ( $operation === 'view' && ! $status && $account -> hasPermission ( 'view own unpublished content' ) && $account -> isAuthenticated () && $account -> id () == $uid ) {
2016-04-20 09:56:34 -07:00
return AccessResult :: allowed () -> cachePerPermissions () -> cachePerUser () -> addCacheableDependency ( $node );
2015-08-17 17:00:26 -07:00
}
// Evaluate node grants.
2015-10-08 11:40:12 -07:00
return $this -> grantStorage -> access ( $node , $operation , $account );
2015-08-17 17:00:26 -07:00
}
/**
* { @ inheritdoc }
*/
protected function checkCreateAccess ( AccountInterface $account , array $context , $entity_bundle = NULL ) {
return AccessResult :: allowedIf ( $account -> hasPermission ( 'create ' . $entity_bundle . ' content' )) -> cachePerPermissions ();
}
/**
* { @ inheritdoc }
*/
protected function checkFieldAccess ( $operation , FieldDefinitionInterface $field_definition , AccountInterface $account , FieldItemListInterface $items = NULL ) {
// Only users with the administer nodes permission can edit administrative
// fields.
$administrative_fields = array ( 'uid' , 'status' , 'created' , 'promote' , 'sticky' );
if ( $operation == 'edit' && in_array ( $field_definition -> getName (), $administrative_fields , TRUE )) {
return AccessResult :: allowedIfHasPermission ( $account , 'administer nodes' );
}
// No user can change read only fields.
$read_only_fields = array ( 'revision_timestamp' , 'revision_uid' );
if ( $operation == 'edit' && in_array ( $field_definition -> getName (), $read_only_fields , TRUE )) {
return AccessResult :: forbidden ();
}
// Users have access to the revision_log field either if they have
// administrative permissions or if the new revision option is enabled.
if ( $operation == 'edit' && $field_definition -> getName () == 'revision_log' ) {
if ( $account -> hasPermission ( 'administer nodes' )) {
return AccessResult :: allowed () -> cachePerPermissions ();
}
return AccessResult :: allowedIf ( $items -> getEntity () -> type -> entity -> isNewRevision ()) -> cachePerPermissions ();
}
return parent :: checkFieldAccess ( $operation , $field_definition , $account , $items );
}
/**
* { @ inheritdoc }
*/
public function acquireGrants ( NodeInterface $node ) {
$grants = $this -> moduleHandler -> invokeAll ( 'node_access_records' , array ( $node ));
// Let modules alter the grants.
$this -> moduleHandler -> alter ( 'node_access_records' , $grants , $node );
// If no grants are set and the node is published, then use the default grant.
if ( empty ( $grants ) && $node -> isPublished ()) {
$grants [] = array ( 'realm' => 'all' , 'gid' => 0 , 'grant_view' => 1 , 'grant_update' => 0 , 'grant_delete' => 0 );
}
return $grants ;
}
/**
* { @ inheritdoc }
*/
public function writeGrants ( NodeInterface $node , $delete = TRUE ) {
$grants = $this -> acquireGrants ( $node );
$this -> grantStorage -> write ( $node , $grants , NULL , $delete );
}
/**
* { @ inheritdoc }
*/
public function writeDefaultGrant () {
$this -> grantStorage -> writeDefault ();
}
/**
* { @ inheritdoc }
*/
public function deleteGrants () {
$this -> grantStorage -> delete ();
}
/**
* { @ inheritdoc }
*/
public function countGrants () {
return $this -> grantStorage -> count ();
}
/**
* { @ inheritdoc }
*/
public function checkAllGrants ( AccountInterface $account ) {
return $this -> grantStorage -> checkAll ( $account );
}
}