foldershare-8.x-1.2/src/Plugin/FolderShareCommand/Rename.php
src/Plugin/FolderShareCommand/Rename.php
<?php
namespace Drupal\foldershare\Plugin\FolderShareCommand;
use Drupal\Core\Form\FormStateInterface;
use Drupal\foldershare\Settings;
use Drupal\foldershare\Entity\FolderShare;
use Drupal\foldershare\Entity\Exception\RuntimeExceptionWithMarkup;
use Drupal\foldershare\Entity\Exception\ValidationException;
/**
* Defines a command plugin to rename a file or folder.
*
* The command sets the name of a single selected entity.
*
* Configuration parameters:
* - 'parentId': the parent folder, if any.
* - 'selectionIds': selected entity to rename.
* - 'name': the new name.
*
* @ingroup foldershare
*
* @FolderShareCommand(
* id = "foldersharecommand_rename",
* label = @Translation("Rename"),
* menuNameDefault = @Translation("Rename..."),
* menuName = @Translation("Rename..."),
* description = @Translation("Rename a selected file or folder."),
* category = "edit",
* weight = 20,
* parentConstraints = {
* "kinds" = {
* "rootlist",
* "any",
* },
* "access" = "view",
* },
* selectionConstraints = {
* "types" = {
* "parent",
* "one",
* },
* "kinds" = {
* "any",
* },
* "access" = "update",
* },
* )
*/
class Rename extends FolderShareCommandBase {
/*--------------------------------------------------------------------
*
* Configuration.
*
*--------------------------------------------------------------------*/
/**
* {@inheritdoc}
*/
public function defaultConfiguration() {
// Include room for the new name in the configuration.
$config = parent::defaultConfiguration();
$config['name'] = '';
return $config;
}
/**
* {@inheritdoc}
*/
public function validateParameters() {
if ($this->parametersValidated === TRUE) {
return;
}
// Get the parent folder, if any.
$parent = $this->getParent();
// Get the selected item. If none, use the parent instead.
$itemIds = $this->getSelectionIds();
if (empty($itemIds) === TRUE) {
$item = $this->getParent();
}
else {
$item = FolderShare::load(reset($itemIds));
}
// Check if the name is legal. This throws an exception if not valid.
$newName = $this->configuration['name'];
$item->checkName($newName);
// Check if the new name is unique within the parent folder or root list.
if ($parent !== NULL) {
if ($parent->isNameUnique($newName, (int) $item->id()) === FALSE) {
throw new ValidationException(
FolderShare::getStandardNameInUseExceptionMessage($newName));
}
}
elseif (FolderShare::isRootNameUnique($newName, (int) $item->id()) === FALSE) {
throw new ValidationException(
FolderShare::getStandardNameInUseExceptionMessage($newName));
}
$this->parametersValidated = TRUE;
}
/*--------------------------------------------------------------------
*
* Configuration form setup.
*
*--------------------------------------------------------------------*/
/**
* {@inheritdoc}
*/
public function hasConfigurationForm() {
return TRUE;
}
/**
* {@inheritdoc}
*/
public function getDescription(bool $forPage) {
$selectionIds = $this->getSelectionIds();
if (empty($selectionIds) === TRUE) {
$item = $this->getParent();
}
else {
$item = FolderShare::load(reset($selectionIds));
}
$isShared = $item->getRootItem()->isAccessShared();
if ($isShared === TRUE) {
return [
'',
t('This item is shared. Changing its name may affect other users.'),
];
}
return [];
}
/**
* {@inheritdoc}
*/
public function getTitle(bool $forPage) {
// The title varies for page vs. dialog:
//
// - Dialog: "Rename".
//
// - Page: "Rename NAME?" or "Rename shared NAME?".
// This follows Drupal convention.
if ($forPage === FALSE) {
return t('Rename');
}
$selectionIds = $this->getSelectionIds();
if (empty($selectionIds) === TRUE) {
$item = $this->getParent();
}
else {
$item = FolderShare::load(reset($selectionIds));
}
$isShared = $item->getRootItem()->isAccessShared();
if ($isShared === TRUE) {
return t(
'Rename shared "@name"?',
[
'@name' => $item->getName(),
]);
}
return t(
'Rename shared "@name"?',
[
'@name' => $item->getName(),
]);
}
/**
* {@inheritdoc}
*/
public function getSubmitButtonName() {
return t('Rename');
}
/*--------------------------------------------------------------------
*
* Configuration form.
*
*--------------------------------------------------------------------*/
/**
* {@inheritdoc}
*/
public function buildConfigurationForm(
array $form,
FormStateInterface $formState) {
// Get the current item name to use as the form default value.
$itemIds = $this->getSelectionIds();
if (empty($itemIds) === TRUE) {
$item = $this->getParent();
}
else {
$item = FolderShare::load(reset($itemIds));
}
$this->configuration['name'] = $item->getName();
// 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).
//
// Add a text field prompt for the new name.
$form['rename'] = [
'#type' => 'textfield',
'#name' => 'rename',
'#weight' => 10,
'#title' => t('New name:'),
'#size' => 30,
'#maxlength' => 255,
'#required' => TRUE,
'#default_value' => $this->configuration['name'],
'#attributes' => [
'autofocus' => 'autofocus',
'spellcheck' => 'false',
],
];
$form['rename-description'] = [
'#type' => 'html_tag',
'#name' => 'rename-description',
'#weight' => 20,
'#tag' => 'p',
'#value' => t(
'Enter a new name. Use any mix of characters except ":", "/", "\\".'),
'#attributes' => [
'class' => [
'rename-description',
],
],
];
$form['status'] = [
'#type' => 'status_messages',
'#weight' => 30,
];
return $form;
}
/**
* {@inheritdoc}
*/
public function validateConfigurationForm(
array &$form,
FormStateInterface $formState) {
// Get the entered text for the item.
$name = $formState->getValue('rename');
// Validate the name alone, without considering file name extensions
// or uniqueness.
if (FolderShare::isNameLegal($name) === FALSE) {
// Since the field is required, Drupal adds a default error message
// when the field is left empty. Get rid of that so we can provide a
// more helpful message.
$formState->clearErrors();
$formState->setErrorByName(
'rename',
strip_tags(
(string) FolderShare::getStandardIllegalNameExceptionMessage($name)));
$formState->setRebuild();
return;
}
// Update the configuration.
$this->configuration['name'] = $formState->getValue('rename');
// Do a full validation.
try {
$this->validateParameters();
}
catch (RuntimeExceptionWithMarkup $e) {
// Unfortunately, setErrorByName() will not accept complex markup,
// such as for multi-line error messages. If we pass the markup,
// the function strips it down to the last line of text. To avoid
// this, we have to pass the message text instead.
$formState->setErrorByName('rename', $e->getMessage());
$formState->setRebuild();
}
catch (\Exception $e) {
$formState->setErrorByName('rename', $e->getMessage());
$formState->setRebuild();
}
}
/**
* {@inheritdoc}
*/
public function submitConfigurationForm(
array &$form,
FormStateInterface $formState) {
if ($this->isValidated() === TRUE) {
$this->execute();
}
}
/*---------------------------------------------------------------------
*
* Execution behavior.
*
*---------------------------------------------------------------------*/
/**
* {@inheritdoc}
*/
public function getExecuteBehavior() {
if (empty($this->getSelectionIds()) === TRUE) {
// When there is no selection, execution falls back to operating
// on the current parent. After a change, the breadcrumbs or
// other page decoration may differ. We need to refresh the page.
return FolderShareCommandInterface::POST_EXECUTE_PAGE_REFRESH;
}
// When there is a selection, execution changes that selection on the
// current page. While columns may change, the page doesn't, so we
// only need to refresh the view.
return FolderShareCommandInterface::POST_EXECUTE_VIEW_REFRESH;
}
/*--------------------------------------------------------------------
*
* Execute.
*
*--------------------------------------------------------------------*/
/**
* {@inheritdoc}
*/
public function execute() {
$itemIds = $this->getSelectionIds();
if (empty($itemIds) === TRUE) {
$item = $this->getParent();
}
else {
$item = FolderShare::load(reset($itemIds));
}
try {
$this->validateParameters();
$item->rename($this->configuration['name']);
}
catch (RuntimeExceptionWithMarkup $e) {
\Drupal::messenger()->addMessage($e->getMarkup(), 'error', TRUE);
}
catch (\Exception $e) {
\Drupal::messenger()->addMessage($e->getMessage(), 'error');
}
if (Settings::getCommandNormalCompletionReportEnable() === TRUE) {
\Drupal::messenger()->addMessage(
t(
"The @kind has been renamed.",
[
'@kind' => FolderShare::translateKind($item->getKind()),
]),
'status');
}
}
}
