Issue #3358049 by narendraR, lauriii, srishtiiee, Utkarsh_33, Wim Leers, tim.plunkett, tedbow, bnjmnm, smustgrave, Berdir, amateescu, larowlan: Save FieldStorageConfig at the same time as FieldConfig
parent
2b9d2a95ac
commit
d2cdfb1940
|
@ -6,6 +6,7 @@ use Drupal\Core\Config\Entity\ConfigEntityBase;
|
|||
use Drupal\Core\Entity\EntityStorageInterface;
|
||||
use Drupal\Core\Entity\FieldableEntityInterface;
|
||||
use Drupal\Core\Field\TypedData\FieldItemDataDefinition;
|
||||
use Drupal\field\Entity\FieldStorageConfig;
|
||||
|
||||
/**
|
||||
* Base class for configurable field definitions.
|
||||
|
@ -468,10 +469,17 @@ abstract class FieldConfigBase extends ConfigEntityBase implements FieldConfigIn
|
|||
* @todo Investigate in https://www.drupal.org/node/1977206.
|
||||
*/
|
||||
public function __sleep() {
|
||||
$properties = get_object_vars($this);
|
||||
|
||||
// Only serialize necessary properties, excluding those that can be
|
||||
// recalculated.
|
||||
$properties = get_object_vars($this);
|
||||
unset($properties['fieldStorage'], $properties['itemDefinition'], $properties['original']);
|
||||
unset($properties['itemDefinition'], $properties['original']);
|
||||
|
||||
// Field storage can be recalculated if it's not new.
|
||||
if (array_key_exists('fieldStorage', $properties) && $properties['fieldStorage'] instanceof FieldStorageConfig && !$properties['fieldStorage']->isNew()) {
|
||||
unset($properties['fieldStorage']);
|
||||
}
|
||||
|
||||
return array_keys($properties);
|
||||
}
|
||||
|
||||
|
|
|
@ -370,7 +370,17 @@ class FieldItemList extends ItemList implements FieldItemListInterface {
|
|||
]);
|
||||
}
|
||||
else {
|
||||
$widget = $field_widget_plugin_manager->getInstance(['field_definition' => $definition]);
|
||||
$options = [
|
||||
'field_definition' => $this->getFieldDefinition(),
|
||||
];
|
||||
// If the field does not have a widget configured in the 'default' form
|
||||
// mode, check if there are default entity form display options defined
|
||||
// for the 'default' form mode in the form state.
|
||||
// @see \Drupal\field_ui\Controller\FieldConfigAddController::fieldConfigAddConfigureForm
|
||||
if (($default_options = $form_state->get('default_options')) && isset($default_options['entity_form_display']['default'])) {
|
||||
$options['configuration'] = $default_options['entity_form_display']['default'];
|
||||
}
|
||||
$widget = $field_widget_plugin_manager->getInstance($options);
|
||||
}
|
||||
|
||||
$form_state->set('default_value_widget', $widget);
|
||||
|
|
|
@ -158,12 +158,12 @@ class CommentFieldsTest extends CommentTestBase {
|
|||
'field_name' => 'user_comment',
|
||||
];
|
||||
$this->drupalGet('admin/config/people/accounts/fields/add-field');
|
||||
$this->submitForm($edit, 'Save and continue');
|
||||
$this->submitForm($edit, 'Continue');
|
||||
|
||||
// Try to save the comment field without selecting a comment type.
|
||||
$edit = [];
|
||||
$this->drupalGet('admin/config/people/accounts/fields/user.user.field_user_comment/storage');
|
||||
$this->submitForm($edit, 'Save field settings');
|
||||
$this->drupalGet('admin/config/people/accounts/add-storage/user/field_user_comment');
|
||||
$this->submitForm($edit, 'Continue');
|
||||
// We should get an error message.
|
||||
$this->assertSession()->pageTextContains('The submitted value in the Comment type element is not allowed.');
|
||||
|
||||
|
@ -180,8 +180,8 @@ class CommentFieldsTest extends CommentTestBase {
|
|||
$edit = [
|
||||
'settings[comment_type]' => 'user_comment_type',
|
||||
];
|
||||
$this->drupalGet('admin/config/people/accounts/fields/user.user.field_user_comment/storage');
|
||||
$this->submitForm($edit, 'Save field settings');
|
||||
$this->drupalGet('admin/config/people/accounts/add-storage/user/field_user_comment');
|
||||
$this->submitForm($edit, 'Continue');
|
||||
// We shouldn't get an error message.
|
||||
$this->assertSession()->pageTextNotContains('The submitted value in the Comment type element is not allowed.');
|
||||
|
||||
|
@ -190,7 +190,7 @@ class CommentFieldsTest extends CommentTestBase {
|
|||
$edit = [
|
||||
'settings[per_page]' => 0,
|
||||
];
|
||||
$this->drupalGet('admin/config/people/accounts/fields/user.user.field_user_comment');
|
||||
$this->drupalGet('admin/config/people/accounts/add-field/user/field_user_comment');
|
||||
$this->submitForm($edit, 'Save settings');
|
||||
$this->assertSession()->statusMessageContains('Saved User comment configuration.', 'status');
|
||||
}
|
||||
|
|
|
@ -6,6 +6,8 @@ use Drupal\Core\Config\Entity\ConfigEntityBase;
|
|||
use Drupal\Core\Entity\EntityStorageInterface;
|
||||
use Drupal\Core\Entity\FieldableEntityInterface;
|
||||
use Drupal\Core\Entity\FieldableEntityStorageInterface;
|
||||
use Drupal\Core\Entity\Plugin\DataType\EntityAdapter;
|
||||
use Drupal\Core\Field\BaseFieldDefinition;
|
||||
use Drupal\Core\Field\FieldException;
|
||||
use Drupal\Core\Field\FieldStorageDefinitionInterface;
|
||||
use Drupal\Core\TypedData\OptionsProviderInterface;
|
||||
|
@ -680,7 +682,19 @@ class FieldStorageConfig extends ConfigEntityBase implements FieldStorageConfigI
|
|||
// runtime item object, so that it can be used as the options provider
|
||||
// without modifying the entity being worked on.
|
||||
if (is_subclass_of($this->getFieldItemClass(), OptionsProviderInterface::class)) {
|
||||
$items = $entity->get($this->getName());
|
||||
try {
|
||||
$items = $entity->get($this->getName());
|
||||
}
|
||||
catch (\InvalidArgumentException $e) {
|
||||
// When a field doesn't exist, create a new field item list using a
|
||||
// temporary base field definition. This step is necessary since there
|
||||
// may not be a field configuration for the storage when creating a new
|
||||
// field.
|
||||
// @todo Simplify in https://www.drupal.org/project/drupal/issues/3347291.
|
||||
$field_storage = BaseFieldDefinition::createFromFieldStorageDefinition($this);
|
||||
$entity_adapter = EntityAdapter::createFromEntity($entity);
|
||||
$items = \Drupal::typedDataManager()->create($field_storage, name: $field_storage->getName(), parent: $entity_adapter);
|
||||
}
|
||||
return \Drupal::service('plugin.manager.field.field_type')->createFieldItem($items, 0);
|
||||
}
|
||||
// @todo: Allow setting custom options provider, see
|
||||
|
@ -724,7 +738,7 @@ class FieldStorageConfig extends ConfigEntityBase implements FieldStorageConfigI
|
|||
* TRUE if the field has data for any entity; FALSE otherwise.
|
||||
*/
|
||||
public function hasData() {
|
||||
return \Drupal::entityTypeManager()->getStorage($this->entity_type)->countFieldData($this, TRUE);
|
||||
return !$this->isNew() && \Drupal::entityTypeManager()->getStorage($this->entity_type)->countFieldData($this, TRUE);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -4,6 +4,7 @@ namespace Drupal\Tests\field\Functional\EntityReference;
|
|||
|
||||
use Behat\Mink\Element\NodeElement;
|
||||
use Drupal\Core\Field\FieldStorageDefinitionInterface;
|
||||
use Drupal\Core\Messenger\MessengerInterface;
|
||||
use Drupal\field\Entity\FieldConfig;
|
||||
use Drupal\node\Entity\Node;
|
||||
use Drupal\taxonomy\Entity\Vocabulary;
|
||||
|
@ -119,7 +120,7 @@ class EntityReferenceAdminTest extends BrowserTestBase {
|
|||
$edit = [
|
||||
'cardinality' => FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED,
|
||||
];
|
||||
$this->submitForm($edit, 'Save field settings');
|
||||
$this->submitForm($edit, 'Continue');
|
||||
|
||||
// Add the view to the test field.
|
||||
$edit = [
|
||||
|
@ -131,6 +132,8 @@ class EntityReferenceAdminTest extends BrowserTestBase {
|
|||
'settings[handler_settings][view][view_and_display]' => 'node_test_view:entity_reference_1',
|
||||
];
|
||||
$this->submitForm($edit, 'Save settings');
|
||||
$this->assertSession()->statusMessageContains("Saved Test Entity Reference Field configuration.", MessengerInterface::TYPE_STATUS);
|
||||
$this->assertFieldExistsOnOverview('Test Entity Reference Field');
|
||||
|
||||
// Create nodes.
|
||||
$node1 = Node::create([
|
||||
|
@ -205,7 +208,7 @@ class EntityReferenceAdminTest extends BrowserTestBase {
|
|||
$edit = [
|
||||
'cardinality' => -1,
|
||||
];
|
||||
$this->submitForm($edit, 'Save field settings');
|
||||
$this->submitForm($edit, 'Save');
|
||||
$this->drupalGet($bundle_path . '/fields/' . $field_path);
|
||||
$term_name = $this->randomString();
|
||||
$result = \Drupal::entityQuery('taxonomy_term')
|
||||
|
@ -219,6 +222,7 @@ class EntityReferenceAdminTest extends BrowserTestBase {
|
|||
'settings[handler_settings][auto_create]' => 1,
|
||||
];
|
||||
$this->submitForm($edit, 'Save settings');
|
||||
$this->assertFieldExistsOnOverview($taxonomy_term_field_name);
|
||||
$this->drupalGet($bundle_path . '/fields/' . $field_path);
|
||||
$edit = [
|
||||
'set_default_value' => '1',
|
||||
|
@ -226,6 +230,7 @@ class EntityReferenceAdminTest extends BrowserTestBase {
|
|||
'default_value_input[field_' . $taxonomy_term_field_name . '][0][target_id]' => $term_name,
|
||||
];
|
||||
$this->submitForm($edit, 'Save settings');
|
||||
$this->assertFieldExistsOnOverview($taxonomy_term_field_name);
|
||||
// The term should now exist.
|
||||
$result = \Drupal::entityQuery('taxonomy_term')
|
||||
->condition('name', $term_name)
|
||||
|
@ -382,7 +387,7 @@ class EntityReferenceAdminTest extends BrowserTestBase {
|
|||
$field_edit['settings[handler_settings][target_bundles][' . $bundle . ']'] = TRUE;
|
||||
}
|
||||
|
||||
$this->fieldUIAddNewField($bundle_path, $field_name, NULL, 'entity_reference', $storage_edit, $field_edit);
|
||||
$this->fieldUIAddNewField($bundle_path, $field_name, $field_name, 'entity_reference', $storage_edit, $field_edit);
|
||||
|
||||
// Returns the generated field name.
|
||||
return $field_name;
|
||||
|
|
|
@ -136,7 +136,7 @@ class EntityReferenceAdminTest extends WebDriverTestBase {
|
|||
$this->assertFieldSelectOptions('settings[target_type]', array_keys(\Drupal::entityTypeManager()->getDefinitions()));
|
||||
|
||||
// Second step: 'Field settings' form.
|
||||
$this->submitForm([], 'Save field settings');
|
||||
$this->submitForm([], 'Continue');
|
||||
|
||||
// The base handler should be selected by default.
|
||||
$this->assertSession()->fieldValueEquals('settings[handler]', 'default:node');
|
||||
|
@ -268,7 +268,7 @@ class EntityReferenceAdminTest extends WebDriverTestBase {
|
|||
'settings[target_type]' => 'taxonomy_term',
|
||||
];
|
||||
$this->drupalGet($bundle_path . '/fields/' . $field_name . '/storage');
|
||||
$this->submitForm($edit, 'Save field settings');
|
||||
$this->submitForm($edit, 'Save');
|
||||
$this->drupalGet($bundle_path . '/fields/' . $field_name);
|
||||
$this->assertSession()->fieldExists('settings[handler_settings][auto_create]');
|
||||
|
||||
|
@ -279,7 +279,7 @@ class EntityReferenceAdminTest extends WebDriverTestBase {
|
|||
'settings[target_type]' => 'user',
|
||||
];
|
||||
$this->drupalGet($bundle_path . '/fields/' . $field_name . '/storage');
|
||||
$this->submitForm($edit, 'Save field settings');
|
||||
$this->submitForm($edit, 'Save');
|
||||
$this->drupalGet($bundle_path . '/fields/' . $field_name);
|
||||
$this->assertSession()->fieldValueEquals('settings[handler_settings][filter][type]', '_none');
|
||||
$this->assertSession()->fieldValueEquals('settings[handler_settings][sort][field]', '_none');
|
||||
|
@ -299,7 +299,7 @@ class EntityReferenceAdminTest extends WebDriverTestBase {
|
|||
'settings[target_type]' => 'node',
|
||||
];
|
||||
$this->drupalGet($bundle_path . '/fields/' . $field_name . '/storage');
|
||||
$this->submitForm($edit, 'Save field settings');
|
||||
$this->submitForm($edit, 'Save');
|
||||
|
||||
// Try to select the views handler.
|
||||
$this->drupalGet($bundle_path . '/fields/' . $field_name);
|
||||
|
@ -332,7 +332,7 @@ class EntityReferenceAdminTest extends WebDriverTestBase {
|
|||
'settings[target_type]' => 'entity_test',
|
||||
];
|
||||
$this->drupalGet($bundle_path . '/fields/' . $field_name . '/storage');
|
||||
$this->submitForm($edit, 'Save field settings');
|
||||
$this->submitForm($edit, 'Save');
|
||||
$this->drupalGet($bundle_path . '/fields/' . $field_name);
|
||||
$page->findField('settings[handler]')->setValue('views');
|
||||
$assert_session
|
||||
|
|
|
@ -12,6 +12,7 @@ use Drupal\Core\Entity\EntityViewModeInterface;
|
|||
use Drupal\Core\Entity\EntityFormModeInterface;
|
||||
use Drupal\Core\Url;
|
||||
use Drupal\field_ui\FieldUI;
|
||||
use Drupal\field_ui\Form\FieldConfigEditForm;
|
||||
use Drupal\field_ui\Plugin\Derivative\FieldUiLocalTask;
|
||||
|
||||
/**
|
||||
|
@ -79,6 +80,7 @@ function field_ui_theme() {
|
|||
function field_ui_entity_type_build(array &$entity_types) {
|
||||
/** @var \Drupal\Core\Entity\EntityTypeInterface[] $entity_types */
|
||||
$entity_types['field_config']->setFormClass('edit', 'Drupal\field_ui\Form\FieldConfigEditForm');
|
||||
$entity_types['field_config']->setFormClass('default', FieldConfigEditForm::class);
|
||||
$entity_types['field_config']->setFormClass('delete', 'Drupal\field_ui\Form\FieldConfigDeleteForm');
|
||||
$entity_types['field_config']->setListBuilderClass('Drupal\field_ui\FieldConfigListBuilder');
|
||||
|
||||
|
|
|
@ -0,0 +1,77 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Drupal\field_ui\Controller;
|
||||
|
||||
use Drupal\Core\Controller\ControllerBase;
|
||||
use Drupal\Core\Entity\EntityReferenceSelection\SelectionPluginManagerInterface;
|
||||
use Drupal\Core\Field\FieldTypePluginManagerInterface;
|
||||
use Drupal\Core\TempStore\PrivateTempStore;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
|
||||
/**
|
||||
* Controller for building the field instance form.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
final class FieldConfigAddController extends ControllerBase {
|
||||
|
||||
/**
|
||||
* FieldConfigAddController constructor.
|
||||
*
|
||||
* @param \Drupal\Core\TempStore\PrivateTempStore $tempStore
|
||||
* The private tempstore.
|
||||
* @param \Drupal\Core\Field\FieldTypePluginManagerInterface $fieldTypeManager
|
||||
* The field type plugin manager.
|
||||
* @param \Drupal\Core\Entity\EntityReferenceSelection\SelectionPluginManagerInterface $selectionManager
|
||||
* The entity reference selection plugin manager.
|
||||
*/
|
||||
public function __construct(
|
||||
protected readonly PrivateTempStore $tempStore,
|
||||
protected readonly FieldTypePluginManagerInterface $fieldTypeManager,
|
||||
protected readonly SelectionPluginManagerInterface $selectionManager,
|
||||
) {}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container) {
|
||||
return new static(
|
||||
$container->get('tempstore.private')->get('field_ui'),
|
||||
$container->get('plugin.manager.field.field_type'),
|
||||
$container->get('plugin.manager.entity_reference_selection')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the field config instance form.
|
||||
*
|
||||
* @param string $entity_type
|
||||
* The entity type.
|
||||
* @param string $field_name
|
||||
* The name of the field to create.
|
||||
*
|
||||
* @return array
|
||||
* The field instance edit form.
|
||||
*/
|
||||
public function fieldConfigAddConfigureForm(string $entity_type, string $field_name): array {
|
||||
// @see \Drupal\field_ui\Form\FieldStorageAddForm::submitForm
|
||||
$temp_storage = $this->tempStore->get($entity_type . ':' . $field_name);
|
||||
if (!$temp_storage) {
|
||||
throw new NotFoundHttpException();
|
||||
}
|
||||
|
||||
/** @var \Drupal\Core\Field\FieldConfigInterface $entity */
|
||||
$entity = $this->entityTypeManager()->getStorage('field_config')->create([
|
||||
...$temp_storage['field_config_values'],
|
||||
'field_storage' => $temp_storage['field_storage'],
|
||||
]);
|
||||
|
||||
return $this->entityFormBuilder()->getForm($entity, 'default', [
|
||||
'default_options' => $temp_storage['default_options'],
|
||||
]);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Drupal\field_ui\Controller;
|
||||
|
||||
use Drupal\Core\Controller\ControllerBase;
|
||||
use Drupal\Core\TempStore\PrivateTempStore;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
|
||||
/**
|
||||
* Controller for building the field storage form.
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* @todo remove in https://www.drupal.org/project/drupal/issues/3347291.
|
||||
*/
|
||||
final class FieldStorageAddController extends ControllerBase {
|
||||
|
||||
/**
|
||||
* FieldStorageAddController constructor.
|
||||
*
|
||||
* @param \Drupal\Core\TempStore\PrivateTempStore $tempStore
|
||||
* The private tempstore.
|
||||
*/
|
||||
public function __construct(protected readonly PrivateTempStore $tempStore) {}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container) {
|
||||
return new static(
|
||||
$container->get('tempstore.private')->get('field_ui')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the field storage form.
|
||||
*
|
||||
* @param string $entity_type
|
||||
* The entity type.
|
||||
* @param string $field_name
|
||||
* The name of the field to create.
|
||||
* @param string $bundle
|
||||
* The bundle where the field is being created.
|
||||
*
|
||||
* @return array
|
||||
* The field storage form.
|
||||
*/
|
||||
public function storageAddConfigureForm(string $entity_type, string $field_name, string $bundle): array {
|
||||
// @see \Drupal\field_ui\Form\FieldStorageAddForm::submitForm
|
||||
$temp_storage = $this->tempStore->get($entity_type . ':' . $field_name);
|
||||
if (!$temp_storage) {
|
||||
throw new NotFoundHttpException();
|
||||
}
|
||||
|
||||
return $this->entityFormBuilder()->getForm($temp_storage['field_storage'], 'edit', [
|
||||
'entity_type_id' => $entity_type,
|
||||
'bundle' => $bundle,
|
||||
]);
|
||||
}
|
||||
|
||||
}
|
|
@ -2,13 +2,16 @@
|
|||
|
||||
namespace Drupal\field_ui\Form;
|
||||
|
||||
use Drupal\Core\Entity\EntityDisplayRepositoryInterface;
|
||||
use Drupal\Core\Entity\EntityForm;
|
||||
use Drupal\Core\Entity\EntityStorageException;
|
||||
use Drupal\Core\Entity\EntityTypeBundleInfoInterface;
|
||||
use Drupal\Core\Entity\FieldableEntityInterface;
|
||||
use Drupal\Core\Entity\Plugin\DataType\EntityAdapter;
|
||||
use Drupal\Core\Field\FieldFilteredMarkup;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\Core\Render\Element;
|
||||
use Drupal\Core\TempStore\PrivateTempStore;
|
||||
use Drupal\Core\TypedData\TypedDataInterface;
|
||||
use Drupal\Core\TypedData\TypedDataManagerInterface;
|
||||
use Drupal\Core\Url;
|
||||
|
@ -23,6 +26,8 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
|
|||
*/
|
||||
class FieldConfigEditForm extends EntityForm {
|
||||
|
||||
use FieldStorageCreationTrait;
|
||||
|
||||
/**
|
||||
* The entity being used by this form.
|
||||
*
|
||||
|
@ -37,6 +42,20 @@ class FieldConfigEditForm extends EntityForm {
|
|||
*/
|
||||
protected $entityTypeBundleInfo;
|
||||
|
||||
/**
|
||||
* The name of the entity type.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected string $entityTypeId;
|
||||
|
||||
/**
|
||||
* The entity bundle.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected string $bundle;
|
||||
|
||||
/**
|
||||
* Constructs a new FieldConfigDeleteForm object.
|
||||
*
|
||||
|
@ -44,9 +63,25 @@ class FieldConfigEditForm extends EntityForm {
|
|||
* The entity type bundle info service.
|
||||
* @param \Drupal\Core\TypedData\TypedDataManagerInterface $typedDataManager
|
||||
* The type data manger.
|
||||
* @param \Drupal\Core\Entity\EntityDisplayRepositoryInterface|null $entityDisplayRepository
|
||||
* The entity display repository.
|
||||
* @param \Drupal\Core\TempStore\PrivateTempStore|null $tempStore
|
||||
* The private tempstore.
|
||||
*/
|
||||
public function __construct(EntityTypeBundleInfoInterface $entity_type_bundle_info, protected TypedDataManagerInterface $typedDataManager) {
|
||||
public function __construct(
|
||||
EntityTypeBundleInfoInterface $entity_type_bundle_info,
|
||||
protected TypedDataManagerInterface $typedDataManager,
|
||||
protected ?EntityDisplayRepositoryInterface $entityDisplayRepository = NULL,
|
||||
protected ?PrivateTempStore $tempStore = NULL) {
|
||||
$this->entityTypeBundleInfo = $entity_type_bundle_info;
|
||||
if ($this->entityDisplayRepository === NULL) {
|
||||
@trigger_error('Calling FieldConfigEditForm::__construct() without the $entityDisplayRepository argument is deprecated in drupal:10.2.0 and will be required in drupal:11.0.0. See https://www.drupal.org/node/3383771', E_USER_DEPRECATED);
|
||||
$this->entityDisplayRepository = \Drupal::service('entity_display.repository');
|
||||
}
|
||||
if ($this->tempStore === NULL) {
|
||||
@trigger_error('Calling FieldConfigEditForm::__construct() without the $tempStore argument is deprecated in drupal:10.2.0 and will be required in drupal:11.0.0. See https://www.drupal.org/node/3383771', E_USER_DEPRECATED);
|
||||
$this->tempStore = \Drupal::service('tempstore.private')->get('field_ui');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -55,7 +90,9 @@ class FieldConfigEditForm extends EntityForm {
|
|||
public static function create(ContainerInterface $container) {
|
||||
return new static(
|
||||
$container->get('entity_type.bundle.info'),
|
||||
$container->get('typed_data_manager')
|
||||
$container->get('typed_data_manager'),
|
||||
$container->get('entity_display.repository'),
|
||||
$container->get('tempstore.private')->get('field_ui')
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -261,7 +298,34 @@ class FieldConfigEditForm extends EntityForm {
|
|||
* {@inheritdoc}
|
||||
*/
|
||||
public function save(array $form, FormStateInterface $form_state) {
|
||||
$temp_storage = $this->tempStore->get($this->entity->getTargetEntityTypeId() . ':' . $this->entity->getName());
|
||||
if ($this->entity->isNew()) {
|
||||
// @todo remove in https://www.drupal.org/project/drupal/issues/3347291.
|
||||
if ($temp_storage && $temp_storage['field_storage']->isNew()) {
|
||||
// Save field storage.
|
||||
try {
|
||||
$temp_storage['field_storage']->save();
|
||||
}
|
||||
catch (EntityStorageException $e) {
|
||||
$this->tempStore->delete($this->entity->getTargetEntityTypeId() . ':' . $this->entity->getName());
|
||||
$form_state->setRedirectUrl(FieldUI::getOverviewRouteInfo($this->entity->getTargetEntityTypeId(), $this->entity->getTargetBundle()));
|
||||
$this->messenger()->addError($this->t('An error occurred while saving the field: @error', ['@error' => $e->getMessage()]));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Save field config.
|
||||
$this->entity->save();
|
||||
if (isset($form_state->getStorage()['default_options'])) {
|
||||
$default_options = $form_state->getStorage()['default_options'];
|
||||
// Configure the default display modes.
|
||||
$this->entityTypeId = $temp_storage['field_config_values']['entity_type'];
|
||||
$this->bundle = $temp_storage['field_config_values']['bundle'];
|
||||
$this->configureEntityFormDisplay($temp_storage['field_config_values']['field_name'], $default_options['entity_form_display'] ?? []);
|
||||
$this->configureEntityViewDisplay($temp_storage['field_config_values']['field_name'], $default_options['entity_view_display'] ?? []);
|
||||
// Delete the temp store entry.
|
||||
$this->tempStore->delete($this->entity->getTargetEntityTypeId() . ':' . $this->entity->getName());
|
||||
}
|
||||
|
||||
$this->messenger()->addStatus($this->t('Saved %label configuration.', ['%label' => $this->entity->getLabel()]));
|
||||
|
||||
|
|
|
@ -5,7 +5,6 @@ namespace Drupal\field_ui\Form;
|
|||
use Drupal\Component\Utility\Html;
|
||||
use Drupal\Component\Utility\SortArray;
|
||||
use Drupal\Core\Config\ConfigFactoryInterface;
|
||||
use Drupal\Core\Entity\EntityDisplayRepositoryInterface;
|
||||
use Drupal\Core\Entity\EntityFieldManagerInterface;
|
||||
use Drupal\Core\Entity\EntityTypeManagerInterface;
|
||||
use Drupal\Core\Field\FallbackFieldTypeCategory;
|
||||
|
@ -13,6 +12,7 @@ use Drupal\Core\Field\FieldTypeCategoryManagerInterface;
|
|||
use Drupal\Core\Field\FieldTypePluginManagerInterface;
|
||||
use Drupal\Core\Form\FormBase;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\Core\TempStore\PrivateTempStore;
|
||||
use Drupal\field\Entity\FieldStorageConfig;
|
||||
use Drupal\field_ui\FieldUI;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
@ -24,8 +24,6 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
|
|||
*/
|
||||
class FieldStorageAddForm extends FormBase {
|
||||
|
||||
use FieldStorageCreationTrait;
|
||||
|
||||
/**
|
||||
* The name of the entity type.
|
||||
*
|
||||
|
@ -54,13 +52,6 @@ class FieldStorageAddForm extends FormBase {
|
|||
*/
|
||||
protected $entityFieldManager;
|
||||
|
||||
/**
|
||||
* The entity display repository.
|
||||
*
|
||||
* @var \Drupal\Core\Entity\EntityDisplayRepositoryInterface
|
||||
*/
|
||||
protected $entityDisplayRepository;
|
||||
|
||||
/**
|
||||
* The field type plugin manager.
|
||||
*
|
||||
|
@ -86,17 +77,20 @@ class FieldStorageAddForm extends FormBase {
|
|||
* The configuration factory.
|
||||
* @param \Drupal\Core\Entity\EntityFieldManagerInterface $entity_field_manager
|
||||
* (optional) The entity field manager.
|
||||
* @param \Drupal\Core\Entity\EntityDisplayRepositoryInterface $entity_display_repository
|
||||
* (optional) The entity display repository.
|
||||
* @param \Drupal\Core\TempStore\PrivateTempStore|null $tempStore
|
||||
* The private tempstore.
|
||||
* @param \Drupal\Core\Field\FieldTypeCategoryManagerInterface|null $fieldTypeCategoryManager
|
||||
* The field type category plugin manager.
|
||||
*/
|
||||
public function __construct(EntityTypeManagerInterface $entity_type_manager, FieldTypePluginManagerInterface $field_type_plugin_manager, ConfigFactoryInterface $config_factory, EntityFieldManagerInterface $entity_field_manager, EntityDisplayRepositoryInterface $entity_display_repository, protected ?FieldTypeCategoryManagerInterface $fieldTypeCategoryManager = NULL) {
|
||||
public function __construct(EntityTypeManagerInterface $entity_type_manager, FieldTypePluginManagerInterface $field_type_plugin_manager, ConfigFactoryInterface $config_factory, EntityFieldManagerInterface $entity_field_manager, protected ?PrivateTempStore $tempStore = NULL, protected ?FieldTypeCategoryManagerInterface $fieldTypeCategoryManager = NULL) {
|
||||
$this->entityTypeManager = $entity_type_manager;
|
||||
$this->fieldTypePluginManager = $field_type_plugin_manager;
|
||||
$this->configFactory = $config_factory;
|
||||
$this->entityFieldManager = $entity_field_manager;
|
||||
$this->entityDisplayRepository = $entity_display_repository;
|
||||
if ($this->tempStore === NULL) {
|
||||
@trigger_error('Calling FieldStorageAddForm::__construct() without the $tempStore argument is deprecated in drupal:10.2.0 and will be required in drupal:11.0.0. See https://www.drupal.org/node/3383719', E_USER_DEPRECATED);
|
||||
$this->tempStore = \Drupal::service('tempstore.private')->get('field_ui');
|
||||
}
|
||||
if ($this->fieldTypeCategoryManager === NULL) {
|
||||
@trigger_error('Calling FieldStorageAddForm::__construct() without the $fieldTypeCategoryManager argument is deprecated in drupal:10.2.0 and will be required in drupal:11.0.0. See https://www.drupal.org/node/3375740', E_USER_DEPRECATED);
|
||||
$this->fieldTypeCategoryManager = \Drupal::service('plugin.manager.field.field_type_category');
|
||||
|
@ -119,7 +113,7 @@ class FieldStorageAddForm extends FormBase {
|
|||
$container->get('plugin.manager.field.field_type'),
|
||||
$container->get('config.factory'),
|
||||
$container->get('entity_field.manager'),
|
||||
$container->get('entity_display.repository'),
|
||||
$container->get('tempstore.private')->get('field_ui'),
|
||||
$container->get('plugin.manager.field.field_type_category'),
|
||||
);
|
||||
}
|
||||
|
@ -349,7 +343,7 @@ class FieldStorageAddForm extends FormBase {
|
|||
$form['actions'] = ['#type' => 'actions'];
|
||||
$form['actions']['submit'] = [
|
||||
'#type' => 'submit',
|
||||
'#value' => $this->t('Save and continue'),
|
||||
'#value' => $this->t('Continue'),
|
||||
'#button_type' => 'primary',
|
||||
];
|
||||
|
||||
|
@ -421,6 +415,8 @@ class FieldStorageAddForm extends FormBase {
|
|||
'entity_type' => $this->entityTypeId,
|
||||
'bundle' => $this->bundle,
|
||||
];
|
||||
$default_options = [];
|
||||
|
||||
// Check if we're dealing with a preconfigured field.
|
||||
if (strpos($field_storage_type, 'field_ui:') === 0) {
|
||||
[, $field_type, $preset_key] = explode(':', $field_storage_type, 3);
|
||||
|
@ -446,40 +442,32 @@ class FieldStorageAddForm extends FormBase {
|
|||
];
|
||||
|
||||
try {
|
||||
// Create the field storage.
|
||||
$this->entityTypeManager->getStorage('field_storage_config')
|
||||
->create($field_storage_values)->save();
|
||||
|
||||
// Create the field.
|
||||
$field = $this->entityTypeManager->getStorage('field_config')
|
||||
->create($field_values);
|
||||
$field->save();
|
||||
|
||||
// Configure the display modes.
|
||||
$this->configureEntityFormDisplay($field_name, $default_options['entity_form_display'] ?? []);
|
||||
$this->configureEntityViewDisplay($field_name, $default_options['entity_view_display'] ?? []);
|
||||
$field_storage_entity = $this->entityTypeManager->getStorage('field_storage_config')->create($field_storage_values);
|
||||
}
|
||||
catch (\Exception $e) {
|
||||
$this->messenger()->addError($this->t(
|
||||
'There was a problem creating field %label: @message',
|
||||
['%label' => $values['label'], '@message' => $e->getMessage()]));
|
||||
$this->messenger()->addError($this->t('There was a problem creating field %label: @message', ['%label' => $values['label'], '@message' => $e->getMessage()]));
|
||||
return;
|
||||
}
|
||||
|
||||
// Save field and field storage values in tempstore.
|
||||
$this->tempStore->set($this->entityTypeId . ':' . $field_name, [
|
||||
'field_storage' => $field_storage_entity,
|
||||
'field_config_values' => $field_values,
|
||||
'default_options' => $default_options,
|
||||
]);
|
||||
|
||||
// Configure next steps in the multi-part form.
|
||||
$destinations = [];
|
||||
$route_parameters = [
|
||||
'field_config' => $field->id(),
|
||||
'entity_type' => $this->entityTypeId,
|
||||
'field_name' => $field_name,
|
||||
] + FieldUI::getRouteBundleParameter($entity_type, $this->bundle);
|
||||
// Always show the field settings step, as the cardinality needs to be
|
||||
// configured for new fields.
|
||||
$destinations[] = [
|
||||
'route_name' => "entity.field_config.{$this->entityTypeId}_storage_edit_form",
|
||||
'route_name' => "field_ui.field_storage_add_{$this->entityTypeId}",
|
||||
'route_parameters' => $route_parameters,
|
||||
];
|
||||
|
||||
$destinations[] = [
|
||||
'route_name' => "entity.field_config.{$this->entityTypeId}_field_edit_form",
|
||||
'route_name' => "field_ui.field_add_{$this->entityTypeId}",
|
||||
'route_parameters' => $route_parameters,
|
||||
];
|
||||
$destinations[] = [
|
||||
|
@ -494,8 +482,6 @@ class FieldStorageAddForm extends FormBase {
|
|||
|
||||
// Store new field information for any additional submit handlers.
|
||||
$form_state->set(['fields_added', '_add_new_field'], $field_name);
|
||||
|
||||
$this->messenger()->addMessage($this->t('Your settings have been saved.'));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -3,11 +3,15 @@
|
|||
namespace Drupal\field_ui\Form;
|
||||
|
||||
use Drupal\Core\Entity\EntityForm;
|
||||
use Drupal\Core\Entity\Plugin\DataType\EntityAdapter;
|
||||
use Drupal\Core\Field\FieldStorageDefinitionInterface;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\Core\Routing\RouteMatchInterface;
|
||||
use Drupal\Core\TempStore\PrivateTempStore;
|
||||
use Drupal\Core\TypedData\TypedDataManagerInterface;
|
||||
use Drupal\field\Entity\FieldConfig;
|
||||
use Drupal\field_ui\FieldUI;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
|
||||
/**
|
||||
|
@ -24,6 +28,34 @@ class FieldStorageConfigEditForm extends EntityForm {
|
|||
*/
|
||||
protected $entity;
|
||||
|
||||
/**
|
||||
* FieldStorageConfigEditForm constructor.
|
||||
*
|
||||
* @param \Drupal\Core\TypedData\TypedDataManagerInterface $typedDataManager
|
||||
* The typed data manager.
|
||||
* @param \Drupal\Core\TempStore\PrivateTempStore|null $tempStore
|
||||
* The private tempstore.
|
||||
*/
|
||||
public function __construct(
|
||||
protected TypedDataManagerInterface $typedDataManager,
|
||||
protected ?PrivateTempStore $tempStore = NULL,
|
||||
) {
|
||||
if ($this->tempStore === NULL) {
|
||||
@trigger_error('Calling FieldStorageConfigEditForm::__construct() without the $tempStore argument is deprecated in drupal:10.2.0 and will be required in drupal:11.0.0. See https://www.drupal.org/node/3383720', E_USER_DEPRECATED);
|
||||
$this->tempStore = \Drupal::service('tempstore.private')->get('field_ui');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container) {
|
||||
return new static(
|
||||
$container->get('typed_data_manager'),
|
||||
$container->get('tempstore.private')->get('field_ui')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
@ -64,9 +96,10 @@ class FieldStorageConfigEditForm extends EntityForm {
|
|||
* {@inheritdoc}
|
||||
*/
|
||||
public function form(array $form, FormStateInterface $form_state) {
|
||||
$temp_storage = $this->tempStore->get($this->entity->getTargetEntityTypeId() . ':' . $this->entity->getName());
|
||||
$form = parent::form($form, $form_state);
|
||||
|
||||
$field_label = $form_state->get('field_config')->label();
|
||||
$field_label = $this->entity->isNew() ? $temp_storage['field_config_values']['label'] : $form_state->get('field_config')->label();
|
||||
$form['#title'] = $field_label;
|
||||
$form['#prefix'] = '<p>' . $this->t('These settings apply to the %field field everywhere it is used. Some also impact the way that data is stored and cannot be changed once data has been created.', ['%field' => $field_label]) . '</p>';
|
||||
|
||||
|
@ -85,7 +118,18 @@ class FieldStorageConfigEditForm extends EntityForm {
|
|||
'entity_id' => NULL,
|
||||
];
|
||||
$entity = _field_create_entity_from_ids($ids);
|
||||
$items = $entity->get($this->entity->getName());
|
||||
if (!$this->entity->isNew()) {
|
||||
$items = $entity->get($this->entity->getName());
|
||||
}
|
||||
else {
|
||||
// Create a temporary field config so that we can access the field
|
||||
// definition.
|
||||
$field_config = $this->entityTypeManager->getStorage('field_config')->create([
|
||||
...$temp_storage['field_config_values'],
|
||||
'field_storage' => $temp_storage['field_storage'],
|
||||
]);
|
||||
$items = $this->typedDataManager->create($field_config, name: $this->entity->getName(), parent: EntityAdapter::createFromEntity($entity));
|
||||
}
|
||||
$item = $items->first() ?: $items->appendItem();
|
||||
$form['settings'] += $item->storageSettingsForm($form, $form_state, $this->entity->hasData());
|
||||
|
||||
|
@ -164,7 +208,7 @@ class FieldStorageConfigEditForm extends EntityForm {
|
|||
*/
|
||||
protected function actions(array $form, FormStateInterface $form_state) {
|
||||
$elements = parent::actions($form, $form_state);
|
||||
$elements['submit']['#value'] = $this->t('Save field settings');
|
||||
$elements['submit']['#value'] = $this->entity->isNew() ? $this->t('Continue') : $this->t('Save');
|
||||
|
||||
return $elements;
|
||||
}
|
||||
|
@ -218,10 +262,19 @@ class FieldStorageConfigEditForm extends EntityForm {
|
|||
* {@inheritdoc}
|
||||
*/
|
||||
public function save(array $form, FormStateInterface $form_state) {
|
||||
$field_label = $form_state->get('field_config')->label();
|
||||
// Save field storage entity values in tempstore.
|
||||
if ($this->entity->isNew()) {
|
||||
$temp_storage = $this->tempStore->get($this->entity->getTargetEntityTypeId() . ':' . $this->entity->getName());
|
||||
$field_label = $temp_storage['field_config_values']['label'];
|
||||
$temp_storage['field_storage'] = $this->entity;
|
||||
$this->tempStore->set($this->entity->getTargetEntityTypeId() . ':' . $this->entity->getName(), $temp_storage);
|
||||
}
|
||||
try {
|
||||
$this->entity->save();
|
||||
$this->messenger()->addStatus($this->t('Updated field %label field settings.', ['%label' => $field_label]));
|
||||
if (!$this->entity->isNew()) {
|
||||
$field_label = $form_state->get('field_config')->label();
|
||||
$this->entity->save();
|
||||
$this->messenger()->addMessage($this->t('Your settings have been saved.'));
|
||||
}
|
||||
$request = $this->getRequest();
|
||||
if (($destinations = $request->query->all('destinations')) && $next_destination = FieldUI::getNextDestination($destinations)) {
|
||||
$request->query->remove('destinations');
|
||||
|
|
|
@ -5,6 +5,8 @@ namespace Drupal\field_ui\Routing;
|
|||
use Drupal\Core\Entity\EntityTypeManagerInterface;
|
||||
use Drupal\Core\Routing\RouteSubscriberBase;
|
||||
use Drupal\Core\Routing\RoutingEvents;
|
||||
use Drupal\field_ui\Controller\FieldConfigAddController;
|
||||
use Drupal\field_ui\Controller\FieldStorageAddController;
|
||||
use Symfony\Component\Routing\Route;
|
||||
use Symfony\Component\Routing\RouteCollection;
|
||||
|
||||
|
@ -109,6 +111,29 @@ class RouteSubscriber extends RouteSubscriberBase {
|
|||
);
|
||||
$collection->add("field_ui.field_storage_config_add_$entity_type_id", $route);
|
||||
|
||||
$route = new Route(
|
||||
"$path/add-field/{entity_type}/{field_name}",
|
||||
[
|
||||
'_controller' => FieldConfigAddController::class . '::fieldConfigAddConfigureForm',
|
||||
'_title' => 'Add field',
|
||||
] + $defaults,
|
||||
['_permission' => 'administer ' . $entity_type_id . ' fields'],
|
||||
$options
|
||||
);
|
||||
$collection->add("field_ui.field_add_$entity_type_id", $route);
|
||||
|
||||
// @todo remove in https://www.drupal.org/project/drupal/issues/3347291.
|
||||
$route = new Route(
|
||||
"$path/add-storage/{entity_type}/{field_name}",
|
||||
[
|
||||
'_controller' => FieldStorageAddController::class . '::storageAddConfigureForm',
|
||||
'_title' => 'Add storage',
|
||||
] + $defaults,
|
||||
['_permission' => 'administer ' . $entity_type_id . ' fields'],
|
||||
$options
|
||||
);
|
||||
$collection->add("field_ui.field_storage_add_$entity_type_id", $route);
|
||||
|
||||
$route = new Route(
|
||||
"$path/fields/reuse",
|
||||
[
|
||||
|
|
|
@ -240,7 +240,7 @@ class ManageFieldsFunctionalTest extends BrowserTestBase {
|
|||
$edit = [
|
||||
'settings[test_field_storage_setting]' => $string,
|
||||
];
|
||||
$this->submitForm($edit, 'Save field settings');
|
||||
$this->submitForm($edit, 'Save');
|
||||
|
||||
// Go to the field edit page.
|
||||
$this->drupalGet('admin/structure/types/manage/' . $this->contentType . '/fields/' . $field_id);
|
||||
|
@ -291,7 +291,7 @@ class ManageFieldsFunctionalTest extends BrowserTestBase {
|
|||
'cardinality_number' => '',
|
||||
];
|
||||
$this->drupalGet($field_edit_path);
|
||||
$this->submitForm($edit, 'Save field settings');
|
||||
$this->submitForm($edit, 'Save');
|
||||
$this->assertSession()->pageTextContains('Number of values is required.');
|
||||
|
||||
// Submit a custom number.
|
||||
|
@ -300,8 +300,7 @@ class ManageFieldsFunctionalTest extends BrowserTestBase {
|
|||
'cardinality_number' => 6,
|
||||
];
|
||||
$this->drupalGet($field_edit_path);
|
||||
$this->submitForm($edit, 'Save field settings');
|
||||
$this->assertSession()->pageTextContains('Updated field Body field settings.');
|
||||
$this->submitForm($edit, 'Save');
|
||||
$this->drupalGet($field_edit_path);
|
||||
$this->assertSession()->fieldValueEquals('cardinality', 'number');
|
||||
$this->assertSession()->fieldValueEquals('cardinality_number', 6);
|
||||
|
@ -324,7 +323,7 @@ class ManageFieldsFunctionalTest extends BrowserTestBase {
|
|||
'cardinality_number' => 1,
|
||||
];
|
||||
$this->drupalGet($field_edit_path);
|
||||
$this->submitForm($edit, 'Save field settings');
|
||||
$this->submitForm($edit, 'Save');
|
||||
$this->assertSession()->pageTextContains("There is 1 entity with 2 or more values in this field");
|
||||
|
||||
// Create a second entity with three values.
|
||||
|
@ -337,8 +336,7 @@ class ManageFieldsFunctionalTest extends BrowserTestBase {
|
|||
'cardinality' => FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED,
|
||||
];
|
||||
$this->drupalGet($field_edit_path);
|
||||
$this->submitForm($edit, 'Save field settings');
|
||||
$this->assertSession()->pageTextContains('Updated field Body field settings.');
|
||||
$this->submitForm($edit, 'Save');
|
||||
$this->drupalGet($field_edit_path);
|
||||
$this->assertSession()->fieldValueEquals('cardinality', FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED);
|
||||
$this->assertSession()->fieldValueEquals('cardinality_number', 1);
|
||||
|
@ -350,7 +348,7 @@ class ManageFieldsFunctionalTest extends BrowserTestBase {
|
|||
'cardinality_number' => 1,
|
||||
];
|
||||
$this->drupalGet($field_edit_path);
|
||||
$this->submitForm($edit, 'Save field settings');
|
||||
$this->submitForm($edit, 'Save');
|
||||
$this->assertSession()->pageTextContains("There are 2 entities with 2 or more values in this field");
|
||||
|
||||
$edit = [
|
||||
|
@ -358,7 +356,7 @@ class ManageFieldsFunctionalTest extends BrowserTestBase {
|
|||
'cardinality_number' => 2,
|
||||
];
|
||||
$this->drupalGet($field_edit_path);
|
||||
$this->submitForm($edit, 'Save field settings');
|
||||
$this->submitForm($edit, 'Save');
|
||||
$this->assertSession()->pageTextContains("There is 1 entity with 3 or more values in this field");
|
||||
|
||||
$edit = [
|
||||
|
@ -366,7 +364,7 @@ class ManageFieldsFunctionalTest extends BrowserTestBase {
|
|||
'cardinality_number' => 3,
|
||||
];
|
||||
$this->drupalGet($field_edit_path);
|
||||
$this->submitForm($edit, 'Save field settings');
|
||||
$this->submitForm($edit, 'Save');
|
||||
|
||||
// Test the cardinality validation is not access sensitive.
|
||||
|
||||
|
@ -375,7 +373,7 @@ class ManageFieldsFunctionalTest extends BrowserTestBase {
|
|||
'cardinality' => (string) FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED,
|
||||
];
|
||||
$this->drupalGet($field_edit_path);
|
||||
$this->submitForm($edit, 'Save field settings');
|
||||
$this->submitForm($edit, 'Save');
|
||||
$node = $this->drupalCreateNode([
|
||||
'private' => TRUE,
|
||||
'uid' => 0,
|
||||
|
@ -396,21 +394,21 @@ class ManageFieldsFunctionalTest extends BrowserTestBase {
|
|||
'cardinality_number' => 2,
|
||||
];
|
||||
$this->drupalGet($field_edit_path);
|
||||
$this->submitForm($edit, 'Save field settings');
|
||||
$this->submitForm($edit, 'Save');
|
||||
$this->assertSession()->pageTextContains("There are 2 entities with 3 or more values in this field");
|
||||
$edit = [
|
||||
'cardinality' => 'number',
|
||||
'cardinality_number' => 3,
|
||||
];
|
||||
$this->drupalGet($field_edit_path);
|
||||
$this->submitForm($edit, 'Save field settings');
|
||||
$this->submitForm($edit, 'Save');
|
||||
$this->assertSession()->pageTextContains("There is 1 entity with 4 or more values in this field");
|
||||
$edit = [
|
||||
'cardinality' => 'number',
|
||||
'cardinality_number' => 4,
|
||||
];
|
||||
$this->drupalGet($field_edit_path);
|
||||
$this->submitForm($edit, 'Save field settings');
|
||||
$this->submitForm($edit, 'Save');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -490,7 +488,7 @@ class ManageFieldsFunctionalTest extends BrowserTestBase {
|
|||
'field_name' => $field_exceed_max_length_input,
|
||||
];
|
||||
$this->drupalGet('admin/structure/types/manage/' . $this->contentType . '/fields/add-field');
|
||||
$this->submitForm($edit, 'Save and continue');
|
||||
$this->submitForm($edit, 'Continue');
|
||||
$this->assertSession()->pageTextContains('Machine-readable name cannot be longer than 22 characters but is currently 23 characters long.');
|
||||
|
||||
// Create a valid field.
|
||||
|
@ -642,14 +640,14 @@ class ManageFieldsFunctionalTest extends BrowserTestBase {
|
|||
$edit['field_name'] = 'title';
|
||||
$bundle_path = 'admin/structure/types/manage/' . $this->contentType;
|
||||
$this->drupalGet("{$bundle_path}/fields/add-field");
|
||||
$this->submitForm($edit, 'Save and continue');
|
||||
$this->submitForm($edit, 'Continue');
|
||||
$this->assertSession()->pageTextContains('The machine-readable name is already in use. It must be unique.');
|
||||
|
||||
// Try with a base field.
|
||||
$edit['field_name'] = 'sticky';
|
||||
$bundle_path = 'admin/structure/types/manage/' . $this->contentType;
|
||||
$this->drupalGet("{$bundle_path}/fields/add-field");
|
||||
$this->submitForm($edit, 'Save and continue');
|
||||
$this->submitForm($edit, 'Continue');
|
||||
$this->assertSession()->pageTextContains('The machine-readable name is already in use. It must be unique.');
|
||||
}
|
||||
|
||||
|
@ -755,11 +753,17 @@ class ManageFieldsFunctionalTest extends BrowserTestBase {
|
|||
public function testDuplicateFieldName() {
|
||||
// field_tags already exists, so we're expecting an error when trying to
|
||||
// create a new field with the same name.
|
||||
$url = 'admin/structure/types/manage/' . $this->contentType;
|
||||
$this->fieldUIAddNewField($url, 'tags', $this->randomMachineName(), 'entity_reference', [], [], FALSE);
|
||||
$url = 'admin/structure/types/manage/' . $this->contentType . '/fields/add-field';
|
||||
$this->drupalGet($url);
|
||||
$edit = [
|
||||
'label' => $this->randomMachineName(),
|
||||
'field_name' => 'tags',
|
||||
'new_storage_type' => 'boolean',
|
||||
];
|
||||
$this->submitForm($edit, 'Continue');
|
||||
|
||||
$this->assertSession()->pageTextContains('The machine-readable name is already in use. It must be unique.');
|
||||
$this->assertSession()->addressEquals($url . '/fields/add-field');
|
||||
$this->assertSession()->addressEquals($url);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -770,7 +774,7 @@ class ManageFieldsFunctionalTest extends BrowserTestBase {
|
|||
'query' => ['destinations' => ['http://example.com']],
|
||||
];
|
||||
$this->drupalGet('admin/structure/types/manage/article/fields/node.article.body/storage', $options);
|
||||
$this->submitForm([], 'Save field settings');
|
||||
$this->submitForm([], 'Save');
|
||||
// The external redirect should not fire.
|
||||
$this->assertSession()->addressEquals('admin/structure/types/manage/article/fields/node.article.body/storage?destinations%5B0%5D=http%3A//example.com');
|
||||
$this->assertSession()->statusCodeEquals(200);
|
||||
|
|
|
@ -2,7 +2,11 @@
|
|||
|
||||
namespace Drupal\Tests\field_ui\Functional;
|
||||
|
||||
use Drupal\field\Entity\FieldConfig;
|
||||
use Drupal\field\Entity\FieldStorageConfig;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
use Drupal\Tests\field_ui\Traits\FieldUiTestTrait;
|
||||
use Drupal\user\Entity\User;
|
||||
|
||||
// cSpell:ignore downlander
|
||||
|
||||
|
@ -13,10 +17,12 @@ use Drupal\Tests\BrowserTestBase;
|
|||
*/
|
||||
class ManageFieldsTest extends BrowserTestBase {
|
||||
|
||||
use FieldUiTestTrait;
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $modules = [
|
||||
'field_test',
|
||||
'field_ui',
|
||||
'field_ui_test',
|
||||
'node',
|
||||
|
@ -28,13 +34,20 @@ class ManageFieldsTest extends BrowserTestBase {
|
|||
*/
|
||||
protected $defaultTheme = 'stark';
|
||||
|
||||
/**
|
||||
* A user with permission to administer node fields, etc.
|
||||
*
|
||||
* @var \Drupal\user\UserInterface
|
||||
*/
|
||||
protected $adminUser;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp(): void {
|
||||
parent::setUp();
|
||||
$account = $this->drupalCreateUser(['administer node fields']);
|
||||
$this->drupalLogin($account);
|
||||
$this->adminUser = $this->drupalCreateUser(['administer node fields']);
|
||||
$this->drupalLogin($this->adminUser);
|
||||
$this->config('system.logging')
|
||||
->set('error_level', ERROR_REPORTING_DISPLAY_ALL)
|
||||
->save();
|
||||
|
@ -112,4 +125,182 @@ class ManageFieldsTest extends BrowserTestBase {
|
|||
$this->assertStringContainsString($allowed_bundles_text, $element->getText());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests adding a field.
|
||||
*/
|
||||
public function testAddField() {
|
||||
$page = $this->getSession()->getPage();
|
||||
$type = $this->drupalCreateContentType([
|
||||
'name' => 'Article',
|
||||
'type' => 'article',
|
||||
]);
|
||||
|
||||
// Create a new field without actually saving it.
|
||||
$this->fieldUIAddNewField('admin/structure/types/manage/' . $type->id(), 'test_field', 'Test field', 'test_field', [], [], FALSE);
|
||||
// Assert that the field was not created.
|
||||
$this->assertNull(FieldStorageConfig::loadByName('node', "field_test_field"));
|
||||
|
||||
$this->drupalGet('/admin/structure/types/manage/' . $type->id() . '/fields/add-field');
|
||||
$edit = [
|
||||
'label' => 'Test field',
|
||||
'field_name' => 'test_field',
|
||||
'new_storage_type' => 'test_field',
|
||||
];
|
||||
$this->submitForm($edit, 'Continue');
|
||||
$this->assertSession()->statusMessageNotContains('Saved');
|
||||
|
||||
// Change the storage form values.
|
||||
$edit = ['cardinality_number' => 5];
|
||||
$this->submitForm($edit, 'Continue');
|
||||
$this->assertSession()->statusMessageNotContains('Saved');
|
||||
|
||||
// Go back to the field storage form.
|
||||
$this->drupalGet('/admin/structure/types/manage/' . $type->id() . '/add-storage/node/field_test_field');
|
||||
// Assert that the form values persist.
|
||||
$this->assertEquals(5, $page->findField('cardinality_number')->getValue());
|
||||
|
||||
// Try creating a field with the same machine name.
|
||||
$this->drupalGet('/admin/structure/types/manage/' . $type->id() . '/fields/add-field');
|
||||
$edit = [
|
||||
'label' => 'Test field',
|
||||
'field_name' => 'test_field',
|
||||
'new_storage_type' => 'test_field',
|
||||
];
|
||||
$this->submitForm($edit, 'Continue');
|
||||
// Assert that the values in the field storage form are reset.
|
||||
$this->assertEquals(1, $page->findField('cardinality_number')->getValue());
|
||||
|
||||
// Assert that the field is created with the new settings.
|
||||
$this->submitForm([], 'Continue');
|
||||
$this->assertSession()->statusMessageNotContains('Saved');
|
||||
$this->submitForm([], 'Save settings');
|
||||
$this->assertSession()->statusMessageContains('Saved');
|
||||
|
||||
$this->assertEquals(1, FieldStorageConfig::loadByName('node', 'field_test_field')->getCardinality());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests multiple users adding a field with the same name.
|
||||
*/
|
||||
public function testAddFieldWithMultipleUsers() {
|
||||
$page = $this->getSession()->getPage();
|
||||
// Create two users.
|
||||
$user1 = $this->drupalCreateUser(['administer node fields']);
|
||||
$user2 = $this->drupalCreateUser(['administer node fields']);
|
||||
|
||||
$node_type = $this->drupalCreateContentType();
|
||||
$bundle_path = '/admin/structure/types/manage/' . $node_type->id();
|
||||
|
||||
// Start adding a field as user 1, stop prior to saving, but keep the URL.
|
||||
$this->drupalLogin($user1);
|
||||
$this->drupalGet($bundle_path . '/fields/add-field');
|
||||
$edit = [
|
||||
'label' => 'Test field',
|
||||
'field_name' => 'test_field',
|
||||
'new_storage_type' => 'test_field',
|
||||
];
|
||||
$this->submitForm($edit, 'Continue');
|
||||
// Make changes to the storage form.
|
||||
$edit = ['cardinality_number' => 5];
|
||||
$storage_form_url = $this->getUrl();
|
||||
$this->submitForm($edit, 'Continue');
|
||||
$this->drupalLogout();
|
||||
|
||||
// Actually add a field as user 2.
|
||||
$this->drupalLogin($user2);
|
||||
$this->drupalGet($bundle_path . '/fields/add-field');
|
||||
$edit = [
|
||||
'label' => 'Test field',
|
||||
'field_name' => 'test_field',
|
||||
'new_storage_type' => 'test_field',
|
||||
];
|
||||
$this->submitForm($edit, 'Continue');
|
||||
$allowed_no_of_values = $page->findField('cardinality_number')->getValue();
|
||||
// Assert that the changes made by any user do not affect other users until
|
||||
// the field is saved.
|
||||
$this->assertEquals(1, $allowed_no_of_values);
|
||||
$this->submitForm(['cardinality_number' => 2], 'Continue');
|
||||
$this->submitForm([], 'Save settings');
|
||||
$this->assertSession()->pageTextContains("Saved Test field configuration.");
|
||||
$this->drupalLogout();
|
||||
|
||||
// Continue adding a field as user 1, using the URL saved previously.
|
||||
$this->drupalLogin($user1);
|
||||
$this->drupalGet($storage_form_url);
|
||||
$this->submitForm([], 'Continue');
|
||||
// Assert that the user can go on with configuring a field with a machine
|
||||
// that is already taken.
|
||||
$this->assertSession()->pageTextNotContains('error');
|
||||
$this->submitForm([], 'Save settings');
|
||||
// An error is thrown only after the final 'Save'.
|
||||
$this->assertSession()->statusMessageContains("An error occurred while saving the field: 'field_storage_config' entity with ID 'node.field_test_field' already exists.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests editing field when the field exists in temp store.
|
||||
*/
|
||||
public function testEditFieldWithLeftOverFieldInTempStore() {
|
||||
$user = $this->drupalCreateUser(['administer node fields']);
|
||||
|
||||
$node_type = $this->drupalCreateContentType();
|
||||
$bundle_path = '/admin/structure/types/manage/' . $node_type->id();
|
||||
|
||||
// Start adding a field but stop prior to saving.
|
||||
$this->drupalLogin($user);
|
||||
$this->drupalGet($bundle_path . '/fields/add-field');
|
||||
$edit = [
|
||||
'label' => 'Test field',
|
||||
'field_name' => 'test_field',
|
||||
'new_storage_type' => 'test_field',
|
||||
];
|
||||
$this->submitForm($edit, 'Continue');
|
||||
|
||||
/** @var \Drupal\field\FieldStorageConfigInterface $storage */
|
||||
$storage = $this->container->get('entity_type.manager')
|
||||
->getStorage('field_storage_config')
|
||||
->create([
|
||||
'type' => 'test_field',
|
||||
'field_name' => 'test_field',
|
||||
'entity_type' => 'node',
|
||||
]);
|
||||
$storage->save();
|
||||
|
||||
$this->container->get('entity_type.manager')
|
||||
->getStorage('field_config')
|
||||
->create([
|
||||
'field_storage' => $storage,
|
||||
'bundle' => $node_type->id(),
|
||||
'entity_type' => 'node',
|
||||
])
|
||||
->save();
|
||||
|
||||
$this->drupalGet("$bundle_path/fields/node.{$node_type->id()}.test_field/storage");
|
||||
$this->submitForm([], 'Save');
|
||||
$this->assertSession()->statusMessageContains('Your settings have been saved.', 'status');
|
||||
|
||||
$this->drupalGet("$bundle_path/fields/node.{$node_type->id()}.test_field");
|
||||
$this->submitForm([], 'Save settings');
|
||||
$this->assertSession()->statusMessageContains('Saved test_field configuration.', 'status');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests creating entity reference field to non-bundleable entity type.
|
||||
*/
|
||||
public function testEntityReferenceToNonBundleableEntity() {
|
||||
$type = $this->drupalCreateContentType([
|
||||
'name' => 'kittens',
|
||||
'type' => 'kittens',
|
||||
]);
|
||||
$bundle_path = 'admin/structure/types/manage/' . $type->id();
|
||||
$field_name = 'field_user_reference';
|
||||
|
||||
$field_edit = [
|
||||
'set_default_value' => '1',
|
||||
"default_value_input[$field_name][0][target_id]" => $this->adminUser->label() . ' (' . $this->adminUser->id() . ')',
|
||||
];
|
||||
$this->fieldUIAddNewField($bundle_path, 'user_reference', NULL, 'field_ui:entity_reference:user', [], $field_edit);
|
||||
$field = FieldConfig::loadByName('node', 'kittens', $field_name);
|
||||
$this->assertEquals([['target_id' => $this->adminUser->id()]], $field->getDefaultValue(User::create(['name' => '1337'])));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -180,7 +180,7 @@ class ManageFieldsTest extends WebDriverTestBase {
|
|||
$page->fillField('label', $field_name);
|
||||
|
||||
// Test validation.
|
||||
$page->pressButton('Save and continue');
|
||||
$page->pressButton('Continue');
|
||||
$assert_session->pageTextContains('You need to select a field type.');
|
||||
$assert_session->elementExists('css', '[name="new_storage_type"].error');
|
||||
$assert_session->pageTextNotContains('Choose an option below');
|
||||
|
@ -190,7 +190,7 @@ class ManageFieldsTest extends WebDriverTestBase {
|
|||
$assert_session->assertWaitOnAjaxRequest();
|
||||
$this->assertTrue($assert_session->elementExists('css', '[name="new_storage_type"][value="number"]')->isSelected());
|
||||
$assert_session->pageTextContains('Choose an option below');
|
||||
$page->pressButton('Save and continue');
|
||||
$page->pressButton('Continue');
|
||||
$assert_session->pageTextContains('You need to select a field type.');
|
||||
$assert_session->elementNotExists('css', '[name="new_storage_type"].error');
|
||||
$assert_session->elementExists('css', '[name="group_field_options_wrapper"].error');
|
||||
|
@ -211,9 +211,12 @@ class ManageFieldsTest extends WebDriverTestBase {
|
|||
$this->assertNotEmpty($text_plain = $page->find('xpath', '//*[text() = "Text (plain)"]')->getParent());
|
||||
$text_plain->click();
|
||||
$this->assertTrue($assert_session->elementExists('css', '[name="group_field_options_wrapper"][value="string"]')->isSelected());
|
||||
|
||||
$page->pressButton('Save and continue');
|
||||
$assert_session->pageTextContains('Your settings have been saved.');
|
||||
$page->pressButton('Continue');
|
||||
$this->assertMatchesRegularExpression('/.*article\/add-storage\/node\/field_test_field_1.*/', $this->getUrl());
|
||||
$page->pressButton('Continue');
|
||||
$this->assertMatchesRegularExpression('/.*article\/add-field\/node\/field_test_field_1.*/', $this->getUrl());
|
||||
$page->pressButton('Save settings');
|
||||
$assert_session->pageTextContains('Saved ' . $field_name . ' configuration.');
|
||||
$this->assertNotNull($field_storage = FieldStorageConfig::loadByName('node', "field_$field_name"));
|
||||
$this->assertEquals('string', $field_storage->getType());
|
||||
|
||||
|
@ -237,8 +240,12 @@ class ManageFieldsTest extends WebDriverTestBase {
|
|||
$this->assertTrue($assert_session->elementExists('css', '[name="new_storage_type"][value="test_field"]')->isSelected());
|
||||
$assert_session->pageTextNotContains('Choose an option below');
|
||||
|
||||
$page->pressButton('Save and continue');
|
||||
$assert_session->pageTextContains('Your settings have been saved.');
|
||||
$page->pressButton('Continue');
|
||||
$this->assertMatchesRegularExpression('/.*article\/add-storage\/node\/field_test_field_2.*/', $this->getUrl());
|
||||
$page->pressButton('Continue');
|
||||
$this->assertMatchesRegularExpression('/.*article\/add-field\/node\/field_test_field_2.*/', $this->getUrl());
|
||||
$page->pressButton('Save settings');
|
||||
$assert_session->pageTextContains('Saved ' . $field_name . ' configuration.');
|
||||
$this->assertNotNull($field_storage = FieldStorageConfig::loadByName('node', "field_$field_name"));
|
||||
$this->assertEquals('test_field', $field_storage->getType());
|
||||
}
|
||||
|
|
|
@ -61,17 +61,11 @@ trait FieldUiJSTestTrait {
|
|||
$this->assertTrue($field_field_name->isVisible());
|
||||
$field_field_name->setValue($field_name);
|
||||
|
||||
$page->findButton('Save and continue')->click();
|
||||
$page->findButton('Continue')->click();
|
||||
$assert_session->waitForText("These settings apply to the $label field everywhere it is used.");
|
||||
if ($save_settings) {
|
||||
$breadcrumb_link = $page->findLink($label);
|
||||
|
||||
// Test breadcrumb.
|
||||
$this->assertTrue($breadcrumb_link->isVisible());
|
||||
|
||||
// Second step: 'Storage settings' form.
|
||||
$page->findButton('Save field settings')->click();
|
||||
$assert_session->pageTextContains("Updated field $label field settings.");
|
||||
$page->findButton('Continue')->click();
|
||||
|
||||
// Third step: 'Field settings' form.
|
||||
$page->findButton('Save settings')->click();
|
||||
|
|
|
@ -42,12 +42,12 @@ trait FieldUiTestTrait {
|
|||
// page before calling this method.
|
||||
if ($bundle_path !== NULL) {
|
||||
$bundle_path = "$bundle_path/fields/add-field";
|
||||
}
|
||||
|
||||
// First step: 'Add field' page.
|
||||
if ($bundle_path !== NULL) {
|
||||
// First step: 'Add field' page.
|
||||
$this->drupalGet($bundle_path);
|
||||
}
|
||||
else {
|
||||
$bundle_path = $this->getUrl();
|
||||
}
|
||||
|
||||
try {
|
||||
// First check if the passed in field type is not part of a group.
|
||||
|
@ -76,27 +76,25 @@ trait FieldUiTestTrait {
|
|||
];
|
||||
}
|
||||
}
|
||||
$this->submitForm($initial_edit, 'Save and continue');
|
||||
$this->submitForm($initial_edit, 'Continue');
|
||||
// Assert that the field is not created.
|
||||
$this->assertFieldDoesNotExist($bundle_path, $label);
|
||||
if ($save_settings) {
|
||||
$this->assertSession()->pageTextContains("These settings apply to the $label field everywhere it is used.");
|
||||
// Test Breadcrumbs.
|
||||
$this->getSession()->getPage()->findLink($label);
|
||||
|
||||
// Second step: 'Storage settings' form.
|
||||
$this->submitForm($storage_edit, 'Save field settings');
|
||||
$this->assertSession()
|
||||
->pageTextContains("Updated field $label field settings.");
|
||||
$this->submitForm($storage_edit, 'Continue');
|
||||
// Assert that the field is not created.
|
||||
$this->assertFieldDoesNotExist($bundle_path, $label);
|
||||
|
||||
// Third step: 'Field settings' form.
|
||||
$this->submitForm($field_edit, 'Save settings');
|
||||
$this->assertSession()->pageTextContains("Saved $label configuration.");
|
||||
|
||||
// Check that the field appears in the overview form.
|
||||
$xpath = $this->assertSession()
|
||||
->buildXPathQuery("//table[@id=\"field-overview\"]//tr/td[1 and text() = :label]", [
|
||||
':label' => $label,
|
||||
]);
|
||||
$this->assertSession()->elementExists('xpath', $xpath);
|
||||
$this->assertFieldExistsOnOverview($label);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -205,4 +203,53 @@ trait FieldUiTestTrait {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the field doesn't exist in the overview form.
|
||||
*
|
||||
* @param string $bundle_path
|
||||
* The bundle path.
|
||||
* @param string $label
|
||||
* The field label.
|
||||
*/
|
||||
protected function assertFieldDoesNotExist(string $bundle_path, string $label) {
|
||||
$original_url = $this->getUrl();
|
||||
$this->drupalGet(explode('/fields', $bundle_path)[0] . '/fields');
|
||||
$this->assertFieldDoesNotExistOnOverview($label);
|
||||
$this->drupalGet($original_url);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the field appears on the overview form.
|
||||
*
|
||||
* @param string $label
|
||||
* The field label.
|
||||
*
|
||||
* @throws \Behat\Mink\Exception\ElementNotFoundException
|
||||
*/
|
||||
protected function assertFieldExistsOnOverview(string $label) {
|
||||
$xpath = $this->assertSession()
|
||||
->buildXPathQuery("//table[@id=\"field-overview\"]//tr/td[1 and text() = :label]", [
|
||||
':label' => $label,
|
||||
]);
|
||||
$element = $this->getSession()->getPage()->find('xpath', $xpath);
|
||||
if ($element === NULL) {
|
||||
throw new ElementNotFoundException($this->getSession()->getDriver(), 'form field', 'label', $label);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the field does not appear on the overview form.
|
||||
*
|
||||
* @param string $label
|
||||
* The field label.
|
||||
*/
|
||||
protected function assertFieldDoesNotExistOnOverview(string $label) {
|
||||
$xpath = $this->assertSession()
|
||||
->buildXPathQuery("//table[@id=\"field-overview\"]//tr/td[1 and text() = :label]", [
|
||||
':label' => $label,
|
||||
]);
|
||||
$element = $this->getSession()->getPage()->find('xpath', $xpath);
|
||||
$this->assertSession()->assert($element === NULL, sprintf('A field "%s" appears on this page, but it should not.', $label));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
namespace Drupal\Tests\field_ui\Unit;
|
||||
|
||||
use Drupal\Core\Entity\EntityDisplayRepositoryInterface;
|
||||
use Drupal\Core\TempStore\PrivateTempStore;
|
||||
use Drupal\field_ui\Form\FieldConfigEditForm;
|
||||
use Drupal\Tests\UnitTestCase;
|
||||
|
||||
|
@ -27,7 +29,9 @@ class FieldConfigEditFormTest extends UnitTestCase {
|
|||
|
||||
$entity_type_bundle_info = $this->createMock('\Drupal\Core\Entity\EntityTypeBundleInfoInterface');
|
||||
$typed_data = $this->createMock('\Drupal\Core\TypedData\TypedDataManagerInterface');
|
||||
$this->fieldConfigEditForm = new FieldConfigEditForm($entity_type_bundle_info, $typed_data);
|
||||
$temp_store = $this->createMock(PrivateTempStore::class);
|
||||
$entity_display_repository = $this->createMock(EntityDisplayRepositoryInterface::class);
|
||||
$this->fieldConfigEditForm = new FieldConfigEditForm($entity_type_bundle_info, $typed_data, $entity_display_repository, $temp_store);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -260,7 +260,7 @@ class FileFieldWidgetTest extends FileFieldTestBase {
|
|||
// Change the field setting to make its files private, and upload a file.
|
||||
$edit = ['settings[uri_scheme]' => 'private'];
|
||||
$this->drupalGet("admin/structure/types/manage/{$type_name}/fields/{$field_id}/storage");
|
||||
$this->submitForm($edit, 'Save field settings');
|
||||
$this->submitForm($edit, 'Save');
|
||||
$nid = $this->uploadNodeFile($test_file, $field_name, $type_name);
|
||||
$node = $node_storage->loadUnchanged($nid);
|
||||
$node_file = File::load($node->{$field_name}->target_id);
|
||||
|
|
|
@ -337,7 +337,7 @@ class ImageFieldDisplayTest extends ImageFieldTestBase {
|
|||
$this->drupalGet('admin/structure/types/manage/article/fields/node.article.' . $field_name . '/storage');
|
||||
$this->submitForm([
|
||||
'cardinality' => FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED,
|
||||
], 'Save field settings');
|
||||
], 'Save');
|
||||
$edit = [
|
||||
'files[' . $field_name . '_1][]' => \Drupal::service('file_system')->realpath($test_image->uri),
|
||||
];
|
||||
|
@ -504,7 +504,7 @@ class ImageFieldDisplayTest extends ImageFieldTestBase {
|
|||
'settings[default_image][title]' => $title,
|
||||
];
|
||||
$this->drupalGet("admin/structure/types/manage/article/fields/node.article.{$field_name}/storage");
|
||||
$this->submitForm($edit, 'Save field settings');
|
||||
$this->submitForm($edit, 'Save');
|
||||
// Clear field definition cache so the new default image is detected.
|
||||
\Drupal::service('entity_field.manager')->clearCachedFieldDefinitions();
|
||||
$field_storage = FieldStorageConfig::loadByName('node', $field_name);
|
||||
|
@ -560,7 +560,7 @@ class ImageFieldDisplayTest extends ImageFieldTestBase {
|
|||
// Can't use fillField cause Mink can't fill hidden fields.
|
||||
$this->drupalGet("admin/structure/types/manage/article/fields/node.article.$field_name/storage");
|
||||
$this->getSession()->getPage()->find('css', 'input[name="settings[default_image][uuid][fids]"]')->setValue(0);
|
||||
$this->getSession()->getPage()->pressButton('Save field settings');
|
||||
$this->getSession()->getPage()->pressButton('Save');
|
||||
|
||||
// Clear field definition cache so the new default image is detected.
|
||||
\Drupal::service('entity_field.manager')->clearCachedFieldDefinitions();
|
||||
|
@ -579,7 +579,7 @@ class ImageFieldDisplayTest extends ImageFieldTestBase {
|
|||
'settings[default_image][title]' => $title,
|
||||
];
|
||||
$this->drupalGet('admin/structure/types/manage/article/fields/node.article.' . $private_field_name . '/storage');
|
||||
$this->submitForm($edit, 'Save field settings');
|
||||
$this->submitForm($edit, 'Save');
|
||||
// Clear field definition cache so the new default image is detected.
|
||||
\Drupal::service('entity_field.manager')->clearCachedFieldDefinitions();
|
||||
|
||||
|
|
|
@ -196,7 +196,8 @@ class MediaUiFunctionalTest extends MediaFunctionalTestBase {
|
|||
$assert_session = $this->assertSession();
|
||||
|
||||
$this->drupalCreateContentType(['type' => 'page', 'name' => 'Page']);
|
||||
$this->fieldUIAddNewField('/admin/structure/types/manage/page', 'foo_field', 'Foo field', 'field_ui:entity_reference:media', [], [], FALSE);
|
||||
$this->createMediaType('image', ['id' => 'image', 'new_revision' => TRUE]);
|
||||
$this->fieldUIAddNewField('/admin/structure/types/manage/page', 'foo_field', 'Foo field', 'field_ui:entity_reference:media', [], ['settings[handler_settings][target_bundles][image]' => TRUE]);
|
||||
$this->drupalGet('/admin/structure/types/manage/page/display');
|
||||
$assert_session->fieldValueEquals('fields[field_foo_field][type]', 'entity_reference_entity_view');
|
||||
}
|
||||
|
@ -340,13 +341,11 @@ class MediaUiFunctionalTest extends MediaFunctionalTestBase {
|
|||
// settings form.
|
||||
// Using submitForm() to avoid dealing with JavaScript on the previous
|
||||
// page in the field creation.
|
||||
$this->fieldUIAddNewField("admin/structure/types/manage/{$content_type->id()}", 'media_reference', "Media (cardinality $cardinality)", 'field_ui:entity_reference:media', [], [], FALSE);
|
||||
$edit = [];
|
||||
$field_edit = [];
|
||||
foreach ($media_types as $type) {
|
||||
$edit["settings[handler_settings][target_bundles][$type]"] = TRUE;
|
||||
$field_edit["settings[handler_settings][target_bundles][$type]"] = TRUE;
|
||||
}
|
||||
$this->drupalGet("admin/structure/types/manage/{$content_type->id()}/fields/node.{$content_type->id()}.field_media_reference");
|
||||
$this->submitForm($edit, "Save settings");
|
||||
$this->fieldUIAddNewField("admin/structure/types/manage/{$content_type->id()}", 'media_reference', "Media (cardinality $cardinality)", 'field_ui:entity_reference:media', [], $field_edit);
|
||||
\Drupal::entityTypeManager()
|
||||
->getStorage('entity_form_display')
|
||||
->load('node.' . $content_type->id() . '.default')
|
||||
|
|
|
@ -70,8 +70,10 @@ class FieldUiIntegrationTest extends MediaLibraryTestBase {
|
|||
$this->assertNotNull($assert_session->waitForField('label'));
|
||||
$page->fillField('label', 'Shatner');
|
||||
$this->waitForText('field_shatner');
|
||||
$page->pressButton('Save and continue');
|
||||
$page->pressButton('Save field settings');
|
||||
$page->pressButton('Continue');
|
||||
$this->assertMatchesRegularExpression('/.*article\/add-storage\/node\/field_shatner.*/', $this->getUrl());
|
||||
$page->pressButton('Continue');
|
||||
$this->assertMatchesRegularExpression('/.*article\/add-field\/node\/field_shatner.*/', $this->getUrl());
|
||||
$assert_session->pageTextNotContains('Undefined index: target_bundles');
|
||||
$this->waitForFieldExists('Type One')->check();
|
||||
$this->assertElementExistsAfterWait('css', '[name="settings[handler_settings][target_bundles][type_one]"][checked="checked"]');
|
||||
|
|
|
@ -560,7 +560,7 @@ class NodeTranslationUITest extends ContentTranslationUITestBase {
|
|||
// details form element.
|
||||
$edit = ['cardinality_number' => 2];
|
||||
$this->drupalGet('admin/structure/types/manage/article/fields/node.article.field_image/storage');
|
||||
$this->submitForm($edit, 'Save field settings');
|
||||
$this->submitForm($edit, 'Save');
|
||||
|
||||
// Make the image field non-translatable.
|
||||
$edit = ['settings[node][article][fields][field_image]' => FALSE];
|
||||
|
|
|
@ -172,8 +172,8 @@ class NodeTypeTranslationTest extends BrowserTestBase {
|
|||
'new_storage_type' => 'email',
|
||||
'label' => 'Email',
|
||||
'field_name' => 'email',
|
||||
], 'Save and continue');
|
||||
$this->submitForm([], 'Save field settings');
|
||||
], 'Continue');
|
||||
$this->submitForm([], 'Continue');
|
||||
$this->submitForm([], 'Save settings');
|
||||
|
||||
$type = $this->randomMachineName(16);
|
||||
|
|
|
@ -373,7 +373,7 @@ class OptionsFieldUITest extends FieldTestBase {
|
|||
$add_button->click();
|
||||
$add_button->click();
|
||||
|
||||
$this->submitForm($input, 'Save field settings');
|
||||
$this->submitForm($input, 'Save');
|
||||
// Verify that the page does not have double escaped HTML tags.
|
||||
$this->assertSession()->responseNotContains('&lt;');
|
||||
|
||||
|
@ -406,8 +406,7 @@ class OptionsFieldUITest extends FieldTestBase {
|
|||
$this->drupalGet($this->adminPath);
|
||||
$page = $this->getSession()->getPage();
|
||||
$page->findButton('Add another item')->click();
|
||||
$this->submitForm($edit, 'Save field settings');
|
||||
$this->assertSession()->pageTextContains('Updated field ' . $this->fieldName . ' field settings.');
|
||||
$this->submitForm($edit, 'Save');
|
||||
|
||||
// Select a default value.
|
||||
$edit = [
|
||||
|
@ -469,7 +468,7 @@ class OptionsFieldUITest extends FieldTestBase {
|
|||
// Assert that the button is disabled again.
|
||||
$this->assertTrue($delete_button_0->hasAttribute('disabled'), 'Button is disabled');
|
||||
// Try to proceed without entering any value.
|
||||
$page->findButton('Save field settings')->click();
|
||||
$page->findButton('Save')->click();
|
||||
|
||||
if ($field_type == 'list_string') {
|
||||
// Asserting only name field as there is no value field for list_string.
|
||||
|
|
|
@ -78,7 +78,7 @@ class OptionsFloatFieldImportTest extends FieldTestBase {
|
|||
'settings[allowed_values][table][1][item][label]' => 'One',
|
||||
];
|
||||
$this->drupalGet($admin_path);
|
||||
$this->submitForm($edit, 'Save field settings');
|
||||
$this->submitForm($edit, 'Save');
|
||||
$field_storage = FieldStorageConfig::loadByName('node', $field_name);
|
||||
$this->assertSame($array = ['0' => 'Zero', '1' => 'One'], $field_storage->getSetting('allowed_values'));
|
||||
|
||||
|
|
|
@ -162,7 +162,7 @@ class OptionsFieldUITest extends WebDriverTestBase {
|
|||
$this->assertHasFocusByAttribute('name', $key_element_name);
|
||||
$this->assertAllowValuesRowCount($expected_rows);
|
||||
}
|
||||
$page->pressButton('Save field settings');
|
||||
$page->pressButton('Save');
|
||||
|
||||
// Test the order of the option list on node form.
|
||||
$this->drupalGet($this->nodeFormPath);
|
||||
|
@ -177,7 +177,7 @@ class OptionsFieldUITest extends WebDriverTestBase {
|
|||
// Change the order the items appear.
|
||||
$drag_handle->dragTo($target);
|
||||
$this->assertOrder(['Second', 'Third', 'First', ''], $is_string_option);
|
||||
$page->pressButton('Save field settings');
|
||||
$page->pressButton('Save');
|
||||
|
||||
$this->drupalGet($this->nodeFormPath);
|
||||
$this->assertNodeFormOrder(['- None -', 'Second', 'Third', 'First']);
|
||||
|
@ -191,7 +191,7 @@ class OptionsFieldUITest extends WebDriverTestBase {
|
|||
$page->pressButton('remove_row_button__1');
|
||||
$this->assertSession()->assertWaitOnAjaxRequest();
|
||||
$this->assertOrder(['Second', 'First', ''], $is_string_option);
|
||||
$page->pressButton('Save field settings');
|
||||
$page->pressButton('Save');
|
||||
|
||||
$this->drupalGet($this->nodeFormPath);
|
||||
$this->assertNodeFormOrder(['- None -', 'Second', 'First']);
|
||||
|
|
|
@ -157,7 +157,7 @@ class SearchPageCacheTagsTest extends BrowserTestBase {
|
|||
]);
|
||||
$this->drupalLogin($admin_user);
|
||||
|
||||
$this->fieldUIAddNewField($bundle_path, 'test__ref', 'Test label', 'entity_reference', [], [], FALSE);
|
||||
$this->fieldUIAddNewField($bundle_path, 'test__ref', 'Test label', 'entity_reference', [], ['settings[handler_settings][target_bundles][page]' => TRUE]);
|
||||
// Create a new node of our newly created node type and fill in the entity
|
||||
// reference field.
|
||||
$edit = [
|
||||
|
|
Loading…
Reference in New Issue