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(); } } |