foldershare-8.x-1.2/src/Plugin/FolderShareCommand/DeleteBase.php
src/Plugin/FolderShareCommand/DeleteBase.php
<?php namespace Drupal\foldershare\Plugin\FolderShareCommand; use Drupal\Core\Form\FormStateInterface; use Drupal\foldershare\Settings; use Drupal\foldershare\Entity\FolderShare; /** * Provides the base class for command plugins that delete files or folders. * * The command deletes all selected entities. Deletion recurses and * deletes all folder content as well. * * Configuration parameters: * - 'parentId': the parent folder, if any. * - 'selectionIds': selected entities to delete. * * @ingroup foldershare */ class DeleteBase extends FolderShareCommandBase { /*-------------------------------------------------------------------- * * Configuration form. * *--------------------------------------------------------------------*/ /** * {@inheritdoc} */ public function hasConfigurationForm() { return TRUE; } /** * {@inheritdoc} */ public function getDescription(bool $forPage ) { if ( $forPage === TRUE) { return $this ->getDescriptionForPage(); } return $this ->getDescriptionForDialog(); } /** * Returns a description for the page. * * @return \Drupal\Core\StringTranslation\TranslatableMarkup * Returns the description for the form. Return an empty string for * no description. */ private function getDescriptionForPage() { $selectionIds = $this ->getSelectionIds(); // // Handle single-item case. // ------------------------ // Be specific on the kind of item being deleted. if ( count ( $selectionIds ) === 1) { $item = FolderShare::load(reset( $selectionIds )); $isShared = $item ->getRootItem()->isAccessShared(); $kind = $item ->getKind(); unset( $item ); if ( $isShared === TRUE) { return t( 'Delete this shared @operand? This will affect all users sharing it. This cannot be undone.' , [ '@operand' => FolderShare::translateKind( $kind ), ]); } return t( 'Delete this @operand? This cannot be undone.' , [ '@operand' => FolderShare::translateKind( $kind ), ]); } // // Handle multiple item case. // -------------------------- // With multiple items to delete, use plural wording. Try to be specific // on the kind of items being deleted, if they are all of the same kind. $selectionKinds = FolderShare::findKindsForIds( $selectionIds ); if ( count ( $selectionKinds ) === 1) { $operand = FolderShare::translateKinds(key( $selectionKinds )); } else { $operand = FolderShare::translateKinds( 'items' ); } // If there is no parent, then the selection are all root items. // Load them all and check if any of them are shared. // // If there is a parent, then just check that parent to get the root // and see if it is shared. Don't load the selection. $parent = $this ->getParent(); if ( $parent === NULL) { $isShared = FALSE; foreach ( $selectionIds as $id ) { $item = FolderShare::load( $id ); if ( $item === NULL) { // The item does not exist. continue ; } if ( $item ->isAccessShared() === TRUE) { $isShared = TRUE; unset( $item ); break ; } unset( $item ); } } else { $root = $parent ->getRootItem(); $isShared = $root ->isAccessShared(); unset( $root ); } // Garbage collect. gc_collect_cycles(); if ( $isShared === TRUE) { return t( 'Delete these shared @operand? This will affect all users sharing them. This cannot be undone.' , [ '@operand' => $operand , ]); } return t( 'Delete these @operand? This cannot be undone.' , [ '@operand' => $operand , ]); } /** * Returns a description for the dialog. * * @return \Drupal\Core\StringTranslation\TranslatableMarkup[] * Returns an array containing the primary and secondary description for * the form. The primary description is often brief and in bold, while the * secondary description provides more explanation and is not bold. * The returned array may be empty if there is no description, or it may * contain only a single message if there is only a primary description. */ private function getDescriptionForDialog() { $selectionIds = $this ->getSelectionIds(); // // Handle single item. // ------------------- // With one item, include the item's name. $nItems = count ( $selectionIds ); if ( $nItems === 1) { $item = FolderShare::load(reset( $selectionIds )); $isShared = $item ->getRootItem()->isAccessShared(); $kind = $item ->getKind(); $name = $item ->getName(); unset( $item ); if ( $isShared === TRUE) { return [ t( 'Delete shared @operand "@name"?' , [ '@operand' => FolderShare::translateKind( $kind ), '@name' => $name , ]), t( 'This item is shared. Deleting it may affect other users. This cannot be undone.' ), ]; } return [ t( 'Delete @operand "@name"?' , [ '@operand' => FolderShare::translateKind( $kind ), '@name' => $name , ]), t( 'This cannot be undone.' ), ]; } // // Handle multiple items. // ---------------------- // With multiple items, include the items' kind. $selectionKinds = FolderShare::findKindsForIds( $selectionIds ); if ( count ( $selectionKinds ) === 1) { $operand = FolderShare::translateKinds(key( $selectionKinds )); } else { $operand = FolderShare::translateKinds( 'items' ); } // If there is no parent, then the selection are all root items. // Load them all and check if any of them are shared. // // If there is a parent, then just check that parent to get the root // and see if it is shared. Don't load the selection. $someShared = FALSE; $allShared = FALSE; $parent = $this ->getParent(); if ( $parent === NULL) { $nShared = 0; foreach ( $selectionIds as $id ) { $item = FolderShare::load( $id ); if ( $item === NULL) { // The item does not exist. continue ; } if ( $item ->isAccessShared() === TRUE) { $nShared ++; } unset( $item ); } if ( $nShared !== 0) { if ( count ( $selectionIds ) === $nShared ) { $allShared = TRUE; } else { $someShared = TRUE; } } } else { $root = $parent ->getRootItem(); $allShared = $root ->isAccessShared(); unset( $root ); } // Garbage collect. gc_collect_cycles(); if ( $allShared === TRUE) { return [ t( 'Delete @count shared @operand?' , [ '@count' => $nItems , '@operand' => $operand , ]), t( 'These @operand are shared. Deleting them may affect other users. This cannot be undone.' , [ '@operand' => $operand , ]), ]; } if ( $someShared === TRUE) { return [ t( 'Delete @count @operand?' , [ '@count' => $nItems , '@operand' => $operand , ]), t( 'Some of these @operand are shared. Deleting them may affect other users. This cannot be undone.' , [ '@operand' => $operand , ]), ]; } return [ t( 'Delete @count @operand?' , [ '@count' => $nItems , '@operand' => $operand , ]), t( 'This cannot be undone.' ), ]; } /** * {@inheritdoc} */ public function getTitle(bool $forPage ) { // The title varies for page vs. dialog: // // - Dialog: "Delete". // // - Page: "Delete NAME?", "Delete shared NAME"", "Delete COUNT OPERANDS?", // or "Delete COUNT shared OPERANDS?". This follows Drupal convention. if ( $forPage === FALSE) { return t( 'Delete' ); } $selectionIds = $this ->getSelectionIds(); // // Handle single item. // ------------------- // Load the item and determine if it is shared. if ( count ( $selectionIds ) === 1) { $item = FolderShare::load( $selectionIds [0]); $isShared = $item ->getRootItem()->isAccessShared(); $name = $item ->getName(); unset( $name ); if ( $isShared === TRUE) { return t( 'Delete shared "@name"?' , [ '@name' => $name , ]); } else { return t( 'Delete "@name"?' , [ '@name' => $name , ]); } } // // Handle multiple items. // ---------------------- // When there are multiple items, determine if they are of uniform // kind or mixed. $selectionKinds = FolderShare::findKindsForIds( $selectionIds ); if ( count ( $selectionKinds ) === 1) { $operand = FolderShare::translateKinds(key( $selectionKinds )); } else { $operand = FolderShare::translateKinds( 'items' ); } // If there is no parent, then the selection are all root items. // Load them all and check if any of them are shared. // // If there is a parent, then just check that parent to get the root // and see if it is shared. Don't load the selection. $allShared = FALSE; if ( $this ->parent === NULL) { $nShared = 0; foreach ( $selectionIds as $id ) { $item = FolderShare::load( $id ); if ( $item === NULL) { // The item does not exist. continue ; } if ( $item ->isAccessShared() === TRUE) { $nShared ++; } unset( $item ); } if ( $nShared !== 0) { if ( count ( $selectionIds ) === $nShared ) { $allShared = TRUE; } } } else { $root = $this ->parent->getRootItem(); $allShared = $root ->isAccessShared(); unset( $root ); } // Garbage collect. gc_collect_cycles(); // Include the count and operand kind. if ( $allShared === TRUE) { return t( "Delete @count shared @operand?" , [ '@count' => count ( $selectionIds ), '@operand' => $operand , ]); } return t( "Delete @count @operand?" , [ '@count' => count ( $selectionIds ), '@operand' => $operand , ]); } /** * {@inheritdoc} */ public function getSubmitButtonName() { return t( 'Delete' ); } /** * {@inheritdoc} */ public function buildConfigurationForm( array $form , FormStateInterface $formState ) { // The command wrapper provides form basics: // - Attached libraries. // - Page title (if not an AJAX dialog). // - Description (from ::getDescription()). // - Submit buttion (labeled with ::getSubmitButtonName()). // - Cancel button (if AJAX dialog). $form [ '#attributes' ][ 'class' ][] = 'confirmation' ; $form [ '#theme' ] = 'confirm_form' ; return $form ; } /** * {@inheritdoc} */ public function validateConfigurationForm( array & $form , FormStateInterface $formState ) { // Nothing to do. } /** * {@inheritdoc} */ public function submitConfigurationForm( array & $form , FormStateInterface $formState ) { $this ->execute(); } /*-------------------------------------------------------------------- * * Execute. * *--------------------------------------------------------------------*/ /** * {@inheritdoc} */ public function execute() { $ids = $this ->getSelectionIds(); try { FolderShare::deleteMultiple( $ids ); } catch (\Exception $e ) { \Drupal::messenger()->addMessage( $e ->getMessage(), 'error' ); } if (Settings::getCommandNormalCompletionReportEnable() === TRUE) { \Drupal::messenger()->addMessage( \Drupal::translation()->formatPlural( count ( $ids ), "The item has been deleted." , "@count items have been deleted." ), 'status' ); } } } |