You are here

groupmedia.module in Group Media 8

Same filename and directory in other branches
  1. 8.2 groupmedia.module

File

groupmedia.module
View source
<?php

use Drupal\Core\Access\AccessResult;
use Drupal\Core\Session\AccountInterface;
use Drupal\group\Entity\GroupContentType;
use Drupal\media_entity\MediaInterface;
use Drupal\media_entity\MediaBundleInterface;

/**
 * Implements hook_ENTITY_TYPE_insert().
 */
function groupmedia_media_bundle_insert(MediaBundleInterface $mediaBundle) {
  \Drupal::service('plugin.manager.group_content_enabler')
    ->clearCachedDefinitions();
}

/**
 * Implements hook_media_access().
 *
 * When trying to view, update or delete a media item it suffices to have the right to
 * do so in only one group the media belongs to. If you wish to prevent any such
 * action on your own terms, implement hook_media_access() in your module.
 */
function groupmedia_media_access(MediaInterface $media, $op, AccountInterface $account) {

  // We do not care about create access as we have our own wizard for that. Any
  // operation aside from 'view', 'update' and 'delete' is also unsupported.
  if (!in_array($op, [
    'view',
    'update',
    'delete',
  ])) {
    return AccessResult::neutral();
  }

  // Some modules, including the code in \Drupal\media_entity\MediaForm::access() may
  // check for 'view', 'update' or 'delete' access on new nodes, even though
  // that makes little sense. We need to account for it to avoid crashes because
  // we would otherwise query the DB with a non-existent node ID.
  if ($media
    ->isNew()) {
    return AccessResult::neutral();
  }
  $plugin_id = 'group_media:' . $media
    ->bundle();

  // Only act if there are group content types for this node type.
  $group_content_types = GroupContentType::loadByContentPluginId($plugin_id);
  if (empty($group_content_types)) {
    return AccessResult::neutral();
  }

  // Load all the group content for this node.
  $group_contents = \Drupal::entityTypeManager()
    ->getStorage('group_content')
    ->loadByProperties([
    'type' => array_keys($group_content_types),
    'entity_id' => $media
      ->id(),
  ]);

  // If the media does not belong to any group, we have nothing to say.
  if (empty($group_contents)) {
    return AccessResult::neutral();
  }

  /** @var \Drupal\group\Entity\GroupInterface[] $groups */
  $groups = [];
  foreach ($group_contents as $group_content) {

    /** @var \Drupal\group\Entity\GroupContentInterface $group_content */
    $group = $group_content
      ->getGroup();
    $groups[$group
      ->id()] = $group;
  }

  // From this point on you need group to allow you to perform the requested
  // operation. If you are not granted access for a node belonging to a group,
  // you should be denied access instead.
  switch ($op) {
    case 'view':
      foreach ($groups as $group) {
        if ($media
          ->isPublished()) {
          if ($group
            ->hasPermission("view {$plugin_id} entity", $account)) {
            return AccessResult::allowed();
          }
        }
        elseif ($group
          ->hasPermission("view unpublished {$plugin_id} entity", $account)) {
          return AccessResult::allowed();
        }
      }
      break;
    case 'update':
    case 'delete':
      foreach ($groups as $group) {
        if ($group
          ->hasPermission("{$op} any {$plugin_id} entity", $account)) {
          return AccessResult::allowed();
        }
        elseif ($account
          ->id() == $media
          ->getPublisherId() && $group
          ->hasPermission("{$op} own {$plugin_id} entity", $account)) {
          return AccessResult::allowed();
        }
      }
      break;
  }
  return AccessResult::forbidden();
}

Functions

Namesort descending Description
groupmedia_media_access Implements hook_media_access().
groupmedia_media_bundle_insert Implements hook_ENTITY_TYPE_insert().