New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add field:delete command #4926
Merged
Merged
Add field:delete command #4926
Changes from all commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
2e43e51
Add field:delete command
DieterHolvoet 12e7564
Add validation for the field-name option
DieterHolvoet 09f0ffc
Validate whether field-name option is a valid field
DieterHolvoet 6bf370c
Merge branch '11.x' into field-delete
weitzman ec31865
Add tests.
weitzman 420af5e
Make entity type argument optional
DieterHolvoet 2baa05f
Update tests and fix PHPCS
weitzman File filter
Filter by extension
Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,160 @@ | ||
<?php | ||
|
||
namespace Drush\Drupal\Commands\core; | ||
|
||
use Drupal\Core\Entity\EntityTypeBundleInfo; | ||
use Drupal\Core\Entity\EntityTypeManagerInterface; | ||
use Drupal\field\Entity\FieldConfig; | ||
use Drupal\field\FieldConfigInterface; | ||
use Drush\Commands\DrushCommands; | ||
use Symfony\Component\Console\Input\InputOption; | ||
|
||
class FieldDeleteCommands extends DrushCommands | ||
{ | ||
use EntityTypeBundleAskTrait; | ||
use EntityTypeBundleValidationTrait; | ||
|
||
/** @var EntityTypeManagerInterface */ | ||
protected $entityTypeManager; | ||
/** @var EntityTypeBundleInfo */ | ||
protected $entityTypeBundleInfo; | ||
|
||
public function __construct( | ||
EntityTypeManagerInterface $entityTypeManager, | ||
EntityTypeBundleInfo $entityTypeBundleInfo | ||
) { | ||
$this->entityTypeManager = $entityTypeManager; | ||
$this->entityTypeBundleInfo = $entityTypeBundleInfo; | ||
} | ||
|
||
/** | ||
* Delete a field | ||
* | ||
* @command field:delete | ||
* @aliases field-delete,fd | ||
* | ||
* @param string $entityType | ||
* The machine name of the entity type | ||
* @param string $bundle | ||
* The machine name of the bundle | ||
* | ||
* @option field-name | ||
* The machine name of the field | ||
* | ||
* @option show-machine-names | ||
* Show machine names instead of labels in option lists. | ||
* | ||
* @usage drush field:delete | ||
DieterHolvoet marked this conversation as resolved.
Show resolved
Hide resolved
|
||
* Delete a field by answering the prompts. | ||
* @usage drush field-delete taxonomy_term tag | ||
* Delete a field and fill in the remaining information through prompts. | ||
* @usage drush field-delete taxonomy_term tag --field-name=field_tag_label | ||
* Delete a field in a non-interactive way. | ||
* | ||
* @version 11.0 | ||
* @see \Drupal\field_ui\Form\FieldConfigDeleteForm | ||
*/ | ||
public function delete(?string $entityType = null, ?string $bundle = null, array $options = [ | ||
'field-name' => InputOption::VALUE_REQUIRED, | ||
'show-machine-names' => InputOption::VALUE_OPTIONAL, | ||
]): void | ||
{ | ||
$this->input->setArgument('entityType', $entityType = $entityType ?? $this->askEntityType()); | ||
$this->validateEntityType($entityType); | ||
|
||
$this->input->setArgument('bundle', $bundle = $bundle ?? $this->askBundle()); | ||
$this->validateBundle($entityType, $bundle); | ||
|
||
$fieldName = $this->input->getOption('field-name') ?? $this->askExisting($entityType, $bundle); | ||
$this->input->setOption('field-name', $fieldName); | ||
|
||
if ($fieldName === '') { | ||
throw new \InvalidArgumentException(dt('The %optionName option is required.', [ | ||
'%optionName' => 'field-name', | ||
])); | ||
} | ||
|
||
/** @var FieldConfig[] $results */ | ||
$results = $this->entityTypeManager | ||
->getStorage('field_config') | ||
->loadByProperties([ | ||
'field_name' => $fieldName, | ||
'entity_type' => $entityType, | ||
'bundle' => $bundle, | ||
]); | ||
|
||
if ($results === []) { | ||
throw new \InvalidArgumentException( | ||
t("Field with name ':fieldName' does not exist on bundle ':bundle'.", [ | ||
':fieldName' => $fieldName, | ||
':bundle' => $bundle, | ||
]) | ||
); | ||
} | ||
|
||
$this->deleteFieldConfig(reset($results)); | ||
|
||
// Fields are purged on cron. However field module prevents disabling modules | ||
// when field types they provided are used in a field until it is fully | ||
// purged. In the case that a field has minimal or no content, a single call | ||
// to field_purge_batch() will remove it from the system. Call this with a | ||
// low batch limit to avoid administrators having to wait for cron runs when | ||
// removing fields that meet this criteria. | ||
field_purge_batch(10); | ||
} | ||
|
||
protected function askExisting(string $entityType, string $bundle): string | ||
{ | ||
$choices = []; | ||
/** @var FieldConfigInterface[] $fieldConfigs */ | ||
$fieldConfigs = $this->entityTypeManager | ||
->getStorage('field_config') | ||
->loadByProperties([ | ||
'entity_type' => $entityType, | ||
'bundle' => $bundle, | ||
]); | ||
|
||
foreach ($fieldConfigs as $fieldConfig) { | ||
$label = $this->input->getOption('show-machine-names') | ||
? $fieldConfig->get('field_name') | ||
: $fieldConfig->get('label'); | ||
|
||
$choices[$fieldConfig->get('field_name')] = $label; | ||
} | ||
|
||
if ($choices === []) { | ||
throw new \InvalidArgumentException( | ||
t("Bundle ':bundle' has no fields.", [ | ||
':bundle' => $bundle, | ||
]) | ||
); | ||
} | ||
|
||
return $this->io()->choice('Choose a field to delete', $choices); | ||
} | ||
|
||
protected function deleteFieldConfig(FieldConfigInterface $fieldConfig): void | ||
{ | ||
$fieldStorage = $fieldConfig->getFieldStorageDefinition(); | ||
$bundles = $this->entityTypeBundleInfo->getBundleInfo($fieldConfig->getTargetEntityTypeId()); | ||
$bundleLabel = $bundles[$fieldConfig->getTargetBundle()]['label']; | ||
|
||
if ($fieldStorage && !$fieldStorage->isLocked()) { | ||
$fieldConfig->delete(); | ||
|
||
// If there is only one bundle left for this field storage, it will be | ||
// deleted too, notify the user about dependencies. | ||
if (count($fieldStorage->getBundles()) <= 1) { | ||
$fieldStorage->delete(); | ||
} | ||
|
||
$message = 'The field :field has been deleted from the :type bundle.'; | ||
} else { | ||
$message = 'There was a problem removing the :field from the :type content type.'; | ||
} | ||
|
||
$this->logger()->success( | ||
t($message, [':field' => $fieldConfig->label(), ':type' => $bundleLabel]) | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like we don't use a CustomEvent directly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We do call the
getCustomEventHandlers
method inFieldCreateCommands
, right?