You are here

class MediaRevisionAccessCheck in Media Revisions UI 8

Same name and namespace in other branches
  1. 2.0.x src/Access/MediaRevisionAccessCheck.php \Drupal\media_revisions_ui\Access\MediaRevisionAccessCheck

Provides an access checker for media item revisions.

Core media access class allows only view operation so it is extended to provide access checks for revert and delete operations as well.

Hierarchy

Expanded class hierarchy of MediaRevisionAccessCheck

1 string reference to 'MediaRevisionAccessCheck'
media_revisions_ui.services.yml in ./media_revisions_ui.services.yml
media_revisions_ui.services.yml
1 service uses MediaRevisionAccessCheck
access_check.media.revision in ./media_revisions_ui.services.yml
Drupal\media_revisions_ui\Access\MediaRevisionAccessCheck

File

src/Access/MediaRevisionAccessCheck.php, line 19

Namespace

Drupal\media_revisions_ui\Access
View source
class MediaRevisionAccessCheck extends CoreMediaRevisionAccessCheck {

  /**
   * The entity type manager.
   *
   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
   */
  protected $entityTypeManager;

  /**
   * {@inheritdoc}
   */
  public function __construct(EntityTypeManagerInterface $entity_type_manager) {
    parent::__construct($entity_type_manager);
    $this->entityTypeManager = $entity_type_manager;
  }

  /**
   * {@inheritdoc}
   */
  public function access(Route $route, AccountInterface $account, $media_revision = NULL, MediaInterface $media = NULL) {
    if ($media_revision) {
      $media = $this->mediaStorage
        ->loadRevision($media_revision);
    }
    return parent::access($route, $account, $media_revision, $media)
      ->addCacheTags([
      'media:' . $media
        ->id() . ':revisions_list',
    ]);
  }

  /**
   * {@inheritdoc}
   */
  public function checkAccess(MediaInterface $media, AccountInterface $account, $op = 'view') {
    $bundle = $media
      ->bundle();
    $operations = [
      'view' => 'view all media revisions',
      'update' => 'revert all media revisions',
      'delete' => 'delete all media revisions',
    ];
    $bundleOperations = [
      'view' => "view {$bundle} media revisions",
      'update' => "revert {$bundle} media revisions",
      'delete' => "delete {$bundle} media revisions",
    ];
    if (!$media || !isset($operations[$op]) || !isset($bundleOperations[$op])) {

      // If there was no media to check against, or the $op was not one of the
      // supported ones, we return access denied.
      return FALSE;
    }

    // Statically cache access by revision ID, language code, user account ID,
    // and operation.
    $langcode = $media
      ->language()
      ->getId();
    $cid = $media
      ->getRevisionId() . ':' . $langcode . ':' . $account
      ->id() . ':' . $op;
    if (!isset($this->access[$cid])) {

      // Perform basic permission checks first.
      if (!$account
        ->hasPermission($operations[$op]) && !$account
        ->hasPermission($bundleOperations[$op]) && !$account
        ->hasPermission('administer media')) {
        $this->access[$cid] = FALSE;
        return FALSE;
      }
      $mediaType = $media
        ->getEntityType()
        ->getBundleEntityType();

      /** @var \Drupal\media\MediaTypeInterface $mediaTypeEntity */
      $mediaTypeEntity = $this->entityTypeManager
        ->getStorage($mediaType)
        ->load($media
        ->bundle());

      // If the revisions checkbox is selected for the media type, display the
      // revisions tab.
      if ($mediaTypeEntity
        ->shouldCreateNewRevision() && $op === 'view') {
        $this->access[$cid] = TRUE;
      }
      else {

        // There should be at least two revisions. If the vid of the given media
        // and the vid of the default revision differ, then we already have two
        // different revisions so there is no need for a separate database
        // check. Also, if you try to revert to or delete the default revision,
        // that's not good.
        if ($media
          ->isDefaultRevision() && ($this
          ->countDefaultLanguageRevisions($media) == 1 || $op === 'update' || $op === 'delete')) {
          $this->access[$cid] = FALSE;
        }
        elseif ($account
          ->hasPermission('administer media')) {
          $this->access[$cid] = TRUE;
        }
        else {

          // First check the access to the default revision and finally, if the
          // media passed in is not the default revision then access to that,
          // too.
          $this->access[$cid] = $this->mediaAccess
            ->access($this->mediaStorage
            ->load($media
            ->id()), $op, $account) && ($media
            ->isDefaultRevision() || $this->mediaAccess
            ->access($media, $op, $account));
        }
      }
    }
    return $this->access[$cid];
  }

}

Members

Namesort descending Modifiers Type Description Overrides
MediaRevisionAccessCheck::$access protected property A static cache of access checks.
MediaRevisionAccessCheck::$entityTypeManager protected property The entity type manager.
MediaRevisionAccessCheck::$mediaAccess protected property The media access control handler.
MediaRevisionAccessCheck::$mediaStorage protected property The media storage.
MediaRevisionAccessCheck::access public function Checks routing access for the media item revision. Overrides MediaRevisionAccessCheck::access
MediaRevisionAccessCheck::checkAccess public function Checks media item revision access. Overrides MediaRevisionAccessCheck::checkAccess
MediaRevisionAccessCheck::countDefaultLanguageRevisions protected function Counts the number of revisions in the default language.
MediaRevisionAccessCheck::__construct public function Constructs a new MediaRevisionAccessCheck. Overrides MediaRevisionAccessCheck::__construct