Core and composer updates

This commit is contained in:
Rob Davies 2017-07-03 16:47:07 +01:00
parent a82634bb98
commit 62cac30480
1118 changed files with 21770 additions and 6306 deletions

View file

@ -20,6 +20,12 @@ process:
- type
- widget_type
map:
userreference:
userreference_select: entity_reference
userreference_buttons: entity_reference
userreference_autocomplete: entity_reference
nodereference:
nodereference_select: entity_reference
number_integer:
number: integer
optionwidgets_select: list_integer
@ -40,12 +46,6 @@ process:
filefield:
imagefield_widget: image
filefield_widget: file
date:
date_select: datetime
datestamp:
date_select: datetime
datetime:
date_select: datetime
fr_phone:
phone_textfield: telephone
be_phone:
@ -122,5 +122,6 @@ process:
source:
- '@type'
- global_settings
- type
destination:
plugin: entity:field_storage_config

View file

@ -15,7 +15,7 @@ process:
# field migration.
field_type_exists:
-
plugin: migration
plugin: migration_lookup
migration: d6_field
source:
- field_name
@ -29,7 +29,7 @@ process:
entity_type: 'constants/entity_type'
bundle:
-
plugin: migration
plugin: migration_lookup
migration: d6_node_type
source: type_name
-
@ -37,7 +37,7 @@ process:
method: row
view_mode:
-
plugin: migration
plugin: migration_lookup
migration: d6_view_modes
source:
- view_mode
@ -163,6 +163,14 @@ process:
default: basic_string
int_phone:
default: basic_string
nodereference:
default: entity_reference_label
plain: entity_reference_label
full: entity_reference_entity_view
teaser: entity_reference_entity_view
userreference:
default: entity_reference_label
plain: entity_reference_label
-
plugin: field_type_defaults
"options/settings":
@ -173,6 +181,18 @@ process:
- module
- 'display_settings/format'
map:
nodereference:
default: { }
plain:
link: false
full:
view_mode: full
teaser:
view_mode: teaser
userreference:
default: { }
plain:
link: false
link:
default:
trim_length: '80'

View file

@ -14,7 +14,7 @@ process:
# field migration.
field_type_exists:
-
plugin: migration
plugin: migration_lookup
migration: d6_field
source:
- field_name
@ -29,7 +29,7 @@ process:
field_name: field_name
bundle:
-
plugin: migration
plugin: migration_lookup
migration: d6_node_type
source: type_name
-

View file

@ -16,7 +16,7 @@ process:
# field migration.
field_type_exists:
-
plugin: migration
plugin: migration_lookup
migration: d6_field
source:
- field_name
@ -29,7 +29,7 @@ process:
method: row
bundle:
-
plugin: migration
plugin: migration_lookup
migration: d6_node_type
source: type_name
-
@ -49,11 +49,14 @@ process:
email_textfield: email_default
date_select: datetime_default
date_text: datetime_default
date_popup: datetime_default
imagefield_widget: image_image
phone_textfield: telephone_default
optionwidgets_onoff: boolean_checkbox
optionwidgets_buttons: options_buttons
optionwidgets_select: options_select
nodereference_select: options_select
userreference_select: options_select
'options/settings':
-
plugin: field_instance_widget_settings

View file

@ -13,7 +13,7 @@ process:
# field migration.
field_type_exists:
-
plugin: migration
plugin: migration_lookup
migration: d7_field
source:
- field_name
@ -29,7 +29,7 @@ process:
bundle: bundle
view_mode:
-
plugin: migration
plugin: migration_lookup
migration: d7_view_modes
source:
- entity_type

View file

@ -14,7 +14,7 @@ process:
# field migration.
field_type_exists:
-
plugin: migration
plugin: migration_lookup
migration: d7_field
source:
- field_name

View file

@ -18,6 +18,7 @@ use Drupal\field\FieldStorageConfigInterface;
* id = "field_storage_config",
* label = @Translation("Field storage"),
* handlers = {
* "access" = "Drupal\field\FieldStorageConfigAccessControlHandler",
* "storage" = "Drupal\field\FieldStorageConfigStorage"
* },
* config_prefix = "storage",

View file

@ -2,13 +2,12 @@
namespace Drupal\field;
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Entity\EntityAccessControlHandler;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Session\AccountInterface;
/**
* Defines the access control handler for the field entity type.
* Defines the access control handler for the field config entity type.
*
* @see \Drupal\field\Entity\FieldConfig
*/
@ -18,16 +17,16 @@ class FieldConfigAccessControlHandler extends EntityAccessControlHandler {
* {@inheritdoc}
*/
protected function checkAccess(EntityInterface $entity, $operation, AccountInterface $account) {
if ($operation == 'delete') {
$field_storage_entity = $entity->getFieldStorageDefinition();
if ($field_storage_entity->isLocked()) {
return AccessResult::forbidden()->addCacheableDependency($field_storage_entity);
}
else {
return AccessResult::allowedIfHasPermission($account, 'administer ' . $entity->getTargetEntityTypeId() . ' fields')->addCacheableDependency($field_storage_entity);
}
}
return AccessResult::allowedIfHasPermission($account, 'administer ' . $entity->getTargetEntityTypeId() . ' fields');
// Delegate access control to the underlying field storage config entity:
// the field config entity merely handles configuration for a particular
// bundle of an entity type, the bulk of the logic and configuration is with
// the field storage config entity. Therefore, if an operation is allowed on
// a certain field storage config entity, it should also be allowed for all
// associated field config entities.
// @see \Drupal\Core\Field\FieldDefinitionInterface
/** \Drupal\field\FieldConfigInterface $entity */
$field_storage_entity = $entity->getFieldStorageDefinition();
return $field_storage_entity->access($operation, $account, TRUE);
}
}

View file

@ -0,0 +1,33 @@
<?php
namespace Drupal\field;
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Entity\EntityAccessControlHandler;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Session\AccountInterface;
/**
* Defines the access control handler for the field storage config entity type.
*
* @see \Drupal\field\Entity\FieldStorageConfig
*/
class FieldStorageConfigAccessControlHandler extends EntityAccessControlHandler {
/**
* {@inheritdoc}
*/
protected function checkAccess(EntityInterface $entity, $operation, AccountInterface $account) {
/** \Drupal\field\FieldStorageConfigInterface $entity */
if ($operation === 'delete') {
if ($entity->isLocked()) {
return AccessResult::forbidden()->addCacheableDependency($entity);
}
else {
return AccessResult::allowedIfHasPermission($account, 'administer ' . $entity->getTargetEntityTypeId() . ' fields')->addCacheableDependency($entity);
}
}
return AccessResult::allowedIfHasPermission($account, 'administer ' . $entity->getTargetEntityTypeId() . ' fields');
}
}

View file

@ -9,6 +9,7 @@ use Drupal\migrate\Plugin\MigrationInterface;
use Drupal\migrate\Plugin\migrate\process\StaticMap;
use Drupal\migrate\Row;
use Drupal\migrate_drupal\Plugin\MigrateCckFieldPluginManagerInterface;
use Drupal\migrate_drupal\Plugin\MigrateFieldPluginManagerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
@ -25,6 +26,13 @@ class FieldType extends StaticMap implements ContainerFactoryPluginInterface {
*/
protected $cckPluginManager;
/**
* The field plugin manager.
*
* @var \Drupal\migrate_drupal\Plugin\MigrateFieldPluginManagerInterface
*/
protected $fieldPluginManager;
/**
* The migration object.
*
@ -43,12 +51,15 @@ class FieldType extends StaticMap implements ContainerFactoryPluginInterface {
* The plugin definition.
* @param \Drupal\migrate_drupal\Plugin\MigrateCckFieldPluginManagerInterface $cck_plugin_manager
* The cckfield plugin manager.
* @param \Drupal\migrate_drupal\Plugin\MigrateFieldPluginManagerInterface $field_plugin_manager
* The field plugin manager.
* @param \Drupal\migrate\Plugin\MigrationInterface $migration
* The migration being run.
*/
public function __construct(array $configuration, $plugin_id, $plugin_definition, MigrateCckFieldPluginManagerInterface $cck_plugin_manager, MigrationInterface $migration = NULL) {
public function __construct(array $configuration, $plugin_id, $plugin_definition, MigrateCckFieldPluginManagerInterface $cck_plugin_manager, MigrateFieldPluginManagerInterface $field_plugin_manager, MigrationInterface $migration = NULL) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
$this->cckPluginManager = $cck_plugin_manager;
$this->fieldPluginManager = $field_plugin_manager;
$this->migration = $migration;
}
@ -61,6 +72,7 @@ class FieldType extends StaticMap implements ContainerFactoryPluginInterface {
$plugin_id,
$plugin_definition,
$container->get('plugin.manager.migrate.cckfield'),
$container->get('plugin.manager.migrate.field'),
$migration
);
}
@ -70,13 +82,18 @@ class FieldType extends StaticMap implements ContainerFactoryPluginInterface {
*/
public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) {
$field_type = is_array($value) ? $value[0] : $value;
try {
$plugin_id = $this->cckPluginManager->getPluginIdFromFieldType($field_type, [], $this->migration);
return $this->cckPluginManager->createInstance($plugin_id, [], $this->migration)->getFieldType($row);
$plugin_id = $this->fieldPluginManager->getPluginIdFromFieldType($field_type, [], $this->migration);
return $this->fieldPluginManager->createInstance($plugin_id, [], $this->migration)->getFieldType($row);
}
catch (PluginNotFoundException $e) {
return parent::transform($value, $migrate_executable, $row, $destination_property);
try {
$plugin_id = $this->cckPluginManager->getPluginIdFromFieldType($field_type, [], $this->migration);
return $this->cckPluginManager->createInstance($plugin_id, [], $this->migration)->getFieldType($row);
}
catch (PluginNotFoundException $e) {
return parent::transform($value, $migrate_executable, $row, $destination_property);
}
}
}

View file

@ -21,22 +21,29 @@ class FieldSettings extends ProcessPluginBase {
* Get the field default/mapped settings.
*/
public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) {
list($field_type, $global_settings) = $value;
return $this->getSettings($field_type, $global_settings);
// To maintain backwards compatibility, ensure that $value contains at least
// three elements.
if (count($value) == 2) {
$value[] = NULL;
}
list($field_type, $global_settings, $original_field_type) = $value;
return $this->getSettings($field_type, $global_settings, $original_field_type);
}
/**
* Merge the default D8 and specified D6 settings.
*
* @param string $field_type
* The field type.
* The destination field type.
* @param array $global_settings
* The field settings.
* @param string $original_field_type
* (optional) The original field type before migration.
*
* @return array
* A valid array of settings.
*/
public function getSettings($field_type, $global_settings) {
public function getSettings($field_type, $global_settings, $original_field_type = NULL) {
$max_length = isset($global_settings['max_length']) ? $global_settings['max_length'] : '';
$max_length = empty($max_length) ? 255 : $max_length;
$allowed_values = [];
@ -78,7 +85,12 @@ class FieldSettings extends ProcessPluginBase {
],
];
return isset($settings[$field_type]) ? $settings[$field_type] : [];
if ($original_field_type == 'userreference') {
return ['target_type' => 'user'];
}
else {
return isset($settings[$field_type]) ? $settings[$field_type] : [];
}
}
}

View file

@ -106,6 +106,13 @@ class EntityReferenceFieldTranslatedReferenceViewTest extends BrowserTestBase {
*/
protected $translatedLabel;
/**
* An user with permission to edit the referrer entity.
*
* @var \Drupal\user\UserInterface
*/
protected $webUser;
/**
* Modules to enable.
*
@ -134,6 +141,8 @@ class EntityReferenceFieldTranslatedReferenceViewTest extends BrowserTestBase {
$this->enableTranslation();
$this->setUpEntityReferenceField();
$this->createContent();
$this->webUser = $this->drupalCreateUser(['edit any ' . $this->referrerType->id() . ' content']);
}
/**
@ -143,14 +152,17 @@ class EntityReferenceFieldTranslatedReferenceViewTest extends BrowserTestBase {
// Create a translated referrer entity.
$this->referrerEntity = $this->createReferrerEntity();
$this->assertEntityReferenceDisplay();
$this->assertEntityReferenceFormDisplay();
// Disable translation for referrer content type.
$this->drupalLogin($this->rootUser);
$this->drupalPostForm('admin/config/regional/content-language', ['settings[node][referrer][translatable]' => FALSE], t('Save configuration'));
$this->drupalLogout();
// Create a referrer entity without translation.
$this->referrerEntity = $this->createReferrerEntity(FALSE);
$this->assertEntityReferenceDisplay();
$this->assertEntityReferenceFormDisplay();
}
/**
@ -170,6 +182,23 @@ class EntityReferenceFieldTranslatedReferenceViewTest extends BrowserTestBase {
$this->assertText($this->translatedLabel, 'The translated label of translated reference is displayed.');
}
/**
* Assert entity reference form display.
*/
protected function assertEntityReferenceFormDisplay() {
$this->drupalLogin($this->webUser);
$url = $this->referrerEntity->urlInfo('edit-form');
$translation_url = $this->referrerEntity->urlInfo('edit-form', ['language' => ConfigurableLanguage::load($this->translateToLangcode)]);
$this->drupalGet($url);
$this->assertSession()->fieldValueEquals('test_reference_field[0][target_id]', $this->originalLabel . ' (1)');
$this->assertSession()->fieldValueEquals('test_reference_field[1][target_id]', $this->labelOfNotTranslatedReference . ' (2)');
$this->drupalGet($translation_url);
$this->assertSession()->fieldValueEquals('test_reference_field[0][target_id]', $this->translatedLabel . ' (1)');
$this->assertSession()->fieldValueEquals('test_reference_field[1][target_id]', $this->labelOfNotTranslatedReference . ' (2)');
$this->drupalLogout();
}
/**
* Adds additional languages.
*/

View file

@ -163,6 +163,19 @@ class EntityReferenceFormatterTest extends EntityKernelTestBase {
}
}
/**
* Tests the merging of cache metadata.
*/
public function testCustomCacheTagFormatter() {
/** @var \Drupal\Core\Render\RendererInterface $renderer */
$renderer = $this->container->get('renderer');
$formatter = 'entity_reference_custom_cache_tag';
$build = $this->buildRenderArray([$this->referencedEntity], $formatter);
$renderer->renderRoot($build);
$this->assertTrue(in_array('custom_cache_tag', $build['#cache']['tags']));
}
/**
* Tests the ID formatter.
*/

View file

@ -12,6 +12,11 @@ use Drupal\Tests\migrate_drupal\Kernel\d6\MigrateDrupal6TestBase;
*/
class MigrateFieldFormatterSettingsTest extends MigrateDrupal6TestBase {
/**
* {@inheritdoc}
*/
public static $modules = ['menu_ui'];
/**
* {@inheritdoc}
*/
@ -193,6 +198,30 @@ class MigrateFieldFormatterSettingsTest extends MigrateDrupal6TestBase {
// Test hidden field.
$this->assertComponentNotExists('node.test_planet.teaser', 'field_test_text_single_checkbox');
// Test a node reference field, which should be migrated to an entity
// reference field.
$display = EntityViewDisplay::load('node.employee.default');
$component = $display->getComponent('field_company');
$this->assertInternalType('array', $component);
$this->assertSame('entity_reference_label', $component['type']);
// The default node reference formatter shows the referenced node's title
// as a link.
$this->assertTrue($component['settings']['link']);
$display = EntityViewDisplay::load('node.employee.teaser');
$component = $display->getComponent('field_company');
$this->assertInternalType('array', $component);
$this->assertSame('entity_reference_label', $component['type']);
// The plain node reference formatter shows the referenced node's title,
// unlinked.
$this->assertFalse($component['settings']['link']);
$component = $display->getComponent('field_commander');
$this->assertInternalType('array', $component);
$this->assertSame('entity_reference_label', $component['type']);
// The default user reference formatter links to the referenced user.
$this->assertTrue($component['settings']['link']);
}
}

View file

@ -14,6 +14,11 @@ use Drupal\node\Entity\Node;
*/
class MigrateFieldInstanceTest extends MigrateDrupal6TestBase {
/**
* {@inheritdoc}
*/
public static $modules = ['menu_ui'];
/**
* Tests migration of file variables to file.settings.yml.
*/
@ -96,6 +101,66 @@ class MigrateFieldInstanceTest extends MigrateDrupal6TestBase {
$this->assertIdentical('default link title', $entity->field_test_link->title, 'Field field_test_link default title is correct.');
$this->assertIdentical('https://www.drupal.org', $entity->field_test_link->url, 'Field field_test_link default title is correct.');
$this->assertIdentical([], $entity->field_test_link->options['attributes']);
// Test date field.
$field = FieldConfig::load('node.story.field_test_date');
$this->assertInstanceOf(FieldConfig::class, $field);
$this->assertSame('Date Field', $field->label());
$this->assertSame('An example date field.', $field->getDescription());
$expected = ['datetime_type' => 'datetime'];
$this->assertSame($expected, $field->getSettings());
$expected = [
[
'default_date_type' => 'relative',
'default_date' => 'blank',
],
];
$this->assertSame($expected, $field->getDefaultValueLiteral());
$this->assertTrue($field->isTranslatable());
// Test datetime field.
$field = FieldConfig::load('node.story.field_test_datetime');
$this->assertInstanceOf(FieldConfig::class, $field);
$this->assertSame('Datetime Field', $field->label());
$this->assertSame('An example datetime field.', $field->getDescription());
$expected = ['datetime_type' => 'datetime'];
$this->assertSame($expected, $field->getSettings());
$expected = [];
$this->assertSame($expected, $field->getDefaultValueLiteral());
$this->assertTrue($field->isTranslatable());
// Test datestamp field.
$field = FieldConfig::load('node.story.field_test_datestamp');
$this->assertInstanceOf(FieldConfig::class, $field);
$this->assertSame('Date Stamp Field', $field->label());
$this->assertSame('An example date stamp field.', $field->getDescription());
$expected = [];
$this->assertSame($expected, $field->getSettings());
$expected = [];
$this->assertSame($expected, $field->getDefaultValueLiteral());
$this->assertTrue($field->isTranslatable());
// Test a node reference field, migrated to entity reference.
$field = FieldConfig::load('node.employee.field_company');
$this->assertInstanceOf(FieldConfig::class, $field);
$this->assertSame('entity_reference', $field->getType());
$this->assertSame('Company', $field->label());
$this->assertSame('default:node', $field->getSetting('handler'));
$this->assertSame([], $field->getSetting('handler_settings'));
$this->assertSame('node', $field->getSetting('target_type'));
$this->assertSame([], $field->getDefaultValueLiteral());
$this->assertTrue($field->isTranslatable());
// Test a user reference field, migrated to entity reference.
$field = FieldConfig::load('node.employee.field_commander');
$this->assertInstanceOf(FieldConfig::class, $field);
$this->assertSame('entity_reference', $field->getType());
$this->assertSame('Commanding Officer', $field->label());
$this->assertSame('default:user', $field->getSetting('handler'));
$this->assertSame([], $field->getSetting('handler_settings'));
$this->assertSame('user', $field->getSetting('target_type'));
$this->assertSame([], $field->getDefaultValueLiteral());
$this->assertTrue($field->isTranslatable());
}
/**

View file

@ -27,81 +27,105 @@ class MigrateFieldTest extends MigrateDrupal6TestBase {
// Text field.
/** @var \Drupal\field\Entity\FieldStorageConfig $field_storage */
$field_storage = FieldStorageConfig::load('node.field_test');
$this->assertIdentical('text_long', $field_storage->getType());
$this->assertSame('text_long', $field_storage->getType());
// text_long fields do not have settings.
$this->assertIdentical([], $field_storage->getSettings());
$this->assertSame([], $field_storage->getSettings());
// Integer field.
$field_storage = FieldStorageConfig::load('node.field_test_two');
$this->assertIdentical("integer", $field_storage->getType(), t('Field type is @fieldtype. It should be integer.', ['@fieldtype' => $field_storage->getType()]));
$this->assertSame("integer", $field_storage->getType(), t('Field type is @fieldtype. It should be integer.', ['@fieldtype' => $field_storage->getType()]));
// Float field.
$field_storage = FieldStorageConfig::load('node.field_test_three');
$this->assertIdentical("decimal", $field_storage->getType(), t('Field type is @fieldtype. It should be decimal.', ['@fieldtype' => $field_storage->getType()]));
$this->assertSame("decimal", $field_storage->getType(), t('Field type is @fieldtype. It should be decimal.', ['@fieldtype' => $field_storage->getType()]));
// Link field.
$field_storage = FieldStorageConfig::load('node.field_test_link');
$this->assertIdentical("link", $field_storage->getType(), t('Field type is @fieldtype. It should be link.', ['@fieldtype' => $field_storage->getType()]));
$this->assertSame("link", $field_storage->getType(), t('Field type is @fieldtype. It should be link.', ['@fieldtype' => $field_storage->getType()]));
// File field.
$field_storage = FieldStorageConfig::load('node.field_test_filefield');
$this->assertIdentical("file", $field_storage->getType(), t('Field type is @fieldtype. It should be file.', ['@fieldtype' => $field_storage->getType()]));
$this->assertSame("file", $field_storage->getType(), t('Field type is @fieldtype. It should be file.', ['@fieldtype' => $field_storage->getType()]));
$field_storage = FieldStorageConfig::load('node.field_test_imagefield');
$this->assertIdentical("image", $field_storage->getType(), t('Field type is @fieldtype. It should be image.', ['@fieldtype' => $field_storage->getType()]));
$this->assertSame("image", $field_storage->getType(), t('Field type is @fieldtype. It should be image.', ['@fieldtype' => $field_storage->getType()]));
$settings = $field_storage->getSettings();
$this->assertIdentical('file', $settings['target_type']);
$this->assertIdentical('public', $settings['uri_scheme']);
$this->assertIdentical([], array_filter($settings['default_image']));
$this->assertSame('file', $settings['target_type']);
$this->assertSame('public', $settings['uri_scheme']);
$this->assertSame([], array_filter($settings['default_image']));
// Phone field.
$field_storage = FieldStorageConfig::load('node.field_test_phone');
$this->assertIdentical("telephone", $field_storage->getType(), t('Field type is @fieldtype. It should be telephone.', ['@fieldtype' => $field_storage->getType()]));
$this->assertSame("telephone", $field_storage->getType(), t('Field type is @fieldtype. It should be telephone.', ['@fieldtype' => $field_storage->getType()]));
// Date field.
$field_storage = FieldStorageConfig::load('node.field_test_datetime');
$this->assertIdentical("datetime", $field_storage->getType(), t('Field type is @fieldtype. It should be datetime.', ['@fieldtype' => $field_storage->getType()]));
$this->assertSame("datetime", $field_storage->getType(), t('Field type is @fieldtype. It should be datetime.', ['@fieldtype' => $field_storage->getType()]));
// Date fields.
$field_storage = FieldStorageConfig::load('node.field_test_datetime');
$this->assertSame("datetime", $field_storage->getType(), t('Field type is @fieldtype. It should be datetime.', ['@fieldtype' => $field_storage->getType()]));
$field_storage = FieldStorageConfig::load('node.field_test_datestamp');
$this->assertSame("timestamp", $field_storage->getType(), t('Field type is @fieldtype. It should be timestamp.', ['@fieldtype' => $field_storage->getType()]));
$field_storage = FieldStorageConfig::load('node.field_test_date');
$this->assertSame("datetime", $field_storage->getType(), t('Field type is @fieldtype. It should be datetime.', ['@fieldtype' => $field_storage->getType()]));
// Decimal field with radio buttons.
$field_storage = FieldStorageConfig::load('node.field_test_decimal_radio_buttons');
$this->assertIdentical("list_float", $field_storage->getType(), t('Field type is @fieldtype. It should be list_float.', ['@fieldtype' => $field_storage->getType()]));
$this->assertSame("list_float", $field_storage->getType(), t('Field type is @fieldtype. It should be list_float.', ['@fieldtype' => $field_storage->getType()]));
$this->assertNotNull($field_storage->getSetting('allowed_values')['1.2'], t('First allowed value key is set to 1.2'));
$this->assertNotNull($field_storage->getSetting('allowed_values')['2.1'], t('Second allowed value key is set to 2.1'));
$this->assertIdentical('1.2', $field_storage->getSetting('allowed_values')['1.2'], t('First allowed value is set to 1.2'));
$this->assertIdentical('2.1', $field_storage->getSetting('allowed_values')['2.1'], t('Second allowed value is set to 1.2'));
$this->assertSame('1.2', $field_storage->getSetting('allowed_values')['1.2'], t('First allowed value is set to 1.2'));
$this->assertSame('2.1', $field_storage->getSetting('allowed_values')['2.1'], t('Second allowed value is set to 1.2'));
// Email field.
$field_storage = FieldStorageConfig::load('node.field_test_email');
$this->assertSame("email", $field_storage->getType(), t('Field type is @fieldtype. It should be email.', ['@fieldtype' => $field_storage->getType()]));
// Float field with a single checkbox.
$field_storage = FieldStorageConfig::load('node.field_test_float_single_checkbox');
$this->assertIdentical("boolean", $field_storage->getType(), t('Field type is @fieldtype. It should be boolean.', ['@fieldtype' => $field_storage->getType()]));
$this->assertSame("boolean", $field_storage->getType(), t('Field type is @fieldtype. It should be boolean.', ['@fieldtype' => $field_storage->getType()]));
// Integer field with a select list.
$field_storage = FieldStorageConfig::load('node.field_test_integer_selectlist');
$this->assertIdentical("list_integer", $field_storage->getType(), t('Field type is @fieldtype. It should be list_integer.', ['@fieldtype' => $field_storage->getType()]));
$this->assertSame("list_integer", $field_storage->getType(), t('Field type is @fieldtype. It should be list_integer.', ['@fieldtype' => $field_storage->getType()]));
$this->assertNotNull($field_storage->getSetting('allowed_values')['1234'], t('First allowed value key is set to 1234'));
$this->assertNotNull($field_storage->getSetting('allowed_values')['2341'], t('Second allowed value key is set to 2341'));
$this->assertNotNull($field_storage->getSetting('allowed_values')['3412'], t('Third allowed value key is set to 3412'));
$this->assertNotNull($field_storage->getSetting('allowed_values')['4123'], t('Fourth allowed value key is set to 4123'));
$this->assertIdentical('1234', $field_storage->getSetting('allowed_values')['1234'], t('First allowed value is set to 1234'));
$this->assertIdentical('2341', $field_storage->getSetting('allowed_values')['2341'], t('Second allowed value is set to 2341'));
$this->assertIdentical('3412', $field_storage->getSetting('allowed_values')['3412'], t('Third allowed value is set to 3412'));
$this->assertIdentical('4123', $field_storage->getSetting('allowed_values')['4123'], t('Fourth allowed value is set to 4123'));
$this->assertSame('1234', $field_storage->getSetting('allowed_values')['1234'], t('First allowed value is set to 1234'));
$this->assertSame('2341', $field_storage->getSetting('allowed_values')['2341'], t('Second allowed value is set to 2341'));
$this->assertSame('3412', $field_storage->getSetting('allowed_values')['3412'], t('Third allowed value is set to 3412'));
$this->assertSame('4123', $field_storage->getSetting('allowed_values')['4123'], t('Fourth allowed value is set to 4123'));
// Text field with a single checkbox.
$field_storage = FieldStorageConfig::load('node.field_test_text_single_checkbox');
$this->assertIdentical("boolean", $field_storage->getType(), t('Field type is @fieldtype. It should be boolean.', ['@fieldtype' => $field_storage->getType()]));
$this->assertSame("boolean", $field_storage->getType(), t('Field type is @fieldtype. It should be boolean.', ['@fieldtype' => $field_storage->getType()]));
// Test a node reference field.
$field_storage = FieldStorageConfig::load('node.field_company');
$this->assertInstanceOf(FieldStorageConfig::class, $field_storage);
$this->assertSame('entity_reference', $field_storage->getType());
$this->assertSame('node', $field_storage->getSetting('target_type'));
// Test a user reference field.
$field_storage = FieldStorageConfig::load('node.field_commander');
$this->assertInstanceOf(FieldStorageConfig::class, $field_storage);
$this->assertSame('entity_reference', $field_storage->getType());
$this->assertSame('user', $field_storage->getSetting('target_type'));
// Validate that the source count and processed count match up.
/** @var \Drupal\migrate\Plugin\MigrationInterface $migration */
$migration = $this->getMigration('d6_field');
$this->assertIdentical($migration->getSourcePlugin()->count(), $migration->getIdMap()->processedCount());
$this->assertSame($migration->getSourcePlugin()->count(), $migration->getIdMap()->processedCount());
// Check that we've reported on a conflict in widget_types.
$messages = [];
foreach ($migration->getIdMap()->getMessageIterator() as $message_row) {
$messages[] = $message_row->message;
}
$this->assertIdentical(count($messages), 1);
$this->assertIdentical($messages[0], 'Widget types optionwidgets_onoff, text_textfield are used in Drupal 6 field instances: widget type optionwidgets_onoff applied to the Drupal 8 base field');
$this->assertCount(1, $messages);
$this->assertSame($messages[0], 'Widget types optionwidgets_onoff, text_textfield are used in Drupal 6 field instances: widget type optionwidgets_onoff applied to the Drupal 8 base field');
}
}

View file

@ -12,6 +12,11 @@ use Drupal\Tests\migrate_drupal\Kernel\d6\MigrateDrupal6TestBase;
*/
class MigrateFieldWidgetSettingsTest extends MigrateDrupal6TestBase {
/**
* {@inheritdoc}
*/
public static $modules = ['menu_ui'];
/**
* {@inheritdoc}
*/
@ -96,6 +101,16 @@ class MigrateFieldWidgetSettingsTest extends MigrateDrupal6TestBase {
$component = $form_display->getComponent('field_test_datetime');
$expected['weight'] = 12;
$this->assertIdentical($expected, $component);
$component = entity_get_form_display('node', 'employee', 'default')
->getComponent('field_company');
$this->assertInternalType('array', $component);
$this->assertSame('options_select', $component['type']);
$component = entity_get_form_display('node', 'employee', 'default')
->getComponent('field_commander');
$this->assertInternalType('array', $component);
$this->assertSame('options_select', $component['type']);
}
}

View file

@ -29,6 +29,7 @@ class MigrateFieldInstanceWidgetSettingsTest extends MigrateDrupal7TestBase {
'taxonomy',
'telephone',
'text',
'menu_ui',
];
/**

View file

@ -0,0 +1,43 @@
<?php
namespace Drupal\Tests\field\Unit;
use Drupal\field\Entity\FieldConfig;
use Drupal\field\FieldConfigAccessControlHandler;
/**
* Tests the field config access controller.
*
* @group field
*
* @coversDefaultClass \Drupal\field\FieldConfigAccessControlHandler
*/
class FieldConfigAccessControlHandlerTest extends FieldStorageConfigAccessControlHandlerTest {
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$this->entity = new FieldConfig([
'field_name' => $this->fieldStorage->getName(),
'entity_type' => 'node',
'fieldStorage' => $this->fieldStorage,
'bundle' => 'test_bundle',
'field_type' => 'test_field',
], 'node');
$this->accessControlHandler = new FieldConfigAccessControlHandler($this->entity->getEntityType());
$this->accessControlHandler->setModuleHandler($this->moduleHandler);
}
/**
* Ensures field config access is working properly.
*/
public function testAccess() {
$this->assertAllowOperations([], $this->anon);
$this->assertAllowOperations(['view', 'update', 'delete'], $this->member);
}
}

View file

@ -0,0 +1,200 @@
<?php
namespace Drupal\Tests\field\Unit;
use Drupal\Component\Uuid\UuidInterface;
use Drupal\Core\Cache\Context\CacheContextsManager;
use Drupal\Core\Config\Entity\ConfigEntityTypeInterface;
use Drupal\Core\DependencyInjection\Container;
use Drupal\Core\Entity\EntityManagerInterface;
use Drupal\Core\Entity\EntityStorageInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\field\Entity\FieldStorageConfig;
use Drupal\field\FieldStorageConfigAccessControlHandler;
use Drupal\Tests\UnitTestCase;
/**
* Tests the field storage config access controller.
*
* @group field
*
* @coversDefaultClass \Drupal\field\FieldStorageConfigAccessControlHandler
*/
class FieldStorageConfigAccessControlHandlerTest extends UnitTestCase {
/**
* The field storage config access controller to test.
*
* @var \Drupal\field\FieldStorageConfigAccessControlHandler
*/
protected $accessControlHandler;
/**
* The mock module handler.
*
* @var \Drupal\Core\Extension\ModuleHandlerInterface
*/
protected $moduleHandler;
/**
* The mock account without field storage config access.
*
* @var \Drupal\Core\Session\AccountInterface
*/
protected $anon;
/**
* The mock account with field storage config access.
*
* @var \Drupal\Core\Session\AccountInterface
*/
protected $member;
/**
* The mocked test field storage config.
*
* @var \Drupal\field\FieldStorageConfigInterface
*/
protected $fieldStorage;
/**
* The main entity used for testing.
*
* @var \Drupal\Core\Config\Entity\ConfigEntityInterface
*/
protected $entity;
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$this->anon = $this->getMock(AccountInterface::class);
$this->anon
->expects($this->any())
->method('hasPermission')
->will($this->returnValue(FALSE));
$this->anon
->expects($this->any())
->method('id')
->will($this->returnValue(0));
$this->member = $this->getMock(AccountInterface::class);
$this->member
->expects($this->any())
->method('hasPermission')
->will($this->returnValueMap([
['administer node fields', TRUE],
]));
$this->member
->expects($this->any())
->method('id')
->will($this->returnValue(2));
$storageType = $this->getMock(ConfigEntityTypeInterface::class);
$storageType
->expects($this->any())
->method('getProvider')
->will($this->returnValue('field'));
$storageType
->expects($this->any())
->method('getConfigPrefix')
->will($this->returnValue('field.storage'));
$entityType = $this->getMock(ConfigEntityTypeInterface::class);
$entityType
->expects($this->any())
->method('getProvider')
->will($this->returnValue('node'));
$entityType
->expects($this->any())
->method('getConfigPrefix')
->willReturn('node');
$this->moduleHandler = $this->getMock(ModuleHandlerInterface::class);
$this->moduleHandler
->expects($this->any())
->method('getImplementations')
->will($this->returnValue([]));
$this->moduleHandler
->expects($this->any())
->method('invokeAll')
->will($this->returnValue([]));
$storage_access_control_handler = new FieldStorageConfigAccessControlHandler($storageType);
$storage_access_control_handler->setModuleHandler($this->moduleHandler);
$entityManager = $this->getMock(EntityManagerInterface::class);
$entityManager
->expects($this->any())
->method('getDefinition')
->willReturnMap([
['field_storage_config', TRUE, $storageType],
['node', TRUE, $entityType],
]);
$entityManager
->expects($this->any())
->method('getStorage')
->willReturnMap([
['field_storage_config', $this->getMock(EntityStorageInterface::class)],
]);
$entityManager
->expects($this->any())
->method('getAccessControlHandler')
->willReturnMap([
['field_storage_config', $storage_access_control_handler],
]);
$container = new Container();
$container->set('entity.manager', $entityManager);
$container->set('uuid', $this->getMock(UuidInterface::class));
$container->set('cache_contexts_manager', $this->prophesize(CacheContextsManager::class));
\Drupal::setContainer($container);
$this->fieldStorage = new FieldStorageConfig([
'field_name' => 'test_field',
'entity_type' => 'node',
'type' => 'boolean',
'id' => 'node.test_field',
'uuid' => '6f2f259a-f3c7-42ea-bdd5-111ad1f85ed1',
]);
$this->entity = $this->fieldStorage;
$this->accessControlHandler = $storage_access_control_handler;
}
/**
* Assert method to verify the access by operations.
*
* @param array $allow_operations
* A list of allowed operations.
* @param \Drupal\Core\Session\AccountInterface $user
* The account to use for get access.
*/
public function assertAllowOperations(array $allow_operations, AccountInterface $user) {
foreach (['view', 'update', 'delete'] as $operation) {
$expected = in_array($operation, $allow_operations);
$actual = $this->accessControlHandler->access($this->entity, $operation, $user);
$this->assertSame($expected, $actual, "Access problem with '$operation' operation.");
}
}
/**
* Ensures field storage config access is working properly.
*/
public function testAccess() {
$this->assertAllowOperations([], $this->anon);
$this->assertAllowOperations(['view', 'update', 'delete'], $this->member);
$this->fieldStorage->setLocked(TRUE)->save();
// Unfortunately, EntityAccessControlHandler has a static cache, which we
// therefore must reset manually.
$this->accessControlHandler->resetCache();
$this->assertAllowOperations([], $this->anon);
$this->assertAllowOperations(['view', 'update'], $this->member);
}
}

View file

@ -28,7 +28,7 @@ class FieldSettingsTest extends UnitTestCase {
->disableOriginalConstructor()
->getMock();
$result = $plugin->transform([$field_type, $field_settings], $executable, $row, 'foo');
$result = $plugin->transform([$field_type, $field_settings, NULL], $executable, $row, 'foo');
$this->assertSame($allowed_values, $result['allowed_values']);
}