You are here

public function FlaggingStorage::loadIsFlaggedMultiple in Flag 8.4

Loads a list of flags the entities are flagged with for the given account.

Parameters

\Drupal\Core\Entity\EntityInterface[] $entities: The entities to check. All entities must be of the same type.

\Drupal\Core\Session\AccountInterface $account: The user account to check for.

string $session_id: (optional) The session ID. This must be supplied if $account is the anonymous user.

Return value

string[][] A list of flag_ids that for which the given entity is flagged, either globally or for the given account. Keyed by the entity IDs.

Throws

\LogicException Thrown when $account is anonymous but no associated session ID is specified.

Overrides FlaggingStorageInterface::loadIsFlaggedMultiple

1 call to FlaggingStorage::loadIsFlaggedMultiple()
FlaggingStorage::loadIsFlagged in src/Entity/Storage/FlaggingStorage.php
Loads a list of flags the entity is flagged with for the given account.

File

src/Entity/Storage/FlaggingStorage.php, line 51

Class

FlaggingStorage
Default SQL flagging storage.

Namespace

Drupal\flag\Entity\Storage

Code

public function loadIsFlaggedMultiple(array $entities, AccountInterface $account, $session_id = NULL) {
  if ($account
    ->isAnonymous() && is_null($session_id)) {
    throw new \LogicException('Anonymous users must be identified by session_id');
  }

  // Set a dummy value for $session_id for an authenticated user so that we
  // can use it as a key in the cache array.
  if (!$account
    ->isAnonymous()) {
    $session_id = 0;
  }
  $flag_ids_by_entity = [];
  if (!$entities) {
    return $flag_ids_by_entity;
  }

  // All entities must be of the same type, get the entity type from the
  // first.
  $entity_type_id = reset($entities)
    ->getEntityTypeId();
  $ids_to_load = [];

  // Loop over all requested entities, if they are already in the loaded list,
  // get then from there, merge the global and per-user flags together.
  foreach ($entities as $entity) {
    if (isset($this->flagIdsByEntity[$account
      ->id()][$session_id][$entity_type_id][$entity
      ->id()])) {
      $flag_ids_by_entity[$entity
        ->id()] = array_merge($this->flagIdsByEntity[$account
        ->id()][$session_id][$entity_type_id][$entity
        ->id()], $this->globalFlagIdsByEntity[$entity_type_id][$entity
        ->id()]);
    }
    else {
      $ids_to_load[$entity
        ->id()] = [];
    }
  }

  // If there are no entities that need to be loaded, return the list.
  if (!$ids_to_load) {
    return $flag_ids_by_entity;
  }

  // Initialize the loaded lists with the missing ID's as an empty array.
  if (!isset($this->flagIdsByEntity[$account
    ->id()][$session_id][$entity_type_id])) {
    $this->flagIdsByEntity[$account
      ->id()][$session_id][$entity_type_id] = [];
  }
  if (!isset($this->globalFlagIdsByEntity[$entity_type_id])) {
    $this->globalFlagIdsByEntity[$entity_type_id] = [];
  }
  $this->flagIdsByEntity[$account
    ->id()][$session_id][$entity_type_id] += $ids_to_load;
  $this->globalFlagIdsByEntity[$entity_type_id] += $ids_to_load;
  $flag_ids_by_entity += $ids_to_load;

  // Directly query the table to avoid he overhead of loading the content
  // entities.
  $query = $this->database
    ->select('flagging', 'f')
    ->fields('f', [
    'entity_id',
    'flag_id',
    'global',
  ])
    ->condition('entity_type', $entity_type_id)
    ->condition('entity_id', array_keys($ids_to_load), 'IN');

  // The flagging must either match the user or be global.
  $user_or_global_condition = $query
    ->orConditionGroup()
    ->condition('global', 1);
  if ($account
    ->isAnonymous()) {
    $uid_and_session_condition = $query
      ->andConditionGroup()
      ->condition('uid', $account
      ->id())
      ->condition('session_id', $session_id);
    $user_or_global_condition
      ->condition($uid_and_session_condition);
  }
  else {
    $user_or_global_condition
      ->condition('uid', $account
      ->id());
  }
  $result = $query
    ->condition($user_or_global_condition)
    ->execute();

  // Loop over all results, put them in the cached list and the list that will
  // be returned.
  foreach ($result as $row) {
    if ($row->global) {
      $this->globalFlagIdsByEntity[$entity_type_id][$row->entity_id][$row->flag_id] = $row->flag_id;
    }
    else {
      $this->flagIdsByEntity[$account
        ->id()][$session_id][$entity_type_id][$row->entity_id][$row->flag_id] = $row->flag_id;
    }
    $flag_ids_by_entity[$row->entity_id][$row->flag_id] = $row->flag_id;
  }
  return $flag_ids_by_entity;
}