foldershare-8.x-1.2/src/Entity/FolderShareTraits/FindTrait.php

src/Entity/FolderShareTraits/FindTrait.php
<?php
 
namespace Drupal\foldershare\Entity\FolderShareTraits;
 
use Drupal\Core\Database\Database;
use Drupal\file\FileInterface;
use Drupal\user\Entity\User;
 
/**
 * Find FolderShare entities.
 *
 * This trait includes find methods that query across all FolderShare
 * entities, or within a specific folder, and return IDs, entities, or
 * other values that match criteria.
 *
 * <B>Internal trait</B>
 * This trait is internal to the FolderShare module and used to define
 * features of the FolderShare entity class. It is a mechanism to group
 * functionality to improve code management.
 *
 * @ingroup foldershare
 */
trait FindTrait {
 
  /*---------------------------------------------------------------------
   *
   * Find root-level items.
   *
   *---------------------------------------------------------------------*/
 
  /**
   * Returns a list of root items that meet user and name requirements.
   *
   * An optional user ID may be provided to constrain root items to only
   * those owned by the specified user. If the ID is not given, or it is
   * FolderShareInterface::ANY_USER_ID, root items for any user are returned.
   *
   * An optional name may be provided to constrain root items to only those
   * with the given name. If a name is not given, or it is an empty string,
   * root items with any name are returned.
   *
   * System hidden or disabled root items may or may not be returned, depending
   * upon the parameters.
   *
   * Items marked disabled are in use. They remain visible and are enabled
   * again when they are no longer in use. Typically, disabled items should
   * be included in the returned results, so $includeDisabled defaults to
   * TRUE.
   *
   * Items marked hidden are being deleted. They are not visible and will
   * never be enabled again. Typically, hidden items should not be included
   * in the returned results, so $includeHidden defaults to FALSE.
   *
   * <B>Memory use</B>
   * Warning: There can be a large number of root items. Loading them all
   * into memory at the same time could exceed PHP's memory limit.
   *
   * <B>Run time</B>
   * Warning: There can be a large number of root items. Loading them all
   * at the same time could exceed PHP's execution time limit.
   *
   * <B>Example usage</B>
   * Find all root items for all users, for a specific user, or
   * for a specific user and named "data":
   * @code
   *   $allRootItems = FolderShare::findAllRootItems();
   *
   *   $user = \Drupal::currentUser();
   *   $allRootItemsByUser = FolderShare::findAllRootItems($user->id());
   *
   *   $allRootItemsByUserNamedData = FolderShare::findAllRootItems($user->id(), "data");
   * @endcode
   *
   * @param int $ownerUid
   *   (optional, default = FolderShareInterface::ANY_USER_ID) The user ID for
   *   the root items' owner.
   * @param string $name
   *   (optional, default = '' = any) The name for the root items.
   * @param bool $includeDisabled
   *   (optional, default = TRUE) When TRUE, disabled root items are included.
   *   When FALSE, they are not.
   * @param bool $includeHidden
   *   (optional, default = FALSE) When TRUE, hidden root items are included.
   *   When FALSE, they are not.
   *
   * @return \Drupal\foldershare\FolderShareInterface[]
   *   Returns an unordered associative array where keys are entity IDs
   *   and values are entities for root items.
   *
   * @see ::findAllIds()
   * @see ::findAllRootItemNames()
   * @see ::findAllPublicRootItems()
   * @see ::findAllSharedRootItems()
   */
  public static function findAllRootItems(
    int $ownerUid = self::ANY_USER_ID,
    string $name = '',
    bool $includeDisabled = TRUE,
    bool $includeHidden = FALSE) {
 
    $ids = self::findAllRootItemIds(
      $ownerUid,
      $name,
      $includeDisabled,
      $includeHidden);
 
    if (empty($ids) === TRUE) {
      return [];
    }
 
    return self::loadMultiple($ids);
  }
 
  /**
   * Returns a list of root item IDs that meet user and name requirements.
   *
   * An optional user ID may be provided to constrain root items to only
   * those owned by the specified user. If the ID is not given, or it is
   * FolderShareInterface::ANY_USER_ID, root items for any user are returned.
   *
   * An optional name may be provided to constrain root items to only those
   * with the given name. If a name is not given, or it is an empty string,
   * root items with any name are returned.
   *
   * System hidden or disabled root items may or may not be returned, depending
   * upon the parameters.
   *
   * Items marked disabled are in use. They remain visible and are enabled
   * again when they are no longer in use. Typically, disabled items should
   * be included in the returned results, so $includeDisabled defaults to
   * TRUE.
   *
   * Items marked hidden are being deleted. They are not visible and will
   * never be enabled again. Typically, hidden items should not be included
   * in the returned results, so $includeHidden defaults to FALSE.
   *
   * <B>Example usage</B>
   * Find all root item IDs for all users, for a specific user, or
   * for a specific user and named "data":
   * @code
   *   $allRootItemIds = FolderShare::findAllRootItemIds();
   *
   *   $user = \Drupal::currentUser();
   *   $allRootItemIdsByUser = FolderShare::findAllRootItemIds($user->id());
   *
   *   $allRootItemIdsByUserNamedData = FolderShare::findAllRootItemIds($user->id(), "data");
   * @endcode
   *
   * @param int $ownerUid
   *   (optional, default = FolderShareInterface::ANY_USER_ID) The user ID
   *   for the root items' owner.
   * @param string $name
   *   (optional, default = '' = any) The name for the root items.
   * @param bool $includeDisabled
   *   (optional, default = TRUE) When TRUE, disabled root items are included.
   *   When FALSE, they are not.
   * @param bool $includeHidden
   *   (optional, default = FALSE) When TRUE, hidden root items are included.
   *   When FALSE, they are not.
   *
   * @return int[]
   *   An unordered list of integer entity IDs for root items.
   *
   * @see ::findAllIds()
   * @see ::findAllRootItems()
   * @see ::findAllRootItemNames()
   */
  public static function findAllRootItemIds(
    int $ownerUid = self::ANY_USER_ID,
    string $name = '',
    bool $includeDisabled = TRUE,
    bool $includeHidden = FALSE) {
 
    // Root items have no parent ID or root ID.
    $connection = Database::getConnection();
    $select = $connection->select(self::BASE_TABLE, 'fs');
    $select->addField('fs', 'id', 'id');
    $select->isNull('parentid');
 
    if ($includeDisabled === FALSE) {
      // An empty field is also FALSE, so we have to test for !TRUE.
      $select->condition('systemdisabled', TRUE, '<>');
    }
 
    if ($includeHidden === FALSE) {
      // An empty field is also FALSE, so we have to test for !TRUE.
      $select->condition('systemhidden', TRUE, '<>');
    }
 
    if ($ownerUid >= 0) {
      $select->condition('uid', $ownerUid, '=');
    }
 
    if (empty($name) === FALSE) {
      $select->condition('name', $name, '=');
    }
 
    return $select->execute()->fetchCol(0);
  }
 
  /**
   * Returns a list of root item names that meet user requirements.
   *
   * An optional user ID may be provided to constrain root items to only
   * those owned by the specified user. If the ID is not given, or it is
   * FolderShareInterface::ANY_USER_ID, root items for any user are returned.
   *
   * System hidden or disabled root items may or may not be returned, depending
   * upon the parameters.
   *
   * Items marked disabled are in use. They remain visible and are enabled
   * again when they are no longer in use. Typically, disabled items should
   * be included in the returned results, so $includeDisabled defaults to
   * TRUE.
   *
   * Items marked hidden are being deleted. They are not visible and will
   * never be enabled again. Typically, hidden items should not be included
   * in the returned results, so $includeHidden defaults to FALSE.
   *
   * <B>Example usage</B>
   * Find all root item names for all users or for a specific user:
   * @code
   *   $allRootItems = FolderShare::findAllRootItemNames();
   *
   *   $user = \Drupal::currentUser();
   *   $rootItemNames = FolderShare::findAllRootItemNames($user->id());
   * @endcode
   *
   * @param int $ownerUid
   *   (optional, default = FolderShareInterface:ANY_USER_ID) The user ID
   *   for the root item's owner.
   * @param bool $includeDisabled
   *   (optional, default = TRUE) When TRUE, disabled root items are included.
   *   When FALSE, they are not.
   * @param bool $includeHidden
   *   (optional, default = FALSE) When TRUE, hidden root items are included.
   *   When FALSE, they are not.
   *
   * @return array
   *   Returns an unordered associative array where keys are entity names
   *   and values are entity IDs for root items.
   *
   * @see ::findAllIds()
   * @see ::findAllRootItems()
   * @see ::findAllRootItemIds()
   */
  public static function findAllRootItemNames(
    int $ownerUid = self::ANY_USER_ID,
    bool $includeDisabled = TRUE,
    bool $includeHidden = FALSE) {
 
    // Root items have no parent ID or root ID.
    $connection = Database::getConnection();
    $select = $connection->select(self::BASE_TABLE, 'fs');
    $select->addField('fs', 'id', 'id');
    $select->addField('fs', 'name', 'name');
    $select->isNull('parentid');
 
    if ($includeDisabled === FALSE) {
      // An empty field is also FALSE, so we have to test for !TRUE.
      $select->condition('systemdisabled', TRUE, '<>');
    }
 
    if ($includeHidden === FALSE) {
      // An empty field is also FALSE, so we have to test for !TRUE.
      $select->condition('systemhidden', TRUE, '<>');
    }
 
    if ($ownerUid >= 0) {
      $select->condition('uid', $ownerUid, '=');
    }
 
    $names = [];
    foreach ($select->execute() as $result) {
      $names[$result->name] = (int) $result->id;
    }
 
    return $names;
  }
 
  /**
   * Returns a list of public root items that meet user and name requirements.
   *
   * A public root item is one that is owned by the anonymous user OR one that
   * grants view access to anonymous.
   *
   * An optional user ID may be provided to constrain root items to only
   * those owned by the specified user. If the ID is not given, or it is
   * FolderShareInterface::ANY_USER_ID, root items for any user are returned.
   *
   * An optional name may be provided to constrain root items to only those
   * with the given name. If a name is not given, or it is an empty string,
   * root items with any name are returned.
   *
   * System hidden or disabled root items may or may not be returned, depending
   * upon the parameters.
   *
   * Items marked disabled are in use. They remain visible and are enabled
   * again when they are no longer in use. Typically, disabled items should
   * be included in the returned results, so $includeDisabled defaults to
   * TRUE.
   *
   * Items marked hidden are being deleted. They are not visible and will
   * never be enabled again. Typically, hidden items should not be included
   * in the returned results, so $includeHidden defaults to FALSE.
   *
   * <B>Memory use</B>
   * Warning: There can be a large number of root items. Loading them all
   * into memory at the same time could exceed PHP's memory limit.
   *
   * <B>Run time</B>
   * Warning: There can be a large number of root items. Loading them all
   * at the same time could exceed PHP's execution time limit.
   *
   * @param int $ownerUid
   *   (optional, default = FolderShareInterface::ANY_USER_ID) The user ID
   *   for the root items' owner.
   * @param string $name
   *   (optional, default = '' = any) The name for the root items.
   * @param bool $includeDisabled
   *   (optional, default = TRUE) When TRUE, disabled root items are included.
   *   When FALSE, they are not.
   * @param bool $includeHidden
   *   (optional, default = FALSE) When TRUE, hidden root items are included.
   *   When FALSE, they are not.
   *
   * @return \Drupal\foldershare\FolderShareInterface[]
   *   Returns an unordered associative array where keys are entity IDs
   *   and values are entities for root items.
   *
   * @see ::findAllPublicRootItemIds()
   * @see ::findAllRootItems()
   * @see ::findAllSharedRootItems()
   */
  public static function findAllPublicRootItems(
    int $ownerUid = self::ANY_USER_ID,
    string $name = '',
    bool $includeDisabled = TRUE,
    bool $includeHidden = FALSE) {
 
    $ids = self::findAllPublicRootItemIds(
      $ownerUid,
      $name,
      TRUE,
      FALSE);
 
    if (empty($ids) === TRUE) {
      return [];
    }
 
    return self::loadMultiple($ids);
  }
 
  /**
   * Returns a list of public root IDs that meet user and name requirements.
   *
   * A public root item is one that is owned by the anonymous user OR one that
   * grants view access to anonymous.
   *
   * An optional user ID may be provided to constrain root items to only
   * those owned by the specified user. If the ID is not given, or it is
   * FolderShareInterface::ANY_USER_ID, root items for any user are returned.
   *
   * An optional name may be provided to constrain root items to only those
   * with the given name. If a name is not given, or it is an empty string,
   * root items with any name are returned.
   *
   * System hidden or disabled root items may or may not be returned, depending
   * upon the parameters.
   *
   * Items marked disabled are in use. They remain visible and are enabled
   * again when they are no longer in use. Typically, disabled items should
   * be included in the returned results, so $includeDisabled defaults to
   * TRUE.
   *
   * Items marked hidden are being deleted. They are not visible and will
   * never be enabled again. Typically, hidden items should not be included
   * in the returned results, so $includeHidden defaults to FALSE.
   *
   * <B>Example usage</B>
   * Find all public root item IDs for all users, for a specific user, or
   * for a specific user and named "data":
   * @code
   *   $allPublicRootItemIds = FolderShare::findAllPublicRootItemIds();
   *
   *   $user = \Drupal::currentUser();
   *   $allPublicRootItemIdsByUser = FolderShare::findAllPublicRootItemIds($user->id());
   *
   *   $allPublicRootItemsIdsByUserNamedData = FolderShare::findAllPublicRootItemIds($user->id(), "data");
   * @endcode
   *
   * @param int $ownerUid
   *   (optional, default = FolderShareInterface::ANY_USER_ID) The user ID
   *   for the root items' owner.
   * @param string $name
   *   (optional, default = '' = any) The name for the root items.
   * @param bool $includeDisabled
   *   (optional, default = TRUE) When TRUE, disabled root items are included.
   *   When FALSE, they are not.
   * @param bool $includeHidden
   *   (optional, default = FALSE) When TRUE, hidden root items are included.
   *   When FALSE, they are not.
   *
   * @return int[]
   *   Returns an unordered array of entity IDs.
   *
   * @see ::findAllRootItemsIds()
   * @see ::findAllSharedRootItemsIds()
   */
  public static function findAllPublicRootItemIds(
    int $ownerUid = self::ANY_USER_ID,
    string $name = '',
    bool $includeDisabled = TRUE,
    bool $includeHidden = FALSE) {
 
    // Root items have no parent ID or root ID.
    $connection = Database::getConnection();
    $select = $connection->select(self::BASE_TABLE, 'fs');
    $select->addField('fs', 'id', 'id');
    $select->condition('parentid', NULL, 'IS NULL');
 
    if ($includeDisabled === FALSE) {
      // An empty field is also FALSE, so we have to test for !TRUE.
      $select->condition('systemdisabled', TRUE, '<>');
    }
 
    if ($includeHidden === FALSE) {
      // An empty field is also FALSE, so we have to test for !TRUE.
      $select->condition('systemhidden', TRUE, '<>');
    }
 
    // Join with the list of people granted view access.
    $select->join(
      'foldershare__grantviewuids',
      'view',
      '(view.entity_id = fs.id)');
 
    // Then require one of these cases:
    // - The item's owner is anonymous.
    // - The grants for view access include anonymous.
    $anonymousUid = (int) User::getAnonymousUser()->id();
    $group = $select->orConditionGroup()
      ->condition('uid', $anonymousUid, '=')
      ->condition('view.grantviewuids_target_id', $anonymousUid, '=');
    $select = $select->condition($group);
 
    // Constrain results to those owned by a specified user, or with
    // the specified item name.
    if ($ownerUid >= 0) {
      $select->condition('uid', $ownerUid, '=');
    }
 
    if (empty($name) === FALSE) {
      $select->condition('name', $name, '=');
    }
 
    return $select->execute()->fetchCol(0);
  }
 
  /**
   * Returns a list of shared root items that meet user and name requirements.
   *
   * A shared root item is one that is not owned by the current user AND one
   * that grants view access to the current user.
   *
   * An optional user ID may be provided to constrain root items to only
   * those owned by the specified user. If the ID is not given, or it is
   * FolderShareInterface::ANY_USER_ID, root items for any user are returned.
   *
   * An optional viewer ID may be provided to constrain root items to only
   * those viewable by the specified user. If the ID is not given, or it is
   * FolderShareInterface::CURRENT_USER_ID, root items viewable by the current
   * user are returned.
   *
   * An optional name may be provided to constrain root items to only those
   * with the given name. If a name is not given, or it is an empty string,
   * root items with any name are returned.
   *
   * System hidden or disabled root items may or may not be returned, depending
   * upon the parameters.
   *
   * Items marked disabled are in use. They remain visible and are enabled
   * again when they are no longer in use. Typically, disabled items should
   * be included in the returned results, so $includeDisabled defaults to
   * TRUE.
   *
   * Items marked hidden are being deleted. They are not visible and will
   * never be enabled again. Typically, hidden items should not be included
   * in the returned results, so $includeHidden defaults to FALSE.
   *
   * <B>Memory use</B>
   * Warning: There can be a large number of root items. Loading them all
   * into memory at the same time could exceed PHP's memory limit.
   *
   * <B>Run time</B>
   * Warning: There can be a large number of root items. Loading them all
   * at the same time could exceed PHP's execution time limit.
   *
   * @param int $ownerUid
   *   (optional, default = FolderShareInterface::ANY_USR_ID) The user ID
   *   for the root items owner.
   * @param int $viewerUid
   *   (optional, default = FolderShareInterface::CURRENT_USER_ID) The user ID
   *   for the user that must have view permission (defaults to current user).
   * @param string $name
   *   (optional, default = '' = any) The name for the root items.
   * @param bool $includeDisabled
   *   (optional, default = TRUE) When TRUE, disabled root items are included.
   *   When FALSE, they are not.
   * @param bool $includeHidden
   *   (optional, default = FALSE) When TRUE, hidden root items are included.
   *   When FALSE, they are not.
   *
   * @return \Drupal\foldershare\FolderShareInterface[]
   *   Returns an unordered associative array where keys are entity IDs
   *   and values are entities for root items.
   *
   * @see ::findAllPublicRootItems()
   * @see ::findAllRootItems()
   * @see ::findAllSharedRootItemIds()
   */
  public static function findAllSharedRootItems(
    int $ownerUid = self::ANY_USER_ID,
    int $viewerUid = self::CURRENT_USER_ID,
    string $name = '',
    bool $includeDisabled = TRUE,
    bool $includeHidden = FALSE) {
 
    $ids = self::findAllSharedRootItemIds(
      $ownerUid,
      $viewerUid,
      $name,
      $includeDisabled,
      $includeHidden);
 
    if (empty($ids) === TRUE) {
      return [];
    }
 
    return self::loadMultiple($ids);
  }
 
  /**
   * Returns a list of shared root IDs that meet user and name requirements.
   *
   * A shared root item is one that is not owned by the current user AND one
   * that grants view access to the current user.
   *
   * An optional user ID may be provided to constrain root items to only
   * those owned by the specified user. If the ID is not given, or it is
   * FolderShareInterface::ANY_USER_ID, root items for any user are returned.
   *
   * An optional viewer ID may be provided to constrain root items to only
   * those viewable by the specified user. If the ID is not given, or it is
   * FolderShareInterface::CURRENT_USER_ID, root items viewable by the current
   * user are returned.
   *
   * An optional name may be provided to constrain root items to only those
   * with the given name. If a name is not given, or it is an empty string,
   * root items with any name are returned.
   *
   * System hidden or disabled root items may or may not be returned, depending
   * upon the parameters.
   *
   * Items marked disabled are in use. They remain visible and are enabled
   * again when they are no longer in use. Typically, disabled items should
   * be included in the returned results, so $includeDisabled defaults to
   * TRUE.
   *
   * Items marked hidden are being deleted. They are not visible and will
   * never be enabled again. Typically, hidden items should not be included
   * in the returned results, so $includeHidden defaults to FALSE.
   *
   * <B>Example usage</B>
   * Find all shared root item IDs for all users, for a specific user, or
   * for a specific user and named "data":
   * @code
   *   $allSharedRootItemIds = FolderShare::findAllSharedRootItemIds();
   *
   *   $user = \Drupal::currentUser();
   *   $allSharedRootItemIdsByUser = FolderShare::findAllSharedRootItemIds($user->id());
   *
   *   $allSharedRootItemIdsByUserNamedData = FolderShare::findAllSharedRootItemIds($user->id(), "data");
   * @endcode
   *
   * @param int $ownerUid
   *   (optional, default = FolderShareInterface::ANY_USR_ID) The user ID
   *   for the root items owner.
   * @param int $viewerUid
   *   (optional, default = FolderShareInterface::CURRENT_USER_ID) The user ID
   *   for the user that must have view permission (defaults to current user).
   * @param string $name
   *   (optional, default = '' = any) The name for the root items.
   * @param bool $includeDisabled
   *   (optional, default = TRUE) When TRUE, disabled root items are included.
   *   When FALSE, they are not.
   * @param bool $includeHidden
   *   (optional, default = FALSE) When TRUE, hidden root items are included.
   *   When FALSE, they are not.
   *
   * @return int[]
   *   Returns an unordered array of entity IDs.
   *
   * @see ::findAllPublicRootItemIds()
   * @see ::findAllRootItemIds()
   */
  public static function findAllSharedRootItemIds(
    int $ownerUid = self::ANY_USER_ID,
    int $viewerUid = self::CURRENT_USER_ID,
    string $name = '',
    bool $includeDisabled = TRUE,
    bool $includeHidden = FALSE) {
 
    // Root items have no parent ID or root ID.
    $connection = Database::getConnection();
    $select = $connection->select(self::BASE_TABLE, 'fs');
    $select->addField('fs', 'id', 'id');
    $select->isNull('fs.parentid');
 
    if ($includeDisabled === FALSE) {
      // An empty field is also FALSE, so we have to test for !TRUE.
      $select->condition('systemdisabled', TRUE, '<>');
    }
 
    if ($includeHidden === FALSE) {
      // An empty field is also FALSE, so we have to test for !TRUE.
      $select->condition('systemhidden', TRUE, '<>');
    }
 
    // If a required owner ID is given, add a condition.
    if ($ownerUid >= 0) {
      $select->condition('uid', $ownerUid, '=');
    }
 
    // If a required item name is given, add a condition.
    if (empty($name) === FALSE) {
      $select->condition('name', $name, '=');
    }
 
    // If a required viewer ID is given, add a join and condition.
    if ($viewerUid >= 0) {
      if ($ownerUid < 0) {
        $select->condition('uid', $viewerUid, '<>');
      }
 
      $select->join(
        'foldershare__grantviewuids',
        'view',
        '(view.entity_id = fs.id)');
      $select->condition('view.grantviewuids_target_id', $viewerUid, '=');
    }
 
    return $select->execute()->fetchCol(0);
  }
 
  /*---------------------------------------------------------------------
   *
   * All items.
   *
   *---------------------------------------------------------------------*/
 
  /**
   * Returns a list of item IDs that meet user requirements.
   *
   * An optional user ID may be provided to constrain items to only
   * those owned by the specified user. If the ID is not given, or it is
   * FolderShareInterface::ANY_USER_ID, items for any user are returned.
   *
   * System hidden and disabled items may be included in the list.
   *
   * <B>Example usage</B>
   * Find all item IDs for all users, or all item IDs owned by a specific user:
   * @code
   *   $allItemIds = FolderShare::findAllIds();
   *
   *   $user = \Drupal::currentUser();
   *   $allItemIdsForUser = FolderShare::findAllIds($user->id());
   * @endcode
   *
   * @param int $ownerUid
   *   (optional, default = FolderShareInterface::ANY_USER_ID) The user ID
   *   for the items' owner.
   *
   * @return int[]
   *   An unordered list of integer entity IDs for items.
   *
   * @see ::findAllFoldersAndUserIds()
   * @see ::findAllRootItemIds()
   * @see ::countNumberOfFolders()
   */
  public static function findAllIds(int $ownerUid = self::ANY_USER_ID) {
 
    $query = \Drupal::entityQuery(self::BASE_TABLE);
    if ($ownerUid >= 0) {
      $query->condition('uid', $ownerUid, '=');
    }
 
    return $query->execute();
  }
 
  /*---------------------------------------------------------------------
   *
   * Count queries.
   *
   *---------------------------------------------------------------------*/
 
  /**
   * Returns the total number of bytes used by all files or images.
   *
   * When an optional user ID is provided, the returned total only includes
   * items owned by that user. When the user ID is not provided or is
   * FolderShareInterface::ANY_USER_ID, the returned total is for all users.
   *
   * The returned total only includes space used by stored files or images.
   * Folders and media items are not included. The storage space used for
   * database entries for files and images is not included.
   *
   * System hidden and disabled items may be included in the count.
   *
   * <B>Example usage</B>
   * Get the total amount of non-volatile (e.g. disk) storage space in use
   * for files (but not counting the database itself):
   * @code
   *   $bytes = FolderShare::countNumberOfBytes();
   * @endcode
   *
   * @param int $ownerUid
   *   (optional, default = FolderShareInterface::ANY_USER_ID) The user ID
   *   for the user for whome the count is returned. A value of
   *   FolderShareInterface::ANY_USER_ID returns a total for all users.
   *
   * @return int
   *   Returns the total number of bytes used for files and images.
   *
   * @see ::countNumberOfFiles()
   * @see ::countNumberOfFolders()
   * @see ::hasFiles()
   * @see ::hasFolders()
   */
  public static function countNumberOfBytes(
    int $ownerUid = self::ANY_USER_ID) {
 
    $connection = Database::getConnection();
    $select = $connection->select(self::BASE_TABLE, 'fs');
    $group = $select->orConditionGroup()
      ->condition('kind', self::FILE_KIND, '=')
      ->condition('kind', self::IMAGE_KIND, '=')
      ->condition('kind', self::MEDIA_KIND, '=');
    $select->condition($group);
    $select->addExpression('SUM(size)');
 
    if ($ownerUid >= 0) {
      $select->condition('uid', $ownerUid, '=');
    }
 
    return (int) $select->execute()->fetchField();
  }
 
  /**
   * Counts the total number of items.
   *
   * The returned value counts all FolderShare entities of any kind,
   * including folders, files, images, and media.
   *
   * System hidden and disabled items may be included in the count.
   *
   * <B>Example usage</B>
   * Get the total number of items of any kind:
   * @code
   *   $count = FolderShare::countNumberOfItems();
   * @endcode
   *
   * @param int $ownerUid
   *   (optional, default = FolderShareInterface::ANY_USER_ID) The user ID
   *   for the user for whome the count is returned. A value of
   *   FolderShareInterface::ANY_USER_ID returns a total for all users.
   *
   * @return int
   *   Returns the total number of items.
   *
   * @see ::findAllIds()
   * @see ::countNumberOfBytes()
   * @see ::countNumberOfFiles()
   * @see ::countNumberOfFolders()
   * @see ::hasFiles()
   * @see ::hasFolders()
   */
  public static function countNumberOfItems(
    int $ownerUid = self::ANY_USER_ID) {
 
    $connection = Database::getConnection();
    $select = $connection->select(self::BASE_TABLE, 'fs');
 
    if ($ownerUid >= 0) {
      $select->condition('uid', $ownerUid, '=');
    }
 
    return (int) $select->countQuery()->execute()->fetchField();
  }
 
  /**
   * Counts the total number of file, image, and media items.
   *
   * When an optional user ID is given, the returned total only includes
   * items owned by that user. When the user ID is not provided or is
   * FolderShareInterface::ANY_USER_ID, the returned total is for all users.
   *
   * The returned total counts all FolderShare file, image, and media kinds.
   * Folders are not included.
   *
   * System hidden and disabled items may be included in the count.
   *
   * <B>Example usage</B>
   * Get the total number of file, image, or media items;
   * @code
   *   $count = FolderShare::countNumberOfFiles();
   * @endcode
   *
   * @param int $ownerUid
   *   (optional, default = FolderShareInterface::ANY_USER_ID) The user ID
   *   for the user for whome the count is returned. A value of
   *   FolderShareInterface::ANY_USER_ID returns a total for all users.
   *
   * @return int
   *   Returns the total number of file, image, and media items.
   *
   * @see ::findAllIds()
   * @see ::countNumberOfBytes()
   * @see ::countNumberOfFolders()
   * @see ::hasFiles()
   * @see ::hasFolders()
   */
  public static function countNumberOfFiles(
    int $ownerUid = self::ANY_USER_ID) {
 
    $connection = Database::getConnection();
    $select = $connection->select(self::BASE_TABLE, 'fs');
 
    $group = $select->orConditionGroup()
      ->condition('kind', self::FILE_KIND, '=')
      ->condition('kind', self::IMAGE_KIND, '=')
      ->condition('kind', self::MEDIA_KIND, '=');
 
    $select = $select->condition($group);
 
    if ($ownerUid >= 0) {
      $select->condition('uid', $ownerUid, '=');
    }
 
    return (int) $select->countQuery()->execute()->fetchField();
  }
 
  /**
   * Counts the total number of folders managed by the module.
   *
   * When an optional user ID is given, the returned total only includes
   * items owned by that user. When the user ID is not provided or is
   * FolderShareInterface::ANY_USER_ID, the returned total is for all users.
   *
   * The returned total counts all FolderShare folders. Files, images,
   * and media items are not included.
   *
   * System hidden and disabled items may be included in the count.
   *
   * <B>Example usage</B>
   * Get the total number of folders:
   * @code
   *   $count = FolderShare::countNumberOfFolders();
   * @endcode
   *
   * @param int $ownerUid
   *   (optional, default = FolderShareInterface::ANY_USER_ID) The user ID
   *   for the user for whome the count is returned. A value of
   *   FolderShareInterface::ANY_USER_ID returns a total for all users.
   *
   * @return int
   *   Returns the total number of folders.
   *
   * @see ::findAllIds()
   * @see ::countNumberOfBytes()
   * @see ::countNumberOfFiles()
   * @see ::hasFiles()
   * @see ::hasFolders()
   */
  public static function countNumberOfFolders(
    int $ownerUid = self::ANY_USER_ID) {
 
    $connection = Database::getConnection();
    $select = $connection->select(self::BASE_TABLE, 'fs')
      ->condition('kind', self::FOLDER_KIND, '=');
 
    if ($ownerUid >= 0) {
      $select->condition('uid', $ownerUid, '=');
    }
 
    return (int) $select->countQuery()->execute()->fetchField();
  }
 
  /**
   * Returns TRUE if there are any files, images, or media.
   *
   * System hidden and disabled items may be included.
   *
   * @return bool
   *   Returns TRUE if there are any files, and FALSE otherwise.
   *
   * @see ::countNumberOfBytes()
   * @see ::countNumberOfFiles()
   * @see ::countNumberOfFolders()
   * @see ::hasFolders()
   */
  public static function hasFiles() {
    return (self::countNumberOfFiles() !== 0);
  }
 
  /**
   * Returns TRUE if there are any folders.
   *
   * System hidden and disabled items may be included.
   *
   * @return bool
   *   Returns TRUE if there are any folders, and FALSE otherwise.
   *
   * @see ::countNumberOfBytes()
   * @see ::countNumberOfFiles()
   * @see ::countNumberOfFolders()
   * @see ::hasFiles()
   */
  public static function hasFolders() {
    return (self::countNumberOfFolders() !== 0);
  }
 
  /*---------------------------------------------------------------------
   *
   * Find FolderShare entity by wrapped file or media.
   *
   *---------------------------------------------------------------------*/
 
  /**
   * Finds the FolderShare entity ID wrapping the given File entity.
   *
   * The database is queried to find a file or image FolderShare entity
   * that uses an entity reference to the given file. The ID of the entity
   * is returned, or (1) if no entity is found.
   *
   * A system hidden or disabled item may be returned.
   *
   * @param \Drupal\file\FileInterface $file
   *   The File entity used to search for a FolderShare entity that wraps it.
   *
   * @return bool|int
   *   Returns the FolderShare entity ID of the file or image item that
   *   wraps the given File entity, or a FALSE if not found. If $file is NULL,
   *   a FALSE is returned.
   */
  public static function findFileWrapperId(FileInterface $file) {
    if ($file === NULL) {
      return FALSE;
    }
 
    // Search the database for use of the file's ID in the target ID
    // of the 'file' or 'image' fields.
    $id = $file->id();
 
    $connection = Database::getConnection();
    $query = $connection->select(self::BASE_TABLE, 'fs');
    $query->addField('fs', 'id', 'id');
    $group = $query->orConditionGroup()
      ->condition('file__target_id', $id, '=')
      ->condition('image__target_id', $id, '=');
    $query = $query->condition($group);
    $results = $query->execute()
      ->fetchAll();
 
    if (empty($results) === TRUE) {
      return FALSE;
    }
 
    // There should be at most one entry.
    return (int) $results[0]->id;
  }
 
  /**
   * Finds the FolderShare entity ID wrapping the given Media entity.
   *
   * The database is queried to find a media FolderShare entity that uses an
   * entity reference to the given media entity. The ID of the entity
   * is returned, or (1) if no entity is found.
   *
   * A system hidden or disabled item may be returned.
   *
   * @param \Drupal\media\MediaInterface $media
   *   The Media entity used to search for a FolderShare entity that wraps it.
   *
   * @return int
   *   Returns the FolderShare entity ID of the media item that
   *   wraps the given File entity, or a FALSE if not found. If $media is NULL,
   *   a FALSE is returned.
   */
  public static function findMediaWrapperId(MediaInterface $media) {
    if ($media === NULL) {
      return FALSE;
    }
 
    // Search the database for use of the media's ID in the target ID
    // of the 'media' field.
    $connection = Database::getConnection();
    $query = $connection->select(self::BASE_TABLE, 'fs');
    $query->addField('fs', 'id', 'id');
    $query->condition('media__target_id', $media->id(), '=');
    $results = $query->execute()
      ->fetchAll();
 
    if (empty($results) === TRUE) {
      return FALSE;
    }
 
    // There should be at most one entry.
    return (int) $results[0]->id;
  }
 
  /*---------------------------------------------------------------------
   *
   * Find FolderShare entity by name.
   *
   *---------------------------------------------------------------------*/
 
  /**
   * Finds the ID for a named child within a parent folder.
   *
   * The $parentId argument selects the parent folder to search. If the
   * ID is not valid, the search will not find a match and FALSE is returned.
   *
   * A $name argument indicates the name to child name to search for. If the
   * name is empty, the search will not find a match and FALSE is returned.
   *
   * Since each child of a folder must have a unique name within the folder,
   * this search through a folder's children can return at most one matching
   * child. That single entity ID is returned, or FALSE if no matching
   * child was found.
   *
   * A system hidden or disabled item may be returned.
   *
   * @param int $parentId
   *   The parent folder ID.
   * @param string $name
   *   The name of an item to find.
   *
   * @return bool|int
   *   Returns the entity ID if the item with the given name and parent
   *   folder, or a FALSE if not found.
   */
  public static function findNamedChildId(int $parentId, string $name) {
    if ($parentId < 0 || empty($name) === TRUE) {
      return FALSE;
    }
 
    $connection = Database::getConnection();
    $select = $connection->select(self::BASE_TABLE, 'fs');
    $select->addField('fs', 'id', 'id');
    $select->condition('parentid', $parentId, '=');
    $select->condition('name', $name, '=');
    $ids = $select->execute()->fetchCol(0);
 
    if (empty($ids) === TRUE) {
      return FALSE;
    }
 
    // There should be at most one entry.
    return (int) $ids[0];
  }
 
  /*---------------------------------------------------------------------
   *
   * Find children.
   *
   *---------------------------------------------------------------------*/
 
  /**
   * {@inheritdoc}
   */
  public function findChildrenIds(
    bool $includeDisabled = TRUE,
    bool $includeHidden = FALSE) {
 
    if ($this->isFolder() === FALSE) {
      return [];
    }
 
    $connection = Database::getConnection();
    $select = $connection->select(self::BASE_TABLE, 'fs');
    $select->addField('fs', 'id', 'id');
    $select->condition('parentid', $this->id(), '=');
 
    if ($includeDisabled === FALSE) {
      // An empty field is also FALSE, so we have to test for !TRUE.
      $select->condition('systemdisabled', TRUE, '<>');
    }
 
    if ($includeHidden === FALSE) {
      // An empty field is also FALSE, so we have to test for !TRUE.
      $select->condition('systemhidden', TRUE, '<>');
    }
 
    return $select->execute()->fetchCol(0);
  }
 
  /**
   * {@inheritdoc}
   */
  public function findChildrenNames(
    bool $includeDisabled = TRUE,
    bool $includeHidden = FALSE) {
 
    if ($this->isFolder() === FALSE) {
      return [];
    }
 
    $connection = Database::getConnection();
    $select = $connection->select(self::BASE_TABLE, 'fs');
    $select->addField('fs', 'id', 'id');
    $select->addField('fs', 'name', 'name');
    $select->condition('parentid', $this->id(), '=');
 
    if ($includeDisabled === FALSE) {
      // An empty field is also FALSE, so we have to test for !TRUE.
      $select->condition('systemdisabled', TRUE, '<>');
    }
 
    if ($includeHidden === FALSE) {
      // An empty field is also FALSE, so we have to test for !TRUE.
      $select->condition('systemhidden', TRUE, '<>');
    }
 
    // Process names into an array where keys are names and values are IDs.
    $names = [];
    foreach ($select->execute() as $result) {
      $names[$result->name] = (int) $result->id;
    }
 
    return $names;
  }
 
  /**
   * {@inheritdoc}
   */
  public function findChildren(
    bool $includeDisabled = TRUE,
    bool $includeHidden = FALSE) {
 
    if ($this->isFolder() === FALSE) {
      return [];
    }
 
    return self::loadMultiple($this->findChildrenIds(
      $includeDisabled,
      $includeHidden));
  }
 
  /**
   * {@inheritdoc}
   */
  public function findChildrenNumberOfBytes() {
 
    $connection = Database::getConnection();
    $select = $connection->select(self::BASE_TABLE, 'fs');
    $select->condition('fs.parentid', $this->id(), '=');
 
    // An empty field is also FALSE, so we have to test for !TRUE.
    $select->condition('fs.systemhidden', TRUE, '<>');
 
    $select->addExpression('SUM(fs.size)', 'size');
 
    return (int) $select->execute()->fetchField();
  }
 
  /**
   * {@inheritdoc}
   */
  public function findNumberOfChildren(
    bool $includeDisabled = TRUE,
    bool $includeHidden = FALSE) {
 
    if ($this->isFolder() === FALSE) {
      return 0;
    }
 
    $connection = Database::getConnection();
    $select = $connection->select(self::BASE_TABLE, 'fs');
    $select->addField('fs', 'id', 'id');
    $select->condition('parentid', $this->id(), '=');
 
    if ($includeDisabled === FALSE) {
      // An empty field is also FALSE, so we have to test for !TRUE.
      $select->condition('systemdisabled', TRUE, '<>');
    }
 
    if ($includeHidden === FALSE) {
      // An empty field is also FALSE, so we have to test for !TRUE.
      $select->condition('systemhidden', TRUE, '<>');
    }
 
    return (int) $select->countQuery()->execute()->fetchField();
  }
 
  /*---------------------------------------------------------------------
   *
   * Find children that are files.
   *
   *---------------------------------------------------------------------*/
 
  /**
   * {@inheritdoc}
   */
  public function findFileChildrenIds(
    bool $includeDisabled = TRUE,
    bool $includeHidden = FALSE) {
 
    $connection = Database::getConnection();
    $select = $connection->select(self::BASE_TABLE, 'fs');
    $select->addField('fs', 'id', 'id');
    $select->condition('parentid', $this->id(), '=');
 
    if ($includeDisabled === FALSE) {
      // An empty field is also FALSE, so we have to test for !TRUE.
      $select->condition('systemdisabled', TRUE, '<>');
    }
 
    if ($includeHidden === FALSE) {
      // An empty field is also FALSE, so we have to test for !TRUE.
      $select->condition('systemhidden', TRUE, '<>');
    }
 
    $group = $select->orConditionGroup()
      ->condition('kind', self::FILE_KIND, '=')
      ->condition('kind', self::IMAGE_KIND, '=')
      ->condition('kind', self::MEDIA_KIND, '=');
    $select = $select->condition($group);
 
    return $select->execute()->fetchCol(0);
  }
 
  /**
   * {@inheritdoc}
   */
  public function findFileChildren(
    bool $includeDisabled = TRUE,
    bool $includeHidden = FALSE) {
 
    return self::loadMultiple($this->findFileChildrenIds(
      $includeDisabled,
      $includeHidden));
  }
 
  /*---------------------------------------------------------------------
   *
   * Find children that are folders.
   *
   *---------------------------------------------------------------------*/
 
  /**
   * {@inheritdoc}
   */
  public function findFolderChildrenIds(
    bool $includeDisabled = TRUE,
    bool $includeHidden = FALSE) {
 
    // Query all folders that list this folder as a parent.
    $select = \Drupal::entityQuery(self::ENTITY_TYPE_ID)
      ->condition('kind', self::FOLDER_KIND, '=')
      ->condition('parentid', $this->id(), '=');
 
    if ($includeDisabled === FALSE) {
      // An empty field is also FALSE, so we have to test for !TRUE.
      $select->condition('systemdisabled', TRUE, '<>');
    }
 
    if ($includeHidden === FALSE) {
      // An empty field is also FALSE, so we have to test for !TRUE.
      $select->condition('systemhidden', TRUE, '<>');
    }
 
    return $select->execute();
  }
 
  /**
   * {@inheritdoc}
   */
  public function findFolderChildren(
    bool $includeDisabled = TRUE,
    bool $includeHidden = FALSE) {
 
    return self::loadMultiple($this->findFolderChildrenIds(
      $includeDisabled,
      $includeHidden));
  }
 
  /*---------------------------------------------------------------------
   *
   * Find ancestors.
   *
   *---------------------------------------------------------------------*/
 
  /**
   * {@inheritdoc}
   */
  public function findAncestorFolderIds() {
 
    // If this is a root item, it has no parent and thus no ancestors.
    $parentId = $this->getParentFolderId();
    if ($parentId === self::USER_ROOT_LIST) {
      return [];
    }
 
    $ancestorIds = [$parentId];
    $connection = Database::getConnection();
 
    // Repeatedly query to get each ancestor, saving their IDs.
    while (TRUE) {
      $select = $connection->select(self::BASE_TABLE, 'fs');
      $select->addField('fs', 'parentid', 'parentid');
      $select->condition('id', $parentId, '=');
      $results = $select->execute()->fetchAll();
 
      if (empty($results) === TRUE) {
        break;
      }
 
      $parentId = (int) $results[0]->parentid;
      $ancestorIds[] = $parentId;
    }
 
    // Reverse so that the list is root first.
    return array_reverse($ancestorIds);
  }
 
  /**
   * {@inheritdoc}
   */
  public function findAncestorFolderNames() {
    // If this is a root item, it has no parent and thus no ancestors.
    $parentId = $this->getParentFolderId();
    if ($parentId === self::USER_ROOT_LIST) {
      return [];
    }
 
    $connection = Database::getConnection();
    $ancestorNames = [];
 
    // Repeatedly query to get each ancestor, saving their IDs.
    while ($parentId !== self::USER_ROOT_LIST) {
      $select = $connection->select(self::BASE_TABLE, 'fs');
      $select->addField('fs', 'parentid', 'parentid');
      $select->addField('fs', 'name', 'name');
      $select->condition('id', $parentId, '=');
      $results = $select->execute()->fetchAll();
 
      if (empty($results) === TRUE) {
        break;
      }
 
      $parentId = (int) $results[0]->parentid;
      $ancestorNames[] = $results[0]->name;
    }
 
    // Reverse so that the list is root first.
    return array_reverse($ancestorNames);
  }
 
  /**
   * {@inheritdoc}
   */
  public function findAncestorFolders() {
    return self::loadMultiple($this->findAncestorFolderIds());
  }
 
  /**
   * {@inheritdoc}
   */
  public function isAncestorOfFolderId(int $folderId) {
    if ($folderId < 0) {
      return FALSE;
    }
 
    $folder = self::load($folderId);
    if ($folder === NULL) {
      return FALSE;
    }
 
    // This folder is an ancestor of the given folder if that folder's
    // list of ancestor folder IDs contains this folder's ID.
    return in_array((int) $this->id(), $folder->findAncestorFolderIds());
  }
 
  /*---------------------------------------------------------------------
   *
   * Find descendants.
   *
   *---------------------------------------------------------------------*/
 
  /**
   * {@inheritdoc}
   */
  public function findDescendantIds(
    bool $includeDisabled = TRUE,
    bool $includeHidden = FALSE) {
 
    // If this is not a folder, there are no descendants.
    if ($this->isFolder() === FALSE) {
      return [];
    }
 
    $connection  = Database::getConnection();
    $startingId  = (int) $this->id();
    $pending     = [$startingId];
    $descendants = [];
 
    while (empty($pending) === FALSE) {
      // Get the next pending ID.
      $id = array_shift($pending);
 
      // Add it to the descendant list, if it isn't the starting ID.
      if ($id !== $startingId) {
        $descendants[] = $id;
      }
 
      // Get non-folder children and add them to the descendants list.
      $select = $connection->select(self::BASE_TABLE, 'fs');
      $select->addField('fs', 'id', 'id');
      $select->condition('parentid', $id, '=');
      $select->condition('kind', self::FOLDER_KIND, '<>');
 
      if ($includeDisabled === FALSE) {
        // An empty field is also FALSE, so we have to test for !TRUE.
        $select->condition('systemdisabled', TRUE, '<>');
      }
 
      if ($includeHidden === FALSE) {
        // An empty field is also FALSE, so we have to test for !TRUE.
        $select->condition('systemhidden', TRUE, '<>');
      }
 
      $descendants = array_merge($descendants, $select->execute()->fetchCol(0));
 
      // Get folder children and add them to the pending list.
      $select = $connection->select(self::BASE_TABLE, 'fs');
      $select->addField('fs', 'id', 'id');
      $select->condition('parentid', $id, '=');
      $select->condition('kind', self::FOLDER_KIND, '=');
 
      if ($includeDisabled === FALSE) {
        // An empty field is also FALSE, so we have to test for !TRUE.
        $select->condition('systemdisabled', TRUE, '<>');
      }
 
      if ($includeHidden === FALSE) {
        // An empty field is also FALSE, so we have to test for !TRUE.
        $select->condition('systemhidden', TRUE, '<>');
      }
 
      $pending = array_merge($pending, $select->execute()->fetchCol(0));
    }
 
    return $descendants;
  }
 
  /**
   * {@inheritdoc}
   */
  public function findDescendantIdsByOwnerId(
    int $ownerUid = self::ANY_USER_ID,
    bool $match = TRUE) {
 
    // If this is not a folder, there are no descendants.
    if ($this->isFolder() === FALSE) {
      return [];
    }
 
    $connection  = Database::getConnection();
    $startingId  = (int) $this->id();
    $pending     = [$startingId];
    $descendants = [];
    $matchOp     = ($match === TRUE) ? '=' : '<>';
 
    while (empty($pending) === FALSE) {
      // Get the next pending ID.
      $id = array_shift($pending);
 
      // Get non-folder children that match the owner ID criteria (if any)
      // and add them to the descendants list.
      $select = $connection->select(self::BASE_TABLE, 'fs');
      $select->addField('fs', 'id', 'id');
      $select->condition('parentid', $id, '=');
      $select->condition('kind', self::FOLDER_KIND, '<>');
      if ($ownerUid !== self::ANY_USER_ID) {
        $select->condition('uid', $ownerUid, $matchOp);
      }
 
      $descendants = array_merge($descendants, $select->execute()->fetchCol(0));
 
      // A folder child could have a matching owner ID, while its children
      // do not. First query to get ALL folder children and add them to
      // the pending list. Then query to get only those folder children
      // that match the owner ID criteria (if any) and add them to the
      // descendants list.
      $select = $connection->select(self::BASE_TABLE, 'fs');
      $select->addField('fs', 'id', 'id');
      $select->condition('parentid', $id, '=');
      $select->condition('kind', self::FOLDER_KIND, '=');
 
      $allFolderChildren = $select->execute()->fetchCol(0);
      $pending = array_merge($pending, $allFolderChildren);
 
      if ($ownerUid === self::ANY_USER_ID) {
        // All folder children added to the pending list are also relevant
        // descendants to return.
        $descendants = array_merge($descendants, $allFolderChildren);
      }
      else {
        // Only folder children that match the owner ID criteria should be
        // added to the descendants list.
        $select = $connection->select(self::BASE_TABLE, 'fs');
        $select->addField('fs', 'id', 'id');
        $select->condition('parentid', $id, '=');
        $select->condition('kind', self::FOLDER_KIND, '=');
        $select->condition('uid', $ownerUid, $matchOp);
 
        $matchingFolderChildren = $select->execute()->fetchCol(0);
        $descendants = array_merge($descendants, $matchingFolderChildren);
      }
    }
 
    return $descendants;
  }
 
  /**
   * {@inheritdoc}
   */
  public function findDescendantIdsByRootId(
    int $rootId = self::ANY_ITEM_ID,
    bool $match = TRUE) {
 
    // If this is not a folder, there are no descendants.
    if ($this->isFolder() === FALSE) {
      return [];
    }
 
    $connection  = Database::getConnection();
    $startingId  = (int) $this->id();
    $pending     = [$startingId];
    $descendants = [];
    $matchOp     = ($match === TRUE) ? '=' : '<>';
 
    while (empty($pending) === FALSE) {
      // Get the next pending ID.
      $id = (int) array_shift($pending);
 
      // Get non-folder children that match the root ID criteria (if any)
      // and add them to the descendants list.
      $select = $connection->select(self::BASE_TABLE, 'fs');
      $select->addField('fs', 'id', 'id');
      $select->condition('parentid', $id, '=');
      $select->condition('kind', self::FOLDER_KIND, '<>');
      if ($rootId !== self::ANY_ITEM_ID) {
        $select->condition('rootid', $rootId, $matchOp);
      }
 
      $descendants = array_merge($descendants, $select->execute()->fetchCol(0));
 
      // A folder child could have a matching root ID, while its children
      // do not. First query to get ALL folder children and add them to
      // the pending list. Then query to get only those folder children
      // that match the root ID criteria (if any) and add them to the
      // descendants list.
      $select = $connection->select(self::BASE_TABLE, 'fs');
      $select->addField('fs', 'id', 'id');
      $select->condition('parentid', $id, '=');
      $select->condition('kind', self::FOLDER_KIND, '=');
 
      $allFolderChildren = $select->execute()->fetchCol(0);
      $pending = array_merge($pending, $allFolderChildren);
 
      if ($rootId === self::ANY_ITEM_ID) {
        // All folder children added to the pending list are also relevant
        // descendants to return.
        $descendants = array_merge($descendants, $allFolderChildren);
      }
      else {
        // Only folder children that match the root ID criteria should be
        // added to the descendants list.
        $select = $connection->select(self::BASE_TABLE, 'fs');
        $select->addField('fs', 'id', 'id');
        $select->condition('parentid', $id, '=');
        $select->condition('kind', self::FOLDER_KIND, '=');
        $select->condition('rootid', $rootId, $matchOp);
 
        $matchingFolderChildren = $select->execute()->fetchCol(0);
        $descendants = array_merge($descendants, $matchingFolderChildren);
      }
    }
 
    return $descendants;
  }
 
  /**
   * {@inheritdoc}
   */
  public function isDescendantOfFolderId(int $proposedAncestorId) {
    // There are two ways to implement this:
    //
    // - Get a list of all descendant IDs of the proposed ancestor,
    //   then see if this entity's ID is in that list.
    //
    // - Get a list of all ancestor IDs of this entity, then see if
    //   the proposed ancestor is one of those.
    //
    // The second implementation looks up the folder tree and is much
    // faster than the first implementation, which looks down through
    // the folder tree.
    return in_array($proposedAncestorId, $this->findAncestorFolderIds());
  }
 
  /*---------------------------------------------------------------------
   *
   * Find kinds.
   *
   *---------------------------------------------------------------------*/
 
  /**
   * Finds the kind for each of the given entity IDs.
   *
   * The returned associative array has one key for each FolderShare
   * entity kind present in the ID list. The associated value is an array
   * of integer entity IDs for items of that kind from the ID list.
   * Invalid IDs are silently ignored and will not be included in the
   * returned array.
   *
   * @param int[] $ids
   *   An array of integer FolderShare entity IDs for entities to look up.
   *
   * @return array
   *   Returns an associative array with FolderShare kinds as keys, and
   *   an array of IDs for each kind. If a kind is not present in the
   *   array, then no entity IDs of that kind were found.
   */
  public static function findKindsForIds(array $ids) {
    if (empty($ids) === TRUE) {
      return [];
    }
 
    $connection = Database::getConnection();
    $query = $connection->select(self::BASE_TABLE, 'fs');
    $query->addField('fs', 'id', 'id');
    $query->addField('fs', 'kind', 'kind');
    $query->condition('id', $ids, 'IN');
 
    $ordered = [];
    foreach ($query->execute() as $result) {
      $ordered[$result->kind][] = (int) $result->id;
    }
 
    return $ordered;
  }
 
  /*---------------------------------------------------------------------
   *
   * Find flagged.
   *
   *---------------------------------------------------------------------*/
 
  /**
   * Returns a list of item IDs that are hidden.
   *
   * @return int[]
   *   An unordered list of integer entity IDs for hidden items.
   *
   * @see ::findAllIds()
   */
  public static function findAllHiddenIds() {
 
    $query = \Drupal::entityQuery(self::BASE_TABLE);
    $query->condition('systemhidden', TRUE, '=');
 
    $ids = [];
    foreach ($query->execute() as $result) {
      $ids[] = (int) $result;
    }
 
    return $ids;
  }
 
  /**
   * Returns the number of hidden items.
   *
   * @return int
   *   Returns the number of hidden items.
   *
   * @see ::findAllHiddenIds()
   */
  public static function countNumberOfHiddenItems() {
 
    $connection = Database::getConnection();
    $query = $connection->select(self::BASE_TABLE, 'fs');
    $query->condition('systemhidden', TRUE, '=');
 
    return (int) $query->countQuery()->execute()->fetchField();
  }
 
  /**
   * Returns a list of item IDs that are disabled.
   *
   * @return int[]
   *   An unordered list of integer entity IDs for disabled items.
   *
   * @see ::findAllIds()
   */
  public static function findAllDisabledIds() {
 
    $query = \Drupal::entityQuery(self::BASE_TABLE);
    $query->condition('systemdisabled', TRUE, '=');
 
    $ids = [];
    foreach ($query->execute() as $result) {
      $ids[] = (int) $result;
    }
 
    return $ids;
  }
 
  /**
   * Returns the number of disabled items.
   *
   * @return int
   *   Returns the number of disabled items.
   *
   * @see ::findAllHiddenIds()
   */
  public static function countNumberOfDisabledItems() {
 
    $connection = Database::getConnection();
    $query = $connection->select(self::BASE_TABLE, 'fs');
    $query->condition('systemdisabled', TRUE, '=');
 
    return (int) $query->countQuery()->execute()->fetchField();
  }
 
}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc