Move into nested docroot
This commit is contained in:
parent
83a0d3a149
commit
c8b70abde9
13405 changed files with 0 additions and 0 deletions
37
web/core/modules/field/tests/fixtures/update/drupal-8.email_widget_size_setting-2578741.php
vendored
Normal file
37
web/core/modules/field/tests/fixtures/update/drupal-8.email_widget_size_setting-2578741.php
vendored
Normal file
|
@ -0,0 +1,37 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains SQL necessary to add a new component for an email field/widget to
|
||||
* the 'node.article.default' entity form display.
|
||||
*/
|
||||
|
||||
use Drupal\Core\Database\Database;
|
||||
|
||||
$connection = Database::getConnection();
|
||||
|
||||
$config = $connection->select('config', 'c')
|
||||
->fields('c')
|
||||
->condition('collection', '')
|
||||
->condition('name', 'core.entity_form_display.node.article.default')
|
||||
->execute()
|
||||
->fetchAssoc();
|
||||
|
||||
$data = unserialize($config['data']);
|
||||
|
||||
// Manually add a new component that simulates an email field using the default
|
||||
// email widget.
|
||||
$data['content']['field_email_2578741'] = [
|
||||
'weight' => 20,
|
||||
'settings' => [
|
||||
'placeholder' => '',
|
||||
],
|
||||
'third_party_settings' => [],
|
||||
'type' => 'email_default',
|
||||
];
|
||||
|
||||
$connection->update('config')
|
||||
->fields(['data' => serialize($data)])
|
||||
->condition('collection', '')
|
||||
->condition('name', 'core.entity_form_display.node.article.default')
|
||||
->execute();
|
95
web/core/modules/field/tests/fixtures/update/drupal-8.views_entity_reference_plugins-2429191.php
vendored
Normal file
95
web/core/modules/field/tests/fixtures/update/drupal-8.views_entity_reference_plugins-2429191.php
vendored
Normal file
|
@ -0,0 +1,95 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains database additions to drupal-8.bare.standard.php.gz for testing the
|
||||
* upgrade path of https://www.drupal.org/node/2429191.
|
||||
*/
|
||||
|
||||
use Drupal\Core\Database\Database;
|
||||
use Drupal\Core\Serialization\Yaml;
|
||||
use Drupal\field\Entity\FieldStorageConfig;
|
||||
|
||||
$connection = Database::getConnection();
|
||||
|
||||
// Configuration for a View with an "entity_reference selection" display.
|
||||
$config = Yaml::decode(file_get_contents(__DIR__ . '/views.view.entity_reference_plugins_2429191.yml'));
|
||||
$connection->insert('config')
|
||||
->fields([
|
||||
'collection',
|
||||
'name',
|
||||
'data',
|
||||
])
|
||||
->values([
|
||||
'collection' => '',
|
||||
'name' => 'views.view.' . $config['id'],
|
||||
'data' => serialize($config),
|
||||
])
|
||||
->execute();
|
||||
|
||||
// Configuration for an entity_reference field storage using the View for
|
||||
// selection.
|
||||
$field_ref_views_select_2429191 = Yaml::decode(file_get_contents(__DIR__ . '/field.storage.node.field_ref_views_select_2429191.yml'));
|
||||
|
||||
// Configuration for an entity_reference field storage using the auto-create
|
||||
// feature.
|
||||
$field_ref_autocreate_2412569 = Yaml::decode(file_get_contents(__DIR__ . '/field.storage.node.field_ref_autocreate_2412569.yml'));
|
||||
|
||||
$connection->insert('config')
|
||||
->fields([
|
||||
'collection',
|
||||
'name',
|
||||
'data',
|
||||
])
|
||||
->values([
|
||||
'collection' => '',
|
||||
'name' => 'field.storage.' . $field_ref_views_select_2429191['id'],
|
||||
'data' => serialize($field_ref_views_select_2429191),
|
||||
])
|
||||
->values([
|
||||
'collection' => '',
|
||||
'name' => 'field.storage.' . $field_ref_autocreate_2412569['id'],
|
||||
'data' => serialize($field_ref_autocreate_2412569),
|
||||
])
|
||||
->execute();
|
||||
// We need to Update the registry of "last installed" field definitions.
|
||||
$installed = $connection->select('key_value')
|
||||
->fields('key_value', ['value'])
|
||||
->condition('collection', 'entity.definitions.installed')
|
||||
->condition('name', 'node.field_storage_definitions')
|
||||
->execute()
|
||||
->fetchField();
|
||||
$installed = unserialize($installed);
|
||||
$installed['field_ref_views_select_2429191'] = new FieldStorageConfig($field_ref_views_select_2429191);
|
||||
$installed['field_ref_autocreate_2412569'] = new FieldStorageConfig($field_ref_autocreate_2412569);
|
||||
$connection->update('key_value')
|
||||
->condition('collection', 'entity.definitions.installed')
|
||||
->condition('name', 'node.field_storage_definitions')
|
||||
->fields([
|
||||
'value' => serialize($installed)
|
||||
])
|
||||
->execute();
|
||||
|
||||
// Configuration for an entity_reference field using the View for selection.
|
||||
$field_ref_views_select_2429191 = Yaml::decode(file_get_contents(__DIR__ . '/field.field.node.article.field_ref_views_select_2429191.yml'));
|
||||
|
||||
// Configuration for an entity_reference field using the auto-create feature.
|
||||
$field_ref_autocreate_2412569 = Yaml::decode(file_get_contents(__DIR__ . '/field.field.node.article.field_ref_autocreate_2412569.yml'));
|
||||
|
||||
$connection->insert('config')
|
||||
->fields([
|
||||
'collection',
|
||||
'name',
|
||||
'data',
|
||||
])
|
||||
->values([
|
||||
'collection' => '',
|
||||
'name' => 'field.field.' . $field_ref_views_select_2429191['id'],
|
||||
'data' => serialize($field_ref_views_select_2429191),
|
||||
])
|
||||
->values([
|
||||
'collection' => '',
|
||||
'name' => 'field.field.' . $field_ref_autocreate_2412569['id'],
|
||||
'data' => serialize($field_ref_autocreate_2412569),
|
||||
])
|
||||
->execute();
|
|
@ -0,0 +1,29 @@
|
|||
uuid: d6deba8d-073a-4572-a000-ee2a2de94de2
|
||||
langcode: en
|
||||
status: true
|
||||
dependencies:
|
||||
config:
|
||||
- field.storage.node.field_ref_autocreate_2412569
|
||||
- node.type.article
|
||||
- taxonomy.vocabulary.tags
|
||||
- taxonomy.vocabulary.test
|
||||
id: node.article.field_ref_autocreate_2412569
|
||||
field_name: field_ref_autocreate_2412569
|
||||
entity_type: node
|
||||
bundle: article
|
||||
label: 'Ref Autocreate 2412569'
|
||||
description: ''
|
||||
required: false
|
||||
translatable: false
|
||||
default_value: { }
|
||||
default_value_callback: ''
|
||||
settings:
|
||||
handler: 'default:taxonomy_term'
|
||||
handler_settings:
|
||||
target_bundles:
|
||||
tags: tags
|
||||
test: test
|
||||
sort:
|
||||
field: _none
|
||||
auto_create: true
|
||||
field_type: entity_reference
|
|
@ -0,0 +1,27 @@
|
|||
uuid: ac77b88d-dfa0-4b07-b700-ba50cb51f72a
|
||||
langcode: en
|
||||
status: true
|
||||
dependencies:
|
||||
config:
|
||||
- field.storage.node.field_ref_views_select_2429191
|
||||
- node.type.article
|
||||
module:
|
||||
- entity_reference
|
||||
id: node.article.field_ref_views_select_2429191
|
||||
field_name: field_ref_views_select_2429191
|
||||
entity_type: node
|
||||
bundle: article
|
||||
label: reference_views_select
|
||||
description: ''
|
||||
required: false
|
||||
translatable: false
|
||||
default_value: { }
|
||||
default_value_callback: ''
|
||||
settings:
|
||||
handler: views
|
||||
handler_settings:
|
||||
view:
|
||||
view_name: entity_reference_plugins_2429191
|
||||
display_name: entity_reference_1
|
||||
arguments: { }
|
||||
field_type: entity_reference
|
20
web/core/modules/field/tests/fixtures/update/field.storage.node.field_ref_autocreate_2412569.yml
vendored
Normal file
20
web/core/modules/field/tests/fixtures/update/field.storage.node.field_ref_autocreate_2412569.yml
vendored
Normal file
|
@ -0,0 +1,20 @@
|
|||
uuid: 5e4095a3-8f89-4d7a-b222-34bf5240b646
|
||||
langcode: en
|
||||
status: true
|
||||
dependencies:
|
||||
module:
|
||||
- node
|
||||
- taxonomy
|
||||
id: node.field_ref_autocreate_2412569
|
||||
field_name: field_ref_autocreate_2412569
|
||||
entity_type: node
|
||||
type: entity_reference
|
||||
settings:
|
||||
target_type: taxonomy_term
|
||||
module: core
|
||||
locked: false
|
||||
cardinality: 1
|
||||
translatable: true
|
||||
indexes: { }
|
||||
persist_with_no_fields: false
|
||||
custom_storage: false
|
|
@ -0,0 +1,19 @@
|
|||
uuid: 7f5e9177-56b3-4b84-a936-54bfd4d4c078
|
||||
langcode: en
|
||||
status: true
|
||||
dependencies:
|
||||
module:
|
||||
- entity_reference
|
||||
- node
|
||||
id: node.field_ref_views_select_2429191
|
||||
field_name: field_ref_views_select_2429191
|
||||
entity_type: node
|
||||
type: entity_reference
|
||||
settings:
|
||||
target_type: node
|
||||
module: entity_reference
|
||||
locked: false
|
||||
cardinality: 1
|
||||
translatable: true
|
||||
indexes: { }
|
||||
persist_with_no_fields: false
|
214
web/core/modules/field/tests/fixtures/update/views.view.entity_reference_plugins_2429191.yml
vendored
Normal file
214
web/core/modules/field/tests/fixtures/update/views.view.entity_reference_plugins_2429191.yml
vendored
Normal file
|
@ -0,0 +1,214 @@
|
|||
uuid: 8b3d9ae1-c8f9-4219-af35-53f687e6081b
|
||||
langcode: en
|
||||
status: true
|
||||
dependencies:
|
||||
module:
|
||||
- entity_reference
|
||||
- node
|
||||
- user
|
||||
id: entity_reference_plugins_2429191
|
||||
label: test
|
||||
module: views
|
||||
description: ''
|
||||
tag: ''
|
||||
base_table: node_field_data
|
||||
base_field: nid
|
||||
core: 8.x
|
||||
display:
|
||||
default:
|
||||
display_plugin: default
|
||||
id: default
|
||||
display_title: Master
|
||||
position: 0
|
||||
display_options:
|
||||
access:
|
||||
type: perm
|
||||
options:
|
||||
perm: 'access content'
|
||||
cache:
|
||||
type: tag
|
||||
options: { }
|
||||
query:
|
||||
type: views_query
|
||||
options:
|
||||
disable_sql_rewrite: false
|
||||
distinct: false
|
||||
replica: false
|
||||
query_comment: ''
|
||||
query_tags: { }
|
||||
exposed_form:
|
||||
type: basic
|
||||
options:
|
||||
submit_button: Apply
|
||||
reset_button: false
|
||||
reset_button_label: Reset
|
||||
exposed_sorts_label: 'Sort by'
|
||||
expose_sort_order: true
|
||||
sort_asc_label: Asc
|
||||
sort_desc_label: Desc
|
||||
pager:
|
||||
type: full
|
||||
options:
|
||||
items_per_page: 10
|
||||
offset: 0
|
||||
id: 0
|
||||
total_pages: null
|
||||
expose:
|
||||
items_per_page: false
|
||||
items_per_page_label: 'Items per page'
|
||||
items_per_page_options: '5, 10, 25, 50'
|
||||
items_per_page_options_all: false
|
||||
items_per_page_options_all_label: '- All -'
|
||||
offset: false
|
||||
offset_label: Offset
|
||||
tags:
|
||||
previous: '‹ previous'
|
||||
next: 'next ›'
|
||||
first: '« first'
|
||||
last: 'last »'
|
||||
quantity: 9
|
||||
style:
|
||||
type: default
|
||||
options:
|
||||
grouping: { }
|
||||
row_class: ''
|
||||
default_row_class: true
|
||||
uses_fields: false
|
||||
row:
|
||||
type: fields
|
||||
options:
|
||||
inline: { }
|
||||
separator: ''
|
||||
hide_empty: false
|
||||
default_field_elements: true
|
||||
fields:
|
||||
title:
|
||||
id: title
|
||||
table: node_field_data
|
||||
field: title
|
||||
entity_type: node
|
||||
entity_field: title
|
||||
label: ''
|
||||
alter:
|
||||
alter_text: false
|
||||
make_link: false
|
||||
absolute: false
|
||||
trim: false
|
||||
word_boundary: false
|
||||
ellipsis: false
|
||||
strip_tags: false
|
||||
html: false
|
||||
hide_empty: false
|
||||
empty_zero: false
|
||||
settings:
|
||||
link_to_entity: true
|
||||
plugin_id: field
|
||||
relationship: none
|
||||
group_type: group
|
||||
admin_label: ''
|
||||
exclude: false
|
||||
element_type: ''
|
||||
element_class: ''
|
||||
element_label_type: ''
|
||||
element_label_class: ''
|
||||
element_label_colon: true
|
||||
element_wrapper_type: ''
|
||||
element_wrapper_class: ''
|
||||
element_default_classes: true
|
||||
empty: ''
|
||||
hide_alter_empty: true
|
||||
click_sort_column: value
|
||||
type: string
|
||||
group_column: value
|
||||
group_columns: { }
|
||||
group_rows: true
|
||||
delta_limit: 0
|
||||
delta_offset: 0
|
||||
delta_reversed: false
|
||||
delta_first_last: false
|
||||
multi_type: separator
|
||||
separator: ', '
|
||||
field_api_classes: false
|
||||
filters:
|
||||
status:
|
||||
value: true
|
||||
table: node_field_data
|
||||
field: status
|
||||
plugin_id: boolean
|
||||
entity_type: node
|
||||
entity_field: status
|
||||
id: status
|
||||
expose:
|
||||
operator: ''
|
||||
group: 1
|
||||
title:
|
||||
id: title
|
||||
table: node_field_data
|
||||
field: title
|
||||
relationship: none
|
||||
group_type: group
|
||||
admin_label: ''
|
||||
operator: contains
|
||||
value: foo
|
||||
group: 1
|
||||
exposed: false
|
||||
expose:
|
||||
operator_id: ''
|
||||
label: ''
|
||||
description: ''
|
||||
multiple: false
|
||||
remember: false
|
||||
entity_type: node
|
||||
entity_field: title
|
||||
plugin_id: string
|
||||
sorts:
|
||||
created:
|
||||
id: created
|
||||
table: node_field_data
|
||||
field: created
|
||||
order: DESC
|
||||
entity_type: node
|
||||
entity_field: created
|
||||
plugin_id: date
|
||||
relationship: none
|
||||
group_type: group
|
||||
admin_label: ''
|
||||
exposed: false
|
||||
expose:
|
||||
label: ''
|
||||
granularity: second
|
||||
header: { }
|
||||
footer: { }
|
||||
empty: { }
|
||||
relationships: { }
|
||||
arguments: { }
|
||||
display_extenders: { }
|
||||
cache_metadata:
|
||||
max-age: -1
|
||||
contexts:
|
||||
- 'languages:language_content'
|
||||
- 'languages:language_interface'
|
||||
- url.query_args
|
||||
- 'user.node_grants:view'
|
||||
- user.permissions
|
||||
tags: { }
|
||||
entity_reference_1:
|
||||
display_plugin: entity_reference
|
||||
id: entity_reference_1
|
||||
display_title: 'Entity Reference'
|
||||
position: 1
|
||||
display_options:
|
||||
display_extenders: { }
|
||||
style:
|
||||
type: entity_reference
|
||||
options:
|
||||
search_fields:
|
||||
title: title
|
||||
cache_metadata:
|
||||
max-age: -1
|
||||
contexts:
|
||||
- 'languages:language_content'
|
||||
- 'languages:language_interface'
|
||||
- 'user.node_grants:view'
|
||||
- user.permissions
|
||||
tags: { }
|
|
@ -0,0 +1,7 @@
|
|||
field.formatter.settings.field_plugins_test_text_formatter:
|
||||
type: field.formatter.settings.text_trimmed
|
||||
label: 'Test text formatter display format settings'
|
||||
|
||||
field.widget.settings.field_plugins_test_text_widget:
|
||||
type: field.widget.settings.text_textfield
|
||||
label: 'Test text field widget settings'
|
|
@ -0,0 +1,8 @@
|
|||
name: 'Field Plugins Test'
|
||||
type: module
|
||||
description: 'Support module for the field and entity display tests.'
|
||||
core: 8.x
|
||||
package: Testing
|
||||
version: VERSION
|
||||
dependencies:
|
||||
- text
|
|
@ -0,0 +1,24 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\field_plugins_test\Plugin\Field\FieldFormatter;
|
||||
|
||||
use Drupal\text\Plugin\Field\FieldFormatter\TextTrimmedFormatter;
|
||||
|
||||
/**
|
||||
* Plugin implementation of the 'field_plugins_test_text_formatter' formatter.
|
||||
*
|
||||
* @FieldFormatter(
|
||||
* id = "field_plugins_test_text_formatter",
|
||||
* label = @Translation("Test Trimmed"),
|
||||
* field_types = {
|
||||
* "text",
|
||||
* "text_long",
|
||||
* "text_with_summary"
|
||||
* },
|
||||
* quickedit = {
|
||||
* "editor" = "form"
|
||||
* }
|
||||
* )
|
||||
*/
|
||||
class TestTextTrimmedFormatter extends TextTrimmedFormatter {
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\field_plugins_test\Plugin\Field\FieldWidget;
|
||||
|
||||
use Drupal\text\Plugin\Field\FieldWidget\TextfieldWidget;
|
||||
|
||||
/**
|
||||
* Plugin implementation of the 'field_plugins_test_text_widget' widget.
|
||||
*
|
||||
* @FieldWidget(
|
||||
* id = "field_plugins_test_text_widget",
|
||||
* label = @Translation("Test Text field"),
|
||||
* field_types = {
|
||||
* "text",
|
||||
* "string"
|
||||
* },
|
||||
* )
|
||||
*/
|
||||
class TestTextfieldWidget extends TextfieldWidget {
|
||||
}
|
|
@ -0,0 +1,139 @@
|
|||
field.formatter.settings.field_test_default:
|
||||
type: mapping
|
||||
label: 'Field test default display format settings'
|
||||
mapping:
|
||||
test_formatter_setting:
|
||||
type: string
|
||||
label: 'Test setting'
|
||||
|
||||
field.formatter.settings.field_test_multiple:
|
||||
type: mapping
|
||||
label: 'Multiple field test display format settings'
|
||||
mapping:
|
||||
test_formatter_setting_multiple:
|
||||
type: string
|
||||
label: 'Test setting'
|
||||
alter:
|
||||
type: boolean
|
||||
label: 'Test altering'
|
||||
|
||||
field.formatter.settings.field_empty_setting:
|
||||
type: mapping
|
||||
label: 'Empty setting field display format settings'
|
||||
mapping:
|
||||
field_empty_setting:
|
||||
type: string
|
||||
label: 'Test setting'
|
||||
|
||||
field.formatter.settings.field_test_with_prepare_view:
|
||||
type: mapping
|
||||
label: 'Field prepare step display format settings'
|
||||
mapping:
|
||||
test_formatter_setting_additional:
|
||||
type: string
|
||||
label: 'Test setting'
|
||||
|
||||
field.widget.settings.test_field_widget:
|
||||
type: mapping
|
||||
label: 'Test field widget settings'
|
||||
mapping:
|
||||
test_widget_setting:
|
||||
type: string
|
||||
label: 'Test setting'
|
||||
role:
|
||||
type: string
|
||||
label: 'A referenced role'
|
||||
role2:
|
||||
type: string
|
||||
label: 'A 2nd referenced role'
|
||||
|
||||
field.widget.settings.test_field_widget_multiple:
|
||||
type: mapping
|
||||
label: 'Test multiple field widget settings'
|
||||
mapping:
|
||||
test_widget_setting_multiple:
|
||||
type: string
|
||||
label: 'Test setting'
|
||||
|
||||
field.widget.third_party.color:
|
||||
type: mapping
|
||||
label: 'Field test entity display color module third party settings'
|
||||
mapping:
|
||||
foo:
|
||||
type: string
|
||||
label: 'Foo setting'
|
||||
|
||||
field.storage_settings.test_field:
|
||||
type: mapping
|
||||
label: 'Test field storage settings'
|
||||
mapping:
|
||||
test_field_storage_setting:
|
||||
type: string
|
||||
label: 'Test field storage setting'
|
||||
changeable:
|
||||
type: string
|
||||
label: 'A changeable field storage setting'
|
||||
unchangeable:
|
||||
type: string
|
||||
label: 'An unchangeable field storage setting'
|
||||
config_data_from_storage_setting:
|
||||
type: boolean
|
||||
label: 'Test FieldItemInterface::storageSettingsToConfigData()'
|
||||
translatable_storage_setting:
|
||||
type: label
|
||||
label: 'Translatable storage setting'
|
||||
|
||||
field.storage_settings.test_field_with_dependencies:
|
||||
type: field.storage_settings.test_field
|
||||
label: 'Test field with dependencies storage settings'
|
||||
|
||||
field.storage_settings.hidden_test_field:
|
||||
type: field.storage_settings.test_field
|
||||
label: 'Hidden test field storage settings'
|
||||
|
||||
field.storage_settings.test_field_with_preconfigured_options:
|
||||
type: field.storage_settings.test_field
|
||||
label: 'Test field with preconfigured options storage settings'
|
||||
|
||||
field.field_settings.test_field:
|
||||
type: mapping
|
||||
label: 'Test field field settings'
|
||||
mapping:
|
||||
test_field_setting:
|
||||
type: string
|
||||
label: 'Test field setting'
|
||||
config_data_from_field_setting:
|
||||
type: boolean
|
||||
label: 'Test FieldItemInterface::fieldSettingsToConfigData()'
|
||||
translatable_field_setting:
|
||||
type: label
|
||||
label: 'Translatable field setting'
|
||||
|
||||
field.field_settings.test_field_with_dependencies:
|
||||
type: field.field_settings.test_field
|
||||
label: 'Test field with dependencies field settings'
|
||||
|
||||
field.field_settings.hidden_test_field:
|
||||
type: field.field_settings.test_field
|
||||
label: 'Hidden test field field settings'
|
||||
|
||||
field.field_settings.test_field_with_preconfigured_options:
|
||||
type: field.field_settings.test_field
|
||||
label: 'Test field with preconfigured settings'
|
||||
|
||||
field.value.test_field:
|
||||
type: mapping
|
||||
label: 'Default value'
|
||||
mapping:
|
||||
value:
|
||||
type: label
|
||||
label: 'Value'
|
||||
|
||||
|
||||
field.formatter.third_party.field_test:
|
||||
type: mapping
|
||||
label: 'Field test entity display third party setting'
|
||||
mapping:
|
||||
foo:
|
||||
type: string
|
||||
label: 'Test setting'
|
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Defines an entity type.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements hook_entity_type_alter().
|
||||
*/
|
||||
function field_test_entity_type_alter(array &$entity_types) {
|
||||
/** @var $entity_types \Drupal\Core\Entity\EntityTypeInterface[] */
|
||||
foreach (field_test_entity_info_translatable() as $entity_type => $translatable) {
|
||||
$entity_types[$entity_type]->set('translatable', $translatable);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to enable entity translations.
|
||||
*/
|
||||
function field_test_entity_info_translatable($entity_type_id = NULL, $translatable = NULL) {
|
||||
$stored_value = &drupal_static(__FUNCTION__, array());
|
||||
if (isset($entity_type_id)) {
|
||||
$entity_manager = \Drupal::entityManager();
|
||||
$original = $entity_manager->getDefinition($entity_type_id);
|
||||
$stored_value[$entity_type_id] = $translatable;
|
||||
if ($translatable != $original->isTranslatable()) {
|
||||
$entity_manager->clearCachedDefinitions();
|
||||
$entity_type = $entity_manager->getDefinition($entity_type_id);
|
||||
$entity_manager->onEntityTypeUpdate($entity_type, $original);
|
||||
}
|
||||
}
|
||||
return $stored_value;
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Defines a field type and its formatters and widgets.
|
||||
*/
|
||||
|
||||
use Drupal\Core\Entity\FieldableEntityInterface;
|
||||
use Drupal\Core\Access\AccessResult;
|
||||
use Drupal\Core\Entity\Exception\FieldStorageDefinitionUpdateForbiddenException;
|
||||
use Drupal\Core\Field\FieldDefinitionInterface;
|
||||
use Drupal\Core\Field\FieldItemListInterface;
|
||||
use Drupal\Core\Session\AccountInterface;
|
||||
use Drupal\field\FieldStorageConfigInterface;
|
||||
|
||||
/**
|
||||
* Implements hook_field_widget_info_alter().
|
||||
*/
|
||||
function field_test_field_widget_info_alter(&$info) {
|
||||
$info['test_field_widget_multiple']['field_types'][] = 'test_field';
|
||||
$info['test_field_widget_multiple']['field_types'][] = 'test_field_with_preconfigured_options';
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_field_storage_config_update_forbid().
|
||||
*/
|
||||
function field_test_field_storage_config_update_forbid(FieldStorageConfigInterface $field_storage, FieldStorageConfigInterface $prior_field_storage) {
|
||||
if ($field_storage->getType() == 'test_field' && $field_storage->getSetting('unchangeable') != $prior_field_storage->getSetting('unchangeable')) {
|
||||
throw new FieldStorageDefinitionUpdateForbiddenException("field_test 'unchangeable' setting cannot be changed'");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sample 'default value' callback.
|
||||
*/
|
||||
function field_test_default_value(FieldableEntityInterface $entity, FieldDefinitionInterface $definition) {
|
||||
return array(array('value' => 99));
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_entity_field_access().
|
||||
*/
|
||||
function field_test_entity_field_access($operation, FieldDefinitionInterface $field_definition, AccountInterface $account, FieldItemListInterface $items = NULL) {
|
||||
if ($field_definition->getName() == "field_no_{$operation}_access") {
|
||||
return AccessResult::forbidden();
|
||||
}
|
||||
|
||||
// Only grant view access to test_view_field fields when the user has
|
||||
// 'view test_view_field content' permission.
|
||||
if ($field_definition->getName() == 'test_view_field' && $operation == 'view') {
|
||||
return AccessResult::forbiddenIf(!$account->hasPermission('view test_view_field content'))->cachePerPermissions();
|
||||
}
|
||||
|
||||
return AccessResult::allowed();
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
name: 'Field API Test'
|
||||
type: module
|
||||
description: 'Support module for the Field API tests.'
|
||||
core: 8.x
|
||||
package: Testing
|
||||
version: VERSION
|
||||
dependencies:
|
||||
- entity_test
|
|
@ -0,0 +1,170 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Helper module for the Field API tests.
|
||||
*
|
||||
* The module defines
|
||||
* - an entity type (field_test.entity.inc)
|
||||
* - a field type and its formatters and widgets (field_test.field.inc)
|
||||
* - a field storage backend (field_test.storage.inc)
|
||||
*
|
||||
* The main field_test.module file implements generic hooks and provides some
|
||||
* test helper functions
|
||||
*/
|
||||
|
||||
use Drupal\Core\Entity\EntityTypeInterface;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\field\FieldStorageConfigInterface;
|
||||
|
||||
require_once __DIR__ . '/field_test.entity.inc';
|
||||
require_once __DIR__ . '/field_test.field.inc';
|
||||
|
||||
/**
|
||||
* Store and retrieve keyed data for later verification by unit tests.
|
||||
*
|
||||
* This function is a simple in-memory key-value store with the
|
||||
* distinction that it stores all values for a given key instead of
|
||||
* just the most recently set value. field_test module hooks call
|
||||
* this function to record their arguments, keyed by hook name. The
|
||||
* unit tests later call this function to verify that the correct
|
||||
* hooks were called and were passed the correct arguments.
|
||||
*
|
||||
* This function ignores all calls until the first time it is called
|
||||
* with $key of NULL. Each time it is called with $key of NULL, it
|
||||
* erases all previously stored data from its internal cache, but also
|
||||
* returns the previously stored data to the caller. A typical usage
|
||||
* scenario is:
|
||||
*
|
||||
* @code
|
||||
* // calls to field_test_memorize() here are ignored
|
||||
*
|
||||
* // turn on memorization
|
||||
* field_test_memorize();
|
||||
*
|
||||
* // call some Field API functions that invoke field_test hooks
|
||||
* FieldStorageConfig::create($field_definition)->save();
|
||||
*
|
||||
* // retrieve and reset the memorized hook call data
|
||||
* $mem = field_test_memorize();
|
||||
*
|
||||
* // make sure hook_field_storage_config_create() is invoked correctly
|
||||
* assertEqual(count($mem['field_test_field_storage_config_create']), 1);
|
||||
* assertEqual($mem['field_test_field_storage_config_create'][0], array($field));
|
||||
* @endcode
|
||||
*
|
||||
* @param $key
|
||||
* The key under which to store to $value, or NULL as described above.
|
||||
* @param $value
|
||||
* A value to store for $key.
|
||||
* @return
|
||||
* An array mapping each $key to an array of each $value passed in
|
||||
* for that key.
|
||||
*/
|
||||
function field_test_memorize($key = NULL, $value = NULL) {
|
||||
$memorize = &drupal_static(__FUNCTION__, NULL);
|
||||
|
||||
if (!isset($key)) {
|
||||
$return = $memorize;
|
||||
$memorize = array();
|
||||
return $return;
|
||||
}
|
||||
if (is_array($memorize)) {
|
||||
$memorize[$key][] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Memorize calls to field_test_field_storage_config_create().
|
||||
*/
|
||||
function field_test_field_storage_config_create(FieldStorageConfigInterface $field_storage) {
|
||||
$args = func_get_args();
|
||||
field_test_memorize(__FUNCTION__, $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_entity_display_build_alter().
|
||||
*/
|
||||
function field_test_entity_display_build_alter(&$output, $context) {
|
||||
$display_options = $context['display']->getComponent('test_field');
|
||||
if (isset($display_options['settings']['alter'])) {
|
||||
$output['test_field'][] = array('#markup' => 'field_test_entity_display_build_alter');
|
||||
}
|
||||
|
||||
if (isset($output['test_field'])) {
|
||||
$output['test_field'][] = array('#markup' => 'entity language is ' . $context['entity']->language()->getId());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_field_widget_form_alter().
|
||||
*/
|
||||
function field_test_field_widget_form_alter(&$element, FormStateInterface $form_state, $context) {
|
||||
$field_definition = $context['items']->getFieldDefinition();
|
||||
switch ($field_definition->getName()) {
|
||||
case 'alter_test_text':
|
||||
drupal_set_message('Field size: ' . $context['widget']->getSetting('size'));
|
||||
break;
|
||||
|
||||
case 'alter_test_options':
|
||||
drupal_set_message('Widget type: ' . $context['widget']->getPluginId());
|
||||
break;
|
||||
}
|
||||
// Set a message if this is for the form displayed to set default value for
|
||||
// the field.
|
||||
if ($context['default']) {
|
||||
drupal_set_message('From hook_field_widget_form_alter(): Default form is true.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_query_TAG_alter() for tag 'efq_table_prefixing_test'.
|
||||
*
|
||||
* @see \Drupal\system\Tests\Entity\EntityFieldQueryTest::testTablePrefixing()
|
||||
*/
|
||||
function field_test_query_efq_table_prefixing_test_alter(&$query) {
|
||||
// Add an additional join onto the entity base table. This will cause an
|
||||
// exception if the EFQ does not properly prefix the base table.
|
||||
$query->join('entity_test', 'et2', '%alias.id = entity_test.id');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Implements hook_query_TAG_alter() for tag 'efq_metadata_test'.
|
||||
*
|
||||
* @see \Drupal\system\Tests\Entity\EntityQueryTest::testMetaData()
|
||||
*/
|
||||
function field_test_query_efq_metadata_test_alter(&$query) {
|
||||
global $efq_test_metadata;
|
||||
$efq_test_metadata = $query->getMetadata('foo');
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_entity_extra_field_info_alter().
|
||||
*/
|
||||
function field_test_entity_extra_field_info_alter(&$info) {
|
||||
// Remove all extra fields from the 'no_fields' content type;
|
||||
unset($info['node']['no_fields']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_entity_bundle_field_info_alter().
|
||||
*/
|
||||
function field_test_entity_bundle_field_info_alter(&$fields, EntityTypeInterface $entity_type, $bundle) {
|
||||
if (($field_name = \Drupal::state()->get('field_test_set_constraint', FALSE)) && $entity_type->id() == 'entity_test' && $bundle == 'entity_test' && !empty($fields[$field_name])) {
|
||||
$fields[$field_name]->setPropertyConstraints('value', [
|
||||
'Range' => [
|
||||
'min' => 0,
|
||||
'max' => 32,
|
||||
],
|
||||
]);
|
||||
}
|
||||
if (($field_name = \Drupal::state()->get('field_test_add_constraint', FALSE)) && $entity_type->id() == 'entity_test' && $bundle == 'entity_test' && !empty($fields[$field_name])) {
|
||||
$fields[$field_name]->addPropertyConstraints('value', [
|
||||
'Range' => [
|
||||
'min' => 0,
|
||||
'max' => 32,
|
||||
],
|
||||
]);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
view test_view_field content:
|
||||
title: 'View test field content'
|
||||
description: 'View published test_view_field content.'
|
||||
administer field_test content:
|
||||
title: 'Administer field_test content'
|
||||
description: 'Manage field_test content'
|
|
@ -0,0 +1,27 @@
|
|||
field_test.entity_nested_form:
|
||||
path: '/test-entity/nested/{entity_1}/{entity_2}'
|
||||
defaults:
|
||||
_title: 'Nested entity form'
|
||||
_form: '\Drupal\field_test\Form\NestedEntityTestForm'
|
||||
options:
|
||||
parameters:
|
||||
entity_1:
|
||||
type: 'entity:entity_test'
|
||||
entity_2:
|
||||
type: 'entity:entity_test'
|
||||
requirements:
|
||||
_permission: 'administer entity_test content'
|
||||
|
||||
field_test.entity_constraints_nested_form:
|
||||
path: '/test-entity-constraints/nested/{entity_1}/{entity_2}'
|
||||
defaults:
|
||||
_title: 'Nested entity form'
|
||||
_form: '\Drupal\field_test\Form\NestedEntityTestForm'
|
||||
options:
|
||||
parameters:
|
||||
entity_1:
|
||||
type: 'entity:entity_test_constraints'
|
||||
entity_2:
|
||||
type: 'entity:entity_test_constraints'
|
||||
requirements:
|
||||
_permission: 'administer entity_test content'
|
|
@ -0,0 +1,107 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\field_test\Form;
|
||||
|
||||
use Drupal\Core\Entity\EntityChangedInterface;
|
||||
use Drupal\Core\Entity\EntityInterface;
|
||||
use Drupal\Core\Form\FormBase;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\Core\Entity\Entity\EntityFormDisplay;
|
||||
|
||||
/**
|
||||
* Provides a form for field_test routes.
|
||||
*/
|
||||
class NestedEntityTestForm extends FormBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc]
|
||||
*/
|
||||
public function getFormId() {
|
||||
return 'field_test_entity_nested_form';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc]
|
||||
*/
|
||||
public function buildForm(array $form, FormStateInterface $form_state, EntityInterface $entity_1 = NULL, EntityInterface $entity_2 = NULL) {
|
||||
// First entity.
|
||||
$form_state->set('entity_1', $entity_1);
|
||||
$form_display_1 = EntityFormDisplay::collectRenderDisplay($entity_1, 'default');
|
||||
$form_state->set('form_display_1', $form_display_1);
|
||||
$form_display_1->buildForm($entity_1, $form, $form_state);
|
||||
|
||||
// Second entity.
|
||||
$form_state->set('entity_2', $entity_2);
|
||||
$form_display_2 = EntityFormDisplay::collectRenderDisplay($entity_2, 'default');
|
||||
$form_state->set('form_display_2', $form_display_2);
|
||||
$form['entity_2'] = [
|
||||
'#type' => 'details',
|
||||
'#title' => t('Second entity'),
|
||||
'#tree' => TRUE,
|
||||
'#parents' => ['entity_2'],
|
||||
'#weight' => 50,
|
||||
'#attributes' => ['class' => ['entity-2']]
|
||||
];
|
||||
|
||||
$form_display_2->buildForm($entity_2, $form['entity_2'], $form_state);
|
||||
|
||||
if ($entity_2 instanceof EntityChangedInterface) {
|
||||
// Changed must be sent to the client, for later overwrite error checking.
|
||||
// @see Drupal\field\Tests\NestedFormTest::testNestedEntityFormEntityLevelValidation()
|
||||
$form['entity_2']['changed'] = [
|
||||
'#type' => 'hidden',
|
||||
'#default_value' => $entity_1->getChangedTime(),
|
||||
];
|
||||
}
|
||||
|
||||
$form['save'] = array(
|
||||
'#type' => 'submit',
|
||||
'#value' => t('Save'),
|
||||
'#weight' => 100,
|
||||
);
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc]
|
||||
*/
|
||||
public function validateForm(array &$form, FormStateInterface $form_state) {
|
||||
$entity_1 = $form_state->get('entity_1');
|
||||
/** @var \Drupal\Core\Entity\Display\EntityFormDisplayInterface $form_display_1 */
|
||||
$form_display_1 = $form_state->get('form_display_1');
|
||||
$form_display_1->extractFormValues($entity_1, $form, $form_state);
|
||||
$form_display_1->validateFormValues($entity_1, $form, $form_state);
|
||||
|
||||
$entity_2 = $form_state->get('entity_2');
|
||||
/** @var \Drupal\Core\Entity\Display\EntityFormDisplayInterface $form_display_2 */
|
||||
$form_display_2 = $form_state->get('form_display_2');
|
||||
$extracted = $form_display_2->extractFormValues($entity_2, $form['entity_2'], $form_state);
|
||||
// Extract the values of fields that are not rendered through widgets, by
|
||||
// simply copying from top-level form values. This leaves the fields that
|
||||
// are not being edited within this form untouched.
|
||||
// @see Drupal\field\Tests\NestedFormTest::testNestedEntityFormEntityLevelValidation()
|
||||
foreach ($form_state->getValues()['entity_2'] as $name => $values) {
|
||||
if ($entity_2->hasField($name) && !isset($extracted[$name])) {
|
||||
$entity_2->set($name, $values);
|
||||
}
|
||||
}
|
||||
$form_display_2->validateFormValues($entity_2, $form['entity_2'], $form_state);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc]
|
||||
*/
|
||||
public function submitForm(array &$form, FormStateInterface $form_state) {
|
||||
/** @var \Drupal\Core\Entity\EntityInterface $entity_1 */
|
||||
$entity_1 = $form_state->get('entity_1');
|
||||
$entity_1->save();
|
||||
|
||||
/** @var \Drupal\Core\Entity\EntityInterface $entity_2 */
|
||||
$entity_2 = $form_state->get('entity_2');
|
||||
$entity_2->save();
|
||||
|
||||
drupal_set_message($this->t('test_entities @id_1 and @id_2 have been updated.', array('@id_1' => $entity_1->id(), '@id_2' => $entity_2->id())));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\field_test\Plugin\Field\FieldFormatter;
|
||||
use Drupal\Core\Field\FieldDefinitionInterface;
|
||||
use Drupal\Core\Field\FieldItemListInterface;
|
||||
use Drupal\Core\Field\FormatterBase;
|
||||
|
||||
|
||||
/**
|
||||
* Plugin implementation of the 'field_test_applicable' formatter.
|
||||
*
|
||||
* It is applicable to test_field fields unless their name is 'deny_applicable'.
|
||||
*
|
||||
* @FieldFormatter(
|
||||
* id = "field_test_applicable",
|
||||
* label = @Translation("Applicable"),
|
||||
* description = @Translation("Applicable formatter"),
|
||||
* field_types = {
|
||||
* "test_field"
|
||||
* },
|
||||
* weight = 15,
|
||||
* )
|
||||
*/
|
||||
class TestFieldApplicableFormatter extends FormatterBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function isApplicable(FieldDefinitionInterface $field_definition) {
|
||||
return $field_definition->getName() != 'deny_applicable';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function viewElements(FieldItemListInterface $items, $langcode) {
|
||||
return array('#markup' => 'Nothing to see here');
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\field_test\Plugin\Field\FieldFormatter;
|
||||
|
||||
use Drupal\Core\Field\FormatterBase;
|
||||
use Drupal\Core\Field\FieldItemListInterface;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
|
||||
/**
|
||||
* Plugin implementation of the 'field_test_default' formatter.
|
||||
*
|
||||
* @FieldFormatter(
|
||||
* id = "field_test_default",
|
||||
* label = @Translation("Default"),
|
||||
* description = @Translation("Default formatter"),
|
||||
* field_types = {
|
||||
* "test_field",
|
||||
* "test_field_with_preconfigured_options"
|
||||
* },
|
||||
* weight = 1
|
||||
* )
|
||||
*/
|
||||
class TestFieldDefaultFormatter extends FormatterBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function defaultSettings() {
|
||||
return array(
|
||||
'test_formatter_setting' => 'dummy test string',
|
||||
) + parent::defaultSettings();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function settingsForm(array $form, FormStateInterface $form_state) {
|
||||
$element['test_formatter_setting'] = array(
|
||||
'#title' => t('Setting'),
|
||||
'#type' => 'textfield',
|
||||
'#size' => 20,
|
||||
'#default_value' => $this->getSetting('test_formatter_setting'),
|
||||
'#required' => TRUE,
|
||||
);
|
||||
return $element;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function settingsSummary() {
|
||||
$summary = array();
|
||||
$summary[] = t('@setting: @value', array('@setting' => 'test_formatter_setting', '@value' => $this->getSetting('test_formatter_setting')));
|
||||
return $summary;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function viewElements(FieldItemListInterface $items, $langcode) {
|
||||
$elements = array();
|
||||
|
||||
foreach ($items as $delta => $item) {
|
||||
$elements[$delta] = array('#markup' => $this->getSetting('test_formatter_setting') . '|' . $item->value);
|
||||
}
|
||||
|
||||
return $elements;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\field_test\Plugin\Field\FieldFormatter;
|
||||
|
||||
use Drupal\Core\Field\FieldItemListInterface;
|
||||
use Drupal\Core\Field\FormatterBase;
|
||||
|
||||
/**
|
||||
* Plugin implementation of the 'field_empty_test' formatter.
|
||||
*
|
||||
* @FieldFormatter(
|
||||
* id = "field_empty_test",
|
||||
* label = @Translation("Field empty test"),
|
||||
* field_types = {
|
||||
* "test_field",
|
||||
* },
|
||||
* weight = -5
|
||||
* )
|
||||
*/
|
||||
class TestFieldEmptyFormatter extends FormatterBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function defaultSettings() {
|
||||
return array(
|
||||
'test_empty_string' => '**EMPTY FIELD**',
|
||||
) + parent::defaultSettings();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function viewElements(FieldItemListInterface $items, $langcode) {
|
||||
$elements = array();
|
||||
|
||||
if ($items->isEmpty()) {
|
||||
// For fields with no value, just add the configured "empty" value.
|
||||
$elements[0] = array('#markup' => $this->getSetting('test_empty_string'));
|
||||
}
|
||||
else {
|
||||
foreach ($items as $delta => $item) {
|
||||
// This formatter only needs to output raw for testing.
|
||||
$elements[$delta] = array('#markup' => $item->value);
|
||||
}
|
||||
}
|
||||
|
||||
return $elements;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\field_test\Plugin\Field\FieldFormatter;
|
||||
|
||||
use Drupal\Core\Field\FormatterBase;
|
||||
use Drupal\Core\Field\FieldItemListInterface;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
|
||||
/**
|
||||
* Plugin implementation of the 'field_empty_setting' formatter.
|
||||
*
|
||||
* @FieldFormatter(
|
||||
* id = "field_empty_setting",
|
||||
* label = @Translation("Field empty setting"),
|
||||
* field_types = {
|
||||
* "test_field",
|
||||
* },
|
||||
* weight = -1
|
||||
* )
|
||||
*/
|
||||
class TestFieldEmptySettingFormatter extends FormatterBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function defaultSettings() {
|
||||
return array(
|
||||
'field_empty_setting' => '',
|
||||
) + parent::defaultSettings();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function settingsForm(array $form, FormStateInterface $form_state) {
|
||||
$element['field_empty_setting'] = array(
|
||||
'#title' => t('Setting'),
|
||||
'#type' => 'textfield',
|
||||
'#size' => 20,
|
||||
'#default_value' => $this->getSetting('field_empty_setting'),
|
||||
'#required' => TRUE,
|
||||
);
|
||||
return $element;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function settingsSummary() {
|
||||
$summary = array();
|
||||
$setting = $this->getSetting('field_empty_setting');
|
||||
if (!empty($setting)) {
|
||||
$summary[] = t('Default empty setting now has a value.');
|
||||
}
|
||||
return $summary;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function viewElements(FieldItemListInterface $items, $langcode) {
|
||||
$elements = array();
|
||||
|
||||
if (!empty($items)) {
|
||||
foreach ($items as $delta => $item) {
|
||||
$elements[$delta] = array('#markup' => $this->getSetting('field_empty_setting'));
|
||||
}
|
||||
}
|
||||
|
||||
return $elements;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\field_test\Plugin\Field\FieldFormatter;
|
||||
|
||||
use Drupal\Core\Field\FormatterBase;
|
||||
use Drupal\Core\Field\FieldItemListInterface;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
|
||||
/**
|
||||
* Plugin implementation of the 'field_test_multiple' formatter.
|
||||
*
|
||||
* @FieldFormatter(
|
||||
* id = "field_test_multiple",
|
||||
* label = @Translation("Multiple"),
|
||||
* description = @Translation("Multiple formatter"),
|
||||
* field_types = {
|
||||
* "test_field",
|
||||
* "test_field_with_preconfigured_options"
|
||||
* },
|
||||
* weight = 5
|
||||
* )
|
||||
*/
|
||||
class TestFieldMultipleFormatter extends FormatterBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function defaultSettings() {
|
||||
return array(
|
||||
'test_formatter_setting_multiple' => 'dummy test string',
|
||||
'alter' => FALSE,
|
||||
) + parent::defaultSettings();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function settingsForm(array $form, FormStateInterface $form_state) {
|
||||
$element['test_formatter_setting_multiple'] = array(
|
||||
'#title' => t('Setting'),
|
||||
'#type' => 'textfield',
|
||||
'#size' => 20,
|
||||
'#default_value' => $this->getSetting('test_formatter_setting_multiple'),
|
||||
'#required' => TRUE,
|
||||
);
|
||||
return $element;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function settingsSummary() {
|
||||
$summary = array();
|
||||
$summary[] = t('@setting: @value', array('@setting' => 'test_formatter_setting_multiple', '@value' => $this->getSetting('test_formatter_setting_multiple')));
|
||||
return $summary;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function viewElements(FieldItemListInterface $items, $langcode) {
|
||||
$elements = array();
|
||||
|
||||
if (!empty($items)) {
|
||||
$array = array();
|
||||
foreach ($items as $delta => $item) {
|
||||
$array[] = $delta . ':' . $item->value;
|
||||
}
|
||||
$elements[0] = array('#markup' => $this->getSetting('test_formatter_setting_multiple') . '|' . implode('|', $array));
|
||||
}
|
||||
|
||||
return $elements;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\field_test\Plugin\Field\FieldFormatter;
|
||||
|
||||
use Drupal\Core\Field\FieldItemListInterface;
|
||||
use Drupal\Core\Field\FormatterBase;
|
||||
|
||||
/**
|
||||
* Plugin implementation of the 'field_no_settings' formatter.
|
||||
*
|
||||
* @FieldFormatter(
|
||||
* id = "field_no_settings",
|
||||
* label = @Translation("Field no settings"),
|
||||
* field_types = {
|
||||
* "test_field",
|
||||
* },
|
||||
* weight = -10
|
||||
* )
|
||||
*/
|
||||
class TestFieldNoSettingsFormatter extends FormatterBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function viewElements(FieldItemListInterface $items, $langcode) {
|
||||
$elements = array();
|
||||
|
||||
foreach ($items as $delta => $item) {
|
||||
// This formatter only needs to output raw for testing.
|
||||
$elements[$delta] = array('#markup' => $item->value);
|
||||
}
|
||||
|
||||
return $elements;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,83 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\field_test\Plugin\Field\FieldFormatter;
|
||||
|
||||
use Drupal\Core\Field\FormatterBase;
|
||||
use Drupal\Core\Field\FieldItemListInterface;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
|
||||
/**
|
||||
* Plugin implementation of the 'field_test_with_prepare_view' formatter.
|
||||
*
|
||||
* @FieldFormatter(
|
||||
* id = "field_test_with_prepare_view",
|
||||
* label = @Translation("With prepare step"),
|
||||
* description = @Translation("Tests prepareView() method"),
|
||||
* field_types = {
|
||||
* "test_field"
|
||||
* },
|
||||
* weight = 10
|
||||
* )
|
||||
*/
|
||||
class TestFieldPrepareViewFormatter extends FormatterBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function defaultSettings() {
|
||||
return array(
|
||||
'test_formatter_setting_additional' => 'dummy test string',
|
||||
) + parent::defaultSettings();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function settingsForm(array $form, FormStateInterface $form_state) {
|
||||
$element['test_formatter_setting_additional'] = array(
|
||||
'#title' => t('Setting'),
|
||||
'#type' => 'textfield',
|
||||
'#size' => 20,
|
||||
'#default_value' => $this->getSetting('test_formatter_setting_additional'),
|
||||
'#required' => TRUE,
|
||||
);
|
||||
return $element;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function settingsSummary() {
|
||||
$summary = array();
|
||||
$summary[] = t('@setting: @value', array('@setting' => 'test_formatter_setting_additional', '@value' => $this->getSetting('test_formatter_setting_additional')));
|
||||
return $summary;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function prepareView(array $entities_items) {
|
||||
foreach ($entities_items as $items) {
|
||||
foreach ($items as $item) {
|
||||
// Don't add anything on empty values.
|
||||
if (!$item->isEmpty()) {
|
||||
$item->additional_formatter_value = $item->value + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function viewElements(FieldItemListInterface $items, $langcode) {
|
||||
$elements = array();
|
||||
|
||||
foreach ($items as $delta => $item) {
|
||||
$elements[$delta] = array('#markup' => $this->getSetting('test_formatter_setting_additional') . '|' . $item->value . '|' . $item->additional_formatter_value);
|
||||
}
|
||||
|
||||
return $elements;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\field_test\Plugin\Field\FieldType;
|
||||
|
||||
/**
|
||||
* Defines the 'hidden_test' entity field item.
|
||||
*
|
||||
* @FieldType(
|
||||
* id = "hidden_test_field",
|
||||
* label = @Translation("Hidden from UI test field"),
|
||||
* description = @Translation("Dummy hidden field type used for tests."),
|
||||
* no_ui = TRUE,
|
||||
* default_widget = "test_field_widget",
|
||||
* default_formatter = "field_test_default"
|
||||
* )
|
||||
*/
|
||||
class HiddenTestItem extends TestItem {
|
||||
|
||||
}
|
|
@ -0,0 +1,173 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\field_test\Plugin\Field\FieldType;
|
||||
|
||||
use Drupal\Core\Field\FieldStorageDefinitionInterface;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\Core\TypedData\DataDefinition;
|
||||
use Drupal\Core\Field\FieldItemBase;
|
||||
|
||||
/**
|
||||
* Defines the 'test_field' entity field item.
|
||||
*
|
||||
* @FieldType(
|
||||
* id = "test_field",
|
||||
* label = @Translation("Test field"),
|
||||
* description = @Translation("Dummy field type used for tests."),
|
||||
* default_widget = "test_field_widget",
|
||||
* default_formatter = "field_test_default"
|
||||
* )
|
||||
*/
|
||||
class TestItem extends FieldItemBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function defaultStorageSettings() {
|
||||
return array(
|
||||
'test_field_storage_setting' => 'dummy test string',
|
||||
'changeable' => 'a changeable field storage setting',
|
||||
'unchangeable' => 'an unchangeable field storage setting',
|
||||
'translatable_storage_setting' => 'a translatable field storage setting',
|
||||
) + parent::defaultStorageSettings();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function defaultFieldSettings() {
|
||||
return array(
|
||||
'test_field_setting' => 'dummy test string',
|
||||
'translatable_field_setting' => 'a translatable field setting',
|
||||
) + parent::defaultFieldSettings();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function propertyDefinitions(FieldStorageDefinitionInterface $field_definition) {
|
||||
$properties['value'] = DataDefinition::create('integer')
|
||||
->setLabel(t('Test integer value'))
|
||||
->setRequired(TRUE);
|
||||
|
||||
return $properties;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function schema(FieldStorageDefinitionInterface $field_definition) {
|
||||
return array(
|
||||
'columns' => array(
|
||||
'value' => array(
|
||||
'type' => 'int',
|
||||
'size' => 'medium',
|
||||
),
|
||||
),
|
||||
'indexes' => array(
|
||||
'value' => array('value'),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function storageSettingsForm(array &$form, FormStateInterface $form_state, $has_data) {
|
||||
$form['test_field_storage_setting'] = array(
|
||||
'#type' => 'textfield',
|
||||
'#title' => t('Field test field storage setting'),
|
||||
'#default_value' => $this->getSetting('test_field_storage_setting'),
|
||||
'#required' => FALSE,
|
||||
'#description' => t('A dummy form element to simulate field storage setting.'),
|
||||
);
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function fieldSettingsForm(array $form, FormStateInterface $form_state) {
|
||||
$form['test_field_setting'] = array(
|
||||
'#type' => 'textfield',
|
||||
'#title' => t('Field test field setting'),
|
||||
'#default_value' => $this->getSetting('test_field_setting'),
|
||||
'#required' => FALSE,
|
||||
'#description' => t('A dummy form element to simulate field setting.'),
|
||||
);
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function delete() {
|
||||
// Reports that delete() method is executed for testing purposes.
|
||||
field_test_memorize('field_test_field_delete', array($this->getEntity()));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getConstraints() {
|
||||
$constraint_manager = \Drupal::typedDataManager()->getValidationConstraintManager();
|
||||
$constraints = parent::getConstraints();
|
||||
|
||||
$constraints[] = $constraint_manager->create('ComplexData', array(
|
||||
'value' => array(
|
||||
'TestField' => array(
|
||||
'value' => -1,
|
||||
'message' => t('%name does not accept the value @value.', array('%name' => $this->getFieldDefinition()->getLabel(), '@value' => -1)),
|
||||
)
|
||||
),
|
||||
));
|
||||
|
||||
return $constraints;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function isEmpty() {
|
||||
return empty($this->value);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function storageSettingsToConfigData(array $settings) {
|
||||
$settings['config_data_from_storage_setting'] = 'TRUE';
|
||||
unset($settings['storage_setting_from_config_data']);
|
||||
return $settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function storageSettingsFromConfigData(array $settings) {
|
||||
$settings['storage_setting_from_config_data'] = 'TRUE';
|
||||
unset($settings['config_data_from_storage_setting']);
|
||||
return $settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function fieldSettingsToConfigData(array $settings) {
|
||||
$settings['config_data_from_field_setting'] = 'TRUE';
|
||||
unset($settings['field_setting_from_config_data']);
|
||||
return $settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function fieldSettingsFromConfigData(array $settings) {
|
||||
$settings['field_setting_from_config_data'] = 'TRUE';
|
||||
unset($settings['config_data_from_field_setting']);
|
||||
return $settings;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\field_test\Plugin\Field\FieldType;
|
||||
|
||||
use Drupal\Core\Field\FieldDefinitionInterface;
|
||||
|
||||
|
||||
/**
|
||||
* Defines the 'test_field_with_dependencies' entity field item.
|
||||
*
|
||||
* @FieldType(
|
||||
* id = "test_field_with_dependencies",
|
||||
* label = @Translation("Test field with dependencies"),
|
||||
* description = @Translation("Dummy field type used for tests."),
|
||||
* default_widget = "test_field_widget",
|
||||
* default_formatter = "field_test_default",
|
||||
* config_dependencies = {
|
||||
* "module" = {
|
||||
* "test_module"
|
||||
* }
|
||||
* }
|
||||
* )
|
||||
*/
|
||||
class TestItemWithDependencies extends TestItem {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function calculateDependencies(FieldDefinitionInterface $field_definition) {
|
||||
return ['content' => ['node:article:uuid']];
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\field_test\Plugin\Field\FieldType;
|
||||
|
||||
use Drupal\Core\Field\FieldStorageDefinitionInterface;
|
||||
use Drupal\Core\Field\PreconfiguredFieldUiOptionsInterface;
|
||||
|
||||
/**
|
||||
* Defines the 'test_field_with_preconfigured_options' entity field item.
|
||||
*
|
||||
* @FieldType(
|
||||
* id = "test_field_with_preconfigured_options",
|
||||
* label = @Translation("Test field with preconfigured options"),
|
||||
* description = @Translation("Dummy field type used for tests."),
|
||||
* default_widget = "test_field_widget",
|
||||
* default_formatter = "field_test_default"
|
||||
* )
|
||||
*/
|
||||
class TestItemWithPreconfiguredOptions extends TestItem implements PreconfiguredFieldUiOptionsInterface {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function getPreconfiguredOptions() {
|
||||
return [
|
||||
'custom_options' => [
|
||||
'label' => t('All custom options'),
|
||||
'category' => t('Custom category'),
|
||||
'field_storage_config' => [
|
||||
'cardinality' => FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED,
|
||||
'settings' => [
|
||||
'test_field_storage_setting' => 'preconfigured_storage_setting'
|
||||
],
|
||||
],
|
||||
'field_config' => [
|
||||
'required' => TRUE,
|
||||
'settings' => [
|
||||
'test_field_setting' => 'preconfigured_field_setting',
|
||||
],
|
||||
],
|
||||
'entity_form_display' => [
|
||||
'type' => 'test_field_widget_multiple',
|
||||
],
|
||||
'entity_view_display' => [
|
||||
'type' => 'field_test_multiple',
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\field_test\Plugin\Field\FieldType;
|
||||
|
||||
use Drupal\Core\Field\FieldStorageDefinitionInterface;
|
||||
use Drupal\Core\TypedData\DataDefinition;
|
||||
use Drupal\Core\Field\FieldItemBase;
|
||||
|
||||
/**
|
||||
* Defines the 'test_object_field' entity field item.
|
||||
*
|
||||
* @FieldType(
|
||||
* id = "test_object_field",
|
||||
* label = @Translation("Test object field"),
|
||||
* description = @Translation("Test field type that has an object to test serialization"),
|
||||
* default_widget = "test_object_field_widget",
|
||||
* default_formatter = "object_field_test_default"
|
||||
* )
|
||||
*/
|
||||
class TestObjectItem extends FieldItemBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function propertyDefinitions(FieldStorageDefinitionInterface $field_definition) {
|
||||
$properties['value'] = DataDefinition::create('any')
|
||||
->setLabel(t('Value'))
|
||||
->setRequired(TRUE);
|
||||
|
||||
return $properties;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function schema(FieldStorageDefinitionInterface $field_definition) {
|
||||
return [
|
||||
'columns' => [
|
||||
'value' => [
|
||||
'description' => 'The object item value.',
|
||||
'type' => 'blob',
|
||||
'not null' => TRUE,
|
||||
'serialize' => TRUE,
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setValue($values, $notify = TRUE) {
|
||||
if (isset($values['value'])) {
|
||||
// @todo Remove this in https://www.drupal.org/node/2788637.
|
||||
if (is_string($values['value'])) {
|
||||
$values['value'] = unserialize($values['value']);
|
||||
}
|
||||
}
|
||||
parent::setValue($values, $notify);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,116 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\field_test\Plugin\Field\FieldWidget;
|
||||
|
||||
use Drupal\Core\Field\FieldItemListInterface;
|
||||
use Drupal\Core\Field\WidgetBase;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Symfony\Component\Validator\ConstraintViolationInterface;
|
||||
|
||||
/**
|
||||
* Plugin implementation of the 'test_field_widget' widget.
|
||||
*
|
||||
* @FieldWidget(
|
||||
* id = "test_field_widget",
|
||||
* label = @Translation("Test widget"),
|
||||
* field_types = {
|
||||
* "test_field",
|
||||
* "hidden_test_field",
|
||||
* "test_field_with_preconfigured_options"
|
||||
* },
|
||||
* weight = -10
|
||||
* )
|
||||
*/
|
||||
class TestFieldWidget extends WidgetBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function defaultSettings() {
|
||||
return array(
|
||||
'test_widget_setting' => 'dummy test string',
|
||||
'role' => 'anonymous',
|
||||
'role2' => 'anonymous',
|
||||
) + parent::defaultSettings();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function settingsForm(array $form, FormStateInterface $form_state) {
|
||||
$element['test_widget_setting'] = array(
|
||||
'#type' => 'textfield',
|
||||
'#title' => t('Field test field widget setting'),
|
||||
'#description' => t('A dummy form element to simulate field widget setting.'),
|
||||
'#default_value' => $this->getSetting('test_widget_setting'),
|
||||
'#required' => FALSE,
|
||||
);
|
||||
return $element;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function settingsSummary() {
|
||||
$summary = array();
|
||||
$summary[] = t('@setting: @value', array('@setting' => 'test_widget_setting', '@value' => $this->getSetting('test_widget_setting')));
|
||||
return $summary;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) {
|
||||
$element += array(
|
||||
'#type' => 'textfield',
|
||||
'#default_value' => isset($items[$delta]->value) ? $items[$delta]->value : '',
|
||||
);
|
||||
return array('value' => $element);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function errorElement(array $element, ConstraintViolationInterface $violation, array $form, FormStateInterface $form_state) {
|
||||
return $element['value'];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function calculateDependencies() {
|
||||
$dependencies = parent::calculateDependencies();
|
||||
|
||||
foreach (['role', 'role2'] as $setting) {
|
||||
if (!empty($role_id = $this->getSetting($setting))) {
|
||||
// Create a dependency on the role config entity referenced in settings.
|
||||
$dependencies['config'][] = "user.role.$role_id";
|
||||
}
|
||||
}
|
||||
|
||||
return $dependencies;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function onDependencyRemoval(array $dependencies) {
|
||||
$changed = parent::onDependencyRemoval($dependencies);
|
||||
|
||||
// Only the setting 'role' is resolved here. When the dependency related to
|
||||
// this setting is removed, is expected that the widget component will be
|
||||
// update accordingly in the display entity. The 'role2' setting is
|
||||
// deliberately left out from being updated. When the dependency
|
||||
// corresponding to this setting is removed, is expected that the widget
|
||||
// component will be disabled in the display entity.
|
||||
if (!empty($role_id = $this->getSetting('role'))) {
|
||||
if (!empty($dependencies['config']["user.role.$role_id"])) {
|
||||
$this->setSetting('role', 'anonymous');
|
||||
$changed = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return $changed;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,104 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\field_test\Plugin\Field\FieldWidget;
|
||||
|
||||
use Drupal\Core\Field\FieldDefinitionInterface;
|
||||
use Drupal\Core\Field\FieldItemListInterface;
|
||||
use Drupal\Core\Field\WidgetBase;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Symfony\Component\Validator\ConstraintViolationInterface;
|
||||
|
||||
/**
|
||||
* Plugin implementation of the 'test_field_widget_multiple' widget.
|
||||
*
|
||||
* The 'field_types' entry is left empty, and is populated through
|
||||
* hook_field_widget_info_alter().
|
||||
*
|
||||
* @see field_test_field_widget_info_alter()
|
||||
*
|
||||
* @FieldWidget(
|
||||
* id = "test_field_widget_multiple",
|
||||
* label = @Translation("Test widget - multiple"),
|
||||
* multiple_values = TRUE,
|
||||
* weight = 10
|
||||
* )
|
||||
*/
|
||||
class TestFieldWidgetMultiple extends WidgetBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function defaultSettings() {
|
||||
return array(
|
||||
'test_widget_setting_multiple' => 'dummy test string',
|
||||
) + parent::defaultSettings();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function settingsForm(array $form, FormStateInterface $form_state) {
|
||||
$element['test_widget_setting_multiple'] = array(
|
||||
'#type' => 'textfield',
|
||||
'#title' => t('Field test field widget setting'),
|
||||
'#description' => t('A dummy form element to simulate field widget setting.'),
|
||||
'#default_value' => $this->getSetting('test_widget_setting_multiple'),
|
||||
'#required' => FALSE,
|
||||
);
|
||||
return $element;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function settingsSummary() {
|
||||
$summary = array();
|
||||
$summary[] = t('@setting: @value', array('@setting' => 'test_widget_setting_multiple', '@value' => $this->getSetting('test_widget_setting_multiple')));
|
||||
return $summary;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) {
|
||||
$values = array();
|
||||
foreach ($items as $item) {
|
||||
$values[] = $item->value;
|
||||
}
|
||||
$element += array(
|
||||
'#type' => 'textfield',
|
||||
'#default_value' => implode(', ', $values),
|
||||
'#element_validate' => array(array(get_class($this), 'multipleValidate')),
|
||||
);
|
||||
return $element;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function errorElement(array $element, ConstraintViolationInterface $violation, array $form, FormStateInterface $form_state) {
|
||||
return $element;
|
||||
}
|
||||
|
||||
/**
|
||||
* Element validation helper.
|
||||
*/
|
||||
public static function multipleValidate($element, FormStateInterface $form_state) {
|
||||
$values = array_map('trim', explode(',', $element['#value']));
|
||||
$items = array();
|
||||
foreach ($values as $value) {
|
||||
$items[] = array('value' => $value);
|
||||
}
|
||||
$form_state->setValueForElement($element, $items);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* Used in \Drupal\field\Tests\EntityReference\EntityReferenceAdminTest::testAvailableFormatters().
|
||||
*/
|
||||
public static function isApplicable(FieldDefinitionInterface $field_definition) {
|
||||
// Returns FALSE if machine name of the field equals field_onewidgetfield.
|
||||
return $field_definition->getName() != "field_onewidgetfield";
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\field_test\Plugin\Validation\Constraint;
|
||||
|
||||
use Symfony\Component\Validator\Constraints\NotEqualTo;
|
||||
|
||||
/**
|
||||
* Checks if a value is not equal.
|
||||
*
|
||||
* @Constraint(
|
||||
* id = "TestField",
|
||||
* label = @Translation("Test Field", context = "Validation"),
|
||||
* type = { "integer" }
|
||||
* )
|
||||
*/
|
||||
class TestFieldConstraint extends NotEqualTo {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getRequiredOptions() {
|
||||
return array('value');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function validatedBy() {
|
||||
return '\Symfony\Component\Validator\Constraints\NotEqualToValidator';
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
name: 'Boolean field Test'
|
||||
type: module
|
||||
description: 'Support module for the field and entity display tests.'
|
||||
core: 8.x
|
||||
package: Testing
|
||||
version: VERSION
|
||||
dependencies:
|
||||
- field
|
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Module for testing denying access to boolean fields.
|
||||
*/
|
||||
|
||||
use Drupal\Core\Access\AccessResult;
|
||||
use Drupal\Core\Field\FieldDefinitionInterface;
|
||||
use Drupal\Core\Field\FieldItemListInterface;
|
||||
use Drupal\Core\Session\AccountInterface;
|
||||
|
||||
/**
|
||||
* Implements hook_entity_field_access().
|
||||
*/
|
||||
function field_test_boolean_access_denied_entity_field_access($operation, FieldDefinitionInterface $field_definition, AccountInterface $account, FieldItemListInterface $items = NULL) {
|
||||
return AccessResult::forbiddenIf($field_definition->getName() === \Drupal::state()->get('field.test_boolean_field_access_field'));
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
id: entity_test.entity_test.field_test_import
|
||||
langcode: en
|
||||
field_name: field_test_import
|
||||
entity_type: entity_test
|
||||
bundle: entity_test
|
||||
label: 'Test import field'
|
||||
description: ''
|
||||
required: false
|
||||
default_value: { }
|
||||
default_value_callback: ''
|
||||
settings: { }
|
||||
field_type: text
|
||||
dependencies:
|
||||
config:
|
||||
- field.storage.entity_test.field_test_import
|
|
@ -0,0 +1,15 @@
|
|||
id: entity_test.entity_test.field_test_import_2
|
||||
langcode: en
|
||||
field_name: field_test_import_2
|
||||
entity_type: entity_test
|
||||
bundle: entity_test
|
||||
label: 'Test import field 2 on entity_test bundle'
|
||||
description: ''
|
||||
required: false
|
||||
default_value: { }
|
||||
default_value_callback: ''
|
||||
settings: { }
|
||||
field_type: text
|
||||
dependencies:
|
||||
config:
|
||||
- field.storage.entity_test.field_test_import_2
|
|
@ -0,0 +1,15 @@
|
|||
id: entity_test.test_bundle.field_test_import_2
|
||||
langcode: en
|
||||
field_name: field_test_import_2
|
||||
entity_type: entity_test
|
||||
bundle: test_bundle
|
||||
label: 'Test import field 2 on test bundle'
|
||||
description: ''
|
||||
required: false
|
||||
default_value: { }
|
||||
default_value_callback: ''
|
||||
settings: { }
|
||||
field_type: text
|
||||
dependencies:
|
||||
config:
|
||||
- field.storage.entity_test.field_test_import_2
|
|
@ -0,0 +1,20 @@
|
|||
id: entity_test.field_test_import
|
||||
langcode: en
|
||||
field_name: field_test_import
|
||||
entity_type: entity_test
|
||||
type: text
|
||||
settings:
|
||||
max_length: 255
|
||||
module: text
|
||||
locked: false
|
||||
cardinality: 1
|
||||
translatable: false
|
||||
indexes:
|
||||
format:
|
||||
- format
|
||||
dependencies:
|
||||
module:
|
||||
- entity_test
|
||||
- text
|
||||
persist_with_no_fields: false
|
||||
custom_storage: false
|
|
@ -0,0 +1,20 @@
|
|||
id: entity_test.field_test_import_2
|
||||
langcode: en
|
||||
field_name: field_test_import_2
|
||||
entity_type: entity_test
|
||||
type: text
|
||||
settings:
|
||||
max_length: 255
|
||||
module: text
|
||||
locked: false
|
||||
cardinality: 1
|
||||
translatable: false
|
||||
indexes:
|
||||
format:
|
||||
- format
|
||||
dependencies:
|
||||
module:
|
||||
- entity_test
|
||||
- text
|
||||
persist_with_no_fields: false
|
||||
custom_storage: false
|
|
@ -0,0 +1,6 @@
|
|||
name: 'Field API configuration tests'
|
||||
type: module
|
||||
description: 'Support module for the Field API configuration tests.'
|
||||
core: 8.x
|
||||
package: Testing
|
||||
version: VERSION
|
|
@ -0,0 +1,16 @@
|
|||
id: entity_test.entity_test.field_test_import_sync
|
||||
uuid: ea711065-6940-47cd-813d-618f64095481
|
||||
langcode: en
|
||||
field_name: field_test_import_sync
|
||||
entity_type: entity_test
|
||||
bundle: entity_test
|
||||
label: 'Import from sync'
|
||||
description: ''
|
||||
required: '0'
|
||||
default_value: { }
|
||||
default_value_callback: ''
|
||||
settings: { }
|
||||
field_type: text
|
||||
dependencies:
|
||||
config:
|
||||
- field.storage.entity_test.field_test_import_sync
|
|
@ -0,0 +1,16 @@
|
|||
id: entity_test.test_bundle.field_test_import_sync_2
|
||||
uuid: f07794a2-d7cc-45b6-b40d-13cf021b5552
|
||||
langcode: en
|
||||
field_name: field_test_import_sync_2
|
||||
entity_type: entity_test
|
||||
bundle: test_bundle
|
||||
label: 'Test import field 2 on test bundle'
|
||||
description: ''
|
||||
required: '0'
|
||||
default_value: { }
|
||||
default_value_callback: ''
|
||||
settings: { }
|
||||
field_type: text
|
||||
dependencies:
|
||||
config:
|
||||
- field.storage.entity_test.field_test_import_sync_2
|
|
@ -0,0 +1,16 @@
|
|||
id: entity_test.test_bundle_2.field_test_import_sync_2
|
||||
uuid: 49d6dd19-5097-443d-8f00-fc79525bebce
|
||||
langcode: en
|
||||
field_name: field_test_import_sync_2
|
||||
entity_type: entity_test
|
||||
bundle: test_bundle_2
|
||||
label: 'Test import field 2 on test bundle 2'
|
||||
description: ''
|
||||
required: '0'
|
||||
default_value: { }
|
||||
default_value_callback: ''
|
||||
settings: { }
|
||||
field_type: text
|
||||
dependencies:
|
||||
config:
|
||||
- field.storage.entity_test.field_test_import_sync_2
|
|
@ -0,0 +1,21 @@
|
|||
id: entity_test.field_test_import_sync
|
||||
uuid: 0bf654cc-f14a-4881-b94c-76959e47466b
|
||||
langcode: en
|
||||
field_name: field_test_import_sync
|
||||
entity_type: entity_test
|
||||
type: text
|
||||
settings:
|
||||
max_length: '255'
|
||||
module: text
|
||||
locked: '0'
|
||||
cardinality: '1'
|
||||
translatable: '0'
|
||||
indexes:
|
||||
format:
|
||||
- format
|
||||
dependencies:
|
||||
module:
|
||||
- entity_test
|
||||
- text
|
||||
persist_with_no_fields: false
|
||||
custom_storage: false
|
|
@ -0,0 +1,21 @@
|
|||
id: entity_test.field_test_import_sync_2
|
||||
uuid: 2165d9aa-9a0c-41a1-be02-2a49f3405c00
|
||||
langcode: en
|
||||
field_name: field_test_import_sync_2
|
||||
entity_type: entity_test
|
||||
type: text
|
||||
settings:
|
||||
max_length: '255'
|
||||
module: text
|
||||
locked: '0'
|
||||
cardinality: '1'
|
||||
translatable: '0'
|
||||
indexes:
|
||||
format:
|
||||
- format
|
||||
dependencies:
|
||||
module:
|
||||
- entity_test
|
||||
- text
|
||||
persist_with_no_fields: false
|
||||
custom_storage: false
|
|
@ -0,0 +1,8 @@
|
|||
name: 'Field test views'
|
||||
type: module
|
||||
description: 'Provides default views for views field tests.'
|
||||
package: Testing
|
||||
version: VERSION
|
||||
core: 8.x
|
||||
dependencies:
|
||||
- views
|
|
@ -0,0 +1,52 @@
|
|||
langcode: en
|
||||
status: true
|
||||
dependencies:
|
||||
module:
|
||||
- node
|
||||
- user
|
||||
config:
|
||||
- field.storage.node.field_test
|
||||
id: test_view_field_delete
|
||||
label: test_view_field_delete
|
||||
module: views
|
||||
description: ''
|
||||
tag: default
|
||||
base_table: node
|
||||
base_field: nid
|
||||
core: '8'
|
||||
display:
|
||||
default:
|
||||
display_options:
|
||||
access:
|
||||
type: perm
|
||||
fields:
|
||||
nid:
|
||||
field: nid
|
||||
id: nid
|
||||
table: node
|
||||
plugin_id: field
|
||||
entity_type: node
|
||||
entity_field: nid
|
||||
field_test:
|
||||
id: field_test
|
||||
table: node__field_test
|
||||
field: field_test
|
||||
plugin_id: field
|
||||
entity_type: node
|
||||
entity_field: field_test
|
||||
cache:
|
||||
type: tag
|
||||
exposed_form:
|
||||
type: basic
|
||||
pager:
|
||||
type: full
|
||||
query:
|
||||
type: views_query
|
||||
style:
|
||||
type: default
|
||||
row:
|
||||
type: fields
|
||||
display_plugin: default
|
||||
display_title: Master
|
||||
id: default
|
||||
position: 0
|
|
@ -0,0 +1,64 @@
|
|||
langcode: en
|
||||
status: true
|
||||
dependencies:
|
||||
module:
|
||||
- node
|
||||
- user
|
||||
id: test_view_fieldapi
|
||||
label: test_view_fieldapi
|
||||
module: views
|
||||
description: ''
|
||||
tag: default
|
||||
base_table: node_field_data
|
||||
base_field: nid
|
||||
core: '8'
|
||||
display:
|
||||
default:
|
||||
display_options:
|
||||
access:
|
||||
type: perm
|
||||
fields:
|
||||
nid:
|
||||
field: nid
|
||||
id: nid
|
||||
table: node_field_data
|
||||
plugin_id: field
|
||||
entity_type: node
|
||||
entity_field: nid
|
||||
field_name_0:
|
||||
id: field_name_0
|
||||
table: node__field_name_0
|
||||
field: field_name_0
|
||||
plugin_id: field
|
||||
entity_type: node
|
||||
entity_field: field_name_0
|
||||
field_name_5:
|
||||
id: field_name_5
|
||||
table: node__field_name_5
|
||||
field: field_name_5
|
||||
plugin_id: field
|
||||
entity_type: node
|
||||
entity_field: field_name_5
|
||||
field_no_view_access:
|
||||
id: field_no_view_access
|
||||
table: node__field_no_view_access
|
||||
field: field_no_view_access
|
||||
plugin_id: field
|
||||
entity_type: node
|
||||
entity_field: field_no_view_access
|
||||
cache:
|
||||
type: tag
|
||||
exposed_form:
|
||||
type: basic
|
||||
pager:
|
||||
type: full
|
||||
query:
|
||||
type: views_query
|
||||
style:
|
||||
type: default
|
||||
row:
|
||||
type: fields
|
||||
display_plugin: default
|
||||
display_title: Master
|
||||
id: default
|
||||
position: 0
|
|
@ -0,0 +1,15 @@
|
|||
field.formatter.third_party.field_third_party_test:
|
||||
type: mapping
|
||||
label: 'field_third_party_test third party formatter settings'
|
||||
mapping:
|
||||
field_test_field_formatter_third_party_settings_form:
|
||||
type: string
|
||||
label: field_test_field_formatter_third_party_settings_form
|
||||
|
||||
field.widget.third_party.field_third_party_test:
|
||||
type: mapping
|
||||
label: 'field_third_party_test third party widget settings'
|
||||
mapping:
|
||||
field_test_widget_third_party_settings_form:
|
||||
type: string
|
||||
label: field_test_widget_third_party_settings_form
|
|
@ -0,0 +1,9 @@
|
|||
name: 'Field Third Party Settings Test'
|
||||
type: module
|
||||
description: 'Support module for the Field API tests.'
|
||||
core: 8.x
|
||||
package: Testing
|
||||
version: VERSION
|
||||
dependencies:
|
||||
- entity_test
|
||||
- field_test
|
|
@ -0,0 +1,51 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Test module.
|
||||
*/
|
||||
|
||||
use Drupal\Core\Field\FieldDefinitionInterface;
|
||||
use Drupal\Core\Field\FormatterInterface;
|
||||
use Drupal\Core\Field\WidgetInterface;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
|
||||
/**
|
||||
* Implements hook_field_widget_third_party_settings_form().
|
||||
*/
|
||||
function field_third_party_test_field_widget_third_party_settings_form(WidgetInterface $plugin, FieldDefinitionInterface $field_definition, $form_mode, $form, FormStateInterface $form_state) {
|
||||
$element['field_test_widget_third_party_settings_form'] = array(
|
||||
'#type' => 'textfield',
|
||||
'#title' => t('3rd party widget settings form'),
|
||||
'#default_value' => $plugin->getThirdPartySetting('field_third_party_test', 'field_test_widget_third_party_settings_form'),
|
||||
);
|
||||
return $element;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_field_widget_settings_summary_alter().
|
||||
*/
|
||||
function field_third_party_test_field_widget_settings_summary_alter(&$summary, $context) {
|
||||
$summary[] = 'field_test_field_widget_settings_summary_alter';
|
||||
return $summary;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_field_formatter_third_party_settings_form().
|
||||
*/
|
||||
function field_third_party_test_field_formatter_third_party_settings_form(FormatterInterface $plugin, FieldDefinitionInterface $field_definition, $view_mode, $form, FormStateInterface $form_state) {
|
||||
$element['field_test_field_formatter_third_party_settings_form'] = array(
|
||||
'#type' => 'textfield',
|
||||
'#title' => t('3rd party formatter settings form'),
|
||||
'#default_value' => $plugin->getThirdPartySetting('field_third_party_test', 'field_test_field_formatter_third_party_settings_form'),
|
||||
);
|
||||
return $element;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_field_formatter_settings_summary_alter().
|
||||
*/
|
||||
function field_third_party_test_field_formatter_settings_summary_alter(&$summary, $context) {
|
||||
$summary[] = 'field_test_field_formatter_settings_summary_alter';
|
||||
return $summary;
|
||||
}
|
|
@ -0,0 +1,139 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\field\Kernel\Boolean;
|
||||
|
||||
use Drupal\Component\Utility\Unicode;
|
||||
use Drupal\Core\Entity\Display\EntityViewDisplayInterface;
|
||||
use Drupal\Core\Entity\FieldableEntityInterface;
|
||||
use Drupal\entity_test\Entity\EntityTest;
|
||||
use Drupal\field\Entity\FieldConfig;
|
||||
use Drupal\field\Entity\FieldStorageConfig;
|
||||
use Drupal\KernelTests\KernelTestBase;
|
||||
|
||||
/**
|
||||
* Tests the boolean formatter.
|
||||
*
|
||||
* @group field
|
||||
*/
|
||||
class BooleanFormatterTest extends KernelTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['field', 'text', 'entity_test', 'user', 'system'];
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $entityType;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $bundle;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $fieldName;
|
||||
|
||||
/**
|
||||
* @var \Drupal\Core\Entity\Display\EntityViewDisplayInterface
|
||||
*/
|
||||
protected $display;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$this->installConfig(['field']);
|
||||
$this->installEntitySchema('entity_test');
|
||||
|
||||
$this->entityType = 'entity_test';
|
||||
$this->bundle = $this->entityType;
|
||||
$this->fieldName = Unicode::strtolower($this->randomMachineName());
|
||||
|
||||
$field_storage = FieldStorageConfig::create([
|
||||
'field_name' => $this->fieldName,
|
||||
'entity_type' => $this->entityType,
|
||||
'type' => 'boolean',
|
||||
]);
|
||||
$field_storage->save();
|
||||
|
||||
$instance = FieldConfig::create([
|
||||
'field_storage' => $field_storage,
|
||||
'bundle' => $this->bundle,
|
||||
'label' => $this->randomMachineName(),
|
||||
]);
|
||||
$instance->save();
|
||||
|
||||
$this->display = entity_get_display($this->entityType, $this->bundle, 'default')
|
||||
->setComponent($this->fieldName, [
|
||||
'type' => 'boolean',
|
||||
'settings' => [],
|
||||
]);
|
||||
$this->display->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders fields of a given entity with a given display.
|
||||
*
|
||||
* @param \Drupal\Core\Entity\FieldableEntityInterface $entity
|
||||
* The entity object with attached fields to render.
|
||||
* @param \Drupal\Core\Entity\Display\EntityViewDisplayInterface $display
|
||||
* The display to render the fields in.
|
||||
*
|
||||
* @return string
|
||||
* The rendered entity fields.
|
||||
*/
|
||||
protected function renderEntityFields(FieldableEntityInterface $entity, EntityViewDisplayInterface $display) {
|
||||
$content = $display->build($entity);
|
||||
$content = $this->render($content);
|
||||
return $content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests boolean formatter output.
|
||||
*/
|
||||
public function testBooleanFormatter() {
|
||||
$data = [];
|
||||
$data[] = [0, [], 'Off'];
|
||||
$data[] = [1, [], 'On'];
|
||||
|
||||
$format = ['format' => 'enabled-disabled'];
|
||||
$data[] = [0, $format, 'Disabled'];
|
||||
$data[] = [1, $format, 'Enabled'];
|
||||
|
||||
$format = ['format' => 'unicode-yes-no'];
|
||||
$data[] = [1, $format, '✔'];
|
||||
$data[] = [0, $format, '✖'];
|
||||
|
||||
$format = [
|
||||
'format' => 'custom',
|
||||
'format_custom_false' => 'FALSE',
|
||||
'format_custom_true' => 'TRUE'
|
||||
];
|
||||
$data[] = [0, $format, 'FALSE'];
|
||||
$data[] = [1, $format, 'TRUE'];
|
||||
|
||||
foreach ($data as $test_data) {
|
||||
list($value, $settings, $expected) = $test_data;
|
||||
|
||||
$component = $this->display->getComponent($this->fieldName);
|
||||
$component['settings'] = $settings;
|
||||
$this->display->setComponent($this->fieldName, $component);
|
||||
|
||||
$entity = EntityTest::create([]);
|
||||
$entity->{$this->fieldName}->value = $value;
|
||||
|
||||
// Verify that all HTML is escaped and newlines are retained.
|
||||
$this->renderEntityFields($entity, $this->display);
|
||||
$this->assertRaw($expected);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,80 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\field\Kernel\Boolean;
|
||||
|
||||
use Drupal\Core\Field\FieldItemListInterface;
|
||||
use Drupal\Core\Field\FieldItemInterface;
|
||||
use Drupal\entity_test\Entity\EntityTest;
|
||||
use Drupal\field\Entity\FieldConfig;
|
||||
use Drupal\Tests\field\Kernel\FieldKernelTestBase;
|
||||
use Drupal\field\Entity\FieldStorageConfig;
|
||||
|
||||
/**
|
||||
* Tests the new entity API for the boolean field type.
|
||||
*
|
||||
* @group field
|
||||
*/
|
||||
class BooleanItemTest extends FieldKernelTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
// Create a boolean field and storage for validation.
|
||||
FieldStorageConfig::create(array(
|
||||
'field_name' => 'field_boolean',
|
||||
'entity_type' => 'entity_test',
|
||||
'type' => 'boolean',
|
||||
))->save();
|
||||
FieldConfig::create([
|
||||
'entity_type' => 'entity_test',
|
||||
'field_name' => 'field_boolean',
|
||||
'bundle' => 'entity_test',
|
||||
])->save();
|
||||
|
||||
// Create a form display for the default form mode.
|
||||
entity_get_form_display('entity_test', 'entity_test', 'default')
|
||||
->setComponent('field_boolean', array(
|
||||
'type' => 'boolean_checkbox',
|
||||
))
|
||||
->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests using entity fields of the boolean field type.
|
||||
*/
|
||||
public function testBooleanItem() {
|
||||
// Verify entity creation.
|
||||
$entity = EntityTest::create();
|
||||
$value = '1';
|
||||
$entity->field_boolean = $value;
|
||||
$entity->name->value = $this->randomMachineName();
|
||||
$entity->save();
|
||||
|
||||
// Verify entity has been created properly.
|
||||
$id = $entity->id();
|
||||
$entity = EntityTest::load($id);
|
||||
$this->assertTrue($entity->field_boolean instanceof FieldItemListInterface, 'Field implements interface.');
|
||||
$this->assertTrue($entity->field_boolean[0] instanceof FieldItemInterface, 'Field item implements interface.');
|
||||
$this->assertEqual($entity->field_boolean->value, $value);
|
||||
$this->assertEqual($entity->field_boolean[0]->value, $value);
|
||||
|
||||
// Verify changing the boolean value.
|
||||
$new_value = 0;
|
||||
$entity->field_boolean->value = $new_value;
|
||||
$this->assertEqual($entity->field_boolean->value, $new_value);
|
||||
|
||||
// Read changed entity and assert changed values.
|
||||
$entity->save();
|
||||
$entity = EntityTest::load($id);
|
||||
$this->assertEqual($entity->field_boolean->value, $new_value);
|
||||
|
||||
// Test sample item generation.
|
||||
$entity = EntityTest::create();
|
||||
$entity->field_boolean->generateSampleItems();
|
||||
$this->entityValidateAndSave($entity);
|
||||
}
|
||||
|
||||
}
|
452
web/core/modules/field/tests/src/Kernel/BulkDeleteTest.php
Normal file
452
web/core/modules/field/tests/src/Kernel/BulkDeleteTest.php
Normal file
|
@ -0,0 +1,452 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\field\Kernel;
|
||||
|
||||
use Drupal\Core\Entity\EntityInterface;
|
||||
use Drupal\field\Entity\FieldConfig;
|
||||
use Drupal\field\Entity\FieldStorageConfig;
|
||||
|
||||
/**
|
||||
* Bulk delete storages and fields, and clean up afterwards.
|
||||
*
|
||||
* @group field
|
||||
*/
|
||||
class BulkDeleteTest extends FieldKernelTestBase {
|
||||
|
||||
/**
|
||||
* The fields to use in this test.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $fieldStorages;
|
||||
|
||||
/**
|
||||
* The entities to use in this test.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $entities;
|
||||
|
||||
/**
|
||||
* The entities to use in this test, keyed by bundle.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $entitiesByBundles;
|
||||
|
||||
/**
|
||||
* The bundles for the entities used in this test.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $bundles;
|
||||
|
||||
/**
|
||||
* The entity type to be used in the test classes.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $entityTypeId = 'entity_test';
|
||||
|
||||
/**
|
||||
* Tests that the expected hooks have been invoked on the expected entities.
|
||||
*
|
||||
* @param $expected_hooks
|
||||
* An array keyed by hook name, with one entry per expected invocation.
|
||||
* Each entry is the value of the "$entity" parameter the hook is expected
|
||||
* to have been passed.
|
||||
* @param $actual_hooks
|
||||
* The array of actual hook invocations recorded by field_test_memorize().
|
||||
*/
|
||||
function checkHooksInvocations($expected_hooks, $actual_hooks) {
|
||||
foreach ($expected_hooks as $hook => $invocations) {
|
||||
$actual_invocations = $actual_hooks[$hook];
|
||||
|
||||
// Check that the number of invocations is correct.
|
||||
$this->assertEqual(count($actual_invocations), count($invocations), "$hook() was called the expected number of times.");
|
||||
|
||||
// Check that the hook was called for each expected argument.
|
||||
foreach ($invocations as $argument) {
|
||||
$found = FALSE;
|
||||
foreach ($actual_invocations as $actual_arguments) {
|
||||
// The argument we are looking for is either an array of entities as
|
||||
// the second argument or a single entity object as the first.
|
||||
if ($argument instanceof EntityInterface && $actual_arguments[0]->id() == $argument->id()) {
|
||||
$found = TRUE;
|
||||
break;
|
||||
}
|
||||
// In case of an array, compare the array size and make sure it
|
||||
// contains the same elements.
|
||||
elseif (is_array($argument) && count($actual_arguments[1]) == count($argument) && count(array_diff_key($actual_arguments[1], $argument)) == 0) {
|
||||
$found = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
$this->assertTrue($found, "$hook() was called on expected argument");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$this->fieldStorages = array();
|
||||
$this->entities = array();
|
||||
$this->entitiesByBundles = array();
|
||||
|
||||
// Create two bundles.
|
||||
$this->bundles = array('bb_1' => 'bb_1', 'bb_2' => 'bb_2');
|
||||
foreach ($this->bundles as $name => $desc) {
|
||||
entity_test_create_bundle($name, $desc);
|
||||
}
|
||||
|
||||
// Create two field storages.
|
||||
$field_storage = FieldStorageConfig::create(array(
|
||||
'field_name' => 'bf_1',
|
||||
'entity_type' => $this->entityTypeId,
|
||||
'type' => 'test_field',
|
||||
'cardinality' => 1
|
||||
));
|
||||
$field_storage->save();
|
||||
$this->fieldStorages[] = $field_storage;
|
||||
$field_storage = FieldStorageConfig::create(array(
|
||||
'field_name' => 'bf_2',
|
||||
'entity_type' => $this->entityTypeId,
|
||||
'type' => 'test_field',
|
||||
'cardinality' => 4
|
||||
));
|
||||
$field_storage->save();
|
||||
$this->fieldStorages[] = $field_storage;
|
||||
|
||||
// For each bundle, create each field, and 10 entities with values for the
|
||||
// fields.
|
||||
foreach ($this->bundles as $bundle) {
|
||||
foreach ($this->fieldStorages as $field_storage) {
|
||||
FieldConfig::create([
|
||||
'field_storage' => $field_storage,
|
||||
'bundle' => $bundle,
|
||||
])->save();
|
||||
}
|
||||
for ($i = 0; $i < 10; $i++) {
|
||||
$entity = $this->container->get('entity_type.manager')
|
||||
->getStorage($this->entityTypeId)
|
||||
->create(array('type' => $bundle));
|
||||
foreach ($this->fieldStorages as $field_storage) {
|
||||
$entity->{$field_storage->getName()}->setValue($this->_generateTestFieldValues($field_storage->getCardinality()));
|
||||
}
|
||||
$entity->save();
|
||||
}
|
||||
}
|
||||
$this->entities = $this->container->get('entity_type.manager')
|
||||
->getStorage($this->entityTypeId)->loadMultiple();
|
||||
foreach ($this->entities as $entity) {
|
||||
// This test relies on the entities having stale field definitions
|
||||
// so that the deleted field can be accessed on them. Access the field
|
||||
// now, so that they are always loaded.
|
||||
$entity->bf_1->value;
|
||||
|
||||
// Also keep track of the entities per bundle.
|
||||
$this->entitiesByBundles[$entity->bundle()][$entity->id()] = $entity;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify that deleting a field leaves the field data items in the database
|
||||
* and that the appropriate Field API functions can operate on the deleted
|
||||
* data and field definition.
|
||||
*
|
||||
* This tests how EntityFieldQuery interacts with field deletion and could be
|
||||
* moved to FieldCrudTestCase, but depends on this class's setUp().
|
||||
*/
|
||||
function testDeleteField() {
|
||||
$bundle = reset($this->bundles);
|
||||
$field_storage = reset($this->fieldStorages);
|
||||
$field_name = $field_storage->getName();
|
||||
$factory = \Drupal::service('entity.query');
|
||||
|
||||
// There are 10 entities of this bundle.
|
||||
$found = $factory->get('entity_test')
|
||||
->condition('type', $bundle)
|
||||
->execute();
|
||||
$this->assertEqual(count($found), 10, 'Correct number of entities found before deleting');
|
||||
|
||||
// Delete the field.
|
||||
$field = FieldConfig::loadByName($this->entityTypeId, $bundle, $field_name);
|
||||
$field->delete();
|
||||
|
||||
// The field still exists, deleted.
|
||||
$fields = entity_load_multiple_by_properties('field_config', array('field_storage_uuid' => $field_storage->uuid(), 'deleted' => TRUE, 'include_deleted' => TRUE));
|
||||
$this->assertEqual(count($fields), 1, 'There is one deleted field');
|
||||
$field = $fields[$field->uuid()];
|
||||
$this->assertEqual($field->getTargetBundle(), $bundle, 'The deleted field is for the correct bundle');
|
||||
|
||||
// Check that the actual stored content did not change during delete.
|
||||
$storage = \Drupal::entityManager()->getStorage($this->entityTypeId);
|
||||
/** @var \Drupal\Core\Entity\Sql\DefaultTableMapping $table_mapping */
|
||||
$table_mapping = $storage->getTableMapping();
|
||||
$table = $table_mapping->getDedicatedDataTableName($field_storage);
|
||||
$column = $table_mapping->getFieldColumnName($field_storage, 'value');
|
||||
$result = db_select($table, 't')
|
||||
->fields('t')
|
||||
->execute();
|
||||
foreach ($result as $row) {
|
||||
$this->assertEqual($this->entities[$row->entity_id]->{$field_name}->value, $row->$column);
|
||||
}
|
||||
|
||||
// There are 0 entities of this bundle with non-deleted data.
|
||||
$found = $factory->get('entity_test')
|
||||
->condition('type', $bundle)
|
||||
->condition("$field_name.deleted", 0)
|
||||
->execute();
|
||||
$this->assertFalse($found, 'No entities found after deleting');
|
||||
|
||||
// There are 10 entities of this bundle when deleted fields are allowed, and
|
||||
// their values are correct.
|
||||
$found = $factory->get('entity_test')
|
||||
->condition('type', $bundle)
|
||||
->condition("$field_name.deleted", 1)
|
||||
->sort('id')
|
||||
->execute();
|
||||
$this->assertEqual(count($found), 10, 'Correct number of entities found after deleting');
|
||||
$this->assertFalse(array_diff($found, array_keys($this->entities)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that recreating a field with the name as a deleted field works.
|
||||
*/
|
||||
public function testPurgeWithDeletedAndActiveField() {
|
||||
$bundle = reset($this->bundles);
|
||||
// Create another field storage.
|
||||
$field_name = 'bf_3';
|
||||
$deleted_field_storage = FieldStorageConfig::create(array(
|
||||
'field_name' => $field_name,
|
||||
'entity_type' => $this->entityTypeId,
|
||||
'type' => 'test_field',
|
||||
'cardinality' => 1
|
||||
));
|
||||
$deleted_field_storage->save();
|
||||
// Create the field.
|
||||
FieldConfig::create([
|
||||
'field_storage' => $deleted_field_storage,
|
||||
'bundle' => $bundle,
|
||||
])->save();
|
||||
|
||||
for ($i = 0; $i < 20; $i++) {
|
||||
$entity = $this->container->get('entity_type.manager')
|
||||
->getStorage($this->entityTypeId)
|
||||
->create(array('type' => $bundle));
|
||||
$entity->{$field_name}->setValue($this->_generateTestFieldValues(1));
|
||||
$entity->save();
|
||||
}
|
||||
|
||||
// Delete the field.
|
||||
$deleted_field = FieldConfig::loadByName($this->entityTypeId, $bundle, $field_name);
|
||||
$deleted_field->delete();
|
||||
$deleted_field_uuid = $deleted_field->uuid();
|
||||
|
||||
// Reload the field storage.
|
||||
$field_storages = entity_load_multiple_by_properties('field_storage_config', array('uuid' => $deleted_field_storage->uuid(), 'include_deleted' => TRUE));
|
||||
$deleted_field_storage = reset($field_storages);
|
||||
|
||||
// Create the field again.
|
||||
$field_storage = FieldStorageConfig::create(array(
|
||||
'field_name' => $field_name,
|
||||
'entity_type' => $this->entityTypeId,
|
||||
'type' => 'test_field',
|
||||
'cardinality' => 1
|
||||
));
|
||||
$field_storage->save();
|
||||
FieldConfig::create([
|
||||
'field_storage' => $field_storage,
|
||||
'bundle' => $bundle,
|
||||
])->save();
|
||||
|
||||
// The field still exists, deleted, with the same field name.
|
||||
$fields = entity_load_multiple_by_properties('field_config', array('uuid' => $deleted_field_uuid, 'include_deleted' => TRUE));
|
||||
$this->assertTrue(isset($fields[$deleted_field_uuid]) && $fields[$deleted_field_uuid]->isDeleted(), 'The field exists and is deleted');
|
||||
$this->assertTrue(isset($fields[$deleted_field_uuid]) && $fields[$deleted_field_uuid]->getName() == $field_name);
|
||||
|
||||
for ($i = 0; $i < 10; $i++) {
|
||||
$entity = $this->container->get('entity_type.manager')
|
||||
->getStorage($this->entityTypeId)
|
||||
->create(array('type' => $bundle));
|
||||
$entity->{$field_name}->setValue($this->_generateTestFieldValues(1));
|
||||
$entity->save();
|
||||
}
|
||||
|
||||
// Check that the two field storages have different tables.
|
||||
$storage = \Drupal::entityManager()->getStorage($this->entityTypeId);
|
||||
/** @var \Drupal\Core\Entity\Sql\DefaultTableMapping $table_mapping */
|
||||
$table_mapping = $storage->getTableMapping();
|
||||
$deleted_table_name = $table_mapping->getDedicatedDataTableName($deleted_field_storage, TRUE);
|
||||
$active_table_name = $table_mapping->getDedicatedDataTableName($field_storage);
|
||||
|
||||
field_purge_batch(50);
|
||||
|
||||
// Ensure the new field still has its table and the deleted one has been
|
||||
// removed.
|
||||
$this->assertTrue(\Drupal::database()->schema()->tableExists($active_table_name));
|
||||
$this->assertFalse(\Drupal::database()->schema()->tableExists($deleted_table_name));
|
||||
|
||||
// The field has been removed from the system.
|
||||
$fields = entity_load_multiple_by_properties('field_config', array('field_storage_uuid' => $deleted_field_storage->uuid(), 'deleted' => TRUE, 'include_deleted' => TRUE));
|
||||
$this->assertEqual(count($fields), 0, 'The field is gone');
|
||||
|
||||
// Verify there are still 10 entries in the main table.
|
||||
$count = \Drupal::database()
|
||||
->select('entity_test__' . $field_name, 'f')
|
||||
->fields('f', array('entity_id'))
|
||||
->condition('bundle', $bundle)
|
||||
->countQuery()
|
||||
->execute()
|
||||
->fetchField();
|
||||
$this->assertEqual($count, 10);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify that field data items and fields are purged when a field storage is
|
||||
* deleted.
|
||||
*/
|
||||
function testPurgeField() {
|
||||
// Start recording hook invocations.
|
||||
field_test_memorize();
|
||||
|
||||
$bundle = reset($this->bundles);
|
||||
$field_storage = reset($this->fieldStorages);
|
||||
$field_name = $field_storage->getName();
|
||||
|
||||
// Delete the field.
|
||||
$field = FieldConfig::loadByName($this->entityTypeId, $bundle, $field_name);
|
||||
$field->delete();
|
||||
|
||||
// No field hooks were called.
|
||||
$mem = field_test_memorize();
|
||||
$this->assertEqual(count($mem), 0, 'No field hooks were called');
|
||||
|
||||
$batch_size = 2;
|
||||
for ($count = 8; $count >= 0; $count -= $batch_size) {
|
||||
// Purge two entities.
|
||||
field_purge_batch($batch_size);
|
||||
|
||||
// There are $count deleted entities left.
|
||||
$found = \Drupal::entityQuery('entity_test')
|
||||
->condition('type', $bundle)
|
||||
->condition($field_name . '.deleted', 1)
|
||||
->execute();
|
||||
$this->assertEqual(count($found), $count, 'Correct number of entities found after purging 2');
|
||||
}
|
||||
|
||||
// Check hooks invocations.
|
||||
// FieldItemInterface::delete() should have been called once for each entity in the
|
||||
// bundle.
|
||||
$actual_hooks = field_test_memorize();
|
||||
$hooks = array();
|
||||
$entities = $this->entitiesByBundles[$bundle];
|
||||
foreach ($entities as $id => $entity) {
|
||||
$hooks['field_test_field_delete'][] = $entity;
|
||||
}
|
||||
$this->checkHooksInvocations($hooks, $actual_hooks);
|
||||
|
||||
// The field still exists, deleted.
|
||||
$fields = entity_load_multiple_by_properties('field_config', array('field_storage_uuid' => $field_storage->uuid(), 'deleted' => TRUE, 'include_deleted' => TRUE));
|
||||
$this->assertEqual(count($fields), 1, 'There is one deleted field');
|
||||
|
||||
// Purge the field.
|
||||
field_purge_batch($batch_size);
|
||||
|
||||
// The field is gone.
|
||||
$fields = entity_load_multiple_by_properties('field_config', array('field_storage_uuid' => $field_storage->uuid(), 'deleted' => TRUE, 'include_deleted' => TRUE));
|
||||
$this->assertEqual(count($fields), 0, 'The field is gone');
|
||||
|
||||
// The field storage still exists, not deleted, because it has a second
|
||||
// field.
|
||||
$storages = entity_load_multiple_by_properties('field_storage_config', array('uuid' => $field_storage->uuid(), 'include_deleted' => TRUE));
|
||||
$this->assertTrue(isset($storages[$field_storage->uuid()]), 'The field storage exists and is not deleted');
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify that field storages are preserved and purged correctly as multiple
|
||||
* fields are deleted and purged.
|
||||
*/
|
||||
function testPurgeFieldStorage() {
|
||||
// Start recording hook invocations.
|
||||
field_test_memorize();
|
||||
|
||||
$field_storage = reset($this->fieldStorages);
|
||||
$field_name = $field_storage->getName();
|
||||
|
||||
// Delete the first field.
|
||||
$bundle = reset($this->bundles);
|
||||
$field = FieldConfig::loadByName($this->entityTypeId, $bundle, $field_name);
|
||||
$field->delete();
|
||||
|
||||
// Assert that FieldItemInterface::delete() was not called yet.
|
||||
$mem = field_test_memorize();
|
||||
$this->assertEqual(count($mem), 0, 'No field hooks were called.');
|
||||
|
||||
// Purge the data.
|
||||
field_purge_batch(10);
|
||||
|
||||
// Check hooks invocations.
|
||||
// FieldItemInterface::delete() should have been called once for each entity in the
|
||||
// bundle.
|
||||
$actual_hooks = field_test_memorize();
|
||||
$hooks = array();
|
||||
$entities = $this->entitiesByBundles[$bundle];
|
||||
foreach ($entities as $id => $entity) {
|
||||
$hooks['field_test_field_delete'][] = $entity;
|
||||
}
|
||||
$this->checkHooksInvocations($hooks, $actual_hooks);
|
||||
|
||||
// The field still exists, deleted.
|
||||
$fields = entity_load_multiple_by_properties('field_config', array('uuid' => $field->uuid(), 'include_deleted' => TRUE));
|
||||
$this->assertTrue(isset($fields[$field->uuid()]) && $fields[$field->uuid()]->isDeleted(), 'The field exists and is deleted');
|
||||
|
||||
// Purge again to purge the field.
|
||||
field_purge_batch(0);
|
||||
|
||||
// The field is gone.
|
||||
$fields = entity_load_multiple_by_properties('field_config', array('uuid' => $field->uuid(), 'include_deleted' => TRUE));
|
||||
$this->assertEqual(count($fields), 0, 'The field is purged.');
|
||||
// The field storage still exists, not deleted.
|
||||
$storages = entity_load_multiple_by_properties('field_storage_config', array('uuid' => $field_storage->uuid(), 'include_deleted' => TRUE));
|
||||
$this->assertTrue(isset($storages[$field_storage->uuid()]) && !$storages[$field_storage->uuid()]->isDeleted(), 'The field storage exists and is not deleted');
|
||||
|
||||
// Delete the second field.
|
||||
$bundle = next($this->bundles);
|
||||
$field = FieldConfig::loadByName($this->entityTypeId, $bundle, $field_name);
|
||||
$field->delete();
|
||||
|
||||
// Assert that FieldItemInterface::delete() was not called yet.
|
||||
$mem = field_test_memorize();
|
||||
$this->assertEqual(count($mem), 0, 'No field hooks were called.');
|
||||
|
||||
// Purge the data.
|
||||
field_purge_batch(10);
|
||||
|
||||
// Check hooks invocations (same as above, for the 2nd bundle).
|
||||
$actual_hooks = field_test_memorize();
|
||||
$hooks = array();
|
||||
$entities = $this->entitiesByBundles[$bundle];
|
||||
foreach ($entities as $id => $entity) {
|
||||
$hooks['field_test_field_delete'][] = $entity;
|
||||
}
|
||||
$this->checkHooksInvocations($hooks, $actual_hooks);
|
||||
|
||||
// The field and the storage still exist, deleted.
|
||||
$fields = entity_load_multiple_by_properties('field_config', array('uuid' => $field->uuid(), 'include_deleted' => TRUE));
|
||||
$this->assertTrue(isset($fields[$field->uuid()]) && $fields[$field->uuid()]->isDeleted(), 'The field exists and is deleted');
|
||||
$storages = entity_load_multiple_by_properties('field_storage_config', array('uuid' => $field_storage->uuid(), 'include_deleted' => TRUE));
|
||||
$this->assertTrue(isset($storages[$field_storage->uuid()]) && $storages[$field_storage->uuid()]->isDeleted(), 'The field storage exists and is deleted');
|
||||
|
||||
// Purge again to purge the field and the storage.
|
||||
field_purge_batch(0);
|
||||
|
||||
// The field and the storage are gone.
|
||||
$fields = entity_load_multiple_by_properties('field_config', array('uuid' => $field->uuid(), 'include_deleted' => TRUE));
|
||||
$this->assertEqual(count($fields), 0, 'The field is purged.');
|
||||
$storages = entity_load_multiple_by_properties('field_storage_config', array('uuid' => $field_storage->uuid(), 'include_deleted' => TRUE));
|
||||
$this->assertEqual(count($storages), 0, 'The field storage is purged.');
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\field\Kernel;
|
||||
|
||||
use Drupal\Core\Field\FieldDefinitionInterface;
|
||||
use Drupal\Core\Field\FieldStorageDefinitionInterface;
|
||||
|
||||
/**
|
||||
* Tests exposing field definitions for configurable fields.
|
||||
*
|
||||
* @group field
|
||||
*/
|
||||
class ConfigFieldDefinitionTest extends FieldKernelTestBase {
|
||||
|
||||
/**
|
||||
* The entity manager service.
|
||||
*
|
||||
* @var \Drupal\Core\Entity\EntityManagerInterface;
|
||||
*/
|
||||
protected $entityManager;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $entityType;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $bundle;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
// Create a field and a storage of type 'test_field', on the 'entity_test'
|
||||
// entity type.
|
||||
$this->entityType = 'entity_test';
|
||||
$this->bundle = 'entity_test';
|
||||
$this->createFieldWithStorage('', $this->entityType, $this->bundle);
|
||||
$this->entityManager = $this->container->get('entity.manager');
|
||||
|
||||
// Create a second field on 'entity_test_rev'.
|
||||
$this->createFieldWithStorage('_rev', 'entity_test_rev', 'entity_test_rev');
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes sure a field definition is exposed for a configurable field.
|
||||
*/
|
||||
public function testBundleFieldDefinition() {
|
||||
$definitions = $this->entityManager->getFieldDefinitions($this->entityType, $this->bundle);
|
||||
$this->assertTrue(isset($definitions[$this->fieldTestData->field->getName()]));
|
||||
$this->assertTrue($definitions[$this->fieldTestData->field->getName()] instanceof FieldDefinitionInterface);
|
||||
// Make sure fields on other entity types are not exposed.
|
||||
$this->assertFalse(isset($definitions[$this->fieldTestData->field_rev->getName()]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes sure a field storage definition is exposed for a configurable field.
|
||||
*/
|
||||
public function testFieldStorageDefinition() {
|
||||
$field_storage_definitions = $this->entityManager->getFieldStorageDefinitions($this->entityType);
|
||||
$this->assertTrue(isset($field_storage_definitions[$this->fieldTestData->field->getName()]));
|
||||
$this->assertTrue($field_storage_definitions[$this->fieldTestData->field->getName()] instanceof FieldStorageDefinitionInterface);
|
||||
// Make sure storages on other entity types are not exposed.
|
||||
$this->assertFalse(isset($field_storage_definitions[$this->fieldTestData->field_rev->getName()]));
|
||||
}
|
||||
|
||||
}
|
312
web/core/modules/field/tests/src/Kernel/DisplayApiTest.php
Normal file
312
web/core/modules/field/tests/src/Kernel/DisplayApiTest.php
Normal file
|
@ -0,0 +1,312 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\field\Kernel;
|
||||
|
||||
use Drupal\Core\Entity\Entity\EntityViewMode;
|
||||
use Drupal\entity_test\Entity\EntityTest;
|
||||
use Drupal\field\Entity\FieldConfig;
|
||||
use Drupal\field\Entity\FieldStorageConfig;
|
||||
|
||||
/**
|
||||
* Tests the field display API.
|
||||
*
|
||||
* @group field
|
||||
*/
|
||||
class DisplayApiTest extends FieldKernelTestBase {
|
||||
|
||||
/**
|
||||
* The field name to use in this test.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $fieldName;
|
||||
|
||||
/**
|
||||
* The field label to use in this test.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $label;
|
||||
|
||||
/**
|
||||
* The field cardinality to use in this test.
|
||||
*
|
||||
* @var number
|
||||
*/
|
||||
protected $cardinality;
|
||||
|
||||
/**
|
||||
* The field display options to use in this test.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $displayOptions;
|
||||
|
||||
/**
|
||||
* The test entity.
|
||||
*
|
||||
* @var \Drupal\Core\Entity\EntityInterface
|
||||
*/
|
||||
protected $entity;
|
||||
|
||||
/**
|
||||
* An array of random values, in the format expected for field values.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $values;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['system'];
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
// Create a field and its storage.
|
||||
$this->fieldName = 'test_field';
|
||||
$this->label = $this->randomMachineName();
|
||||
$this->cardinality = 4;
|
||||
|
||||
$field_storage = array(
|
||||
'field_name' => $this->fieldName,
|
||||
'entity_type' => 'entity_test',
|
||||
'type' => 'test_field',
|
||||
'cardinality' => $this->cardinality,
|
||||
);
|
||||
$field = array(
|
||||
'field_name' => $this->fieldName,
|
||||
'entity_type' => 'entity_test',
|
||||
'bundle' => 'entity_test',
|
||||
'label' => $this->label,
|
||||
);
|
||||
|
||||
$this->displayOptions = array(
|
||||
'default' => array(
|
||||
'type' => 'field_test_default',
|
||||
'settings' => array(
|
||||
'test_formatter_setting' => $this->randomMachineName(),
|
||||
),
|
||||
),
|
||||
'teaser' => array(
|
||||
'type' => 'field_test_default',
|
||||
'settings' => array(
|
||||
'test_formatter_setting' => $this->randomMachineName(),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
FieldStorageConfig::create($field_storage)->save();
|
||||
FieldConfig::create($field)->save();
|
||||
// Create a display for the default view mode.
|
||||
entity_get_display($field['entity_type'], $field['bundle'], 'default')
|
||||
->setComponent($this->fieldName, $this->displayOptions['default'])
|
||||
->save();
|
||||
// Create a display for the teaser view mode.
|
||||
EntityViewMode::create(array('id' => 'entity_test.teaser', 'targetEntityType' => 'entity_test'))->save();
|
||||
entity_get_display($field['entity_type'], $field['bundle'], 'teaser')
|
||||
->setComponent($this->fieldName, $this->displayOptions['teaser'])
|
||||
->save();
|
||||
|
||||
// Create an entity with values.
|
||||
$this->values = $this->_generateTestFieldValues($this->cardinality);
|
||||
$this->entity = EntityTest::create();
|
||||
$this->entity->{$this->fieldName}->setValue($this->values);
|
||||
$this->entity->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the FieldItemListInterface::view() method.
|
||||
*/
|
||||
function testFieldItemListView() {
|
||||
$items = $this->entity->get($this->fieldName);
|
||||
|
||||
\Drupal::service('theme_handler')->install(['classy']);
|
||||
\Drupal::service('theme_handler')->setDefault('classy');
|
||||
|
||||
// No display settings: check that default display settings are used.
|
||||
$build = $items->view();
|
||||
$this->render($build);
|
||||
$settings = \Drupal::service('plugin.manager.field.formatter')->getDefaultSettings('field_test_default');
|
||||
$setting = $settings['test_formatter_setting'];
|
||||
$this->assertText($this->label, 'Label was displayed.');
|
||||
foreach ($this->values as $delta => $value) {
|
||||
$this->assertText($setting . '|' . $value['value'], format_string('Value @delta was displayed with expected setting.', array('@delta' => $delta)));
|
||||
}
|
||||
|
||||
// Display settings: Check hidden field.
|
||||
$display = array(
|
||||
'label' => 'hidden',
|
||||
'type' => 'field_test_multiple',
|
||||
'settings' => array(
|
||||
'test_formatter_setting_multiple' => $this->randomMachineName(),
|
||||
'alter' => TRUE,
|
||||
),
|
||||
);
|
||||
$build = $items->view($display);
|
||||
$this->render($build);
|
||||
$setting = $display['settings']['test_formatter_setting_multiple'];
|
||||
$this->assertNoText($this->label, 'Label was not displayed.');
|
||||
$this->assertText('field_test_entity_display_build_alter', 'Alter fired, display passed.');
|
||||
$this->assertText('entity language is en', 'Language is placed onto the context.');
|
||||
$array = array();
|
||||
foreach ($this->values as $delta => $value) {
|
||||
$array[] = $delta . ':' . $value['value'];
|
||||
}
|
||||
$this->assertText($setting . '|' . implode('|', $array), 'Values were displayed with expected setting.');
|
||||
|
||||
// Display settings: Check visually_hidden field.
|
||||
$display = array(
|
||||
'label' => 'visually_hidden',
|
||||
'type' => 'field_test_multiple',
|
||||
'settings' => array(
|
||||
'test_formatter_setting_multiple' => $this->randomMachineName(),
|
||||
'alter' => TRUE,
|
||||
),
|
||||
);
|
||||
$build = $items->view($display);
|
||||
$this->render($build);
|
||||
$setting = $display['settings']['test_formatter_setting_multiple'];
|
||||
$this->assertRaw('visually-hidden', 'Label was visually hidden.');
|
||||
$this->assertText('field_test_entity_display_build_alter', 'Alter fired, display passed.');
|
||||
$this->assertText('entity language is en', 'Language is placed onto the context.');
|
||||
$array = array();
|
||||
foreach ($this->values as $delta => $value) {
|
||||
$array[] = $delta . ':' . $value['value'];
|
||||
}
|
||||
$this->assertText($setting . '|' . implode('|', $array), 'Values were displayed with expected setting.');
|
||||
|
||||
// Check the prepare_view steps are invoked.
|
||||
$display = array(
|
||||
'label' => 'hidden',
|
||||
'type' => 'field_test_with_prepare_view',
|
||||
'settings' => array(
|
||||
'test_formatter_setting_additional' => $this->randomMachineName(),
|
||||
),
|
||||
);
|
||||
$build = $items->view($display);
|
||||
$this->render($build);
|
||||
$setting = $display['settings']['test_formatter_setting_additional'];
|
||||
$this->assertNoText($this->label, 'Label was not displayed.');
|
||||
$this->assertNoText('field_test_entity_display_build_alter', 'Alter not fired.');
|
||||
foreach ($this->values as $delta => $value) {
|
||||
$this->assertText($setting . '|' . $value['value'] . '|' . ($value['value'] + 1), format_string('Value @delta was displayed with expected setting.', array('@delta' => $delta)));
|
||||
}
|
||||
|
||||
// View mode: check that display settings specified in the display object
|
||||
// are used.
|
||||
$build = $items->view('teaser');
|
||||
$this->render($build);
|
||||
$setting = $this->displayOptions['teaser']['settings']['test_formatter_setting'];
|
||||
$this->assertText($this->label, 'Label was displayed.');
|
||||
foreach ($this->values as $delta => $value) {
|
||||
$this->assertText($setting . '|' . $value['value'], format_string('Value @delta was displayed with expected setting.', array('@delta' => $delta)));
|
||||
}
|
||||
|
||||
// Unknown view mode: check that display settings for 'default' view mode
|
||||
// are used.
|
||||
$build = $items->view('unknown_view_mode');
|
||||
$this->render($build);
|
||||
$setting = $this->displayOptions['default']['settings']['test_formatter_setting'];
|
||||
$this->assertText($this->label, 'Label was displayed.');
|
||||
foreach ($this->values as $delta => $value) {
|
||||
$this->assertText($setting . '|' . $value['value'], format_string('Value @delta was displayed with expected setting.', array('@delta' => $delta)));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the FieldItemInterface::view() method.
|
||||
*/
|
||||
function testFieldItemView() {
|
||||
// No display settings: check that default display settings are used.
|
||||
$settings = \Drupal::service('plugin.manager.field.formatter')->getDefaultSettings('field_test_default');
|
||||
$setting = $settings['test_formatter_setting'];
|
||||
foreach ($this->values as $delta => $value) {
|
||||
$item = $this->entity->{$this->fieldName}[$delta];
|
||||
$build = $item->view();
|
||||
$this->render($build);
|
||||
$this->assertText($setting . '|' . $value['value'], format_string('Value @delta was displayed with expected setting.', array('@delta' => $delta)));
|
||||
}
|
||||
|
||||
// Check that explicit display settings are used.
|
||||
$display = array(
|
||||
'type' => 'field_test_multiple',
|
||||
'settings' => array(
|
||||
'test_formatter_setting_multiple' => $this->randomMachineName(),
|
||||
),
|
||||
);
|
||||
$setting = $display['settings']['test_formatter_setting_multiple'];
|
||||
foreach ($this->values as $delta => $value) {
|
||||
$item = $this->entity->{$this->fieldName}[$delta];
|
||||
$build = $item->view($display);
|
||||
$this->render($build);
|
||||
$this->assertText($setting . '|0:' . $value['value'], format_string('Value @delta was displayed with expected setting.', array('@delta' => $delta)));
|
||||
}
|
||||
|
||||
// Check that prepare_view steps are invoked.
|
||||
$display = array(
|
||||
'type' => 'field_test_with_prepare_view',
|
||||
'settings' => array(
|
||||
'test_formatter_setting_additional' => $this->randomMachineName(),
|
||||
),
|
||||
);
|
||||
$setting = $display['settings']['test_formatter_setting_additional'];
|
||||
foreach ($this->values as $delta => $value) {
|
||||
$item = $this->entity->{$this->fieldName}[$delta];
|
||||
$build = $item->view($display);
|
||||
$this->render($build);
|
||||
$this->assertText($setting . '|' . $value['value'] . '|' . ($value['value'] + 1), format_string('Value @delta was displayed with expected setting.', array('@delta' => $delta)));
|
||||
}
|
||||
|
||||
// View mode: check that display settings specified in the field are used.
|
||||
$setting = $this->displayOptions['teaser']['settings']['test_formatter_setting'];
|
||||
foreach ($this->values as $delta => $value) {
|
||||
$item = $this->entity->{$this->fieldName}[$delta];
|
||||
$build = $item->view('teaser');
|
||||
$this->render($build);
|
||||
$this->assertText($setting . '|' . $value['value'], format_string('Value @delta was displayed with expected setting.', array('@delta' => $delta)));
|
||||
}
|
||||
|
||||
// Unknown view mode: check that display settings for 'default' view mode
|
||||
// are used.
|
||||
$setting = $this->displayOptions['default']['settings']['test_formatter_setting'];
|
||||
foreach ($this->values as $delta => $value) {
|
||||
$item = $this->entity->{$this->fieldName}[$delta];
|
||||
$build = $item->view('unknown_view_mode');
|
||||
$this->render($build);
|
||||
$this->assertText($setting . '|' . $value['value'], format_string('Value @delta was displayed with expected setting.', array('@delta' => $delta)));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that the prepareView() formatter method still fires for empty values.
|
||||
*/
|
||||
function testFieldEmpty() {
|
||||
// Uses \Drupal\field_test\Plugin\Field\FieldFormatter\TestFieldEmptyFormatter.
|
||||
$display = array(
|
||||
'label' => 'hidden',
|
||||
'type' => 'field_empty_test',
|
||||
'settings' => array(
|
||||
'test_empty_string' => '**EMPTY FIELD**' . $this->randomMachineName(),
|
||||
),
|
||||
);
|
||||
// $this->entity is set by the setUp() method and by default contains 4
|
||||
// numeric values. We only want to test the display of this one field.
|
||||
$build = $this->entity->get($this->fieldName)->view($display);
|
||||
$this->render($build);
|
||||
// The test field by default contains values, so should not display the
|
||||
// default "empty" text.
|
||||
$this->assertNoText($display['settings']['test_empty_string']);
|
||||
|
||||
// Now remove the values from the test field and retest.
|
||||
$this->entity->{$this->fieldName} = array();
|
||||
$this->entity->save();
|
||||
$build = $this->entity->get($this->fieldName)->view($display);
|
||||
$this->render($build);
|
||||
// This time, as the field values have been removed, we *should* show the
|
||||
// default "empty" text.
|
||||
$this->assertText($display['settings']['test_empty_string']);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,77 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\field\Kernel\Email;
|
||||
|
||||
use Drupal\Core\Field\FieldItemListInterface;
|
||||
use Drupal\Core\Field\FieldItemInterface;
|
||||
use Drupal\entity_test\Entity\EntityTest;
|
||||
use Drupal\field\Entity\FieldConfig;
|
||||
use Drupal\Tests\field\Kernel\FieldKernelTestBase;
|
||||
use Drupal\field\Entity\FieldStorageConfig;
|
||||
|
||||
/**
|
||||
* Tests the new entity API for the email field type.
|
||||
*
|
||||
* @group field
|
||||
*/
|
||||
class EmailItemTest extends FieldKernelTestBase {
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
// Create an email field storage and field for validation.
|
||||
FieldStorageConfig::create(array(
|
||||
'field_name' => 'field_email',
|
||||
'entity_type' => 'entity_test',
|
||||
'type' => 'email',
|
||||
))->save();
|
||||
FieldConfig::create([
|
||||
'entity_type' => 'entity_test',
|
||||
'field_name' => 'field_email',
|
||||
'bundle' => 'entity_test',
|
||||
])->save();
|
||||
|
||||
// Create a form display for the default form mode.
|
||||
entity_get_form_display('entity_test', 'entity_test', 'default')
|
||||
->setComponent('field_email', array(
|
||||
'type' => 'email_default',
|
||||
))
|
||||
->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests using entity fields of the email field type.
|
||||
*/
|
||||
public function testEmailItem() {
|
||||
// Verify entity creation.
|
||||
$entity = EntityTest::create();
|
||||
$value = 'test@example.com';
|
||||
$entity->field_email = $value;
|
||||
$entity->name->value = $this->randomMachineName();
|
||||
$entity->save();
|
||||
|
||||
// Verify entity has been created properly.
|
||||
$id = $entity->id();
|
||||
$entity = EntityTest::load($id);
|
||||
$this->assertTrue($entity->field_email instanceof FieldItemListInterface, 'Field implements interface.');
|
||||
$this->assertTrue($entity->field_email[0] instanceof FieldItemInterface, 'Field item implements interface.');
|
||||
$this->assertEqual($entity->field_email->value, $value);
|
||||
$this->assertEqual($entity->field_email[0]->value, $value);
|
||||
|
||||
// Verify changing the email value.
|
||||
$new_value = $this->randomMachineName();
|
||||
$entity->field_email->value = $new_value;
|
||||
$this->assertEqual($entity->field_email->value, $new_value);
|
||||
|
||||
// Read changed entity and assert changed values.
|
||||
$entity->save();
|
||||
$entity = EntityTest::load($id);
|
||||
$this->assertEqual($entity->field_email->value, $new_value);
|
||||
|
||||
// Test sample item generation.
|
||||
$entity = EntityTest::create();
|
||||
$entity->field_email->generateSampleItems();
|
||||
$this->entityValidateAndSave($entity);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,99 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\field\Kernel\Entity\Update;
|
||||
|
||||
use Drupal\Core\Entity\Exception\FieldStorageDefinitionUpdateForbiddenException;
|
||||
use Drupal\entity_test\Entity\EntityTestRev;
|
||||
use Drupal\field\Entity\FieldConfig;
|
||||
use Drupal\field\Entity\FieldStorageConfig;
|
||||
use Drupal\KernelTests\KernelTestBase;
|
||||
|
||||
/**
|
||||
* Tests that schema changes in fields with data are detected during updates.
|
||||
*
|
||||
* @group Entity
|
||||
*/
|
||||
class SqlContentEntityStorageSchemaColumnTest extends KernelTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['entity_test', 'field', 'text', 'user'];
|
||||
|
||||
/**
|
||||
* The created entity.
|
||||
*
|
||||
* @var \Drupal\Core\Entity\Entity
|
||||
*/
|
||||
protected $entity;
|
||||
|
||||
/**
|
||||
* The field.
|
||||
*
|
||||
* @var \Drupal\field\FieldConfigInterface
|
||||
*/
|
||||
protected $field;
|
||||
|
||||
/**
|
||||
* The field storage.
|
||||
*
|
||||
* @var \Drupal\field\FieldStorageConfigInterface
|
||||
*/
|
||||
protected $fieldStorage;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$this->installEntitySchema('entity_test_rev');
|
||||
$this->installEntitySchema('user');
|
||||
|
||||
$field_name = 'test';
|
||||
$this->fieldStorage = FieldStorageConfig::create([
|
||||
'field_name' => $field_name,
|
||||
'entity_type' => 'entity_test_rev',
|
||||
'type' => 'string',
|
||||
'cardinality' => 1,
|
||||
]);
|
||||
$this->fieldStorage->save();
|
||||
|
||||
$this->field = FieldConfig::create([
|
||||
'field_name' => $field_name,
|
||||
'entity_type' => 'entity_test_rev',
|
||||
'bundle' => 'entity_test_rev',
|
||||
'required' => TRUE,
|
||||
]);
|
||||
$this->field->save();
|
||||
|
||||
// Create an entity with field data.
|
||||
$this->entity = EntityTestRev::create([
|
||||
'user_id' => mt_rand(1, 10),
|
||||
'name' => $this->randomMachineName(),
|
||||
$field_name => $this->randomString(),
|
||||
]);
|
||||
$this->entity->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that column-level schema changes are detected for fields with data.
|
||||
*/
|
||||
public function testColumnUpdate() {
|
||||
// Change the field type in the stored schema.
|
||||
$schema = \Drupal::keyValue('entity.storage_schema.sql')->get('entity_test_rev.field_schema_data.test');
|
||||
$schema['entity_test_rev__test']['fields']['test_value']['type'] = 'varchar_ascii';
|
||||
\Drupal::keyValue('entity.storage_schema.sql')->set('entity_test_rev.field_schema_data.test', $schema);
|
||||
|
||||
// Now attempt to run automatic updates. An exception should be thrown
|
||||
// since there is data in the table.
|
||||
try {
|
||||
\Drupal::service('entity.definition_update_manager')->applyUpdates();
|
||||
$this->fail('Failed to detect a schema change in a field with data.');
|
||||
}
|
||||
catch (FieldStorageDefinitionUpdateForbiddenException $e) {
|
||||
$this->pass('Detected a schema change in a field with data.');
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,423 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\field\Kernel\EntityReference;
|
||||
|
||||
use Drupal\Core\Cache\Cache;
|
||||
use Drupal\Core\Cache\CacheableMetadata;
|
||||
use Drupal\Core\Field\FieldStorageDefinitionInterface;
|
||||
use Drupal\Core\Field\Plugin\Field\FieldFormatter\EntityReferenceEntityFormatter;
|
||||
use Drupal\field\Entity\FieldConfig;
|
||||
use Drupal\field\Entity\FieldStorageConfig;
|
||||
use Drupal\field\Tests\EntityReference\EntityReferenceTestTrait;
|
||||
use Drupal\filter\Entity\FilterFormat;
|
||||
use Drupal\KernelTests\Core\Entity\EntityKernelTestBase;
|
||||
use Drupal\user\Entity\Role;
|
||||
use Drupal\user\RoleInterface;
|
||||
use Drupal\entity_test\Entity\EntityTestLabel;
|
||||
|
||||
/**
|
||||
* Tests the formatters functionality.
|
||||
*
|
||||
* @group entity_reference
|
||||
*/
|
||||
class EntityReferenceFormatterTest extends EntityKernelTestBase {
|
||||
|
||||
use EntityReferenceTestTrait;
|
||||
|
||||
/**
|
||||
* The entity type used in this test.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $entityType = 'entity_test';
|
||||
|
||||
/**
|
||||
* The bundle used in this test.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $bundle = 'entity_test';
|
||||
|
||||
/**
|
||||
* The name of the field used in this test.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $fieldName = 'field_test';
|
||||
|
||||
/**
|
||||
* The entity to be referenced in this test.
|
||||
*
|
||||
* @var \Drupal\Core\Entity\EntityInterface
|
||||
*/
|
||||
protected $referencedEntity;
|
||||
|
||||
/**
|
||||
* The entity that is not yet saved to its persistent storage to be referenced
|
||||
* in this test.
|
||||
*
|
||||
* @var \Drupal\Core\Entity\EntityInterface
|
||||
*/
|
||||
protected $unsavedReferencedEntity;
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
// Use Classy theme for testing markup output.
|
||||
\Drupal::service('theme_handler')->install(['classy']);
|
||||
\Drupal::service('theme_handler')->setDefault('classy');
|
||||
$this->installEntitySchema('entity_test');
|
||||
// Grant the 'view test entity' permission.
|
||||
$this->installConfig(array('user'));
|
||||
Role::load(RoleInterface::ANONYMOUS_ID)
|
||||
->grantPermission('view test entity')
|
||||
->save();
|
||||
|
||||
// The label formatter rendering generates links, so build the router.
|
||||
$this->container->get('router.builder')->rebuild();
|
||||
|
||||
$this->createEntityReferenceField($this->entityType, $this->bundle, $this->fieldName, 'Field test', $this->entityType, 'default', array(), FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED);
|
||||
|
||||
// Set up a field, so that the entity that'll be referenced bubbles up a
|
||||
// cache tag when rendering it entirely.
|
||||
FieldStorageConfig::create(array(
|
||||
'field_name' => 'body',
|
||||
'entity_type' => $this->entityType,
|
||||
'type' => 'text',
|
||||
'settings' => array(),
|
||||
))->save();
|
||||
FieldConfig::create([
|
||||
'entity_type' => $this->entityType,
|
||||
'bundle' => $this->bundle,
|
||||
'field_name' => 'body',
|
||||
'label' => 'Body',
|
||||
])->save();
|
||||
entity_get_display($this->entityType, $this->bundle, 'default')
|
||||
->setComponent('body', array(
|
||||
'type' => 'text_default',
|
||||
'settings' => array(),
|
||||
))
|
||||
->save();
|
||||
|
||||
FilterFormat::create(array(
|
||||
'format' => 'full_html',
|
||||
'name' => 'Full HTML',
|
||||
))->save();
|
||||
|
||||
// Create the entity to be referenced.
|
||||
$this->referencedEntity = $this->container->get('entity_type.manager')
|
||||
->getStorage($this->entityType)
|
||||
->create(array('name' => $this->randomMachineName()));
|
||||
$this->referencedEntity->body = array(
|
||||
'value' => '<p>Hello, world!</p>',
|
||||
'format' => 'full_html',
|
||||
);
|
||||
$this->referencedEntity->save();
|
||||
|
||||
// Create another entity to be referenced but do not save it.
|
||||
$this->unsavedReferencedEntity = $this->container->get('entity_type.manager')
|
||||
->getStorage($this->entityType)
|
||||
->create(array('name' => $this->randomMachineName()));
|
||||
$this->unsavedReferencedEntity->body = array(
|
||||
'value' => '<p>Hello, unsaved world!</p>',
|
||||
'format' => 'full_html',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert inaccessible items don't change the data of the fields.
|
||||
*/
|
||||
public function testAccess() {
|
||||
// Revoke the 'view test entity' permission for this test.
|
||||
Role::load(RoleInterface::ANONYMOUS_ID)
|
||||
->revokePermission('view test entity')
|
||||
->save();
|
||||
|
||||
$field_name = $this->fieldName;
|
||||
|
||||
$referencing_entity = $this->container->get('entity_type.manager')
|
||||
->getStorage($this->entityType)
|
||||
->create(array('name' => $this->randomMachineName()));
|
||||
$referencing_entity->save();
|
||||
$referencing_entity->{$field_name}->entity = $this->referencedEntity;
|
||||
|
||||
// Assert user doesn't have access to the entity.
|
||||
$this->assertFalse($this->referencedEntity->access('view'), 'Current user does not have access to view the referenced entity.');
|
||||
|
||||
$formatter_manager = $this->container->get('plugin.manager.field.formatter');
|
||||
|
||||
// Get all the existing formatters.
|
||||
foreach ($formatter_manager->getOptions('entity_reference') as $formatter => $name) {
|
||||
// Set formatter type for the 'full' view mode.
|
||||
entity_get_display($this->entityType, $this->bundle, 'default')
|
||||
->setComponent($field_name, array(
|
||||
'type' => $formatter,
|
||||
))
|
||||
->save();
|
||||
|
||||
// Invoke entity view.
|
||||
entity_view($referencing_entity, 'default');
|
||||
|
||||
// Verify the un-accessible item still exists.
|
||||
$this->assertEqual($referencing_entity->{$field_name}->target_id, $this->referencedEntity->id(), format_string('The un-accessible item still exists after @name formatter was executed.', array('@name' => $name)));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the ID formatter.
|
||||
*/
|
||||
public function testIdFormatter() {
|
||||
$formatter = 'entity_reference_entity_id';
|
||||
$build = $this->buildRenderArray([$this->referencedEntity, $this->unsavedReferencedEntity], $formatter);
|
||||
|
||||
$this->assertEqual($build[0]['#plain_text'], $this->referencedEntity->id(), sprintf('The markup returned by the %s formatter is correct for an item with a saved entity.', $formatter));
|
||||
$this->assertEqual($build[0]['#cache']['tags'], $this->referencedEntity->getCacheTags(), sprintf('The %s formatter has the expected cache tags.', $formatter));
|
||||
$this->assertTrue(!isset($build[1]), sprintf('The markup returned by the %s formatter is correct for an item with a unsaved entity.', $formatter));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the entity formatter.
|
||||
*/
|
||||
public function testEntityFormatter() {
|
||||
/** @var \Drupal\Core\Render\RendererInterface $renderer */
|
||||
$renderer = $this->container->get('renderer');
|
||||
$formatter = 'entity_reference_entity_view';
|
||||
$build = $this->buildRenderArray([$this->referencedEntity, $this->unsavedReferencedEntity], $formatter);
|
||||
|
||||
// Test the first field item.
|
||||
$expected_rendered_name_field_1 = '
|
||||
<div class="field field--name-name field--type-string field--label-hidden field__item">' . $this->referencedEntity->label() . '</div>
|
||||
';
|
||||
$expected_rendered_body_field_1 = '
|
||||
<div class="clearfix text-formatted field field--name-body field--type-text field--label-above">
|
||||
<div class="field__label">Body</div>
|
||||
<div class="field__item"><p>Hello, world!</p></div>
|
||||
</div>
|
||||
';
|
||||
$renderer->renderRoot($build[0]);
|
||||
$this->assertEqual($build[0]['#markup'], 'default | ' . $this->referencedEntity->label() . $expected_rendered_name_field_1 . $expected_rendered_body_field_1, sprintf('The markup returned by the %s formatter is correct for an item with a saved entity.', $formatter));
|
||||
$expected_cache_tags = Cache::mergeTags(\Drupal::entityManager()->getViewBuilder($this->entityType)->getCacheTags(), $this->referencedEntity->getCacheTags());
|
||||
$expected_cache_tags = Cache::mergeTags($expected_cache_tags, FilterFormat::load('full_html')->getCacheTags());
|
||||
$this->assertEqual($build[0]['#cache']['tags'], $expected_cache_tags, format_string('The @formatter formatter has the expected cache tags.', array('@formatter' => $formatter)));
|
||||
|
||||
// Test the second field item.
|
||||
$expected_rendered_name_field_2 = '
|
||||
<div class="field field--name-name field--type-string field--label-hidden field__item">' . $this->unsavedReferencedEntity->label() . '</div>
|
||||
';
|
||||
$expected_rendered_body_field_2 = '
|
||||
<div class="clearfix text-formatted field field--name-body field--type-text field--label-above">
|
||||
<div class="field__label">Body</div>
|
||||
<div class="field__item"><p>Hello, unsaved world!</p></div>
|
||||
</div>
|
||||
';
|
||||
|
||||
$renderer->renderRoot($build[1]);
|
||||
$this->assertEqual($build[1]['#markup'], 'default | ' . $this->unsavedReferencedEntity->label() . $expected_rendered_name_field_2 . $expected_rendered_body_field_2, sprintf('The markup returned by the %s formatter is correct for an item with a unsaved entity.', $formatter));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the recursive rendering protection of the entity formatter.
|
||||
*/
|
||||
public function testEntityFormatterRecursiveRendering() {
|
||||
/** @var \Drupal\Core\Render\RendererInterface $renderer */
|
||||
$renderer = $this->container->get('renderer');
|
||||
$formatter = 'entity_reference_entity_view';
|
||||
$view_builder = $this->entityManager->getViewBuilder($this->entityType);
|
||||
|
||||
// Set the default view mode to use the 'entity_reference_entity_view'
|
||||
// formatter.
|
||||
entity_get_display($this->entityType, $this->bundle, 'default')
|
||||
->setComponent($this->fieldName, [
|
||||
'type' => $formatter,
|
||||
])
|
||||
->save();
|
||||
|
||||
$referencing_entity_1 = entity_create($this->entityType, ['name' => $this->randomMachineName()]);
|
||||
$referencing_entity_1->save();
|
||||
|
||||
// Create a self-reference.
|
||||
$referencing_entity_1->{$this->fieldName}->entity = $referencing_entity_1;
|
||||
$referencing_entity_1->save();
|
||||
|
||||
// Check that the recursive rendering stops after it reaches the specified
|
||||
// limit.
|
||||
$build = $view_builder->view($referencing_entity_1, 'default');
|
||||
$output = $renderer->renderRoot($build);
|
||||
|
||||
// The title of entity_test entities is printed twice by default, so we have
|
||||
// to multiply the formatter's recursive rendering protection limit by 2.
|
||||
// Additionally, we have to take into account 2 additional occurrences of
|
||||
// the entity title because we're rendering the full entity, not just the
|
||||
// reference field.
|
||||
$expected_occurrences = EntityReferenceEntityFormatter::RECURSIVE_RENDER_LIMIT * 2 + 2;
|
||||
$actual_occurrences = substr_count($output, $referencing_entity_1->name->value);
|
||||
$this->assertEqual($actual_occurrences, $expected_occurrences);
|
||||
|
||||
// Repeat the process with another entity in order to check that the
|
||||
// 'recursive_render_id' counter is generated properly.
|
||||
$referencing_entity_2 = entity_create($this->entityType, ['name' => $this->randomMachineName()]);
|
||||
$referencing_entity_2->save();
|
||||
$referencing_entity_2->{$this->fieldName}->entity = $referencing_entity_2;
|
||||
$referencing_entity_2->save();
|
||||
|
||||
$build = $view_builder->view($referencing_entity_2, 'default');
|
||||
$output = $renderer->renderRoot($build);
|
||||
|
||||
$actual_occurrences = substr_count($output, $referencing_entity_2->name->value);
|
||||
$this->assertEqual($actual_occurrences, $expected_occurrences);
|
||||
|
||||
// Now render both entities at the same time and check again.
|
||||
$build = $view_builder->viewMultiple([$referencing_entity_1, $referencing_entity_2], 'default');
|
||||
$output = $renderer->renderRoot($build);
|
||||
|
||||
$actual_occurrences = substr_count($output, $referencing_entity_1->name->value);
|
||||
$this->assertEqual($actual_occurrences, $expected_occurrences);
|
||||
|
||||
$actual_occurrences = substr_count($output, $referencing_entity_2->name->value);
|
||||
$this->assertEqual($actual_occurrences, $expected_occurrences);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the same entity referenced from different places.
|
||||
*/
|
||||
public function testEntityReferenceRecursiveProtectionWithManyRenderedEntities() {
|
||||
$formatter = 'entity_reference_entity_view';
|
||||
$view_builder = $this->entityManager->getViewBuilder($this->entityType);
|
||||
|
||||
// Set the default view mode to use the 'entity_reference_entity_view'
|
||||
// formatter.
|
||||
entity_get_display($this->entityType, $this->bundle, 'default')
|
||||
->setComponent($this->fieldName, [
|
||||
'type' => $formatter,
|
||||
])
|
||||
->save();
|
||||
|
||||
$storage = $this->entityManager->getStorage($this->entityType);
|
||||
/** @var \Drupal\Core\Entity\ContentEntityInterface $referenced_entity */
|
||||
$referenced_entity = $storage->create(['name' => $this->randomMachineName()]);
|
||||
|
||||
$range = range(0, 30);
|
||||
$referencing_entities = array_map(function () use ($storage, $referenced_entity) {
|
||||
$referencing_entity = $storage->create([
|
||||
'name' => $this->randomMachineName(),
|
||||
$this->fieldName => $referenced_entity,
|
||||
]);
|
||||
$referencing_entity->save();
|
||||
return $referencing_entity;
|
||||
}, $range);
|
||||
|
||||
$build = $view_builder->viewMultiple($referencing_entities, 'default');
|
||||
$output = $this->render($build);
|
||||
|
||||
// The title of entity_test entities is printed twice by default, so we have
|
||||
// to multiply the formatter's recursive rendering protection limit by 2.
|
||||
// Additionally, we have to take into account 2 additional occurrences of
|
||||
// the entity title because we're rendering the full entity, not just the
|
||||
// reference field.
|
||||
$expected_occurrences = 30 * 2 + 2;
|
||||
$actual_occurrences = substr_count($output, $referenced_entity->get('name')->value);
|
||||
$this->assertEquals($expected_occurrences, $actual_occurrences);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Tests the label formatter.
|
||||
*/
|
||||
public function testLabelFormatter() {
|
||||
$this->installEntitySchema('entity_test_label');
|
||||
/** @var \Drupal\Core\Render\RendererInterface $renderer */
|
||||
$renderer = $this->container->get('renderer');
|
||||
$formatter = 'entity_reference_label';
|
||||
|
||||
// The 'link' settings is TRUE by default.
|
||||
$build = $this->buildRenderArray([$this->referencedEntity, $this->unsavedReferencedEntity], $formatter);
|
||||
|
||||
$expected_field_cacheability = [
|
||||
'contexts' => [],
|
||||
'tags' => [],
|
||||
'max-age' => Cache::PERMANENT,
|
||||
];
|
||||
$this->assertEqual($build['#cache'], $expected_field_cacheability, 'The field render array contains the entity access cacheability metadata');
|
||||
$expected_item_1 = array(
|
||||
'#type' => 'link',
|
||||
'#title' => $this->referencedEntity->label(),
|
||||
'#url' => $this->referencedEntity->urlInfo(),
|
||||
'#options' => $this->referencedEntity->urlInfo()->getOptions(),
|
||||
'#cache' => array(
|
||||
'contexts' => [
|
||||
'user.permissions',
|
||||
],
|
||||
'tags' => $this->referencedEntity->getCacheTags(),
|
||||
),
|
||||
);
|
||||
$this->assertEqual($renderer->renderRoot($build[0]), $renderer->renderRoot($expected_item_1), sprintf('The markup returned by the %s formatter is correct for an item with a saved entity.', $formatter));
|
||||
$this->assertEqual(CacheableMetadata::createFromRenderArray($build[0]), CacheableMetadata::createFromRenderArray($expected_item_1));
|
||||
|
||||
// The second referenced entity is "autocreated", therefore not saved and
|
||||
// lacking any URL info.
|
||||
$expected_item_2 = array(
|
||||
'#plain_text' => $this->unsavedReferencedEntity->label(),
|
||||
'#cache' => array(
|
||||
'contexts' => [
|
||||
'user.permissions',
|
||||
],
|
||||
'tags' => $this->unsavedReferencedEntity->getCacheTags(),
|
||||
'max-age' => Cache::PERMANENT,
|
||||
),
|
||||
);
|
||||
$this->assertEqual($build[1], $expected_item_2, sprintf('The render array returned by the %s formatter is correct for an item with a unsaved entity.', $formatter));
|
||||
|
||||
// Test with the 'link' setting set to FALSE.
|
||||
$build = $this->buildRenderArray([$this->referencedEntity, $this->unsavedReferencedEntity], $formatter, array('link' => FALSE));
|
||||
$this->assertEqual($build[0]['#plain_text'], $this->referencedEntity->label(), sprintf('The markup returned by the %s formatter is correct for an item with a saved entity.', $formatter));
|
||||
$this->assertEqual($build[1]['#plain_text'], $this->unsavedReferencedEntity->label(), sprintf('The markup returned by the %s formatter is correct for an item with a unsaved entity.', $formatter));
|
||||
|
||||
// Test an entity type that doesn't have any link templates, which means
|
||||
// \Drupal\Core\Entity\EntityInterface::urlInfo() will throw an exception
|
||||
// and the label formatter will output only the label instead of a link.
|
||||
$field_storage_config = FieldStorageConfig::loadByName($this->entityType, $this->fieldName);
|
||||
$field_storage_config->setSetting('target_type', 'entity_test_label');
|
||||
$field_storage_config->save();
|
||||
|
||||
$referenced_entity_with_no_link_template = EntityTestLabel::create(array(
|
||||
'name' => $this->randomMachineName(),
|
||||
));
|
||||
$referenced_entity_with_no_link_template->save();
|
||||
|
||||
$build = $this->buildRenderArray([$referenced_entity_with_no_link_template], $formatter, array('link' => TRUE));
|
||||
$this->assertEqual($build[0]['#plain_text'], $referenced_entity_with_no_link_template->label(), sprintf('The markup returned by the %s formatter is correct for an entity type with no valid link template.', $formatter));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets field values and returns a render array as built by
|
||||
* \Drupal\Core\Field\FieldItemListInterface::view().
|
||||
*
|
||||
* @param \Drupal\Core\Entity\EntityInterface[] $referenced_entities
|
||||
* An array of entity objects that will be referenced.
|
||||
* @param string $formatter
|
||||
* The formatted plugin that will be used for building the render array.
|
||||
* @param array $formatter_options
|
||||
* Settings specific to the formatter. Defaults to the formatter's default
|
||||
* settings.
|
||||
*
|
||||
* @return array
|
||||
* A render array.
|
||||
*/
|
||||
protected function buildRenderArray(array $referenced_entities, $formatter, $formatter_options = array()) {
|
||||
// Create the entity that will have the entity reference field.
|
||||
$referencing_entity = $this->container->get('entity_type.manager')
|
||||
->getStorage($this->entityType)
|
||||
->create(array('name' => $this->randomMachineName()));
|
||||
|
||||
$items = $referencing_entity->get($this->fieldName);
|
||||
|
||||
// Assign the referenced entities.
|
||||
foreach ($referenced_entities as $referenced_entity) {
|
||||
$items[] = ['entity' => $referenced_entity];
|
||||
}
|
||||
|
||||
// Build the renderable array for the field.
|
||||
return $items->view(array('type' => $formatter, 'settings' => $formatter_options));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,536 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\field\Kernel\EntityReference;
|
||||
|
||||
use Drupal\comment\Entity\Comment;
|
||||
use Drupal\Component\Render\FormattableMarkup;
|
||||
use Drupal\Component\Utility\Unicode;
|
||||
use Drupal\Core\Field\FieldItemListInterface;
|
||||
use Drupal\Core\Field\FieldItemInterface;
|
||||
use Drupal\Core\Field\FieldStorageDefinitionInterface;
|
||||
use Drupal\Core\StringTranslation\TranslatableMarkup;
|
||||
use Drupal\Core\Language\LanguageInterface;
|
||||
use Drupal\entity_test\Entity\EntityTest;
|
||||
use Drupal\entity_test\Entity\EntityTestStringId;
|
||||
use Drupal\field\Entity\FieldConfig;
|
||||
use Drupal\field\Entity\FieldStorageConfig;
|
||||
use Drupal\field\Tests\EntityReference\EntityReferenceTestTrait;
|
||||
use Drupal\Tests\field\Kernel\FieldKernelTestBase;
|
||||
use Drupal\file\Entity\File;
|
||||
use Drupal\node\Entity\Node;
|
||||
use Drupal\taxonomy\Entity\Term;
|
||||
use Drupal\taxonomy\Entity\Vocabulary;
|
||||
use Drupal\user\Entity\User;
|
||||
|
||||
|
||||
/**
|
||||
* Tests the new entity API for the entity reference field type.
|
||||
*
|
||||
* @group entity_reference
|
||||
*/
|
||||
class EntityReferenceItemTest extends FieldKernelTestBase {
|
||||
|
||||
use EntityReferenceTestTrait;
|
||||
|
||||
/**
|
||||
* Modules to install.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['node', 'comment', 'file', 'taxonomy', 'text', 'filter', 'views', 'field'];
|
||||
|
||||
/**
|
||||
* The taxonomy vocabulary to test with.
|
||||
*
|
||||
* @var \Drupal\taxonomy\VocabularyInterface
|
||||
*/
|
||||
protected $vocabulary;
|
||||
|
||||
/**
|
||||
* The taxonomy term to test with.
|
||||
*
|
||||
* @var \Drupal\taxonomy\TermInterface
|
||||
*/
|
||||
protected $term;
|
||||
|
||||
/**
|
||||
* The test entity with a string ID.
|
||||
*
|
||||
* @var \Drupal\entity_test\Entity\EntityTestStringId
|
||||
*/
|
||||
protected $entityStringId;
|
||||
|
||||
/**
|
||||
* Sets up the test.
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$this->installEntitySchema('entity_test_string_id');
|
||||
$this->installEntitySchema('taxonomy_term');
|
||||
$this->installEntitySchema('node');
|
||||
$this->installEntitySchema('comment');
|
||||
$this->installEntitySchema('file');
|
||||
|
||||
$this->installSchema('comment', ['comment_entity_statistics']);
|
||||
$this->installSchema('node', ['node_access']);
|
||||
|
||||
$this->vocabulary = Vocabulary::create([
|
||||
'name' => $this->randomMachineName(),
|
||||
'vid' => Unicode::strtolower($this->randomMachineName()),
|
||||
'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED,
|
||||
]);
|
||||
$this->vocabulary->save();
|
||||
|
||||
$this->term = Term::create([
|
||||
'name' => $this->randomMachineName(),
|
||||
'vid' => $this->vocabulary->id(),
|
||||
'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED,
|
||||
]);
|
||||
$this->term->save();
|
||||
|
||||
$this->entityStringId = EntityTestStringId::create([
|
||||
'id' => $this->randomMachineName(),
|
||||
]);
|
||||
$this->entityStringId->save();
|
||||
|
||||
// Use the util to create an instance.
|
||||
$this->createEntityReferenceField('entity_test', 'entity_test', 'field_test_taxonomy_term', 'Test content entity reference', 'taxonomy_term');
|
||||
$this->createEntityReferenceField('entity_test', 'entity_test', 'field_test_entity_test_string_id', 'Test content entity reference with string ID', 'entity_test_string_id');
|
||||
$this->createEntityReferenceField('entity_test', 'entity_test', 'field_test_taxonomy_vocabulary', 'Test config entity reference', 'taxonomy_vocabulary');
|
||||
$this->createEntityReferenceField('entity_test', 'entity_test', 'field_test_node', 'Test node entity reference', 'node', 'default', [], FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED);
|
||||
$this->createEntityReferenceField('entity_test', 'entity_test', 'field_test_user', 'Test user entity reference', 'user');
|
||||
$this->createEntityReferenceField('entity_test', 'entity_test', 'field_test_comment', 'Test comment entity reference', 'comment');
|
||||
$this->createEntityReferenceField('entity_test', 'entity_test', 'field_test_file', 'Test file entity reference', 'file');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the entity reference field type for referencing content entities.
|
||||
*/
|
||||
public function testContentEntityReferenceItem() {
|
||||
$tid = $this->term->id();
|
||||
|
||||
// Just being able to create the entity like this verifies a lot of code.
|
||||
$entity = EntityTest::create();
|
||||
$entity->field_test_taxonomy_term->target_id = $tid;
|
||||
$entity->name->value = $this->randomMachineName();
|
||||
$entity->save();
|
||||
|
||||
$entity = EntityTest::load($entity->id());
|
||||
$this->assertTrue($entity->field_test_taxonomy_term instanceof FieldItemListInterface, 'Field implements interface.');
|
||||
$this->assertTrue($entity->field_test_taxonomy_term[0] instanceof FieldItemInterface, 'Field item implements interface.');
|
||||
$this->assertEqual($entity->field_test_taxonomy_term->target_id, $tid);
|
||||
$this->assertEqual($entity->field_test_taxonomy_term->entity->getName(), $this->term->getName());
|
||||
$this->assertEqual($entity->field_test_taxonomy_term->entity->id(), $tid);
|
||||
$this->assertEqual($entity->field_test_taxonomy_term->entity->uuid(), $this->term->uuid());
|
||||
// Verify that the label for the target ID property definition is correct.
|
||||
$label = $entity->field_test_taxonomy_term->getFieldDefinition()->getFieldStorageDefinition()->getPropertyDefinition('target_id')->getLabel();
|
||||
$this->assertTrue($label instanceof TranslatableMarkup);
|
||||
$this->assertEqual($label->render(), 'Taxonomy term ID');
|
||||
|
||||
// Change the name of the term via the reference.
|
||||
$new_name = $this->randomMachineName();
|
||||
$entity->field_test_taxonomy_term->entity->setName($new_name);
|
||||
$entity->field_test_taxonomy_term->entity->save();
|
||||
// Verify it is the correct name.
|
||||
$term = Term::load($tid);
|
||||
$this->assertEqual($term->getName(), $new_name);
|
||||
|
||||
// Make sure the computed term reflects updates to the term id.
|
||||
$term2 = Term::create([
|
||||
'name' => $this->randomMachineName(),
|
||||
'vid' => $this->term->bundle(),
|
||||
'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED,
|
||||
]);
|
||||
$term2->save();
|
||||
|
||||
// Test all the possible ways of assigning a value.
|
||||
$entity->field_test_taxonomy_term->target_id = $term->id();
|
||||
$this->assertEqual($entity->field_test_taxonomy_term->entity->id(), $term->id());
|
||||
$this->assertEqual($entity->field_test_taxonomy_term->entity->getName(), $term->getName());
|
||||
|
||||
$entity->field_test_taxonomy_term = [['target_id' => $term2->id()]];
|
||||
$this->assertEqual($entity->field_test_taxonomy_term->entity->id(), $term2->id());
|
||||
$this->assertEqual($entity->field_test_taxonomy_term->entity->getName(), $term2->getName());
|
||||
|
||||
// Test value assignment via the computed 'entity' property.
|
||||
$entity->field_test_taxonomy_term->entity = $term;
|
||||
$this->assertEqual($entity->field_test_taxonomy_term->target_id, $term->id());
|
||||
$this->assertEqual($entity->field_test_taxonomy_term->entity->getName(), $term->getName());
|
||||
|
||||
$entity->field_test_taxonomy_term = [['entity' => $term2]];
|
||||
$this->assertEqual($entity->field_test_taxonomy_term->target_id, $term2->id());
|
||||
$this->assertEqual($entity->field_test_taxonomy_term->entity->getName(), $term2->getName());
|
||||
|
||||
// Test assigning an invalid item throws an exception.
|
||||
try {
|
||||
$entity->field_test_taxonomy_term = ['target_id' => 'invalid', 'entity' => $term2];
|
||||
$this->fail('Assigning an invalid item throws an exception.');
|
||||
}
|
||||
catch (\InvalidArgumentException $e) {
|
||||
$this->pass('Assigning an invalid item throws an exception.');
|
||||
}
|
||||
|
||||
// Delete terms so we have nothing to reference and try again
|
||||
$term->delete();
|
||||
$term2->delete();
|
||||
$entity = EntityTest::create(array('name' => $this->randomMachineName()));
|
||||
$entity->save();
|
||||
|
||||
// Test the generateSampleValue() method.
|
||||
$entity = EntityTest::create();
|
||||
$entity->field_test_taxonomy_term->generateSampleItems();
|
||||
$entity->field_test_taxonomy_vocabulary->generateSampleItems();
|
||||
$this->entityValidateAndSave($entity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests referencing content entities with string IDs.
|
||||
*/
|
||||
public function testContentEntityReferenceItemWithStringId() {
|
||||
$entity = EntityTest::create();
|
||||
$entity->field_test_entity_test_string_id->target_id = $this->entityStringId->id();
|
||||
$entity->save();
|
||||
$storage = \Drupal::entityManager()->getStorage('entity_test');
|
||||
$storage->resetCache();
|
||||
$this->assertEqual($this->entityStringId->id(), $storage->load($entity->id())->field_test_entity_test_string_id->target_id);
|
||||
// Verify that the label for the target ID property definition is correct.
|
||||
$label = $entity->field_test_taxonomy_term->getFieldDefinition()->getFieldStorageDefinition()->getPropertyDefinition('target_id')->getLabel();
|
||||
$this->assertTrue($label instanceof TranslatableMarkup);
|
||||
$this->assertEqual($label->render(), 'Taxonomy term ID');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the entity reference field type for referencing config entities.
|
||||
*/
|
||||
public function testConfigEntityReferenceItem() {
|
||||
$referenced_entity_id = $this->vocabulary->id();
|
||||
|
||||
// Just being able to create the entity like this verifies a lot of code.
|
||||
$entity = EntityTest::create();
|
||||
$entity->field_test_taxonomy_vocabulary->target_id = $referenced_entity_id;
|
||||
$entity->name->value = $this->randomMachineName();
|
||||
$entity->save();
|
||||
|
||||
$entity = EntityTest::load($entity->id());
|
||||
$this->assertTrue($entity->field_test_taxonomy_vocabulary instanceof FieldItemListInterface, 'Field implements interface.');
|
||||
$this->assertTrue($entity->field_test_taxonomy_vocabulary[0] instanceof FieldItemInterface, 'Field item implements interface.');
|
||||
$this->assertEqual($entity->field_test_taxonomy_vocabulary->target_id, $referenced_entity_id);
|
||||
$this->assertEqual($entity->field_test_taxonomy_vocabulary->entity->label(), $this->vocabulary->label());
|
||||
$this->assertEqual($entity->field_test_taxonomy_vocabulary->entity->id(), $referenced_entity_id);
|
||||
$this->assertEqual($entity->field_test_taxonomy_vocabulary->entity->uuid(), $this->vocabulary->uuid());
|
||||
|
||||
// Change the name of the term via the reference.
|
||||
$new_name = $this->randomMachineName();
|
||||
$entity->field_test_taxonomy_vocabulary->entity->set('name', $new_name);
|
||||
$entity->field_test_taxonomy_vocabulary->entity->save();
|
||||
// Verify it is the correct name.
|
||||
$vocabulary = Vocabulary::load($referenced_entity_id);
|
||||
$this->assertEqual($vocabulary->label(), $new_name);
|
||||
|
||||
// Make sure the computed term reflects updates to the term id.
|
||||
$vocabulary2 = $vocabulary = Vocabulary::create([
|
||||
'name' => $this->randomMachineName(),
|
||||
'vid' => Unicode::strtolower($this->randomMachineName()),
|
||||
'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED,
|
||||
]);
|
||||
$vocabulary2->save();
|
||||
|
||||
$entity->field_test_taxonomy_vocabulary->target_id = $vocabulary2->id();
|
||||
$this->assertEqual($entity->field_test_taxonomy_vocabulary->entity->id(), $vocabulary2->id());
|
||||
$this->assertEqual($entity->field_test_taxonomy_vocabulary->entity->label(), $vocabulary2->label());
|
||||
|
||||
// Delete terms so we have nothing to reference and try again
|
||||
$this->vocabulary->delete();
|
||||
$vocabulary2->delete();
|
||||
$entity = EntityTest::create(array('name' => $this->randomMachineName()));
|
||||
$entity->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests entity auto create.
|
||||
*/
|
||||
public function testEntityAutoCreate() {
|
||||
// The term entity is unsaved here.
|
||||
$term = Term::create(array(
|
||||
'name' => $this->randomMachineName(),
|
||||
'vid' => $this->term->bundle(),
|
||||
'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED,
|
||||
));
|
||||
$entity = EntityTest::create();
|
||||
// Now assign the unsaved term to the field.
|
||||
$entity->field_test_taxonomy_term->entity = $term;
|
||||
$entity->name->value = $this->randomMachineName();
|
||||
// This is equal to storing an entity to tempstore or cache and retrieving
|
||||
// it back. An example for this is node preview.
|
||||
$entity = serialize($entity);
|
||||
$entity = unserialize($entity);
|
||||
// And then the entity.
|
||||
$entity->save();
|
||||
$term = \Drupal::entityManager()->loadEntityByUuid($term->getEntityTypeId(), $term->uuid());
|
||||
$this->assertEqual($entity->field_test_taxonomy_term->entity->id(), $term->id());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test saving order sequence doesn't matter.
|
||||
*/
|
||||
public function testEntitySaveOrder() {
|
||||
// The term entity is unsaved here.
|
||||
$term = Term::create([
|
||||
'name' => $this->randomMachineName(),
|
||||
'vid' => $this->term->bundle(),
|
||||
'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED,
|
||||
]);
|
||||
$entity = EntityTest::create();
|
||||
// Now assign the unsaved term to the field.
|
||||
$entity->field_test_taxonomy_term->entity = $term;
|
||||
$entity->name->value = $this->randomMachineName();
|
||||
// Now get the field value.
|
||||
$value = $entity->get('field_test_taxonomy_term');
|
||||
$this->assertTrue(empty($value['target_id']));
|
||||
$this->assertNull($entity->field_test_taxonomy_term->target_id);
|
||||
// And then set it.
|
||||
$entity->field_test_taxonomy_term = $value;
|
||||
// Now save the term.
|
||||
$term->save();
|
||||
// And then the entity.
|
||||
$entity->save();
|
||||
$this->assertEqual($entity->field_test_taxonomy_term->entity->id(), $term->id());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that the 'handler' field setting stores the proper plugin ID.
|
||||
*/
|
||||
public function testSelectionHandlerSettings() {
|
||||
$field_name = Unicode::strtolower($this->randomMachineName());
|
||||
$field_storage = FieldStorageConfig::create(array(
|
||||
'field_name' => $field_name,
|
||||
'entity_type' => 'entity_test',
|
||||
'type' => 'entity_reference',
|
||||
'settings' => array(
|
||||
'target_type' => 'entity_test'
|
||||
),
|
||||
));
|
||||
$field_storage->save();
|
||||
|
||||
// Do not specify any value for the 'handler' setting in order to verify
|
||||
// that the default handler with the correct derivative is used.
|
||||
$field = FieldConfig::create(array(
|
||||
'field_storage' => $field_storage,
|
||||
'bundle' => 'entity_test',
|
||||
));
|
||||
$field->save();
|
||||
$field = FieldConfig::load($field->id());
|
||||
$this->assertEqual($field->getSetting('handler'), 'default:entity_test');
|
||||
|
||||
// Change the target_type in the field storage, and check that the handler
|
||||
// was correctly reassigned in the field.
|
||||
$field_storage->setSetting('target_type', 'entity_test_rev');
|
||||
$field_storage->save();
|
||||
$field = FieldConfig::load($field->id());
|
||||
$this->assertEqual($field->getSetting('handler'), 'default:entity_test_rev');
|
||||
|
||||
// Change the handler to another, non-derivative plugin.
|
||||
$field->setSetting('handler', 'views');
|
||||
$field->save();
|
||||
$field = FieldConfig::load($field->id());
|
||||
$this->assertEqual($field->getSetting('handler'), 'views');
|
||||
|
||||
// Change the target_type in the field storage again, and check that the
|
||||
// non-derivative handler was unchanged.
|
||||
$field_storage->setSetting('target_type', 'entity_test_rev');
|
||||
$field_storage->save();
|
||||
$field = FieldConfig::load($field->id());
|
||||
$this->assertEqual($field->getSetting('handler'), 'views');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests ValidReferenceConstraint with newly created and unsaved entities.
|
||||
*/
|
||||
public function testAutocreateValidation() {
|
||||
// The term entity is unsaved here.
|
||||
$term = Term::create(array(
|
||||
'name' => $this->randomMachineName(),
|
||||
'vid' => $this->term->bundle(),
|
||||
'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED,
|
||||
));
|
||||
$entity = EntityTest::create([
|
||||
'field_test_taxonomy_term' => [
|
||||
'entity' => $term,
|
||||
'target_id' => NULL,
|
||||
],
|
||||
]);
|
||||
$errors = $entity->validate();
|
||||
// Using target_id of NULL is valid with an unsaved entity.
|
||||
$this->assertEqual(0, count($errors));
|
||||
// Using target_id of NULL is not valid with a saved entity.
|
||||
$term->save();
|
||||
$entity = EntityTest::create([
|
||||
'field_test_taxonomy_term' => [
|
||||
'entity' => $term,
|
||||
'target_id' => NULL,
|
||||
],
|
||||
]);
|
||||
$errors = $entity->validate();
|
||||
$this->assertEqual(1, count($errors));
|
||||
$this->assertEqual($errors[0]->getMessage(), 'This value should not be null.');
|
||||
$this->assertEqual($errors[0]->getPropertyPath(), 'field_test_taxonomy_term.0');
|
||||
// This should rectify the issue, favoring the entity over the target_id.
|
||||
$entity->save();
|
||||
$errors = $entity->validate();
|
||||
$this->assertEqual(0, count($errors));
|
||||
|
||||
// Test with an unpublished and unsaved node.
|
||||
$title = $this->randomString();
|
||||
$node = Node::create([
|
||||
'title' => $title,
|
||||
'type' => 'node',
|
||||
'status' => NODE_NOT_PUBLISHED,
|
||||
]);
|
||||
|
||||
$entity = EntityTest::create([
|
||||
'field_test_node' => [
|
||||
'entity' => $node,
|
||||
],
|
||||
]);
|
||||
|
||||
$errors = $entity->validate();
|
||||
$this->assertEqual(1, count($errors));
|
||||
$this->assertEqual($errors[0]->getMessage(), new FormattableMarkup('This entity (%type: %label) cannot be referenced.', ['%type' => 'node', '%label' => $title]));
|
||||
$this->assertEqual($errors[0]->getPropertyPath(), 'field_test_node.0.entity');
|
||||
|
||||
// Publish the node and try again.
|
||||
$node->setPublished(TRUE);
|
||||
$errors = $entity->validate();
|
||||
$this->assertEqual(0, count($errors));
|
||||
|
||||
// Test with a mix of valid and invalid nodes.
|
||||
$unsaved_unpublished_node_title = $this->randomString();
|
||||
$unsaved_unpublished_node = Node::create([
|
||||
'title' => $unsaved_unpublished_node_title,
|
||||
'type' => 'node',
|
||||
'status' => NODE_NOT_PUBLISHED,
|
||||
]);
|
||||
|
||||
$saved_unpublished_node_title = $this->randomString();
|
||||
$saved_unpublished_node = Node::create([
|
||||
'title' => $saved_unpublished_node_title,
|
||||
'type' => 'node',
|
||||
'status' => NODE_NOT_PUBLISHED,
|
||||
]);
|
||||
$saved_unpublished_node->save();
|
||||
|
||||
$saved_published_node_title = $this->randomString();
|
||||
$saved_published_node = Node::create([
|
||||
'title' => $saved_published_node_title,
|
||||
'type' => 'node',
|
||||
'status' => NODE_PUBLISHED,
|
||||
]);
|
||||
$saved_published_node->save();
|
||||
|
||||
$entity = EntityTest::create([
|
||||
'field_test_node' => [
|
||||
[
|
||||
'entity' => $unsaved_unpublished_node,
|
||||
],
|
||||
[
|
||||
'target_id' => $saved_unpublished_node->id(),
|
||||
],
|
||||
[
|
||||
'target_id' => $saved_published_node->id(),
|
||||
],
|
||||
],
|
||||
]);
|
||||
|
||||
$errors = $entity->validate();
|
||||
$this->assertEqual(2, count($errors));
|
||||
$this->assertEqual($errors[0]->getMessage(), new FormattableMarkup('This entity (%type: %label) cannot be referenced.', ['%type' => 'node', '%label' => $unsaved_unpublished_node_title]));
|
||||
$this->assertEqual($errors[0]->getPropertyPath(), 'field_test_node.0.entity');
|
||||
$this->assertEqual($errors[1]->getMessage(), new FormattableMarkup('This entity (%type: %label) cannot be referenced.', ['%type' => 'node', '%label' => $saved_unpublished_node->id()]));
|
||||
$this->assertEqual($errors[1]->getPropertyPath(), 'field_test_node.1.target_id');
|
||||
|
||||
// Publish one of the nodes and try again.
|
||||
$saved_unpublished_node->setPublished(TRUE);
|
||||
$saved_unpublished_node->save();
|
||||
$errors = $entity->validate();
|
||||
$this->assertEqual(1, count($errors));
|
||||
$this->assertEqual($errors[0]->getMessage(), new FormattableMarkup('This entity (%type: %label) cannot be referenced.', ['%type' => 'node', '%label' => $unsaved_unpublished_node_title]));
|
||||
$this->assertEqual($errors[0]->getPropertyPath(), 'field_test_node.0.entity');
|
||||
|
||||
// Publish the last invalid node and try again.
|
||||
$unsaved_unpublished_node->setPublished(TRUE);
|
||||
$errors = $entity->validate();
|
||||
$this->assertEqual(0, count($errors));
|
||||
|
||||
// Test with an unpublished and unsaved comment.
|
||||
$title = $this->randomString();
|
||||
$comment = Comment::create([
|
||||
'subject' => $title,
|
||||
'comment_type' => 'comment',
|
||||
'status' => 0,
|
||||
]);
|
||||
|
||||
$entity = EntityTest::create([
|
||||
'field_test_comment' => [
|
||||
'entity' => $comment,
|
||||
],
|
||||
]);
|
||||
|
||||
$errors = $entity->validate();
|
||||
$this->assertEqual(1, count($errors));
|
||||
$this->assertEqual($errors[0]->getMessage(), new FormattableMarkup('This entity (%type: %label) cannot be referenced.', ['%type' => 'comment', '%label' => $title]));
|
||||
$this->assertEqual($errors[0]->getPropertyPath(), 'field_test_comment.0.entity');
|
||||
|
||||
// Publish the comment and try again.
|
||||
$comment->setPublished(TRUE);
|
||||
$errors = $entity->validate();
|
||||
$this->assertEqual(0, count($errors));
|
||||
|
||||
// Test with an inactive and unsaved user.
|
||||
$name = $this->randomString();
|
||||
$user = User::create([
|
||||
'name' => $name,
|
||||
'status' => 0,
|
||||
]);
|
||||
|
||||
$entity = EntityTest::create([
|
||||
'field_test_user' => [
|
||||
'entity' => $user,
|
||||
],
|
||||
]);
|
||||
|
||||
$errors = $entity->validate();
|
||||
$this->assertEqual(1, count($errors));
|
||||
$this->assertEqual($errors[0]->getMessage(), new FormattableMarkup('This entity (%type: %label) cannot be referenced.', ['%type' => 'user', '%label' => $name]));
|
||||
$this->assertEqual($errors[0]->getPropertyPath(), 'field_test_user.0.entity');
|
||||
|
||||
// Activate the user and try again.
|
||||
$user->activate();
|
||||
$errors = $entity->validate();
|
||||
$this->assertEqual(0, count($errors));
|
||||
|
||||
// Test with a temporary and unsaved file.
|
||||
$filename = $this->randomMachineName() . '.txt';
|
||||
$file = File::create([
|
||||
'filename' => $filename,
|
||||
'status' => 0,
|
||||
]);
|
||||
|
||||
$entity = EntityTest::create([
|
||||
'field_test_file' => [
|
||||
'entity' => $file,
|
||||
],
|
||||
]);
|
||||
|
||||
$errors = $entity->validate();
|
||||
$this->assertEqual(1, count($errors));
|
||||
$this->assertEqual($errors[0]->getMessage(), new FormattableMarkup('This entity (%type: %label) cannot be referenced.', ['%type' => 'file', '%label' => $filename]));
|
||||
$this->assertEqual($errors[0]->getPropertyPath(), 'field_test_file.0.entity');
|
||||
|
||||
// Set the file as permanent and try again.
|
||||
$file->setPermanent();
|
||||
$errors = $entity->validate();
|
||||
$this->assertEqual(0, count($errors));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,125 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\field\Kernel\EntityReference;
|
||||
|
||||
use Drupal\Component\Utility\Unicode;
|
||||
use Drupal\field\Entity\FieldConfig;
|
||||
use Drupal\field\Tests\EntityReference\EntityReferenceTestTrait;
|
||||
use Drupal\node\Entity\NodeType;
|
||||
use Drupal\KernelTests\KernelTestBase;
|
||||
use Drupal\taxonomy\Entity\Vocabulary;
|
||||
|
||||
/**
|
||||
* Tests entity reference field settings.
|
||||
*
|
||||
* @group field
|
||||
*/
|
||||
class EntityReferenceSettingsTest extends KernelTestBase {
|
||||
|
||||
use EntityReferenceTestTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['node', 'taxonomy', 'field', 'user', 'text', 'entity_reference', 'entity_test', 'system'];
|
||||
|
||||
/**
|
||||
* Testing node type.
|
||||
*
|
||||
* @var \Drupal\node\Entity\NodeType
|
||||
*/
|
||||
protected $nodeType;
|
||||
|
||||
/**
|
||||
* Testing vocabulary.
|
||||
*
|
||||
* @var \Drupal\taxonomy\Entity\Vocabulary
|
||||
*/
|
||||
protected $vocabulary;
|
||||
|
||||
/**
|
||||
* An entity bundle that is not stored as a configuration entity.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $customBundle;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setup();
|
||||
|
||||
$this->installEntitySchema('node');
|
||||
$this->installEntitySchema('taxonomy_term');
|
||||
$this->installEntitySchema('entity_test');
|
||||
|
||||
$this->nodeType = NodeType::create([
|
||||
'type' => Unicode::strtolower($this->randomMachineName()),
|
||||
'name' => $this->randomString(),
|
||||
]);
|
||||
$this->nodeType->save();
|
||||
|
||||
$this->vocabulary = Vocabulary::create([
|
||||
'vid' => Unicode::strtolower($this->randomMachineName()),
|
||||
'name' => $this->randomString(),
|
||||
]);
|
||||
$this->vocabulary->save();
|
||||
|
||||
// Create a custom bundle.
|
||||
$this->customBundle = 'test_bundle_' . Unicode::strtolower($this->randomMachineName());
|
||||
entity_test_create_bundle($this->customBundle, NULL, 'entity_test');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that config bundle deletions are mirrored in field config settings.
|
||||
*/
|
||||
public function testConfigTargetBundleDeletion() {
|
||||
// Attach an entity reference field to $this->nodeType.
|
||||
$name = Unicode::strtolower($this->randomMachineName());
|
||||
$label = $this->randomString();
|
||||
$vid = $this->vocabulary->id();
|
||||
$handler_settings = ['target_bundles' => [$vid => $vid]];
|
||||
$this->createEntityReferenceField('node', $this->nodeType->id(), $name, $label, 'taxonomy_term', 'default', $handler_settings);
|
||||
|
||||
// Check that the 'target_bundle' setting contains the vocabulary.
|
||||
$field_config = FieldConfig::loadByName('node', $this->nodeType->id(), $name);
|
||||
$actual_handler_settings = $field_config->getSetting('handler_settings');
|
||||
$this->assertEqual($handler_settings, $actual_handler_settings);
|
||||
|
||||
// Delete the vocabulary.
|
||||
$this->vocabulary->delete();
|
||||
|
||||
// Check that the deleted vocabulary is no longer present in the
|
||||
// 'target_bundles' field setting.
|
||||
$field_config = FieldConfig::loadByName('node', $this->nodeType->id(), $name);
|
||||
$handler_settings = $field_config->getSetting('handler_settings');
|
||||
$this->assertTrue(empty($handler_settings['target_bundles']));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that deletions of custom bundles are mirrored in field settings.
|
||||
*/
|
||||
public function testCustomTargetBundleDeletion() {
|
||||
// Attach an entity reference field to $this->nodeType.
|
||||
$name = Unicode::strtolower($this->randomMachineName());
|
||||
$label = $this->randomString();
|
||||
$handler_settings = ['target_bundles' => [$this->customBundle => $this->customBundle]];
|
||||
$this->createEntityReferenceField('node', $this->nodeType->id(), $name, $label, 'entity_test', 'default', $handler_settings);
|
||||
|
||||
// Check that the 'target_bundle' setting contains the custom bundle.
|
||||
$field_config = FieldConfig::loadByName('node', $this->nodeType->id(), $name);
|
||||
$actual_handler_settings = $field_config->getSetting('handler_settings');
|
||||
$this->assertEqual($handler_settings, $actual_handler_settings);
|
||||
|
||||
// Delete the custom bundle.
|
||||
entity_test_delete_bundle($this->customBundle, 'entity_test');
|
||||
|
||||
// Check that the deleted bundle is no longer present in the
|
||||
// 'target_bundles' field setting.
|
||||
$field_config = FieldConfig::loadByName('node', $this->nodeType->id(), $name);
|
||||
$handler_settings = $field_config->getSetting('handler_settings');
|
||||
$this->assertTrue(empty($handler_settings['target_bundles']));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,279 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\field\Kernel\EntityReference\Views;
|
||||
|
||||
use Drupal\entity_test\Entity\EntityTestMulChanged;
|
||||
use Drupal\field\Tests\EntityReference\EntityReferenceTestTrait;
|
||||
use Drupal\entity_test\Entity\EntityTest;
|
||||
use Drupal\entity_test\Entity\EntityTestMul;
|
||||
use Drupal\Tests\views\Kernel\ViewsKernelTestBase;
|
||||
use Drupal\views\Tests\ViewTestData;
|
||||
use Drupal\views\Views;
|
||||
|
||||
/**
|
||||
* Tests entity reference relationship data.
|
||||
*
|
||||
* @group entity_reference
|
||||
*
|
||||
* @see core_field_views_data()
|
||||
*/
|
||||
class EntityReferenceRelationshipTest extends ViewsKernelTestBase {
|
||||
|
||||
use EntityReferenceTestTrait;
|
||||
|
||||
/**
|
||||
* Views used by this test.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $testViews = array(
|
||||
'test_entity_reference_entity_test_view',
|
||||
'test_entity_reference_entity_test_view_long',
|
||||
'test_entity_reference_reverse_entity_test_view',
|
||||
'test_entity_reference_entity_test_mul_view',
|
||||
'test_entity_reference_reverse_entity_test_mul_view',
|
||||
);
|
||||
|
||||
/**
|
||||
* Modules to install.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['user', 'field', 'entity_test', 'views', 'entity_reference_test_views'];
|
||||
|
||||
/**
|
||||
* The entity_test entities used by the test.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $entities = array();
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp($import_test_views = TRUE) {
|
||||
parent::setUp();
|
||||
|
||||
$this->installEntitySchema('user');
|
||||
$this->installEntitySchema('entity_test');
|
||||
$this->installEntitySchema('entity_test_mul');
|
||||
$this->installEntitySchema('entity_test_mul_changed');
|
||||
|
||||
// Create reference from entity_test to entity_test_mul.
|
||||
$this->createEntityReferenceField('entity_test', 'entity_test', 'field_test_data', 'field_test_data', 'entity_test_mul');
|
||||
|
||||
// Create reference from entity_test_mul to entity_test.
|
||||
$this->createEntityReferenceField('entity_test_mul', 'entity_test_mul', 'field_data_test', 'field_data_test', 'entity_test');
|
||||
|
||||
// Create another field for testing with a long name. So it's storage name
|
||||
// will become hashed. Use entity_test_mul_changed, so the resulting field
|
||||
// tables created will be greater than 48 chars long.
|
||||
// @see \Drupal\Core\Entity\Sql\DefaultTableMapping::generateFieldTableName()
|
||||
$this->createEntityReferenceField('entity_test_mul_changed', 'entity_test_mul_changed', 'field_test_data_with_a_long_name', 'field_test_data_with_a_long_name', 'entity_test');
|
||||
|
||||
ViewTestData::createTestViews(get_class($this), array('entity_reference_test_views'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests using the views relationship.
|
||||
*/
|
||||
public function testNoDataTableRelationship() {
|
||||
|
||||
// Create some test entities which link each other.
|
||||
$referenced_entity = EntityTestMul::create();
|
||||
$referenced_entity->save();
|
||||
|
||||
$entity = EntityTest::create();
|
||||
$entity->field_test_data->target_id = $referenced_entity->id();
|
||||
$entity->save();
|
||||
$this->assertEqual($entity->field_test_data[0]->entity->id(), $referenced_entity->id());
|
||||
$this->entities[] = $entity;
|
||||
|
||||
$entity = EntityTest::create();
|
||||
$entity->field_test_data->target_id = $referenced_entity->id();
|
||||
$entity->save();
|
||||
$this->assertEqual($entity->field_test_data[0]->entity->id(), $referenced_entity->id());
|
||||
$this->entities[] = $entity;
|
||||
|
||||
Views::viewsData()->clear();
|
||||
|
||||
// Check the generated views data.
|
||||
$views_data = Views::viewsData()->get('entity_test__field_test_data');
|
||||
$this->assertEqual($views_data['field_test_data']['relationship']['id'], 'standard');
|
||||
$this->assertEqual($views_data['field_test_data']['relationship']['base'], 'entity_test_mul_property_data');
|
||||
$this->assertEqual($views_data['field_test_data']['relationship']['base field'], 'id');
|
||||
$this->assertEqual($views_data['field_test_data']['relationship']['relationship field'], 'field_test_data_target_id');
|
||||
$this->assertEqual($views_data['field_test_data']['relationship']['entity type'], 'entity_test_mul');
|
||||
|
||||
// Check the backwards reference.
|
||||
$views_data = Views::viewsData()->get('entity_test_mul_property_data');
|
||||
$this->assertEqual($views_data['reverse__entity_test__field_test_data']['relationship']['id'], 'entity_reverse');
|
||||
$this->assertEqual($views_data['reverse__entity_test__field_test_data']['relationship']['base'], 'entity_test');
|
||||
$this->assertEqual($views_data['reverse__entity_test__field_test_data']['relationship']['base field'], 'id');
|
||||
$this->assertEqual($views_data['reverse__entity_test__field_test_data']['relationship']['field table'], 'entity_test__field_test_data');
|
||||
$this->assertEqual($views_data['reverse__entity_test__field_test_data']['relationship']['field field'], 'field_test_data_target_id');
|
||||
$this->assertEqual($views_data['reverse__entity_test__field_test_data']['relationship']['field_name'], 'field_test_data');
|
||||
$this->assertEqual($views_data['reverse__entity_test__field_test_data']['relationship']['entity_type'], 'entity_test');
|
||||
$this->assertEqual($views_data['reverse__entity_test__field_test_data']['relationship']['join_extra'][0], ['field' => 'deleted', 'value' => 0, 'numeric' => TRUE]);
|
||||
|
||||
// Check an actual test view.
|
||||
$view = Views::getView('test_entity_reference_entity_test_view');
|
||||
$this->executeView($view);
|
||||
/** @var \Drupal\views\ResultRow $row */
|
||||
foreach ($view->result as $index => $row) {
|
||||
// Check that the actual ID of the entity is the expected one.
|
||||
$this->assertEqual($row->id, $this->entities[$index]->id());
|
||||
|
||||
// Also check that we have the correct result entity.
|
||||
$this->assertEqual($row->_entity->id(), $this->entities[$index]->id());
|
||||
|
||||
// Test the forward relationship.
|
||||
$this->assertEqual($row->entity_test_mul_property_data_entity_test__field_test_data_i, 1);
|
||||
|
||||
// Test that the correct relationship entity is on the row.
|
||||
$this->assertEqual($row->_relationship_entities['field_test_data']->id(), 1);
|
||||
$this->assertEqual($row->_relationship_entities['field_test_data']->bundle(), 'entity_test_mul');
|
||||
}
|
||||
|
||||
// Check the backwards reference view.
|
||||
$view = Views::getView('test_entity_reference_reverse_entity_test_view');
|
||||
$this->executeView($view);
|
||||
/** @var \Drupal\views\ResultRow $row */
|
||||
foreach ($view->result as $index => $row) {
|
||||
$this->assertEqual($row->id, 1);
|
||||
$this->assertEqual($row->_entity->id(), 1);
|
||||
|
||||
// Test the backwards relationship.
|
||||
$this->assertEqual($row->field_test_data_entity_test_mul_property_data_id, $this->entities[$index]->id());
|
||||
|
||||
// Test that the correct relationship entity is on the row.
|
||||
$this->assertEqual($row->_relationship_entities['reverse__entity_test__field_test_data']->id(), $this->entities[$index]->id());
|
||||
$this->assertEqual($row->_relationship_entities['reverse__entity_test__field_test_data']->bundle(), 'entity_test');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests views data generated for relationship.
|
||||
*
|
||||
* @see entity_reference_field_views_data()
|
||||
*/
|
||||
public function testDataTableRelationship() {
|
||||
|
||||
// Create some test entities which link each other.
|
||||
$referenced_entity = EntityTest::create();
|
||||
$referenced_entity->save();
|
||||
|
||||
$entity = EntityTestMul::create();
|
||||
$entity->field_data_test->target_id = $referenced_entity->id();
|
||||
$entity->save();
|
||||
$this->assertEqual($entity->field_data_test[0]->entity->id(), $referenced_entity->id());
|
||||
$this->entities[] = $entity;
|
||||
|
||||
$entity = EntityTestMul::create();
|
||||
$entity->field_data_test->target_id = $referenced_entity->id();
|
||||
$entity->save();
|
||||
$this->assertEqual($entity->field_data_test[0]->entity->id(), $referenced_entity->id());
|
||||
$this->entities[] = $entity;
|
||||
|
||||
Views::viewsData()->clear();
|
||||
|
||||
// Check the generated views data.
|
||||
$views_data = Views::viewsData()->get('entity_test_mul__field_data_test');
|
||||
$this->assertEqual($views_data['field_data_test']['relationship']['id'], 'standard');
|
||||
$this->assertEqual($views_data['field_data_test']['relationship']['base'], 'entity_test');
|
||||
$this->assertEqual($views_data['field_data_test']['relationship']['base field'], 'id');
|
||||
$this->assertEqual($views_data['field_data_test']['relationship']['relationship field'], 'field_data_test_target_id');
|
||||
$this->assertEqual($views_data['field_data_test']['relationship']['entity type'], 'entity_test');
|
||||
|
||||
// Check the backwards reference.
|
||||
$views_data = Views::viewsData()->get('entity_test');
|
||||
$this->assertEqual($views_data['reverse__entity_test_mul__field_data_test']['relationship']['id'], 'entity_reverse');
|
||||
$this->assertEqual($views_data['reverse__entity_test_mul__field_data_test']['relationship']['base'], 'entity_test_mul_property_data');
|
||||
$this->assertEqual($views_data['reverse__entity_test_mul__field_data_test']['relationship']['base field'], 'id');
|
||||
$this->assertEqual($views_data['reverse__entity_test_mul__field_data_test']['relationship']['field table'], 'entity_test_mul__field_data_test');
|
||||
$this->assertEqual($views_data['reverse__entity_test_mul__field_data_test']['relationship']['field field'], 'field_data_test_target_id');
|
||||
$this->assertEqual($views_data['reverse__entity_test_mul__field_data_test']['relationship']['field_name'], 'field_data_test');
|
||||
$this->assertEqual($views_data['reverse__entity_test_mul__field_data_test']['relationship']['entity_type'], 'entity_test_mul');
|
||||
$this->assertEqual($views_data['reverse__entity_test_mul__field_data_test']['relationship']['join_extra'][0], ['field' => 'deleted', 'value' => 0, 'numeric' => TRUE]);
|
||||
|
||||
// Check an actual test view.
|
||||
$view = Views::getView('test_entity_reference_entity_test_mul_view');
|
||||
$this->executeView($view);
|
||||
/** @var \Drupal\views\ResultRow $row */
|
||||
foreach ($view->result as $index => $row) {
|
||||
// Check that the actual ID of the entity is the expected one.
|
||||
$this->assertEqual($row->id, $this->entities[$index]->id());
|
||||
|
||||
// Also check that we have the correct result entity.
|
||||
$this->assertEqual($row->_entity->id(), $this->entities[$index]->id());
|
||||
|
||||
// Test the forward relationship.
|
||||
$this->assertEqual($row->entity_test_entity_test_mul__field_data_test_id, 1);
|
||||
|
||||
// Test that the correct relationship entity is on the row.
|
||||
$this->assertEqual($row->_relationship_entities['field_data_test']->id(), 1);
|
||||
$this->assertEqual($row->_relationship_entities['field_data_test']->bundle(), 'entity_test');
|
||||
|
||||
}
|
||||
|
||||
// Check the backwards reference view.
|
||||
$view = Views::getView('test_entity_reference_reverse_entity_test_mul_view');
|
||||
$this->executeView($view);
|
||||
/** @var \Drupal\views\ResultRow $row */
|
||||
foreach ($view->result as $index => $row) {
|
||||
$this->assertEqual($row->id, 1);
|
||||
$this->assertEqual($row->_entity->id(), 1);
|
||||
|
||||
// Test the backwards relationship.
|
||||
$this->assertEqual($row->field_data_test_entity_test_id, $this->entities[$index]->id());
|
||||
|
||||
// Test that the correct relationship entity is on the row.
|
||||
$this->assertEqual($row->_relationship_entities['reverse__entity_test_mul__field_data_test']->id(), $this->entities[$index]->id());
|
||||
$this->assertEqual($row->_relationship_entities['reverse__entity_test_mul__field_data_test']->bundle(), 'entity_test_mul');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests views data generated for relationship.
|
||||
*
|
||||
* @see entity_reference_field_views_data()
|
||||
*/
|
||||
public function testDataTableRelationshipWithLongFieldName() {
|
||||
// Create some test entities which link each other.
|
||||
$referenced_entity = EntityTest::create();
|
||||
$referenced_entity->save();
|
||||
|
||||
$entity = EntityTestMulChanged::create();
|
||||
$entity->field_test_data_with_a_long_name->target_id = $referenced_entity->id();
|
||||
$entity->save();
|
||||
$this->entities[] = $entity;
|
||||
|
||||
$entity = EntityTestMulChanged::create();
|
||||
$entity->field_test_data_with_a_long_name->target_id = $referenced_entity->id();
|
||||
$entity->save();
|
||||
$this->entities[] = $entity;
|
||||
|
||||
Views::viewsData()->clear();
|
||||
|
||||
// Check an actual test view.
|
||||
$view = Views::getView('test_entity_reference_entity_test_view_long');
|
||||
$this->executeView($view);
|
||||
/** @var \Drupal\views\ResultRow $row */
|
||||
foreach ($view->result as $index => $row) {
|
||||
// Check that the actual ID of the entity is the expected one.
|
||||
$this->assertEqual($row->id, $this->entities[$index]->id());
|
||||
|
||||
// Also check that we have the correct result entity.
|
||||
$this->assertEqual($row->_entity->id(), $this->entities[$index]->id());
|
||||
|
||||
// Test the forward relationship.
|
||||
//$this->assertEqual($row->entity_test_entity_test_mul__field_data_test_id, 1);
|
||||
|
||||
// Test that the correct relationship entity is on the row.
|
||||
$this->assertEqual($row->_relationship_entities['field_test_data_with_a_long_name']->id(), 1);
|
||||
$this->assertEqual($row->_relationship_entities['field_test_data_with_a_long_name']->bundle(), 'entity_test');
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
381
web/core/modules/field/tests/src/Kernel/FieldAttachOtherTest.php
Normal file
381
web/core/modules/field/tests/src/Kernel/FieldAttachOtherTest.php
Normal file
|
@ -0,0 +1,381 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\field\Kernel;
|
||||
|
||||
use Drupal\Core\Form\FormState;
|
||||
use Drupal\entity_test\Entity\EntityTest;
|
||||
|
||||
/**
|
||||
* Tests other Field API functions.
|
||||
*
|
||||
* @group field
|
||||
* @todo move this to the Entity module
|
||||
*/
|
||||
class FieldAttachOtherTest extends FieldKernelTestBase {
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$this->container->get('router.builder')->rebuild();
|
||||
$this->installEntitySchema('entity_test_rev');
|
||||
$this->createFieldWithStorage();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test rendering fields with EntityDisplay build().
|
||||
*/
|
||||
function testEntityDisplayBuild() {
|
||||
$this->createFieldWithStorage('_2');
|
||||
|
||||
$entity_type = 'entity_test';
|
||||
$entity_init = $this->container->get('entity_type.manager')
|
||||
->getStorage($entity_type)
|
||||
->create();
|
||||
|
||||
// Populate values to be displayed.
|
||||
$values = $this->_generateTestFieldValues($this->fieldTestData->field_storage->getCardinality());
|
||||
$entity_init->{$this->fieldTestData->field_name}->setValue($values);
|
||||
$values_2 = $this->_generateTestFieldValues($this->fieldTestData->field_storage_2->getCardinality());
|
||||
$entity_init->{$this->fieldTestData->field_name_2}->setValue($values_2);
|
||||
|
||||
// Simple formatter, label displayed.
|
||||
$entity = clone($entity_init);
|
||||
$display = entity_get_display($entity_type, $entity->bundle(), 'full');
|
||||
|
||||
$formatter_setting = $this->randomMachineName();
|
||||
$display_options = array(
|
||||
'label' => 'above',
|
||||
'type' => 'field_test_default',
|
||||
'settings' => array(
|
||||
'test_formatter_setting' => $formatter_setting,
|
||||
),
|
||||
);
|
||||
$display->setComponent($this->fieldTestData->field_name, $display_options);
|
||||
|
||||
$formatter_setting_2 = $this->randomMachineName();
|
||||
$display_options_2 = array(
|
||||
'label' => 'above',
|
||||
'type' => 'field_test_default',
|
||||
'settings' => array(
|
||||
'test_formatter_setting' => $formatter_setting_2,
|
||||
),
|
||||
);
|
||||
$display->setComponent($this->fieldTestData->field_name_2, $display_options_2);
|
||||
|
||||
// View all fields.
|
||||
$content = $display->build($entity);
|
||||
$this->render($content);
|
||||
$this->assertRaw($this->fieldTestData->field->getLabel(), "First field's label is displayed.");
|
||||
foreach ($values as $delta => $value) {
|
||||
$this->assertRaw("$formatter_setting|{$value['value']}", "Value $delta is displayed, formatter settings are applied.");
|
||||
}
|
||||
$this->assertRaw($this->fieldTestData->field_2->getLabel(), "Second field's label is displayed.");
|
||||
foreach ($values_2 as $delta => $value) {
|
||||
$this->assertRaw("$formatter_setting_2|{$value['value']}", "Value $delta is displayed, formatter settings are applied.");
|
||||
}
|
||||
|
||||
// Label hidden.
|
||||
$entity = clone($entity_init);
|
||||
$display_options['label'] = 'hidden';
|
||||
$display->setComponent($this->fieldTestData->field_name, $display_options);
|
||||
$content = $display->build($entity);
|
||||
$this->render($content);
|
||||
$this->assertNoRaw($this->fieldTestData->field->getLabel(), "Hidden label: label is not displayed.");
|
||||
|
||||
// Field hidden.
|
||||
$entity = clone($entity_init);
|
||||
$display->removeComponent($this->fieldTestData->field_name);
|
||||
$content = $display->build($entity);
|
||||
$this->render($content);
|
||||
$this->assertNoRaw($this->fieldTestData->field->getLabel(), "Hidden field: label is not displayed.");
|
||||
foreach ($values as $delta => $value) {
|
||||
$this->assertNoRaw("$formatter_setting|{$value['value']}", "Hidden field: value $delta is not displayed.");
|
||||
}
|
||||
|
||||
// Multiple formatter.
|
||||
$entity = clone($entity_init);
|
||||
$formatter_setting = $this->randomMachineName();
|
||||
$display->setComponent($this->fieldTestData->field_name, array(
|
||||
'label' => 'above',
|
||||
'type' => 'field_test_multiple',
|
||||
'settings' => array(
|
||||
'test_formatter_setting_multiple' => $formatter_setting,
|
||||
),
|
||||
));
|
||||
$content = $display->build($entity);
|
||||
$this->render($content);
|
||||
$expected_output = $formatter_setting;
|
||||
foreach ($values as $delta => $value) {
|
||||
$expected_output .= "|$delta:{$value['value']}";
|
||||
}
|
||||
$this->assertRaw($expected_output, "Multiple formatter: all values are displayed, formatter settings are applied.");
|
||||
|
||||
// Test a formatter that uses hook_field_formatter_prepare_view().
|
||||
$entity = clone($entity_init);
|
||||
$formatter_setting = $this->randomMachineName();
|
||||
$display->setComponent($this->fieldTestData->field_name, array(
|
||||
'label' => 'above',
|
||||
'type' => 'field_test_with_prepare_view',
|
||||
'settings' => array(
|
||||
'test_formatter_setting_additional' => $formatter_setting,
|
||||
),
|
||||
));
|
||||
$content = $display->build($entity);
|
||||
$this->render($content);
|
||||
foreach ($values as $delta => $value) {
|
||||
$expected = $formatter_setting . '|' . $value['value'] . '|' . ($value['value'] + 1);
|
||||
$this->assertRaw($expected, "Value $delta is displayed, formatter settings are applied.");
|
||||
}
|
||||
|
||||
// TODO:
|
||||
// - check display order with several fields
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests rendering fields with EntityDisplay::buildMultiple().
|
||||
*/
|
||||
function testEntityDisplayViewMultiple() {
|
||||
// Use a formatter that has a prepareView() step.
|
||||
$display = entity_get_display('entity_test', 'entity_test', 'full')
|
||||
->setComponent($this->fieldTestData->field_name, array(
|
||||
'type' => 'field_test_with_prepare_view',
|
||||
));
|
||||
|
||||
// Create two entities.
|
||||
$entity1 = EntityTest::create(array('id' => 1, 'type' => 'entity_test'));
|
||||
$entity1->{$this->fieldTestData->field_name}->setValue($this->_generateTestFieldValues(1));
|
||||
$entity2 = EntityTest::create(array('id' => 2, 'type' => 'entity_test'));
|
||||
$entity2->{$this->fieldTestData->field_name}->setValue($this->_generateTestFieldValues(1));
|
||||
|
||||
// Run buildMultiple(), and check that the entities come out as expected.
|
||||
$display->buildMultiple(array($entity1, $entity2));
|
||||
$item1 = $entity1->{$this->fieldTestData->field_name}[0];
|
||||
$this->assertEqual($item1->additional_formatter_value, $item1->value + 1, 'Entity 1 ran through the prepareView() formatter method.');
|
||||
$item2 = $entity2->{$this->fieldTestData->field_name}[0];
|
||||
$this->assertEqual($item2->additional_formatter_value, $item2->value + 1, 'Entity 2 ran through the prepareView() formatter method.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test entity cache.
|
||||
*
|
||||
* Complements unit test coverage in
|
||||
* \Drupal\Tests\Core\Entity\Sql\SqlContentEntityStorageTest.
|
||||
*/
|
||||
function testEntityCache() {
|
||||
// Initialize random values and a test entity.
|
||||
$entity_init = EntityTest::create(array('type' => $this->fieldTestData->field->getTargetBundle()));
|
||||
$values = $this->_generateTestFieldValues($this->fieldTestData->field_storage->getCardinality());
|
||||
|
||||
// Non-cacheable entity type.
|
||||
$entity_type = 'entity_test';
|
||||
$cid = "values:$entity_type:" . $entity_init->id();
|
||||
|
||||
// Check that no initial cache entry is present.
|
||||
$this->assertFalse(\Drupal::cache('entity')->get($cid), 'Non-cached: no initial cache entry');
|
||||
|
||||
// Save, and check that no cache entry is present.
|
||||
$entity = clone($entity_init);
|
||||
$entity->{$this->fieldTestData->field_name}->setValue($values);
|
||||
$entity = $this->entitySaveReload($entity);
|
||||
$cid = "values:$entity_type:" . $entity->id();
|
||||
$this->assertFalse(\Drupal::cache('entity')->get($cid), 'Non-cached: no cache entry on insert and load');
|
||||
|
||||
// Cacheable entity type.
|
||||
$entity_type = 'entity_test_rev';
|
||||
$this->createFieldWithStorage('_2', $entity_type);
|
||||
|
||||
$entity_init = $this->container->get('entity_type.manager')
|
||||
->getStorage($entity_type)
|
||||
->create(array(
|
||||
'type' => $entity_type,
|
||||
));
|
||||
|
||||
// Check that no initial cache entry is present.
|
||||
$cid = "values:$entity_type:" . $entity->id();
|
||||
$this->assertFalse(\Drupal::cache('entity')->get($cid), 'Cached: no initial cache entry');
|
||||
|
||||
// Save, and check that no cache entry is present.
|
||||
$entity = clone($entity_init);
|
||||
$entity->{$this->fieldTestData->field_name_2} = $values;
|
||||
$entity->save();
|
||||
$cid = "values:$entity_type:" . $entity->id();
|
||||
|
||||
$this->assertFalse(\Drupal::cache('entity')->get($cid), 'Cached: no cache entry on insert');
|
||||
// Load, and check that a cache entry is present with the expected values.
|
||||
$controller = $this->container->get('entity.manager')->getStorage($entity->getEntityTypeId());
|
||||
$controller->resetCache();
|
||||
$cached_entity = $controller->load($entity->id());
|
||||
$cache = \Drupal::cache('entity')->get($cid);
|
||||
$this->assertEqual($cache->data, $cached_entity, 'Cached: correct cache entry on load');
|
||||
|
||||
// Update with different values, and check that the cache entry is wiped.
|
||||
$values = $this->_generateTestFieldValues($this->fieldTestData->field_storage_2->getCardinality());
|
||||
$entity->{$this->fieldTestData->field_name_2} = $values;
|
||||
$entity->save();
|
||||
$this->assertFalse(\Drupal::cache('entity')->get($cid), 'Cached: no cache entry on update');
|
||||
|
||||
// Load, and check that a cache entry is present with the expected values.
|
||||
$controller->resetCache();
|
||||
$cached_entity = $controller->load($entity->id());
|
||||
$cache = \Drupal::cache('entity')->get($cid);
|
||||
$this->assertEqual($cache->data, $cached_entity, 'Cached: correct cache entry on load');
|
||||
|
||||
// Create a new revision, and check that the cache entry is wiped.
|
||||
$values = $this->_generateTestFieldValues($this->fieldTestData->field_storage_2->getCardinality());
|
||||
$entity->{$this->fieldTestData->field_name_2} = $values;
|
||||
$entity->setNewRevision();
|
||||
$entity->save();
|
||||
$this->assertFalse(\Drupal::cache('entity')->get($cid), 'Cached: no cache entry on new revision creation');
|
||||
|
||||
// Load, and check that a cache entry is present with the expected values.
|
||||
$controller->resetCache();
|
||||
$cached_entity = $controller->load($entity->id());
|
||||
$cache = \Drupal::cache('entity')->get($cid);
|
||||
$this->assertEqual($cache->data, $cached_entity, 'Cached: correct cache entry on load');
|
||||
|
||||
// Delete, and check that the cache entry is wiped.
|
||||
$entity->delete();
|
||||
$this->assertFalse(\Drupal::cache('entity')->get($cid), 'Cached: no cache entry after delete');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests \Drupal\Core\Entity\Display\EntityFormDisplayInterface::buildForm().
|
||||
*
|
||||
* This could be much more thorough, but it does verify that the correct
|
||||
* widgets show up.
|
||||
*/
|
||||
function testEntityFormDisplayBuildForm() {
|
||||
$this->createFieldWithStorage('_2');
|
||||
|
||||
$entity_type = 'entity_test';
|
||||
$entity = entity_create($entity_type, array('id' => 1, 'revision_id' => 1, 'type' => $this->fieldTestData->field->getTargetBundle()));
|
||||
|
||||
// Test generating widgets for all fields.
|
||||
$display = entity_get_form_display($entity_type, $this->fieldTestData->field->getTargetBundle(), 'default');
|
||||
$form = array();
|
||||
$form_state = new FormState();
|
||||
$display->buildForm($entity, $form, $form_state);
|
||||
|
||||
$this->assertEqual($form[$this->fieldTestData->field_name]['widget']['#title'], $this->fieldTestData->field->getLabel(), "First field's form title is {$this->fieldTestData->field->getLabel()}");
|
||||
$this->assertEqual($form[$this->fieldTestData->field_name_2]['widget']['#title'], $this->fieldTestData->field_2->getLabel(), "Second field's form title is {$this->fieldTestData->field_2->getLabel()}");
|
||||
for ($delta = 0; $delta < $this->fieldTestData->field_storage->getCardinality(); $delta++) {
|
||||
// field_test_widget uses 'textfield'
|
||||
$this->assertEqual($form[$this->fieldTestData->field_name]['widget'][$delta]['value']['#type'], 'textfield', "First field's form delta $delta widget is textfield");
|
||||
}
|
||||
for ($delta = 0; $delta < $this->fieldTestData->field_storage_2->getCardinality(); $delta++) {
|
||||
// field_test_widget uses 'textfield'
|
||||
$this->assertEqual($form[$this->fieldTestData->field_name_2]['widget'][$delta]['value']['#type'], 'textfield', "Second field's form delta $delta widget is textfield");
|
||||
}
|
||||
|
||||
// Test generating widgets for all fields.
|
||||
$display = entity_get_form_display($entity_type, $this->fieldTestData->field->getTargetBundle(), 'default');
|
||||
foreach ($display->getComponents() as $name => $options) {
|
||||
if ($name != $this->fieldTestData->field_name_2) {
|
||||
$display->removeComponent($name);
|
||||
}
|
||||
}
|
||||
$form = array();
|
||||
$form_state = new FormState();
|
||||
$display->buildForm($entity, $form, $form_state);
|
||||
|
||||
$this->assertFalse(isset($form[$this->fieldTestData->field_name]), 'The first field does not exist in the form');
|
||||
$this->assertEqual($form[$this->fieldTestData->field_name_2]['widget']['#title'], $this->fieldTestData->field_2->getLabel(), "Second field's form title is {$this->fieldTestData->field_2->getLabel()}");
|
||||
for ($delta = 0; $delta < $this->fieldTestData->field_storage_2->getCardinality(); $delta++) {
|
||||
// field_test_widget uses 'textfield'
|
||||
$this->assertEqual($form[$this->fieldTestData->field_name_2]['widget'][$delta]['value']['#type'], 'textfield', "Second field's form delta $delta widget is textfield");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests \Drupal\Core\Entity\Display\EntityFormDisplayInterface::extractFormValues().
|
||||
*/
|
||||
function testEntityFormDisplayExtractFormValues() {
|
||||
$this->createFieldWithStorage('_2');
|
||||
|
||||
$entity_type = 'entity_test';
|
||||
$entity_init = $this->container->get('entity_type.manager')
|
||||
->getStorage($entity_type)
|
||||
->create(array('id' => 1, 'revision_id' => 1, 'type' => $this->fieldTestData->field->getTargetBundle()));
|
||||
|
||||
// Build the form for all fields.
|
||||
$display = entity_get_form_display($entity_type, $this->fieldTestData->field->getTargetBundle(), 'default');
|
||||
$form = array();
|
||||
$form_state = new FormState();
|
||||
$display->buildForm($entity_init, $form, $form_state);
|
||||
|
||||
// Simulate incoming values.
|
||||
// First field.
|
||||
$values = array();
|
||||
$weights = array();
|
||||
for ($delta = 0; $delta < $this->fieldTestData->field_storage->getCardinality(); $delta++) {
|
||||
$values[$delta]['value'] = mt_rand(1, 127);
|
||||
// Assign random weight.
|
||||
do {
|
||||
$weight = mt_rand(0, $this->fieldTestData->field_storage->getCardinality());
|
||||
} while (in_array($weight, $weights));
|
||||
$weights[$delta] = $weight;
|
||||
$values[$delta]['_weight'] = $weight;
|
||||
}
|
||||
// Leave an empty value. 'field_test' fields are empty if empty().
|
||||
$values[1]['value'] = 0;
|
||||
// Second field.
|
||||
$values_2 = array();
|
||||
$weights_2 = array();
|
||||
for ($delta = 0; $delta < $this->fieldTestData->field_storage_2->getCardinality(); $delta++) {
|
||||
$values_2[$delta]['value'] = mt_rand(1, 127);
|
||||
// Assign random weight.
|
||||
do {
|
||||
$weight = mt_rand(0, $this->fieldTestData->field_storage_2->getCardinality());
|
||||
} while (in_array($weight, $weights_2));
|
||||
$weights_2[$delta] = $weight;
|
||||
$values_2[$delta]['_weight'] = $weight;
|
||||
}
|
||||
// Leave an empty value. 'field_test' fields are empty if empty().
|
||||
$values_2[1]['value'] = 0;
|
||||
|
||||
// Pretend the form has been built.
|
||||
$form_state->setFormObject(\Drupal::entityManager()->getFormObject($entity_type, 'default'));
|
||||
\Drupal::formBuilder()->prepareForm('field_test_entity_form', $form, $form_state);
|
||||
\Drupal::formBuilder()->processForm('field_test_entity_form', $form, $form_state);
|
||||
$form_state->setValue($this->fieldTestData->field_name, $values);
|
||||
$form_state->setValue($this->fieldTestData->field_name_2, $values_2);
|
||||
|
||||
// Extract values for all fields.
|
||||
$entity = clone($entity_init);
|
||||
$display->extractFormValues($entity, $form, $form_state);
|
||||
|
||||
asort($weights);
|
||||
asort($weights_2);
|
||||
$expected_values = array();
|
||||
$expected_values_2 = array();
|
||||
foreach ($weights as $key => $value) {
|
||||
if ($key != 1) {
|
||||
$expected_values[] = array('value' => $values[$key]['value']);
|
||||
}
|
||||
}
|
||||
$this->assertIdentical($entity->{$this->fieldTestData->field_name}->getValue(), $expected_values, 'Submit filters empty values');
|
||||
foreach ($weights_2 as $key => $value) {
|
||||
if ($key != 1) {
|
||||
$expected_values_2[] = array('value' => $values_2[$key]['value']);
|
||||
}
|
||||
}
|
||||
$this->assertIdentical($entity->{$this->fieldTestData->field_name_2}->getValue(), $expected_values_2, 'Submit filters empty values');
|
||||
|
||||
// Call EntityFormDisplayInterface::extractFormValues() for a single field (the second field).
|
||||
foreach ($display->getComponents() as $name => $options) {
|
||||
if ($name != $this->fieldTestData->field_name_2) {
|
||||
$display->removeComponent($name);
|
||||
}
|
||||
}
|
||||
$entity = clone($entity_init);
|
||||
$display->extractFormValues($entity, $form, $form_state);
|
||||
$expected_values_2 = array();
|
||||
foreach ($weights_2 as $key => $value) {
|
||||
if ($key != 1) {
|
||||
$expected_values_2[] = array('value' => $values_2[$key]['value']);
|
||||
}
|
||||
}
|
||||
$this->assertTrue($entity->{$this->fieldTestData->field_name}->isEmpty(), 'The first field is empty in the entity object');
|
||||
$this->assertIdentical($entity->{$this->fieldTestData->field_name_2}->getValue(), $expected_values_2, 'Submit filters empty values');
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,376 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\field\Kernel;
|
||||
use Drupal\Component\Utility\Unicode;
|
||||
use Drupal\field\Entity\FieldConfig;
|
||||
use Drupal\field\Entity\FieldStorageConfig;
|
||||
|
||||
/**
|
||||
* Tests storage-related Field Attach API functions.
|
||||
*
|
||||
* @group field
|
||||
* @todo move this to the Entity module
|
||||
*/
|
||||
class FieldAttachStorageTest extends FieldKernelTestBase {
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$this->installEntitySchema('entity_test_rev');
|
||||
}
|
||||
|
||||
/**
|
||||
* Check field values insert, update and load.
|
||||
*
|
||||
* Works independently of the underlying field storage backend. Inserts or
|
||||
* updates random field data and then loads and verifies the data.
|
||||
*/
|
||||
function testFieldAttachSaveLoad() {
|
||||
$entity_type = 'entity_test_rev';
|
||||
$this->createFieldWithStorage('', $entity_type);
|
||||
$cardinality = $this->fieldTestData->field_storage->getCardinality();
|
||||
|
||||
// TODO : test empty values filtering and "compression" (store consecutive deltas).
|
||||
// Preparation: create three revisions and store them in $revision array.
|
||||
$values = array();
|
||||
$entity = $this->container->get('entity_type.manager')
|
||||
->getStorage($entity_type)
|
||||
->create();
|
||||
for ($revision_id = 0; $revision_id < 3; $revision_id++) {
|
||||
// Note: we try to insert one extra value.
|
||||
$current_values = $this->_generateTestFieldValues($cardinality + 1);
|
||||
$entity->{$this->fieldTestData->field_name}->setValue($current_values);
|
||||
$entity->setNewRevision();
|
||||
$entity->save();
|
||||
$entity_id = $entity->id();
|
||||
$current_revision = $entity->getRevisionId();
|
||||
$values[$current_revision] = $current_values;
|
||||
}
|
||||
|
||||
$storage = $this->container->get('entity.manager')->getStorage($entity_type);
|
||||
$storage->resetCache();
|
||||
$entity = $storage->load($entity_id);
|
||||
// Confirm current revision loads the correct data.
|
||||
// Number of values per field loaded equals the field cardinality.
|
||||
$this->assertEqual(count($entity->{$this->fieldTestData->field_name}), $cardinality, 'Current revision: expected number of values');
|
||||
for ($delta = 0; $delta < $cardinality; $delta++) {
|
||||
// The field value loaded matches the one inserted or updated.
|
||||
$this->assertEqual($entity->{$this->fieldTestData->field_name}[$delta]->value, $values[$current_revision][$delta]['value'], format_string('Current revision: expected value %delta was found.', array('%delta' => $delta)));
|
||||
}
|
||||
|
||||
// Confirm each revision loads the correct data.
|
||||
foreach (array_keys($values) as $revision_id) {
|
||||
$entity = $storage->loadRevision($revision_id);
|
||||
// Number of values per field loaded equals the field cardinality.
|
||||
$this->assertEqual(count($entity->{$this->fieldTestData->field_name}), $cardinality, format_string('Revision %revision_id: expected number of values.', array('%revision_id' => $revision_id)));
|
||||
for ($delta = 0; $delta < $cardinality; $delta++) {
|
||||
// The field value loaded matches the one inserted or updated.
|
||||
$this->assertEqual($entity->{$this->fieldTestData->field_name}[$delta]->value, $values[$revision_id][$delta]['value'], format_string('Revision %revision_id: expected value %delta was found.', array('%revision_id' => $revision_id, '%delta' => $delta)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the 'multiple' load feature.
|
||||
*/
|
||||
function testFieldAttachLoadMultiple() {
|
||||
$entity_type = 'entity_test_rev';
|
||||
|
||||
// Define 2 bundles.
|
||||
$bundles = array(
|
||||
1 => 'test_bundle_1',
|
||||
2 => 'test_bundle_2',
|
||||
);
|
||||
entity_test_create_bundle($bundles[1]);
|
||||
entity_test_create_bundle($bundles[2]);
|
||||
// Define 3 fields:
|
||||
// - field_1 is in bundle_1 and bundle_2,
|
||||
// - field_2 is in bundle_1,
|
||||
// - field_3 is in bundle_2.
|
||||
$field_bundles_map = array(
|
||||
1 => array(1, 2),
|
||||
2 => array(1),
|
||||
3 => array(2),
|
||||
);
|
||||
for ($i = 1; $i <= 3; $i++) {
|
||||
$field_names[$i] = 'field_' . $i;
|
||||
$field_storage = FieldStorageConfig::create(array(
|
||||
'field_name' => $field_names[$i],
|
||||
'entity_type' => $entity_type,
|
||||
'type' => 'test_field',
|
||||
));
|
||||
$field_storage->save();
|
||||
$field_ids[$i] = $field_storage->uuid();
|
||||
foreach ($field_bundles_map[$i] as $bundle) {
|
||||
FieldConfig::create([
|
||||
'field_name' => $field_names[$i],
|
||||
'entity_type' => $entity_type,
|
||||
'bundle' => $bundles[$bundle],
|
||||
])->save();
|
||||
}
|
||||
}
|
||||
|
||||
// Create one test entity per bundle, with random values.
|
||||
foreach ($bundles as $index => $bundle) {
|
||||
$entities[$index] = $this->container->get('entity_type.manager')
|
||||
->getStorage($entity_type)
|
||||
->create(array('id' => $index, 'revision_id' => $index, 'type' => $bundle));
|
||||
$entity = clone($entities[$index]);
|
||||
foreach ($field_names as $field_name) {
|
||||
if (!$entity->hasField($field_name)) {
|
||||
continue;
|
||||
}
|
||||
$values[$index][$field_name] = mt_rand(1, 127);
|
||||
$entity->$field_name->setValue(array('value' => $values[$index][$field_name]));
|
||||
}
|
||||
$entity->enforceIsnew();
|
||||
$entity->save();
|
||||
}
|
||||
|
||||
// Check that a single load correctly loads field values for both entities.
|
||||
$controller = \Drupal::entityManager()->getStorage($entity->getEntityTypeId());
|
||||
$controller->resetCache();
|
||||
$entities = $controller->loadMultiple();
|
||||
foreach ($entities as $index => $entity) {
|
||||
foreach ($field_names as $field_name) {
|
||||
if (!$entity->hasField($field_name)) {
|
||||
continue;
|
||||
}
|
||||
// The field value loaded matches the one inserted.
|
||||
$this->assertEqual($entity->{$field_name}->value, $values[$index][$field_name], format_string('Entity %index: expected value was found.', array('%index' => $index)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests insert and update with empty or NULL fields.
|
||||
*/
|
||||
function testFieldAttachSaveEmptyData() {
|
||||
$entity_type = 'entity_test';
|
||||
$this->createFieldWithStorage('', $entity_type);
|
||||
|
||||
$entity_init = $this->container->get('entity_type.manager')
|
||||
->getStorage($entity_type)
|
||||
->create(array('id' => 1));
|
||||
|
||||
// Insert: Field is NULL.
|
||||
$entity = clone $entity_init;
|
||||
$entity->{$this->fieldTestData->field_name} = NULL;
|
||||
$entity->enforceIsNew();
|
||||
$entity = $this->entitySaveReload($entity);
|
||||
$this->assertTrue($entity->{$this->fieldTestData->field_name}->isEmpty(), 'Insert: NULL field results in no value saved');
|
||||
|
||||
// All saves after this point should be updates, not inserts.
|
||||
$entity_init->enforceIsNew(FALSE);
|
||||
|
||||
// Add some real data.
|
||||
$entity = clone($entity_init);
|
||||
$values = $this->_generateTestFieldValues(1);
|
||||
$entity->{$this->fieldTestData->field_name} = $values;
|
||||
$entity = $this->entitySaveReload($entity);
|
||||
$this->assertEqual($entity->{$this->fieldTestData->field_name}->getValue(), $values, 'Field data saved');
|
||||
|
||||
// Update: Field is NULL. Data should be wiped.
|
||||
$entity = clone($entity_init);
|
||||
$entity->{$this->fieldTestData->field_name} = NULL;
|
||||
$entity = $this->entitySaveReload($entity);
|
||||
$this->assertTrue($entity->{$this->fieldTestData->field_name}->isEmpty(), 'Update: NULL field removes existing values');
|
||||
|
||||
// Re-add some data.
|
||||
$entity = clone($entity_init);
|
||||
$values = $this->_generateTestFieldValues(1);
|
||||
$entity->{$this->fieldTestData->field_name} = $values;
|
||||
$entity = $this->entitySaveReload($entity);
|
||||
$this->assertEqual($entity->{$this->fieldTestData->field_name}->getValue(), $values, 'Field data saved');
|
||||
|
||||
// Update: Field is empty array. Data should be wiped.
|
||||
$entity = clone($entity_init);
|
||||
$entity->{$this->fieldTestData->field_name} = array();
|
||||
$entity = $this->entitySaveReload($entity);
|
||||
$this->assertTrue($entity->{$this->fieldTestData->field_name}->isEmpty(), 'Update: empty array removes existing values');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test insert with empty or NULL fields, with default value.
|
||||
*/
|
||||
function testFieldAttachSaveEmptyDataDefaultValue() {
|
||||
$entity_type = 'entity_test_rev';
|
||||
$this->createFieldWithStorage('', $entity_type);
|
||||
|
||||
// Add a default value function.
|
||||
$this->fieldTestData->field->set('default_value_callback', 'field_test_default_value');
|
||||
$this->fieldTestData->field->save();
|
||||
|
||||
// Verify that fields are populated with default values.
|
||||
$entity_init = $this->container->get('entity_type.manager')
|
||||
->getStorage($entity_type)
|
||||
->create(array('id' => 1, 'revision_id' => 1));
|
||||
$default = field_test_default_value($entity_init, $this->fieldTestData->field);
|
||||
$this->assertEqual($entity_init->{$this->fieldTestData->field_name}->getValue(), $default, 'Default field value correctly populated.');
|
||||
|
||||
// Insert: Field is NULL.
|
||||
$entity = clone($entity_init);
|
||||
$entity->{$this->fieldTestData->field_name} = NULL;
|
||||
$entity->enforceIsNew();
|
||||
$entity = $this->entitySaveReload($entity);
|
||||
$this->assertTrue($entity->{$this->fieldTestData->field_name}->isEmpty(), 'Insert: NULL field results in no value saved');
|
||||
|
||||
// Verify that prepopulated field values are not overwritten by defaults.
|
||||
$value = array(array('value' => $default[0]['value'] - mt_rand(1, 127)));
|
||||
$entity = $this->container->get('entity_type.manager')
|
||||
->getStorage($entity_type)
|
||||
->create(array('type' => $entity_init->bundle(), $this->fieldTestData->field_name => $value));
|
||||
$this->assertEqual($entity->{$this->fieldTestData->field_name}->getValue(), $value, 'Prepopulated field value correctly maintained.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test entity deletion.
|
||||
*/
|
||||
function testFieldAttachDelete() {
|
||||
$entity_type = 'entity_test_rev';
|
||||
$this->createFieldWithStorage('', $entity_type);
|
||||
$cardinality = $this->fieldTestData->field_storage->getCardinality();
|
||||
$entity = $this->container->get('entity_type.manager')
|
||||
->getStorage($entity_type)
|
||||
->create(array('type' => $this->fieldTestData->field->getTargetBundle()));
|
||||
$vids = array();
|
||||
|
||||
// Create revision 0
|
||||
$values = $this->_generateTestFieldValues($cardinality);
|
||||
$entity->{$this->fieldTestData->field_name} = $values;
|
||||
$entity->save();
|
||||
$vids[] = $entity->getRevisionId();
|
||||
|
||||
// Create revision 1
|
||||
$entity->setNewRevision();
|
||||
$entity->save();
|
||||
$vids[] = $entity->getRevisionId();
|
||||
|
||||
// Create revision 2
|
||||
$entity->setNewRevision();
|
||||
$entity->save();
|
||||
$vids[] = $entity->getRevisionId();
|
||||
$controller = $this->container->get('entity.manager')->getStorage($entity->getEntityTypeId());
|
||||
$controller->resetCache();
|
||||
|
||||
// Confirm each revision loads
|
||||
foreach ($vids as $vid) {
|
||||
$revision = $controller->loadRevision($vid);
|
||||
$this->assertEqual(count($revision->{$this->fieldTestData->field_name}), $cardinality, "The test entity revision $vid has $cardinality values.");
|
||||
}
|
||||
|
||||
// Delete revision 1, confirm the other two still load.
|
||||
$controller->deleteRevision($vids[1]);
|
||||
$controller->resetCache();
|
||||
foreach (array(0, 2) as $key) {
|
||||
$vid = $vids[$key];
|
||||
$revision = $controller->loadRevision($vid);
|
||||
$this->assertEqual(count($revision->{$this->fieldTestData->field_name}), $cardinality, "The test entity revision $vid has $cardinality values.");
|
||||
}
|
||||
|
||||
// Confirm the current revision still loads
|
||||
$controller->resetCache();
|
||||
$current = $controller->load($entity->id());
|
||||
$this->assertEqual(count($current->{$this->fieldTestData->field_name}), $cardinality, "The test entity current revision has $cardinality values.");
|
||||
|
||||
// Delete all field data, confirm nothing loads
|
||||
$entity->delete();
|
||||
$controller->resetCache();
|
||||
foreach (array(0, 1, 2) as $vid) {
|
||||
$revision = $controller->loadRevision($vid);
|
||||
$this->assertFalse($revision);
|
||||
}
|
||||
$this->assertFalse($controller->load($entity->id()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test entity_bundle_create().
|
||||
*/
|
||||
function testEntityCreateBundle() {
|
||||
$entity_type = 'entity_test_rev';
|
||||
$this->createFieldWithStorage('', $entity_type);
|
||||
$cardinality = $this->fieldTestData->field_storage->getCardinality();
|
||||
|
||||
// Create a new bundle.
|
||||
$new_bundle = 'test_bundle_' . Unicode::strtolower($this->randomMachineName());
|
||||
entity_test_create_bundle($new_bundle, NULL, $entity_type);
|
||||
|
||||
// Add a field to that bundle.
|
||||
$this->fieldTestData->field_definition['bundle'] = $new_bundle;
|
||||
FieldConfig::create($this->fieldTestData->field_definition)->save();
|
||||
|
||||
// Save an entity with data in the field.
|
||||
$entity = $this->container->get('entity_type.manager')
|
||||
->getStorage($entity_type)
|
||||
->create(array('type' => $this->fieldTestData->field->getTargetBundle()));
|
||||
$values = $this->_generateTestFieldValues($cardinality);
|
||||
$entity->{$this->fieldTestData->field_name} = $values;
|
||||
|
||||
// Verify the field data is present on load.
|
||||
$entity = $this->entitySaveReload($entity);
|
||||
$this->assertEqual(count($entity->{$this->fieldTestData->field_name}), $cardinality, "Data is retrieved for the new bundle");
|
||||
}
|
||||
|
||||
/**
|
||||
* Test entity_bundle_delete().
|
||||
*/
|
||||
function testEntityDeleteBundle() {
|
||||
$entity_type = 'entity_test_rev';
|
||||
$this->createFieldWithStorage('', $entity_type);
|
||||
|
||||
// Create a new bundle.
|
||||
$new_bundle = 'test_bundle_' . Unicode::strtolower($this->randomMachineName());
|
||||
entity_test_create_bundle($new_bundle, NULL, $entity_type);
|
||||
|
||||
// Add a field to that bundle.
|
||||
$this->fieldTestData->field_definition['bundle'] = $new_bundle;
|
||||
FieldConfig::create($this->fieldTestData->field_definition)->save();
|
||||
|
||||
// Create a second field for the test bundle
|
||||
$field_name = Unicode::strtolower($this->randomMachineName() . '_field_name');
|
||||
$field_storage = array(
|
||||
'field_name' => $field_name,
|
||||
'entity_type' => $entity_type,
|
||||
'type' => 'test_field',
|
||||
'cardinality' => 1,
|
||||
);
|
||||
FieldStorageConfig::create($field_storage)->save();
|
||||
$field = array(
|
||||
'field_name' => $field_name,
|
||||
'entity_type' => $entity_type,
|
||||
'bundle' => $this->fieldTestData->field->getTargetBundle(),
|
||||
'label' => $this->randomMachineName() . '_label',
|
||||
'description' => $this->randomMachineName() . '_description',
|
||||
'weight' => mt_rand(0, 127),
|
||||
);
|
||||
FieldConfig::create($field)->save();
|
||||
|
||||
// Save an entity with data for both fields
|
||||
$entity = $this->container->get('entity_type.manager')
|
||||
->getStorage($entity_type)
|
||||
->create(array('type' => $this->fieldTestData->field->getTargetBundle()));
|
||||
$values = $this->_generateTestFieldValues($this->fieldTestData->field_storage->getCardinality());
|
||||
$entity->{$this->fieldTestData->field_name} = $values;
|
||||
$entity->{$field_name} = $this->_generateTestFieldValues(1);
|
||||
$entity = $this->entitySaveReload($entity);
|
||||
|
||||
// Verify the fields are present on load
|
||||
$this->assertEqual(count($entity->{$this->fieldTestData->field_name}), 4, 'First field got loaded');
|
||||
$this->assertEqual(count($entity->{$field_name}), 1, 'Second field got loaded');
|
||||
|
||||
// Delete the bundle.
|
||||
entity_test_delete_bundle($this->fieldTestData->field->getTargetBundle(), $entity_type);
|
||||
|
||||
// Verify no data gets loaded
|
||||
$controller = $this->container->get('entity.manager')->getStorage($entity->getEntityTypeId());
|
||||
$controller->resetCache();
|
||||
$entity = $controller->load($entity->id());
|
||||
|
||||
$this->assertTrue(empty($entity->{$this->fieldTestData->field_name}), 'No data for first field');
|
||||
$this->assertTrue(empty($entity->{$field_name}), 'No data for second field');
|
||||
|
||||
// Verify that the fields are gone.
|
||||
$this->assertFalse(FieldConfig::load('entity_test.' . $this->fieldTestData->field->getTargetBundle() . '.' . $this->fieldTestData->field_name), "First field is deleted");
|
||||
$this->assertFalse(FieldConfig::load('entity_test.' . $field['bundle'] . '.' . $field_name), "Second field is deleted");
|
||||
}
|
||||
|
||||
}
|
303
web/core/modules/field/tests/src/Kernel/FieldCrudTest.php
Normal file
303
web/core/modules/field/tests/src/Kernel/FieldCrudTest.php
Normal file
|
@ -0,0 +1,303 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\field\Kernel;
|
||||
|
||||
use Drupal\Component\Utility\Unicode;
|
||||
use Drupal\Core\Entity\EntityStorageException;
|
||||
use Drupal\Core\Field\FieldException;
|
||||
use Drupal\entity_test\Entity\EntityTest;
|
||||
use Drupal\field\Entity\FieldStorageConfig;
|
||||
use Drupal\field\Entity\FieldConfig;
|
||||
|
||||
/**
|
||||
* Create field entities by attaching fields to entities.
|
||||
*
|
||||
* @group field
|
||||
*/
|
||||
class FieldCrudTest extends FieldKernelTestBase {
|
||||
|
||||
/**
|
||||
* The field storage entity.
|
||||
*
|
||||
* @var \Drupal\field\Entity\FieldStorageConfig
|
||||
*/
|
||||
protected $fieldStorage;
|
||||
|
||||
/**
|
||||
* The field entity definition.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $fieldStorageDefinition;
|
||||
|
||||
/**
|
||||
* The field entity definition.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $fieldDefinition;
|
||||
|
||||
function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$this->fieldStorageDefinition = array(
|
||||
'field_name' => Unicode::strtolower($this->randomMachineName()),
|
||||
'entity_type' => 'entity_test',
|
||||
'type' => 'test_field',
|
||||
);
|
||||
$this->fieldStorage = FieldStorageConfig::create($this->fieldStorageDefinition);
|
||||
$this->fieldStorage->save();
|
||||
$this->fieldDefinition = array(
|
||||
'field_name' => $this->fieldStorage->getName(),
|
||||
'entity_type' => 'entity_test',
|
||||
'bundle' => 'entity_test',
|
||||
);
|
||||
}
|
||||
|
||||
// TODO : test creation with
|
||||
// - a full fledged $field structure, check that all the values are there
|
||||
// - a minimal $field structure, check all default values are set
|
||||
// defer actual $field comparison to a helper function, used for the two cases above,
|
||||
// and for testUpdateField
|
||||
|
||||
/**
|
||||
* Test the creation of a field.
|
||||
*/
|
||||
function testCreateField() {
|
||||
// Set a state flag so that field_test.module knows to add an in-memory
|
||||
// constraint for this field.
|
||||
\Drupal::state()->set('field_test_add_constraint', $this->fieldStorage->getName());
|
||||
/** @var \Drupal\Core\Field\FieldConfigInterface $field */
|
||||
$field = FieldConfig::create($this->fieldDefinition);
|
||||
$field->save();
|
||||
|
||||
$field = FieldConfig::load($field->id());
|
||||
$this->assertTrue($field->getSetting('field_setting_from_config_data'));
|
||||
$this->assertNull($field->getSetting('config_data_from_field_setting'));
|
||||
|
||||
// Read the configuration. Check against raw configuration data rather than
|
||||
// the loaded ConfigEntity, to be sure we check that the defaults are
|
||||
// applied on write.
|
||||
$config = $this->config('field.field.' . $field->id())->get();
|
||||
$field_type_manager = \Drupal::service('plugin.manager.field.field_type');
|
||||
|
||||
$this->assertTrue($config['settings']['config_data_from_field_setting']);
|
||||
$this->assertTrue(!isset($config['settings']['field_setting_from_config_data']));
|
||||
|
||||
// Since we are working with raw configuration, this needs to be unset
|
||||
// manually.
|
||||
// @see Drupal\field_test\Plugin\Field\FieldType\TestItem::fieldSettingsFromConfigData()
|
||||
unset($config['settings']['config_data_from_field_setting']);
|
||||
|
||||
// Check that default values are set.
|
||||
$this->assertEqual($config['required'], FALSE, 'Required defaults to false.');
|
||||
$this->assertIdentical($config['label'], $this->fieldDefinition['field_name'], 'Label defaults to field name.');
|
||||
$this->assertIdentical($config['description'], '', 'Description defaults to empty string.');
|
||||
|
||||
// Check that default settings are set.
|
||||
$this->assertEqual($config['settings'], $field_type_manager->getDefaultFieldSettings($this->fieldStorageDefinition['type']), 'Default field settings have been written.');
|
||||
|
||||
// Check that the denormalized 'field_type' was properly written.
|
||||
$this->assertEqual($config['field_type'], $this->fieldStorageDefinition['type']);
|
||||
|
||||
// Test constraints are applied. A Range constraint is added dynamically to
|
||||
// limit the field to values between 0 and 32.
|
||||
// @see field_test_entity_bundle_field_info_alter()
|
||||
$this->doFieldValidationTests();
|
||||
|
||||
// Test FieldConfigBase::setPropertyConstraints().
|
||||
\Drupal::state()->set('field_test_set_constraint', $this->fieldStorage->getName());
|
||||
\Drupal::state()->set('field_test_add_constraint', FALSE);
|
||||
\Drupal::entityManager()->clearCachedFieldDefinitions();
|
||||
$this->doFieldValidationTests();
|
||||
|
||||
// Guarantee that the field/bundle combination is unique.
|
||||
try {
|
||||
FieldConfig::create($this->fieldDefinition)->save();
|
||||
$this->fail(t('Cannot create two fields with the same field / bundle combination.'));
|
||||
}
|
||||
catch (EntityStorageException $e) {
|
||||
$this->pass(t('Cannot create two fields with the same field / bundle combination.'));
|
||||
}
|
||||
|
||||
// Check that the specified field exists.
|
||||
try {
|
||||
$this->fieldDefinition['field_name'] = $this->randomMachineName();
|
||||
FieldConfig::create($this->fieldDefinition)->save();
|
||||
$this->fail(t('Cannot create a field with a non-existing storage.'));
|
||||
}
|
||||
catch (FieldException $e) {
|
||||
$this->pass(t('Cannot create a field with a non-existing storage.'));
|
||||
}
|
||||
|
||||
// TODO: test other failures.
|
||||
}
|
||||
|
||||
/**
|
||||
* Test creating a field with custom storage set.
|
||||
*/
|
||||
public function testCreateFieldCustomStorage() {
|
||||
$field_name = Unicode::strtolower($this->randomMachineName());
|
||||
\Drupal::state()->set('field_test_custom_storage', $field_name);
|
||||
|
||||
$field_storage = FieldStorageConfig::create([
|
||||
'field_name' => $field_name,
|
||||
'entity_type' => 'entity_test',
|
||||
'type' => 'test_field',
|
||||
'custom_storage' => TRUE,
|
||||
]);
|
||||
$field_storage->save();
|
||||
|
||||
$field = FieldConfig::create([
|
||||
'field_name' => $field_storage->getName(),
|
||||
'entity_type' => 'entity_test',
|
||||
'bundle' => 'entity_test',
|
||||
]);
|
||||
$field->save();
|
||||
|
||||
\Drupal::entityManager()->clearCachedFieldDefinitions();
|
||||
|
||||
// Check that no table has been created for the field.
|
||||
$this->assertFalse(\Drupal::database()->schema()->tableExists('entity_test__' . $field_storage->getName()));
|
||||
|
||||
// Save an entity with a value in the custom storage field and verify no
|
||||
// data is retrieved on load.
|
||||
$entity = EntityTest::create(['name' => $this->randomString(), $field_name => 'Test value']);
|
||||
$this->assertIdentical('Test value', $entity->{$field_name}->value, 'The test value is set on the field.');
|
||||
|
||||
$entity->save();
|
||||
$entity = EntityTest::load($entity->id());
|
||||
|
||||
$this->assertNull($entity->{$field_name}->value, 'The loaded entity field value is NULL.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test reading back a field definition.
|
||||
*/
|
||||
function testReadField() {
|
||||
FieldConfig::create($this->fieldDefinition)->save();
|
||||
|
||||
// Read the field back.
|
||||
$field = FieldConfig::load('entity_test.' . $this->fieldDefinition['bundle'] . '.' . $this->fieldDefinition['field_name']);
|
||||
$this->assertTrue($this->fieldDefinition['field_name'] == $field->getName(), 'The field was properly read.');
|
||||
$this->assertTrue($this->fieldDefinition['entity_type'] == $field->getTargetEntityTypeId(), 'The field was properly read.');
|
||||
$this->assertTrue($this->fieldDefinition['bundle'] == $field->getTargetBundle(), 'The field was properly read.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the update of a field.
|
||||
*/
|
||||
function testUpdateField() {
|
||||
FieldConfig::create($this->fieldDefinition)->save();
|
||||
|
||||
// Check that basic changes are saved.
|
||||
$field = FieldConfig::load('entity_test.' . $this->fieldDefinition['bundle'] . '.' . $this->fieldDefinition['field_name']);
|
||||
$field->setRequired(!$field->isRequired());
|
||||
$field->setLabel($this->randomMachineName());
|
||||
$field->set('description', $this->randomMachineName());
|
||||
$field->setSetting('test_field_setting', $this->randomMachineName());
|
||||
$field->save();
|
||||
|
||||
$field_new = FieldConfig::load('entity_test.' . $this->fieldDefinition['bundle'] . '.' . $this->fieldDefinition['field_name']);
|
||||
$this->assertEqual($field->isRequired(), $field_new->isRequired(), '"required" change is saved');
|
||||
$this->assertEqual($field->getLabel(), $field_new->getLabel(), '"label" change is saved');
|
||||
$this->assertEqual($field->getDescription(), $field_new->getDescription(), '"description" change is saved');
|
||||
|
||||
// TODO: test failures.
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the deletion of a field.
|
||||
*/
|
||||
function testDeleteField() {
|
||||
// TODO: Test deletion of the data stored in the field also.
|
||||
// Need to check that data for a 'deleted' field / storage doesn't get loaded
|
||||
// Need to check data marked deleted is cleaned on cron (not implemented yet...)
|
||||
|
||||
// Create two fields for the same field storage so we can test that only one
|
||||
// is deleted.
|
||||
FieldConfig::create($this->fieldDefinition)->save();
|
||||
$another_field_definition = $this->fieldDefinition;
|
||||
$another_field_definition['bundle'] .= '_another_bundle';
|
||||
entity_test_create_bundle($another_field_definition['bundle']);
|
||||
FieldConfig::create($another_field_definition)->save();
|
||||
|
||||
// Test that the first field is not deleted, and then delete it.
|
||||
$field = current(entity_load_multiple_by_properties('field_config', array('entity_type' => 'entity_test', 'field_name' => $this->fieldDefinition['field_name'], 'bundle' => $this->fieldDefinition['bundle'], 'include_deleted' => TRUE)));
|
||||
$this->assertTrue(!empty($field) && empty($field->deleted), 'A new field is not marked for deletion.');
|
||||
$field->delete();
|
||||
|
||||
// Make sure the field is marked as deleted when it is specifically loaded.
|
||||
$field = current(entity_load_multiple_by_properties('field_config', array('entity_type' => 'entity_test', 'field_name' => $this->fieldDefinition['field_name'], 'bundle' => $this->fieldDefinition['bundle'], 'include_deleted' => TRUE)));
|
||||
$this->assertTrue($field->isDeleted(), 'A deleted field is marked for deletion.');
|
||||
|
||||
// Try to load the field normally and make sure it does not show up.
|
||||
$field = FieldConfig::load('entity_test.' . '.' . $this->fieldDefinition['bundle'] . '.' . $this->fieldDefinition['field_name']);
|
||||
$this->assertTrue(empty($field), 'A deleted field is not loaded by default.');
|
||||
|
||||
// Make sure the other field is not deleted.
|
||||
$another_field = FieldConfig::load('entity_test.' . $another_field_definition['bundle'] . '.' . $another_field_definition['field_name']);
|
||||
$this->assertTrue(!empty($another_field) && empty($another_field->deleted), 'A non-deleted field is not marked for deletion.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the cross deletion behavior between field storages and fields.
|
||||
*/
|
||||
function testDeleteFieldCrossDeletion() {
|
||||
$field_definition_2 = $this->fieldDefinition;
|
||||
$field_definition_2['bundle'] .= '_another_bundle';
|
||||
entity_test_create_bundle($field_definition_2['bundle']);
|
||||
|
||||
// Check that deletion of a field storage deletes its fields.
|
||||
$field_storage = $this->fieldStorage;
|
||||
FieldConfig::create($this->fieldDefinition)->save();
|
||||
FieldConfig::create($field_definition_2)->save();
|
||||
$field_storage->delete();
|
||||
$this->assertFalse(FieldConfig::loadByName('entity_test', $this->fieldDefinition['bundle'], $field_storage->getName()));
|
||||
$this->assertFalse(FieldConfig::loadByName('entity_test', $field_definition_2['bundle'], $field_storage->getName()));
|
||||
|
||||
// Check that deletion of the last field deletes the storage.
|
||||
$field_storage = FieldStorageConfig::create($this->fieldStorageDefinition);
|
||||
$field_storage->save();
|
||||
$field = FieldConfig::create($this->fieldDefinition);
|
||||
$field->save();
|
||||
$field_2 = FieldConfig::create($field_definition_2);
|
||||
$field_2->save();
|
||||
$field->delete();
|
||||
$this->assertTrue(FieldStorageConfig::loadByName('entity_test', $field_storage->getName()));
|
||||
$field_2->delete();
|
||||
$this->assertFalse(FieldStorageConfig::loadByName('entity_test', $field_storage->getName()));
|
||||
|
||||
// Check that deletion of all fields using a storage simultaneously deletes
|
||||
// the storage.
|
||||
$field_storage = FieldStorageConfig::create($this->fieldStorageDefinition);
|
||||
$field_storage->save();
|
||||
$field = FieldConfig::create($this->fieldDefinition);
|
||||
$field->save();
|
||||
$field_2 = FieldConfig::create($field_definition_2);
|
||||
$field_2->save();
|
||||
$this->container->get('entity.manager')->getStorage('field_config')->delete(array($field, $field_2));
|
||||
$this->assertFalse(FieldStorageConfig::loadByName('entity_test', $field_storage->getName()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests configurable field validation.
|
||||
*
|
||||
* @see field_test_entity_bundle_field_info_alter()
|
||||
*/
|
||||
protected function doFieldValidationTests() {
|
||||
$entity = EntityTest::create();
|
||||
$entity->set($this->fieldStorage->getName(), 1);
|
||||
$violations = $entity->validate();
|
||||
$this->assertEqual(count($violations), 0, 'No violations found when in-range value passed.');
|
||||
|
||||
$entity->set($this->fieldStorage->getName(), 33);
|
||||
$violations = $entity->validate();
|
||||
$this->assertEqual(count($violations), 1, 'Violations found when using value outside the range.');
|
||||
$this->assertEqual($violations[0]->getPropertyPath(), $this->fieldStorage->getName() . '.0.value');
|
||||
$this->assertEqual($violations[0]->getMessage(), t('This value should be %limit or less.', [
|
||||
'%limit' => 32,
|
||||
]));
|
||||
}
|
||||
|
||||
}
|
181
web/core/modules/field/tests/src/Kernel/FieldDataCountTest.php
Normal file
181
web/core/modules/field/tests/src/Kernel/FieldDataCountTest.php
Normal file
|
@ -0,0 +1,181 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\field\Kernel;
|
||||
|
||||
use Drupal\Core\Entity\Sql\SqlContentEntityStorage;
|
||||
use Drupal\entity_test\Entity\EntityTest;
|
||||
use Drupal\field\Entity\FieldConfig;
|
||||
use Drupal\field\Entity\FieldStorageConfig;
|
||||
|
||||
/**
|
||||
* Tests counting field data records and the hasData() method on
|
||||
* FieldStorageConfig entity.
|
||||
*
|
||||
* @group field
|
||||
* @see \Drupal\Core\Entity\FieldableEntityStorageInterface::countFieldData()
|
||||
* @see \Drupal\field\Entity\FieldStorageConfig::hasData()
|
||||
*/
|
||||
class FieldDataCountTest extends FieldKernelTestBase {
|
||||
|
||||
/**
|
||||
* @var \Drupal\Core\Entity\DynamicallyFieldableEntityStorageInterface
|
||||
*/
|
||||
protected $storage;
|
||||
|
||||
/**
|
||||
* @var \Drupal\Core\Entity\DynamicallyFieldableEntityStorageInterface
|
||||
*/
|
||||
protected $storageRev;
|
||||
|
||||
/**
|
||||
* @var \Drupal\Core\Entity\DynamicallyFieldableEntityStorageInterface
|
||||
*/
|
||||
protected $storageUser;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$this->installEntitySchema('entity_test_rev');
|
||||
$this->storage = \Drupal::entityManager()->getStorage('entity_test');
|
||||
$this->storageRev = \Drupal::entityManager()->getStorage('entity_test_rev');
|
||||
$this->storageUser = \Drupal::entityManager()->getStorage('user');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests entityCount() and hadData() methods.
|
||||
*/
|
||||
public function testEntityCountAndHasData() {
|
||||
// Create a field with a cardinality of 2 to show that we are counting
|
||||
// entities and not rows in a table.
|
||||
/** @var \Drupal\field\Entity\FieldStorageConfig $field_storage */
|
||||
$field_storage = FieldStorageConfig::create(array(
|
||||
'field_name' => 'field_int',
|
||||
'entity_type' => 'entity_test',
|
||||
'type' => 'integer',
|
||||
'cardinality' => 2,
|
||||
));
|
||||
$field_storage->save();
|
||||
FieldConfig::create([
|
||||
'field_storage' => $field_storage,
|
||||
'bundle' => 'entity_test',
|
||||
])->save();
|
||||
|
||||
$this->assertIdentical($field_storage->hasdata(), FALSE, 'There are no entities with field data.');
|
||||
$this->assertIdentical($this->storage->countFieldData($field_storage), 0, 'There are 0 entities with field data.');
|
||||
|
||||
// Create 1 entity without the field.
|
||||
$entity = EntityTest::create();
|
||||
$entity->name->value = $this->randomMachineName();
|
||||
$entity->save();
|
||||
|
||||
$this->assertIdentical($field_storage->hasdata(), FALSE, 'There are no entities with field data.');
|
||||
$this->assertIdentical($this->storage->countFieldData($field_storage), 0, 'There are 0 entities with field data.');
|
||||
|
||||
// Create 12 entities to ensure that the purging works as expected.
|
||||
for ($i = 0; $i < 12; $i++) {
|
||||
$entity = EntityTest::create();
|
||||
$entity->field_int[] = mt_rand(1, 99);
|
||||
$entity->field_int[] = mt_rand(1, 99);
|
||||
$entity->name[] = $this->randomMachineName();
|
||||
$entity->save();
|
||||
}
|
||||
|
||||
$storage = \Drupal::entityManager()->getStorage('entity_test');
|
||||
if ($storage instanceof SqlContentEntityStorage) {
|
||||
// Count the actual number of rows in the field table.
|
||||
$table_mapping = $storage->getTableMapping();
|
||||
$field_table_name = $table_mapping->getDedicatedDataTableName($field_storage);
|
||||
$result = db_select($field_table_name, 't')
|
||||
->fields('t')
|
||||
->countQuery()
|
||||
->execute()
|
||||
->fetchField();
|
||||
$this->assertEqual($result, 24, 'The field table has 24 rows.');
|
||||
}
|
||||
|
||||
$this->assertIdentical($field_storage->hasdata(), TRUE, 'There are entities with field data.');
|
||||
$this->assertEqual($this->storage->countFieldData($field_storage), 12, 'There are 12 entities with field data.');
|
||||
|
||||
// Ensure the methods work on deleted fields.
|
||||
$field_storage->delete();
|
||||
$this->assertIdentical($field_storage->hasdata(), TRUE, 'There are entities with deleted field data.');
|
||||
$this->assertEqual($this->storage->countFieldData($field_storage), 12, 'There are 12 entities with deleted field data.');
|
||||
|
||||
field_purge_batch(6);
|
||||
$this->assertIdentical($field_storage->hasdata(), TRUE, 'There are entities with deleted field data.');
|
||||
$this->assertEqual($this->storage->countFieldData($field_storage), 6, 'There are 6 entities with deleted field data.');
|
||||
|
||||
$entity_type = 'entity_test_rev';
|
||||
$this->createFieldWithStorage('_2', $entity_type);
|
||||
|
||||
$entity_init = $this->container->get('entity_type.manager')
|
||||
->getStorage($entity_type)
|
||||
->create(array('type' => $entity_type,));
|
||||
$cardinality = $this->fieldTestData->field_storage_2->getCardinality();
|
||||
|
||||
$this->assertIdentical($this->fieldTestData->field_storage_2->hasData(), FALSE, 'There are no entities with field data.');
|
||||
$this->assertIdentical($this->storageRev->countFieldData($this->fieldTestData->field_storage_2), 0, 'There are 0 entities with field data.');
|
||||
|
||||
// Create 1 entity with the field.
|
||||
$entity = clone($entity_init);
|
||||
$values = $this->_generateTestFieldValues($this->fieldTestData->field_storage_2->getCardinality());
|
||||
$entity->{$this->fieldTestData->field_name_2} = $values;
|
||||
$entity->setNewRevision();
|
||||
$entity->save();
|
||||
$first_revision = $entity->getRevisionId();
|
||||
|
||||
$this->assertIdentical($this->fieldTestData->field_storage_2->hasData(), TRUE, 'There are entities with field data.');
|
||||
$this->assertIdentical($this->storageRev->countFieldData($this->fieldTestData->field_storage_2), 1, 'There is 1 entity with field data.');
|
||||
|
||||
$entity->{$this->fieldTestData->field_name_2} = array();
|
||||
$entity->setNewRevision();
|
||||
$entity->save();
|
||||
|
||||
$this->assertIdentical($this->fieldTestData->field_storage_2->hasData(), TRUE, 'There are entities with field data.');
|
||||
|
||||
$storage = $this->container->get('entity.manager')->getStorage($entity_type);
|
||||
$entity = $storage->loadRevision($first_revision);
|
||||
$this->assertEqual(count($entity->{$this->fieldTestData->field_name_2}), $cardinality, format_string('Revision %revision_id: expected number of values.', array('%revision_id' => $first_revision)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify that we can count a table that contains an entry with index 0.
|
||||
*/
|
||||
public function testCountWithIndex0() {
|
||||
// Create a field that will require dedicated storage.
|
||||
/** @var \Drupal\field\Entity\FieldStorageConfig $field_storage */
|
||||
$field_storage = FieldStorageConfig::create(array(
|
||||
'field_name' => 'field_int',
|
||||
'entity_type' => 'user',
|
||||
'type' => 'integer',
|
||||
'cardinality' => 2,
|
||||
));
|
||||
$field_storage->save();
|
||||
FieldConfig::create(array(
|
||||
'field_storage' => $field_storage,
|
||||
'bundle' => 'user',
|
||||
))->save();
|
||||
|
||||
// Create an entry for the anonymous user, who has user ID 0.
|
||||
$user = $this->storageUser
|
||||
->create(array(
|
||||
'uid' => 0,
|
||||
'name' => 'anonymous',
|
||||
'mail' => NULL,
|
||||
'status' => FALSE,
|
||||
'field_int' => 42,
|
||||
));
|
||||
$user->save();
|
||||
|
||||
// Test shared table storage.
|
||||
$storage = $user->getFieldDefinition('name')->getFieldStorageDefinition();
|
||||
$this->assertIdentical(TRUE, $this->storageUser->countFieldData($storage, TRUE));
|
||||
|
||||
// Test dedicated table storage.
|
||||
$storage = $user->getFieldDefinition('field_int')->getFieldStorageDefinition();
|
||||
$this->assertIdentical(TRUE, $this->storageUser->countFieldData($storage, TRUE));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,114 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\field\Kernel;
|
||||
|
||||
use Drupal\Core\Extension\Extension;
|
||||
use Drupal\KernelTests\KernelTestBase;
|
||||
|
||||
/**
|
||||
* Tests the integrity of field API plugin definitions.
|
||||
*
|
||||
* @group field
|
||||
*/
|
||||
class FieldDefinitionIntegrityTest extends KernelTestBase {
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['system'];
|
||||
|
||||
/**
|
||||
* Tests the integrity of field plugin definitions.
|
||||
*/
|
||||
public function testFieldPluginDefinitionIntegrity() {
|
||||
|
||||
// Enable all core modules that provide field plugins.
|
||||
$modules = system_rebuild_module_data();
|
||||
$modules = array_filter($modules, function (Extension $module) {
|
||||
// Filter contrib, hidden, already enabled modules and modules in the
|
||||
// Testing package.
|
||||
if ($module->origin === 'core'
|
||||
&& empty($module->info['hidden'])
|
||||
&& $module->status == FALSE
|
||||
&& $module->info['package'] !== 'Testing'
|
||||
&& is_readable($module->getPath() . '/src/Plugin/Field')) {
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
});
|
||||
$this->enableModules(array_keys($modules));
|
||||
|
||||
/** @var \Drupal\Component\Plugin\Discovery\DiscoveryInterface $field_type_manager */
|
||||
$field_type_manager = \Drupal::service('plugin.manager.field.field_type');
|
||||
|
||||
/** @var \Drupal\Component\Plugin\Discovery\DiscoveryInterface $field_type_manager */
|
||||
$field_formatter_manager = \Drupal::service('plugin.manager.field.formatter');
|
||||
|
||||
/** @var \Drupal\Component\Plugin\Discovery\DiscoveryInterface $field_type_manager */
|
||||
$field_widget_manager = \Drupal::service('plugin.manager.field.widget');
|
||||
|
||||
// Load the IDs of all available field type plugins.
|
||||
$available_field_type_ids = [];
|
||||
foreach ($field_type_manager->getDefinitions() as $definition) {
|
||||
$available_field_type_ids[] = $definition['id'];
|
||||
}
|
||||
|
||||
// Load the IDs of all available field widget plugins.
|
||||
$available_field_widget_ids = [];
|
||||
foreach ($field_widget_manager->getDefinitions() as $definition) {
|
||||
$available_field_widget_ids[] = $definition['id'];
|
||||
}
|
||||
|
||||
// Load the IDs of all available field formatter plugins.
|
||||
$available_field_formatter_ids = [];
|
||||
foreach ($field_formatter_manager->getDefinitions() as $definition) {
|
||||
$available_field_formatter_ids[] = $definition['id'];
|
||||
}
|
||||
|
||||
// Test the field type plugins.
|
||||
foreach ($field_type_manager->getDefinitions() as $definition) {
|
||||
// Test default field widgets.
|
||||
if (isset($definition['default_widget'])) {
|
||||
if (in_array($definition['default_widget'], $available_field_widget_ids)) {
|
||||
$this->pass(sprintf('Field type %s uses an existing field widget by default.', $definition['id']));
|
||||
}
|
||||
else {
|
||||
$this->fail(sprintf('Field type %s uses a non-existent field widget by default: %s', $definition['id'], $definition['default_widget']));
|
||||
}
|
||||
}
|
||||
|
||||
// Test default field formatters.
|
||||
if (isset($definition['default_formatter'])) {
|
||||
if (in_array($definition['default_formatter'], $available_field_formatter_ids)) {
|
||||
$this->pass(sprintf('Field type %s uses an existing field formatter by default.', $definition['id']));
|
||||
}
|
||||
else {
|
||||
$this->fail(sprintf('Field type %s uses a non-existent field formatter by default: %s', $definition['id'], $definition['default_formatter']));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Test the field widget plugins.
|
||||
foreach ($field_widget_manager->getDefinitions() as $definition) {
|
||||
$missing_field_type_ids = array_diff($definition['field_types'], $available_field_type_ids);
|
||||
if ($missing_field_type_ids) {
|
||||
$this->fail(sprintf('Field widget %s integrates with non-existent field types: %s', $definition['id'], implode(', ', $missing_field_type_ids)));
|
||||
}
|
||||
else {
|
||||
$this->pass(sprintf('Field widget %s integrates with existing field types.', $definition['id']));
|
||||
}
|
||||
}
|
||||
|
||||
// Test the field formatter plugins.
|
||||
foreach ($field_formatter_manager->getDefinitions() as $definition) {
|
||||
$missing_field_type_ids = array_diff($definition['field_types'], $available_field_type_ids);
|
||||
if ($missing_field_type_ids) {
|
||||
$this->fail(sprintf('Field formatter %s integrates with non-existent field types: %s', $definition['id'], implode(', ', $missing_field_type_ids)));
|
||||
}
|
||||
else {
|
||||
$this->pass(sprintf('Field formatter %s integrates with existing field types.', $definition['id']));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\field\Kernel;
|
||||
|
||||
use Drupal\field\Entity\FieldConfig;
|
||||
|
||||
/**
|
||||
* Update field storage and fields during config change method invocation.
|
||||
*
|
||||
* @group field
|
||||
*/
|
||||
class FieldImportChangeTest extends FieldKernelTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* The default configuration provided by field_test_config is imported by
|
||||
* \Drupal\Tests\field\Kernel\FieldKernelTestBase::setUp() when it installs
|
||||
* field configuration.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = array('field_test_config');
|
||||
|
||||
/**
|
||||
* Tests importing an updated field.
|
||||
*/
|
||||
function testImportChange() {
|
||||
$this->installConfig(['field_test_config']);
|
||||
$field_storage_id = 'field_test_import';
|
||||
$field_id = "entity_test.entity_test.$field_storage_id";
|
||||
$field_config_name = "field.field.$field_id";
|
||||
|
||||
$active = $this->container->get('config.storage');
|
||||
$sync = $this->container->get('config.storage.sync');
|
||||
$this->copyConfig($active, $sync);
|
||||
|
||||
// Save as files in the sync directory.
|
||||
$field = $active->read($field_config_name);
|
||||
$new_label = 'Test update import field';
|
||||
$field['label'] = $new_label;
|
||||
$sync->write($field_config_name, $field);
|
||||
|
||||
// Import the content of the sync directory.
|
||||
$this->configImporter()->import();
|
||||
|
||||
// Check that the updated config was correctly imported.
|
||||
$field = FieldConfig::load($field_id);
|
||||
$this->assertEqual($field->getLabel(), $new_label, 'field label updated');
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,119 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\field\Kernel;
|
||||
|
||||
use Drupal\field\Entity\FieldConfig;
|
||||
|
||||
use Drupal\field\Entity\FieldStorageConfig;
|
||||
|
||||
/**
|
||||
* Create field storages and fields during config create method invocation.
|
||||
*
|
||||
* @group field
|
||||
*/
|
||||
class FieldImportCreateTest extends FieldKernelTestBase {
|
||||
|
||||
/**
|
||||
* Tests creating field storages and fields during default config import.
|
||||
*/
|
||||
function testImportCreateDefault() {
|
||||
$field_name = 'field_test_import';
|
||||
$field_storage_id = "entity_test.$field_name";
|
||||
$field_id = "entity_test.entity_test.$field_name";
|
||||
$field_name_2 = 'field_test_import_2';
|
||||
$field_storage_id_2 = "entity_test.$field_name_2";
|
||||
$field_id_2a = "entity_test.entity_test.$field_name_2";
|
||||
$field_id_2b = "entity_test.test_bundle.$field_name_2";
|
||||
|
||||
// Check that the field storages and fields do not exist yet.
|
||||
$this->assertFalse(FieldStorageConfig::load($field_storage_id));
|
||||
$this->assertFalse(FieldConfig::load($field_id));
|
||||
$this->assertFalse(FieldStorageConfig::load($field_storage_id_2));
|
||||
$this->assertFalse(FieldConfig::load($field_id_2a));
|
||||
$this->assertFalse(FieldConfig::load($field_id_2b));
|
||||
|
||||
// Create a second bundle for the 'Entity test' entity type.
|
||||
entity_test_create_bundle('test_bundle');
|
||||
|
||||
// Enable field_test_config module and check that the field and storage
|
||||
// shipped in the module's default config were created.
|
||||
\Drupal::service('module_installer')->install(array('field_test_config'));
|
||||
|
||||
// A field storage with one single field.
|
||||
$field_storage = FieldStorageConfig::load($field_storage_id);
|
||||
$this->assertTrue($field_storage, 'The field was created.');
|
||||
$field = FieldConfig::load($field_id);
|
||||
$this->assertTrue($field, 'The field was deleted.');
|
||||
|
||||
// A field storage with two fields.
|
||||
$field_storage_2 = FieldStorageConfig::load($field_storage_id_2);
|
||||
$this->assertTrue($field_storage_2, 'The second field was created.');
|
||||
$this->assertTrue($field->getTargetBundle(), 'test_bundle', 'The second field was created on bundle test_bundle.');
|
||||
$this->assertTrue($field->getTargetBundle(), 'test_bundle_2', 'The second field was created on bundle test_bundle_2.');
|
||||
|
||||
// Tests fields.
|
||||
$ids = \Drupal::entityQuery('field_config')
|
||||
->condition('entity_type', 'entity_test')
|
||||
->condition('bundle', 'entity_test')
|
||||
->execute();
|
||||
$this->assertEqual(count($ids), 2);
|
||||
$this->assertTrue(isset($ids['entity_test.entity_test.field_test_import']));
|
||||
$this->assertTrue(isset($ids['entity_test.entity_test.field_test_import_2']));
|
||||
$ids = \Drupal::entityQuery('field_config')
|
||||
->condition('entity_type', 'entity_test')
|
||||
->condition('bundle', 'test_bundle')
|
||||
->execute();
|
||||
$this->assertEqual(count($ids), 1);
|
||||
$this->assertTrue(isset($ids['entity_test.test_bundle.field_test_import_2']));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests creating field storages and fields during config import.
|
||||
*/
|
||||
function testImportCreate() {
|
||||
// A field storage with one single field.
|
||||
$field_name = 'field_test_import_sync';
|
||||
$field_storage_id = "entity_test.$field_name";
|
||||
$field_id = "entity_test.entity_test.$field_name";
|
||||
$field_storage_config_name = "field.storage.$field_storage_id";
|
||||
$field_config_name = "field.field.$field_id";
|
||||
|
||||
// A field storage with two fields.
|
||||
$field_name_2 = 'field_test_import_sync_2';
|
||||
$field_storage_id_2 = "entity_test.$field_name_2";
|
||||
$field_id_2a = "entity_test.test_bundle.$field_name_2";
|
||||
$field_id_2b = "entity_test.test_bundle_2.$field_name_2";
|
||||
$field_storage_config_name_2 = "field.storage.$field_storage_id_2";
|
||||
$field_config_name_2a = "field.field.$field_id_2a";
|
||||
$field_config_name_2b = "field.field.$field_id_2b";
|
||||
|
||||
$active = $this->container->get('config.storage');
|
||||
$sync = $this->container->get('config.storage.sync');
|
||||
$this->copyConfig($active, $sync);
|
||||
|
||||
// Add the new files to the sync directory.
|
||||
$src_dir = __DIR__ . '/../../modules/field_test_config/sync';
|
||||
$target_dir = config_get_config_directory(CONFIG_SYNC_DIRECTORY);
|
||||
$this->assertTrue(file_unmanaged_copy("$src_dir/$field_storage_config_name.yml", "$target_dir/$field_storage_config_name.yml"));
|
||||
$this->assertTrue(file_unmanaged_copy("$src_dir/$field_config_name.yml", "$target_dir/$field_config_name.yml"));
|
||||
$this->assertTrue(file_unmanaged_copy("$src_dir/$field_storage_config_name_2.yml", "$target_dir/$field_storage_config_name_2.yml"));
|
||||
$this->assertTrue(file_unmanaged_copy("$src_dir/$field_config_name_2a.yml", "$target_dir/$field_config_name_2a.yml"));
|
||||
$this->assertTrue(file_unmanaged_copy("$src_dir/$field_config_name_2b.yml", "$target_dir/$field_config_name_2b.yml"));
|
||||
|
||||
// Import the content of the sync directory.
|
||||
$this->configImporter()->import();
|
||||
|
||||
// Check that the field and storage were created.
|
||||
$field_storage = FieldStorageConfig::load($field_storage_id);
|
||||
$this->assertTrue($field_storage, 'Test import storage field from sync exists');
|
||||
$field = FieldConfig::load($field_id);
|
||||
$this->assertTrue($field, 'Test import field from sync exists');
|
||||
$field_storage = FieldStorageConfig::load($field_storage_id_2);
|
||||
$this->assertTrue($field_storage, 'Test import storage field 2 from sync exists');
|
||||
$field = FieldConfig::load($field_id_2a);
|
||||
$this->assertTrue($field, 'Test import field 2a from sync exists');
|
||||
$field = FieldConfig::load($field_id_2b);
|
||||
$this->assertTrue($field, 'Test import field 2b from sync exists');
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,112 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\field\Kernel;
|
||||
|
||||
use Drupal\Component\Utility\SafeMarkup;
|
||||
use Drupal\field\Entity\FieldConfig;
|
||||
use Drupal\field\Entity\FieldStorageConfig;
|
||||
|
||||
/**
|
||||
* Delete field storages and fields during config delete method invocation.
|
||||
*
|
||||
* @group field
|
||||
*/
|
||||
class FieldImportDeleteTest extends FieldKernelTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* The default configuration provided by field_test_config is imported by
|
||||
* \Drupal\Tests\field\Kernel\FieldKernelTestBase::setUp() when it installs
|
||||
* field configuration.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = array('field_test_config');
|
||||
|
||||
/**
|
||||
* Tests deleting field storages and fields as part of config import.
|
||||
*/
|
||||
public function testImportDelete() {
|
||||
$this->installConfig(['field_test_config']);
|
||||
// At this point there are 5 field configuration objects in the active
|
||||
// storage.
|
||||
// - field.storage.entity_test.field_test_import
|
||||
// - field.storage.entity_test.field_test_import_2
|
||||
// - field.field.entity_test.entity_test.field_test_import
|
||||
// - field.field.entity_test.entity_test.field_test_import_2
|
||||
// - field.field.entity_test.test_bundle.field_test_import_2
|
||||
|
||||
$field_name = 'field_test_import';
|
||||
$field_storage_id = "entity_test.$field_name";
|
||||
$field_name_2 = 'field_test_import_2';
|
||||
$field_storage_id_2 = "entity_test.$field_name_2";
|
||||
$field_id = "entity_test.entity_test.$field_name";
|
||||
$field_id_2a = "entity_test.entity_test.$field_name_2";
|
||||
$field_id_2b = "entity_test.test_bundle.$field_name_2";
|
||||
$field_storage_config_name = "field.storage.$field_storage_id";
|
||||
$field_storage_config_name_2 = "field.storage.$field_storage_id_2";
|
||||
$field_config_name = "field.field.$field_id";
|
||||
$field_config_name_2a = "field.field.$field_id_2a";
|
||||
$field_config_name_2b = "field.field.$field_id_2b";
|
||||
|
||||
// Create a second bundle for the 'Entity test' entity type.
|
||||
entity_test_create_bundle('test_bundle');
|
||||
|
||||
// Get the uuid's for the field storages.
|
||||
$field_storage_uuid = FieldStorageConfig::load($field_storage_id)->uuid();
|
||||
$field_storage_uuid_2 = FieldStorageConfig::load($field_storage_id_2)->uuid();
|
||||
|
||||
$active = $this->container->get('config.storage');
|
||||
$sync = $this->container->get('config.storage.sync');
|
||||
$this->copyConfig($active, $sync);
|
||||
$this->assertTrue($sync->delete($field_storage_config_name), SafeMarkup::format('Deleted field storage: @field_storage', array('@field_storage' => $field_storage_config_name)));
|
||||
$this->assertTrue($sync->delete($field_storage_config_name_2), SafeMarkup::format('Deleted field storage: @field_storage', array('@field_storage' => $field_storage_config_name_2)));
|
||||
$this->assertTrue($sync->delete($field_config_name), SafeMarkup::format('Deleted field: @field', array('@field' => $field_config_name)));
|
||||
$this->assertTrue($sync->delete($field_config_name_2a), SafeMarkup::format('Deleted field: @field', array('@field' => $field_config_name_2a)));
|
||||
$this->assertTrue($sync->delete($field_config_name_2b), SafeMarkup::format('Deleted field: @field', array('@field' => $field_config_name_2b)));
|
||||
|
||||
$deletes = $this->configImporter()->getUnprocessedConfiguration('delete');
|
||||
$this->assertEqual(count($deletes), 5, 'Importing configuration will delete 3 fields and 2 field storages.');
|
||||
|
||||
// Import the content of the sync directory.
|
||||
$this->configImporter()->import();
|
||||
|
||||
// Check that the field storages and fields are gone.
|
||||
\Drupal::entityManager()->getStorage('field_storage_config')->resetCache(array($field_storage_id));
|
||||
$field_storage = FieldStorageConfig::load($field_storage_id);
|
||||
$this->assertFalse($field_storage, 'The field storage was deleted.');
|
||||
\Drupal::entityManager()->getStorage('field_storage_config')->resetCache(array($field_storage_id_2));
|
||||
$field_storage_2 = FieldStorageConfig::load($field_storage_id_2);
|
||||
$this->assertFalse($field_storage_2, 'The second field storage was deleted.');
|
||||
\Drupal::entityManager()->getStorage('field_config')->resetCache(array($field_id));
|
||||
$field = FieldConfig::load($field_id);
|
||||
$this->assertFalse($field, 'The field was deleted.');
|
||||
\Drupal::entityManager()->getStorage('field_config')->resetCache(array($field_id_2a));
|
||||
$field_2a = FieldConfig::load($field_id_2a);
|
||||
$this->assertFalse($field_2a, 'The second field on test bundle was deleted.');
|
||||
\Drupal::entityManager()->getStorage('field_config')->resetCache(array($field_id_2b));
|
||||
$field_2b = FieldConfig::load($field_id_2b);
|
||||
$this->assertFalse($field_2b, 'The second field on test bundle 2 was deleted.');
|
||||
|
||||
// Check that all config files are gone.
|
||||
$active = $this->container->get('config.storage');
|
||||
$this->assertIdentical($active->listAll($field_storage_config_name), array());
|
||||
$this->assertIdentical($active->listAll($field_storage_config_name_2), array());
|
||||
$this->assertIdentical($active->listAll($field_config_name), array());
|
||||
$this->assertIdentical($active->listAll($field_config_name_2a), array());
|
||||
$this->assertIdentical($active->listAll($field_config_name_2b), array());
|
||||
|
||||
// Check that the storage definition is preserved in state.
|
||||
$deleted_storages = \Drupal::state()->get('field.storage.deleted') ?: array();
|
||||
$this->assertTrue(isset($deleted_storages[$field_storage_uuid]));
|
||||
$this->assertTrue(isset($deleted_storages[$field_storage_uuid_2]));
|
||||
|
||||
// Purge field data, and check that the storage definition has been
|
||||
// completely removed once the data is purged.
|
||||
field_purge_batch(10);
|
||||
$deleted_storages = \Drupal::state()->get('field.storage.deleted') ?: array();
|
||||
$this->assertTrue(empty($deleted_storages), 'Fields are deleted');
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,168 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\field\Kernel;
|
||||
|
||||
use Drupal\entity_test\Entity\EntityTest;
|
||||
use Drupal\field\Entity\FieldConfig;
|
||||
use Drupal\field\Entity\FieldStorageConfig;
|
||||
|
||||
/**
|
||||
* Delete field storages and fields during config synchronization and uninstall
|
||||
* module that provides the field type.
|
||||
*
|
||||
* @group field
|
||||
* @see \Drupal\field\ConfigImporterFieldPurger
|
||||
* @see field_config_import_steps_alter()
|
||||
*/
|
||||
class FieldImportDeleteUninstallTest extends FieldKernelTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = array('telephone');
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
// Module uninstall requires users_data tables.
|
||||
// @see drupal_flush_all_caches()
|
||||
// @see user_modules_uninstalled()
|
||||
$this->installSchema('user', array('users_data'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests deleting field storages and fields as part of config import.
|
||||
*/
|
||||
public function testImportDeleteUninstall() {
|
||||
// Create a field to delete to prove that
|
||||
// \Drupal\field\ConfigImporterFieldPurger does not purge fields that are
|
||||
// not related to the configuration synchronization.
|
||||
$unrelated_field_storage = FieldStorageConfig::create(array(
|
||||
'field_name' => 'field_int',
|
||||
'entity_type' => 'entity_test',
|
||||
'type' => 'integer',
|
||||
));
|
||||
$unrelated_field_storage->save();
|
||||
FieldConfig::create([
|
||||
'field_storage' => $unrelated_field_storage,
|
||||
'bundle' => 'entity_test',
|
||||
])->save();
|
||||
|
||||
// Create a telephone field for validation.
|
||||
$field_storage = FieldStorageConfig::create(array(
|
||||
'field_name' => 'field_test',
|
||||
'entity_type' => 'entity_test',
|
||||
'type' => 'telephone',
|
||||
));
|
||||
$field_storage->save();
|
||||
FieldConfig::create([
|
||||
'field_storage' => $field_storage,
|
||||
'bundle' => 'entity_test',
|
||||
])->save();
|
||||
|
||||
$entity = EntityTest::create();
|
||||
$value = '+0123456789';
|
||||
$entity->field_test = $value;
|
||||
$entity->field_int = '99';
|
||||
$entity->name->value = $this->randomMachineName();
|
||||
$entity->save();
|
||||
|
||||
// Verify entity has been created properly.
|
||||
$id = $entity->id();
|
||||
$entity = EntityTest::load($id);
|
||||
$this->assertEqual($entity->field_test->value, $value);
|
||||
$this->assertEqual($entity->field_test[0]->value, $value);
|
||||
$this->assertEqual($entity->field_int->value, '99');
|
||||
|
||||
// Delete unrelated field before copying configuration and running the
|
||||
// synchronization.
|
||||
$unrelated_field_storage->delete();
|
||||
|
||||
$active = $this->container->get('config.storage');
|
||||
$sync = $this->container->get('config.storage.sync');
|
||||
$this->copyConfig($active, $sync);
|
||||
|
||||
// Stage uninstall of the Telephone module.
|
||||
$core_extension = $this->config('core.extension')->get();
|
||||
unset($core_extension['module']['telephone']);
|
||||
$sync->write('core.extension', $core_extension);
|
||||
|
||||
// Stage the field deletion
|
||||
$sync->delete('field.storage.entity_test.field_test');
|
||||
$sync->delete('field.field.entity_test.entity_test.field_test');
|
||||
|
||||
$steps = $this->configImporter()->initialize();
|
||||
$this->assertIdentical($steps[0], array('\Drupal\field\ConfigImporterFieldPurger', 'process'), 'The additional process configuration synchronization step has been added.');
|
||||
|
||||
// This will purge all the data, delete the field and uninstall the
|
||||
// Telephone module.
|
||||
$this->configImporter()->import();
|
||||
|
||||
$this->assertFalse(\Drupal::moduleHandler()->moduleExists('telephone'));
|
||||
$this->assertFalse(\Drupal::entityManager()->loadEntityByUuid('field_storage_config', $field_storage->uuid()), 'The test field has been deleted by the configuration synchronization');
|
||||
$deleted_storages = \Drupal::state()->get('field.storage.deleted') ?: array();
|
||||
$this->assertFalse(isset($deleted_storages[$field_storage->uuid()]), 'Telephone field has been completed removed from the system.');
|
||||
$this->assertTrue(isset($deleted_storages[$unrelated_field_storage->uuid()]), 'Unrelated field not purged by configuration synchronization.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests purging already deleted field storages and fields during a config
|
||||
* import.
|
||||
*/
|
||||
public function testImportAlreadyDeletedUninstall() {
|
||||
// Create a telephone field for validation.
|
||||
$field_storage = FieldStorageConfig::create(array(
|
||||
'field_name' => 'field_test',
|
||||
'entity_type' => 'entity_test',
|
||||
'type' => 'telephone',
|
||||
));
|
||||
$field_storage->save();
|
||||
$field_storage_uuid = $field_storage->uuid();
|
||||
FieldConfig::create([
|
||||
'field_storage' => $field_storage,
|
||||
'bundle' => 'entity_test',
|
||||
])->save();
|
||||
|
||||
// Create 12 entities to ensure that the purging works as expected.
|
||||
for ($i = 0; $i < 12; $i++) {
|
||||
$entity = EntityTest::create();
|
||||
$value = '+0123456789';
|
||||
$entity->field_test = $value;
|
||||
$entity->name->value = $this->randomMachineName();
|
||||
$entity->save();
|
||||
|
||||
// Verify entity has been created properly.
|
||||
$id = $entity->id();
|
||||
$entity = EntityTest::load($id);
|
||||
$this->assertEqual($entity->field_test->value, $value);
|
||||
}
|
||||
|
||||
// Delete the field.
|
||||
$field_storage->delete();
|
||||
|
||||
$active = $this->container->get('config.storage');
|
||||
$sync = $this->container->get('config.storage.sync');
|
||||
$this->copyConfig($active, $sync);
|
||||
|
||||
// Stage uninstall of the Telephone module.
|
||||
$core_extension = $this->config('core.extension')->get();
|
||||
unset($core_extension['module']['telephone']);
|
||||
$sync->write('core.extension', $core_extension);
|
||||
|
||||
$deleted_storages = \Drupal::state()->get('field.storage.deleted') ?: array();
|
||||
$this->assertTrue(isset($deleted_storages[$field_storage_uuid]), 'Field has been deleted and needs purging before configuration synchronization.');
|
||||
|
||||
$steps = $this->configImporter()->initialize();
|
||||
$this->assertIdentical($steps[0], array('\Drupal\field\ConfigImporterFieldPurger', 'process'), 'The additional process configuration synchronization step has been added.');
|
||||
|
||||
// This will purge all the data, delete the field and uninstall the
|
||||
// Telephone module.
|
||||
$this->configImporter()->import();
|
||||
|
||||
$this->assertFalse(\Drupal::moduleHandler()->moduleExists('telephone'));
|
||||
$deleted_storages = \Drupal::state()->get('field.storage.deleted') ?: array();
|
||||
$this->assertFalse(isset($deleted_storages[$field_storage_uuid]), 'Field has been completed removed from the system.');
|
||||
}
|
||||
|
||||
}
|
204
web/core/modules/field/tests/src/Kernel/FieldKernelTestBase.php
Normal file
204
web/core/modules/field/tests/src/Kernel/FieldKernelTestBase.php
Normal file
|
@ -0,0 +1,204 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\field\Kernel;
|
||||
|
||||
use Drupal\Component\Utility\Unicode;
|
||||
use Drupal\Core\Entity\EntityInterface;
|
||||
use Drupal\Core\Language\LanguageInterface;
|
||||
use Drupal\field\Entity\FieldConfig;
|
||||
use Drupal\field\Entity\FieldStorageConfig;
|
||||
use Drupal\KernelTests\KernelTestBase;
|
||||
|
||||
/**
|
||||
* Parent class for Field API unit tests.
|
||||
*/
|
||||
abstract class FieldKernelTestBase extends KernelTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['user', 'system', 'field', 'text', 'entity_test', 'field_test'];
|
||||
|
||||
/**
|
||||
* Bag of created field storages and fields.
|
||||
*
|
||||
* Allows easy access to test field storage/field names/IDs/objects via:
|
||||
* - $this->fieldTestData->field_name[suffix]
|
||||
* - $this->fieldTestData->field_storage[suffix]
|
||||
* - $this->fieldTestData->field_storage_uuid[suffix]
|
||||
* - $this->fieldTestData->field[suffix]
|
||||
* - $this->fieldTestData->field_definition[suffix]
|
||||
*
|
||||
* @see \Drupal\field\Tests\FieldUnitTestBase::createFieldWithStorage()
|
||||
*
|
||||
* @var \ArrayObject
|
||||
*/
|
||||
protected $fieldTestData;
|
||||
|
||||
/**
|
||||
* Set the default field storage backend for fields created during tests.
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$this->fieldTestData = new \ArrayObject(array(), \ArrayObject::ARRAY_AS_PROPS);
|
||||
|
||||
$this->installEntitySchema('entity_test');
|
||||
$this->installEntitySchema('user');
|
||||
$this->installSchema('system', ['sequences', 'key_value']);
|
||||
|
||||
// Set default storage backend and configure the theme system.
|
||||
$this->installConfig(array('field', 'system'));
|
||||
|
||||
// Create user 1.
|
||||
$storage = \Drupal::entityManager()->getStorage('user');
|
||||
$storage
|
||||
->create(array(
|
||||
'uid' => 1,
|
||||
'name' => 'entity-test',
|
||||
'mail' => 'entity@localhost',
|
||||
'status' => TRUE,
|
||||
))
|
||||
->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a field and an associated field storage.
|
||||
*
|
||||
* @param string $suffix
|
||||
* (optional) A string that should only contain characters that are valid in
|
||||
* PHP variable names as well.
|
||||
* @param string $entity_type
|
||||
* (optional) The entity type on which the field should be created.
|
||||
* Defaults to "entity_test".
|
||||
* @param string $bundle
|
||||
* (optional) The entity type on which the field should be created.
|
||||
* Defaults to the default bundle of the entity type.
|
||||
*/
|
||||
protected function createFieldWithStorage($suffix = '', $entity_type = 'entity_test', $bundle = NULL) {
|
||||
if (empty($bundle)) {
|
||||
$bundle = $entity_type;
|
||||
}
|
||||
$field_name = 'field_name' . $suffix;
|
||||
$field_storage = 'field_storage' . $suffix;
|
||||
$field_storage_uuid = 'field_storage_uuid' . $suffix;
|
||||
$field = 'field' . $suffix;
|
||||
$field_definition = 'field_definition' . $suffix;
|
||||
|
||||
$this->fieldTestData->$field_name = Unicode::strtolower($this->randomMachineName() . '_field_name' . $suffix);
|
||||
$this->fieldTestData->$field_storage = FieldStorageConfig::create(array(
|
||||
'field_name' => $this->fieldTestData->$field_name,
|
||||
'entity_type' => $entity_type,
|
||||
'type' => 'test_field',
|
||||
'cardinality' => 4,
|
||||
));
|
||||
$this->fieldTestData->$field_storage->save();
|
||||
$this->fieldTestData->$field_storage_uuid = $this->fieldTestData->$field_storage->uuid();
|
||||
$this->fieldTestData->$field_definition = array(
|
||||
'field_storage' => $this->fieldTestData->$field_storage,
|
||||
'bundle' => $bundle,
|
||||
'label' => $this->randomMachineName() . '_label',
|
||||
'description' => $this->randomMachineName() . '_description',
|
||||
'settings' => array(
|
||||
'test_field_setting' => $this->randomMachineName(),
|
||||
),
|
||||
);
|
||||
$this->fieldTestData->$field = FieldConfig::create($this->fieldTestData->$field_definition);
|
||||
$this->fieldTestData->$field->save();
|
||||
|
||||
entity_get_form_display($entity_type, $bundle, 'default')
|
||||
->setComponent($this->fieldTestData->$field_name, array(
|
||||
'type' => 'test_field_widget',
|
||||
'settings' => array(
|
||||
'test_widget_setting' => $this->randomMachineName(),
|
||||
)
|
||||
))
|
||||
->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves and reloads an entity.
|
||||
*
|
||||
* @param \Drupal\Core\Entity\EntityInterface $entity
|
||||
* The entity to save.
|
||||
*
|
||||
* @return \Drupal\Core\Entity\EntityInterface
|
||||
* The entity, freshly reloaded from storage.
|
||||
*/
|
||||
protected function entitySaveReload(EntityInterface $entity) {
|
||||
$entity->save();
|
||||
$controller = $this->container->get('entity.manager')->getStorage($entity->getEntityTypeId());
|
||||
$controller->resetCache();
|
||||
return $controller->load($entity->id());
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate and save entity. Fail if violations are found.
|
||||
*
|
||||
* @param \Drupal\Core\Entity\EntityInterface $entity
|
||||
* The entity to save.
|
||||
*/
|
||||
protected function entityValidateAndSave(EntityInterface $entity) {
|
||||
$violations = $entity->validate();
|
||||
if ($violations->count()) {
|
||||
$this->fail($violations);
|
||||
}
|
||||
else {
|
||||
$entity->save();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate random values for a field_test field.
|
||||
*
|
||||
* @param $cardinality
|
||||
* Number of values to generate.
|
||||
* @return
|
||||
* An array of random values, in the format expected for field values.
|
||||
*/
|
||||
protected function _generateTestFieldValues($cardinality) {
|
||||
$values = array();
|
||||
for ($i = 0; $i < $cardinality; $i++) {
|
||||
// field_test fields treat 0 as 'empty value'.
|
||||
$values[$i]['value'] = mt_rand(1, 127);
|
||||
}
|
||||
return $values;
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert that a field has the expected values in an entity.
|
||||
*
|
||||
* This function only checks a single column in the field values.
|
||||
*
|
||||
* @param EntityInterface $entity
|
||||
* The entity to test.
|
||||
* @param $field_name
|
||||
* The name of the field to test
|
||||
* @param $expected_values
|
||||
* The array of expected values.
|
||||
* @param $langcode
|
||||
* (Optional) The language code for the values. Defaults to
|
||||
* \Drupal\Core\Language\LanguageInterface::LANGCODE_NOT_SPECIFIED.
|
||||
* @param $column
|
||||
* (Optional) The name of the column to check. Defaults to 'value'.
|
||||
*/
|
||||
protected function assertFieldValues(EntityInterface $entity, $field_name, $expected_values, $langcode = LanguageInterface::LANGCODE_NOT_SPECIFIED, $column = 'value') {
|
||||
// Re-load the entity to make sure we have the latest changes.
|
||||
$storage = $this->container->get('entity_type.manager')
|
||||
->getStorage($entity->getEntityTypeId());
|
||||
$storage->resetCache([$entity->id()]);
|
||||
$e = $storage->load($this->entityId);
|
||||
|
||||
$field = $values = $e->getTranslation($langcode)->$field_name;
|
||||
// Filter out empty values so that they don't mess with the assertions.
|
||||
$field->filterEmptyItems();
|
||||
$values = $field->getValue();
|
||||
$this->assertEqual(count($values), count($expected_values), 'Expected number of values were saved.');
|
||||
foreach ($expected_values as $key => $value) {
|
||||
$this->assertEqual($values[$key][$column], $value, format_string('Value @value was saved correctly.', array('@value' => $value)));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
457
web/core/modules/field/tests/src/Kernel/FieldStorageCrudTest.php
Normal file
457
web/core/modules/field/tests/src/Kernel/FieldStorageCrudTest.php
Normal file
|
@ -0,0 +1,457 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\field\Kernel;
|
||||
|
||||
use Drupal\Core\Entity\EntityStorageException;
|
||||
use Drupal\Core\Entity\Exception\FieldStorageDefinitionUpdateForbiddenException;
|
||||
use Drupal\Core\Field\FieldException;
|
||||
use Drupal\entity_test\Entity\EntityTest;
|
||||
use Drupal\field\Entity\FieldConfig;
|
||||
use Drupal\field\Entity\FieldStorageConfig;
|
||||
|
||||
/**
|
||||
* Tests field storage create, read, update, and delete.
|
||||
*
|
||||
* @group field
|
||||
*/
|
||||
class FieldStorageCrudTest extends FieldKernelTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = array();
|
||||
|
||||
// TODO : test creation with
|
||||
// - a full fledged $field structure, check that all the values are there
|
||||
// - a minimal $field structure, check all default values are set
|
||||
// defer actual $field comparison to a helper function, used for the two cases above
|
||||
|
||||
/**
|
||||
* Test the creation of a field storage.
|
||||
*/
|
||||
function testCreate() {
|
||||
$field_storage_definition = array(
|
||||
'field_name' => 'field_2',
|
||||
'entity_type' => 'entity_test',
|
||||
'type' => 'test_field',
|
||||
);
|
||||
field_test_memorize();
|
||||
$field_storage = FieldStorageConfig::create($field_storage_definition);
|
||||
$field_storage->save();
|
||||
|
||||
$field_storage = FieldStorageConfig::load($field_storage->id());
|
||||
$this->assertTrue($field_storage->getSetting('storage_setting_from_config_data'));
|
||||
$this->assertNull($field_storage->getSetting('config_data_from_storage_setting'));
|
||||
|
||||
$mem = field_test_memorize();
|
||||
$this->assertIdentical($mem['field_test_field_storage_config_create'][0][0]->getName(), $field_storage_definition['field_name'], 'hook_entity_create() called with correct arguments.');
|
||||
$this->assertIdentical($mem['field_test_field_storage_config_create'][0][0]->getType(), $field_storage_definition['type'], 'hook_entity_create() called with correct arguments.');
|
||||
|
||||
// Read the configuration. Check against raw configuration data rather than
|
||||
// the loaded ConfigEntity, to be sure we check that the defaults are
|
||||
// applied on write.
|
||||
$field_storage_config = $this->config('field.storage.' . $field_storage->id())->get();
|
||||
|
||||
$this->assertTrue($field_storage_config['settings']['config_data_from_storage_setting']);
|
||||
$this->assertTrue(!isset($field_storage_config['settings']['storage_setting_from_config_data']));
|
||||
|
||||
// Since we are working with raw configuration, this needs to be unset
|
||||
// manually.
|
||||
// @see Drupal\field_test\Plugin\Field\FieldType\TestItem::storageSettingsFromConfigData()
|
||||
unset($field_storage_config['settings']['config_data_from_storage_setting']);
|
||||
|
||||
// Ensure that basic properties are preserved.
|
||||
$this->assertEqual($field_storage_config['field_name'], $field_storage_definition['field_name'], 'The field name is properly saved.');
|
||||
$this->assertEqual($field_storage_config['entity_type'], $field_storage_definition['entity_type'], 'The field entity type is properly saved.');
|
||||
$this->assertEqual($field_storage_config['id'], $field_storage_definition['entity_type'] . '.' . $field_storage_definition['field_name'], 'The field id is properly saved.');
|
||||
$this->assertEqual($field_storage_config['type'], $field_storage_definition['type'], 'The field type is properly saved.');
|
||||
|
||||
// Ensure that cardinality defaults to 1.
|
||||
$this->assertEqual($field_storage_config['cardinality'], 1, 'Cardinality defaults to 1.');
|
||||
|
||||
// Ensure that default settings are present.
|
||||
$field_type_manager = \Drupal::service('plugin.manager.field.field_type');
|
||||
$this->assertEqual($field_storage_config['settings'], $field_type_manager->getDefaultStorageSettings($field_storage_definition['type']), 'Default storage settings have been written.');
|
||||
|
||||
// Guarantee that the name is unique.
|
||||
try {
|
||||
FieldStorageConfig::create($field_storage_definition)->save();
|
||||
$this->fail(t('Cannot create two fields with the same name.'));
|
||||
}
|
||||
catch (EntityStorageException $e) {
|
||||
$this->pass(t('Cannot create two fields with the same name.'));
|
||||
}
|
||||
|
||||
// Check that field type is required.
|
||||
try {
|
||||
$field_storage_definition = array(
|
||||
'field_name' => 'field_1',
|
||||
'entity_type' => 'entity_type',
|
||||
);
|
||||
FieldStorageConfig::create($field_storage_definition)->save();
|
||||
$this->fail(t('Cannot create a field with no type.'));
|
||||
}
|
||||
catch (FieldException $e) {
|
||||
$this->pass(t('Cannot create a field with no type.'));
|
||||
}
|
||||
|
||||
// Check that field name is required.
|
||||
try {
|
||||
$field_storage_definition = array(
|
||||
'type' => 'test_field',
|
||||
'entity_type' => 'entity_test',
|
||||
);
|
||||
FieldStorageConfig::create($field_storage_definition)->save();
|
||||
$this->fail(t('Cannot create an unnamed field.'));
|
||||
}
|
||||
catch (FieldException $e) {
|
||||
$this->pass(t('Cannot create an unnamed field.'));
|
||||
}
|
||||
// Check that entity type is required.
|
||||
try {
|
||||
$field_storage_definition = array(
|
||||
'field_name' => 'test_field',
|
||||
'type' => 'test_field'
|
||||
);
|
||||
FieldStorageConfig::create($field_storage_definition)->save();
|
||||
$this->fail('Cannot create a field without an entity type.');
|
||||
}
|
||||
catch (FieldException $e) {
|
||||
$this->pass('Cannot create a field without an entity type.');
|
||||
}
|
||||
|
||||
// Check that field name must start with a letter or _.
|
||||
try {
|
||||
$field_storage_definition = array(
|
||||
'field_name' => '2field_2',
|
||||
'entity_type' => 'entity_test',
|
||||
'type' => 'test_field',
|
||||
);
|
||||
FieldStorageConfig::create($field_storage_definition)->save();
|
||||
$this->fail(t('Cannot create a field with a name starting with a digit.'));
|
||||
}
|
||||
catch (FieldException $e) {
|
||||
$this->pass(t('Cannot create a field with a name starting with a digit.'));
|
||||
}
|
||||
|
||||
// Check that field name must only contain lowercase alphanumeric or _.
|
||||
try {
|
||||
$field_storage_definition = array(
|
||||
'field_name' => 'field#_3',
|
||||
'entity_type' => 'entity_test',
|
||||
'type' => 'test_field',
|
||||
);
|
||||
FieldStorageConfig::create($field_storage_definition)->save();
|
||||
$this->fail(t('Cannot create a field with a name containing an illegal character.'));
|
||||
}
|
||||
catch (FieldException $e) {
|
||||
$this->pass(t('Cannot create a field with a name containing an illegal character.'));
|
||||
}
|
||||
|
||||
// Check that field name cannot be longer than 32 characters long.
|
||||
try {
|
||||
$field_storage_definition = array(
|
||||
'field_name' => '_12345678901234567890123456789012',
|
||||
'entity_type' => 'entity_test',
|
||||
'type' => 'test_field',
|
||||
);
|
||||
FieldStorageConfig::create($field_storage_definition)->save();
|
||||
$this->fail(t('Cannot create a field with a name longer than 32 characters.'));
|
||||
}
|
||||
catch (FieldException $e) {
|
||||
$this->pass(t('Cannot create a field with a name longer than 32 characters.'));
|
||||
}
|
||||
|
||||
// Check that field name can not be an entity key.
|
||||
// "id" is known as an entity key from the "entity_test" type.
|
||||
try {
|
||||
$field_storage_definition = array(
|
||||
'type' => 'test_field',
|
||||
'field_name' => 'id',
|
||||
'entity_type' => 'entity_test',
|
||||
);
|
||||
FieldStorageConfig::create($field_storage_definition)->save();
|
||||
$this->fail(t('Cannot create a field bearing the name of an entity key.'));
|
||||
}
|
||||
catch (FieldException $e) {
|
||||
$this->pass(t('Cannot create a field bearing the name of an entity key.'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that an explicit schema can be provided on creation.
|
||||
*
|
||||
* This behavior is needed to allow field storage creation within updates,
|
||||
* since plugin classes (and thus the field type schema) cannot be accessed.
|
||||
*/
|
||||
function testCreateWithExplicitSchema() {
|
||||
$schema = array(
|
||||
'dummy' => 'foobar'
|
||||
);
|
||||
$field_storage = FieldStorageConfig::create(array(
|
||||
'field_name' => 'field_2',
|
||||
'entity_type' => 'entity_test',
|
||||
'type' => 'test_field',
|
||||
'schema' => $schema,
|
||||
));
|
||||
$this->assertEqual($field_storage->getSchema(), $schema);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests reading field storage definitions.
|
||||
*/
|
||||
function testRead() {
|
||||
$field_storage_definition = array(
|
||||
'field_name' => 'field_1',
|
||||
'entity_type' => 'entity_test',
|
||||
'type' => 'test_field',
|
||||
);
|
||||
$field_storage = FieldStorageConfig::create($field_storage_definition);
|
||||
$field_storage->save();
|
||||
$id = $field_storage->id();
|
||||
|
||||
// Check that 'single column' criteria works.
|
||||
$fields = entity_load_multiple_by_properties('field_storage_config', array('field_name' => $field_storage_definition['field_name']));
|
||||
$this->assertTrue(count($fields) == 1 && isset($fields[$id]), 'The field was properly read.');
|
||||
|
||||
// Check that 'multi column' criteria works.
|
||||
$fields = entity_load_multiple_by_properties('field_storage_config', array('field_name' => $field_storage_definition['field_name'], 'type' => $field_storage_definition['type']));
|
||||
$this->assertTrue(count($fields) == 1 && isset($fields[$id]), 'The field was properly read.');
|
||||
$fields = entity_load_multiple_by_properties('field_storage_config', array('field_name' => $field_storage_definition['field_name'], 'type' => 'foo'));
|
||||
$this->assertTrue(empty($fields), 'No field was found.');
|
||||
|
||||
// Create a field from the field storage.
|
||||
$field_definition = array(
|
||||
'field_name' => $field_storage_definition['field_name'],
|
||||
'entity_type' => 'entity_test',
|
||||
'bundle' => 'entity_test',
|
||||
);
|
||||
FieldConfig::create($field_definition)->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test creation of indexes on data column.
|
||||
*/
|
||||
function testIndexes() {
|
||||
// Check that indexes specified by the field type are used by default.
|
||||
$field_storage = FieldStorageConfig::create(array(
|
||||
'field_name' => 'field_1',
|
||||
'entity_type' => 'entity_test',
|
||||
'type' => 'test_field',
|
||||
));
|
||||
$field_storage->save();
|
||||
$field_storage = FieldStorageConfig::load($field_storage->id());
|
||||
$schema = $field_storage->getSchema();
|
||||
$expected_indexes = array('value' => array('value'));
|
||||
$this->assertEqual($schema['indexes'], $expected_indexes, 'Field type indexes saved by default');
|
||||
|
||||
// Check that indexes specified by the field definition override the field
|
||||
// type indexes.
|
||||
$field_storage = FieldStorageConfig::create(array(
|
||||
'field_name' => 'field_2',
|
||||
'entity_type' => 'entity_test',
|
||||
'type' => 'test_field',
|
||||
'indexes' => array(
|
||||
'value' => array(),
|
||||
),
|
||||
));
|
||||
$field_storage->save();
|
||||
$field_storage = FieldStorageConfig::load($field_storage->id());
|
||||
$schema = $field_storage->getSchema();
|
||||
$expected_indexes = array('value' => array());
|
||||
$this->assertEqual($schema['indexes'], $expected_indexes, 'Field definition indexes override field type indexes');
|
||||
|
||||
// Check that indexes specified by the field definition add to the field
|
||||
// type indexes.
|
||||
$field_storage = FieldStorageConfig::create(array(
|
||||
'field_name' => 'field_3',
|
||||
'entity_type' => 'entity_test',
|
||||
'type' => 'test_field',
|
||||
'indexes' => array(
|
||||
'value_2' => array('value'),
|
||||
),
|
||||
));
|
||||
$field_storage->save();
|
||||
$id = $field_storage->id();
|
||||
$field_storage = FieldStorageConfig::load($id);
|
||||
$schema = $field_storage->getSchema();
|
||||
$expected_indexes = array('value' => array('value'), 'value_2' => array('value'));
|
||||
$this->assertEqual($schema['indexes'], $expected_indexes, 'Field definition indexes are merged with field type indexes');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the deletion of a field storage.
|
||||
*/
|
||||
function testDelete() {
|
||||
// TODO: Also test deletion of the data stored in the field ?
|
||||
|
||||
// Create two fields (so we can test that only one is deleted).
|
||||
$field_storage_definition = array(
|
||||
'field_name' => 'field_1',
|
||||
'type' => 'test_field',
|
||||
'entity_type' => 'entity_test',
|
||||
);
|
||||
FieldStorageConfig::create($field_storage_definition)->save();
|
||||
$another_field_storage_definition = array(
|
||||
'field_name' => 'field_2',
|
||||
'type' => 'test_field',
|
||||
'entity_type' => 'entity_test',
|
||||
);
|
||||
FieldStorageConfig::create($another_field_storage_definition)->save();
|
||||
|
||||
// Create fields for each.
|
||||
$field_definition = array(
|
||||
'field_name' => $field_storage_definition['field_name'],
|
||||
'entity_type' => 'entity_test',
|
||||
'bundle' => 'entity_test',
|
||||
);
|
||||
FieldConfig::create($field_definition)->save();
|
||||
$another_field_definition = $field_definition;
|
||||
$another_field_definition['field_name'] = $another_field_storage_definition['field_name'];
|
||||
FieldConfig::create($another_field_definition)->save();
|
||||
|
||||
// Test that the first field is not deleted, and then delete it.
|
||||
$field_storage = current(entity_load_multiple_by_properties('field_storage_config', array('field_name' => $field_storage_definition['field_name'], 'include_deleted' => TRUE)));
|
||||
$this->assertTrue(!empty($field_storage) && !$field_storage->isDeleted(), 'A new storage is not marked for deletion.');
|
||||
FieldStorageConfig::loadByName('entity_test', $field_storage_definition['field_name'])->delete();
|
||||
|
||||
// Make sure that the field is marked as deleted when it is specifically
|
||||
// loaded.
|
||||
$field_storage = current(entity_load_multiple_by_properties('field_storage_config', array('field_name' => $field_storage_definition['field_name'], 'include_deleted' => TRUE)));
|
||||
$this->assertTrue($field_storage->isDeleted(), 'A deleted storage is marked for deletion.');
|
||||
|
||||
// Make sure that this field is marked as deleted when it is
|
||||
// specifically loaded.
|
||||
$field = current(entity_load_multiple_by_properties('field_config', array('entity_type' => 'entity_test', 'field_name' => $field_definition['field_name'], 'bundle' => $field_definition['bundle'], 'include_deleted' => TRUE)));
|
||||
$this->assertTrue($field->isDeleted(), 'A field whose storage was deleted is marked for deletion.');
|
||||
|
||||
// Try to load the storage normally and make sure it does not show up.
|
||||
$field_storage = FieldStorageConfig::load('entity_test.' . $field_storage_definition['field_name']);
|
||||
$this->assertTrue(empty($field_storage), 'A deleted storage is not loaded by default.');
|
||||
|
||||
// Try to load the field normally and make sure it does not show up.
|
||||
$field = FieldConfig::load('entity_test.' . '.' . $field_definition['bundle'] . '.' . $field_definition['field_name']);
|
||||
$this->assertTrue(empty($field), 'A field whose storage was deleted is not loaded by default.');
|
||||
|
||||
// Make sure the other field and its storage are not deleted.
|
||||
$another_field_storage = FieldStorageConfig::load('entity_test.' . $another_field_storage_definition['field_name']);
|
||||
$this->assertTrue(!empty($another_field_storage) && !$another_field_storage->isDeleted(), 'A non-deleted storage is not marked for deletion.');
|
||||
$another_field = FieldConfig::load('entity_test.' . $another_field_definition['bundle'] . '.' . $another_field_definition['field_name']);
|
||||
$this->assertTrue(!empty($another_field) && !$another_field->isDeleted(), 'A field whose storage was not deleted is not marked for deletion.');
|
||||
|
||||
// Try to create a new field the same name as a deleted field and
|
||||
// write data into it.
|
||||
FieldStorageConfig::create($field_storage_definition)->save();
|
||||
FieldConfig::create($field_definition)->save();
|
||||
$field_storage = FieldStorageConfig::load('entity_test.' . $field_storage_definition['field_name']);
|
||||
$this->assertTrue(!empty($field_storage) && !$field_storage->isDeleted(), 'A new storage with a previously used name is created.');
|
||||
$field = FieldConfig::load('entity_test.' . $field_definition['bundle'] . '.' . $field_definition['field_name'] );
|
||||
$this->assertTrue(!empty($field) && !$field->isDeleted(), 'A new field for a previously used field name is created.');
|
||||
|
||||
// Save an entity with data for the field
|
||||
$entity = EntityTest::create();
|
||||
$values[0]['value'] = mt_rand(1, 127);
|
||||
$entity->{$field_storage->getName()}->value = $values[0]['value'];
|
||||
$entity = $this->entitySaveReload($entity);
|
||||
|
||||
// Verify the field is present on load
|
||||
$this->assertIdentical(count($entity->{$field_storage->getName()}), count($values), "Data in previously deleted field saves and loads correctly");
|
||||
foreach ($values as $delta => $value) {
|
||||
$this->assertEqual($entity->{$field_storage->getName()}[$delta]->value, $values[$delta]['value'], "Data in previously deleted field saves and loads correctly");
|
||||
}
|
||||
}
|
||||
|
||||
function testUpdateFieldType() {
|
||||
$field_storage = FieldStorageConfig::create(array(
|
||||
'field_name' => 'field_type',
|
||||
'entity_type' => 'entity_test',
|
||||
'type' => 'decimal',
|
||||
));
|
||||
$field_storage->save();
|
||||
|
||||
try {
|
||||
$field_storage->set('type', 'integer');
|
||||
$field_storage->save();
|
||||
$this->fail(t('Cannot update a field to a different type.'));
|
||||
}
|
||||
catch (FieldException $e) {
|
||||
$this->pass(t('Cannot update a field to a different type.'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test updating a field storage.
|
||||
*/
|
||||
function testUpdate() {
|
||||
// Create a field with a defined cardinality, so that we can ensure it's
|
||||
// respected. Since cardinality enforcement is consistent across database
|
||||
// systems, it makes a good test case.
|
||||
$cardinality = 4;
|
||||
$field_storage = FieldStorageConfig::create(array(
|
||||
'field_name' => 'field_update',
|
||||
'entity_type' => 'entity_test',
|
||||
'type' => 'test_field',
|
||||
'cardinality' => $cardinality,
|
||||
));
|
||||
$field_storage->save();
|
||||
$field = FieldConfig::create([
|
||||
'field_storage' => $field_storage,
|
||||
'entity_type' => 'entity_test',
|
||||
'bundle' => 'entity_test',
|
||||
]);
|
||||
$field->save();
|
||||
|
||||
do {
|
||||
$entity = EntityTest::create();
|
||||
// Fill in the entity with more values than $cardinality.
|
||||
for ($i = 0; $i < 20; $i++) {
|
||||
// We can not use $i here because 0 values are filtered out.
|
||||
$entity->field_update[] = $i + 1;
|
||||
}
|
||||
// Load back and assert there are $cardinality number of values.
|
||||
$entity = $this->entitySaveReload($entity);
|
||||
$this->assertEqual(count($entity->field_update), $field_storage->getCardinality());
|
||||
// Now check the values themselves.
|
||||
for ($delta = 0; $delta < $cardinality; $delta++) {
|
||||
$this->assertEqual($entity->field_update[$delta]->value, $delta + 1);
|
||||
}
|
||||
// Increase $cardinality and set the field cardinality to the new value.
|
||||
$field_storage->setCardinality(++$cardinality);
|
||||
$field_storage->save();
|
||||
} while ($cardinality < 6);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test field type modules forbidding an update.
|
||||
*/
|
||||
function testUpdateForbid() {
|
||||
$field_storage = FieldStorageConfig::create(array(
|
||||
'field_name' => 'forbidden',
|
||||
'entity_type' => 'entity_test',
|
||||
'type' => 'test_field',
|
||||
'settings' => array(
|
||||
'changeable' => 0,
|
||||
'unchangeable' => 0
|
||||
)));
|
||||
$field_storage->save();
|
||||
$field_storage->setSetting('changeable', $field_storage->getSetting('changeable') + 1);
|
||||
try {
|
||||
$field_storage->save();
|
||||
$this->pass(t("A changeable setting can be updated."));
|
||||
}
|
||||
catch (FieldStorageDefinitionUpdateForbiddenException $e) {
|
||||
$this->fail(t("An unchangeable setting cannot be updated."));
|
||||
}
|
||||
$field_storage->setSetting('unchangeable', $field_storage->getSetting('unchangeable') + 1);
|
||||
try {
|
||||
$field_storage->save();
|
||||
$this->fail(t("An unchangeable setting can be updated."));
|
||||
}
|
||||
catch (FieldStorageDefinitionUpdateForbiddenException $e) {
|
||||
$this->pass(t("An unchangeable setting cannot be updated."));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,125 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\field\Kernel;
|
||||
|
||||
use Drupal\Component\Utility\SafeMarkup;
|
||||
use Drupal\Core\Extension\ExtensionDiscovery;
|
||||
use Drupal\Core\Field\BaseFieldDefinition;
|
||||
use Drupal\entity_test\Entity\EntityTest;
|
||||
|
||||
/**
|
||||
* Tests the field type manager.
|
||||
*
|
||||
* @group field
|
||||
*/
|
||||
class FieldTypePluginManagerTest extends FieldKernelTestBase {
|
||||
|
||||
/**
|
||||
* Tests the default settings convenience methods.
|
||||
*/
|
||||
function testDefaultSettings() {
|
||||
$field_type_manager = \Drupal::service('plugin.manager.field.field_type');
|
||||
foreach (array('test_field', 'shape', 'hidden_test_field') as $type) {
|
||||
$definition = $field_type_manager->getDefinition($type);
|
||||
$this->assertIdentical($field_type_manager->getDefaultStorageSettings($type), $definition['class']::defaultStorageSettings(), format_string("%type storage settings were returned", array('%type' => $type)));
|
||||
$this->assertIdentical($field_type_manager->getDefaultFieldSettings($type), $definition['class']::defaultFieldSettings(), format_string(" %type field settings were returned", array('%type' => $type)));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests creation of field item instances.
|
||||
*/
|
||||
public function testCreateInstance() {
|
||||
/** @var \Drupal\Core\Field\FieldTypePluginManagerInterface $field_type_manager */
|
||||
$field_type_manager = \Drupal::service('plugin.manager.field.field_type');
|
||||
foreach (array('test_field', 'shape', 'hidden_test_field') as $type) {
|
||||
$definition = $field_type_manager->getDefinition($type);
|
||||
|
||||
$class = $definition['class'];
|
||||
$field_name = 'field_' . $type;
|
||||
|
||||
$field_definition = BaseFieldDefinition::create($type);
|
||||
|
||||
$configuration = array(
|
||||
'field_definition' => $field_definition,
|
||||
'name' => $field_name,
|
||||
'parent' => NULL,
|
||||
);
|
||||
|
||||
$instance = $field_type_manager->createInstance($type, $configuration);
|
||||
|
||||
$this->assertTrue($instance instanceof $class, SafeMarkup::format('Created a @class instance', array('@class' => $class)));
|
||||
$this->assertEqual($field_name, $instance->getName(), SafeMarkup::format('Instance name is @name', array('@name' => $field_name)));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests creation of field item instances.
|
||||
*/
|
||||
public function testCreateInstanceWithConfig() {
|
||||
/** @var \Drupal\Core\Field\FieldTypePluginManagerInterface $field_type_manager */
|
||||
$field_type_manager = \Drupal::service('plugin.manager.field.field_type');
|
||||
$type = 'test_field';
|
||||
$definition = $field_type_manager->getDefinition($type);
|
||||
|
||||
$class = $definition['class'];
|
||||
$field_name = 'field_' . $type;
|
||||
|
||||
$field_definition = BaseFieldDefinition::create($type)
|
||||
->setLabel('Jenny')
|
||||
->setDefaultValue(8675309);
|
||||
|
||||
$configuration = array(
|
||||
'field_definition' => $field_definition,
|
||||
'name' => $field_name,
|
||||
'parent' => NULL,
|
||||
);
|
||||
|
||||
$entity = EntityTest::create();
|
||||
|
||||
$instance = $field_type_manager->createInstance($type, $configuration);
|
||||
|
||||
$this->assertTrue($instance instanceof $class, SafeMarkup::format('Created a @class instance', array('@class' => $class)));
|
||||
$this->assertEqual($field_name, $instance->getName(), SafeMarkup::format('Instance name is @name', array('@name' => $field_name)));
|
||||
$this->assertEqual($instance->getFieldDefinition()->getLabel(), 'Jenny', 'Instance label is Jenny');
|
||||
$this->assertEqual($instance->getFieldDefinition()->getDefaultValue($entity), [['value' => 8675309]], 'Instance default_value is 8675309');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests all field items provide an existing main property.
|
||||
*/
|
||||
public function testMainProperty() {
|
||||
// Let's enable all Drupal modules in Drupal core, so we test any field
|
||||
// type plugin.
|
||||
$this->enableAllCoreModules();
|
||||
|
||||
/** @var \Drupal\Core\Field\FieldTypePluginManagerInterface $field_type_manager */
|
||||
$field_type_manager = \Drupal::service('plugin.manager.field.field_type');
|
||||
foreach ($field_type_manager->getDefinitions() as $plugin_id => $definition) {
|
||||
$class = $definition['class'];
|
||||
$property = $class::mainPropertyName();
|
||||
$storage_definition = BaseFieldDefinition::create($plugin_id);
|
||||
$property_definitions = $class::propertyDefinitions($storage_definition);
|
||||
$properties = implode(', ', array_keys($property_definitions));
|
||||
if (!empty($property_definitions)) {
|
||||
$message = sprintf("%s property %s found in %s", $plugin_id, $property, $properties);
|
||||
$this->assertArrayHasKey($property, $class::propertyDefinitions($storage_definition), $message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable all core modules.
|
||||
*/
|
||||
protected function enableAllCoreModules() {
|
||||
$listing = new ExtensionDiscovery(\Drupal::root());
|
||||
$module_list = $listing->scan('module', FALSE);
|
||||
/** @var \Drupal\Core\Extension\ModuleHandlerInterface $module_handler */
|
||||
$module_handler = $this->container->get('module_handler');
|
||||
$module_list = array_filter(array_keys($module_list), function ($module) use ($module_handler, $module_list) {
|
||||
return !$module_handler->moduleExists($module) && substr($module_list[$module]->getPath(), 0, 4) === 'core';
|
||||
});
|
||||
$this->enableModules($module_list);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,97 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\field\Kernel;
|
||||
|
||||
/**
|
||||
* Tests field validation.
|
||||
*
|
||||
* @group field
|
||||
*/
|
||||
class FieldValidationTest extends FieldKernelTestBase {
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $entityType;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $bundle;
|
||||
|
||||
/**
|
||||
* @var \Drupal\Core\Entity\EntityInterface
|
||||
*/
|
||||
private $entity;
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
// Create a field and storage of type 'test_field', on the 'entity_test'
|
||||
// entity type.
|
||||
$this->entityType = 'entity_test';
|
||||
$this->bundle = 'entity_test';
|
||||
$this->createFieldWithStorage('', $this->entityType, $this->bundle);
|
||||
|
||||
// Create an 'entity_test' entity.
|
||||
$this->entity = entity_create($this->entityType, array(
|
||||
'type' => $this->bundle,
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that the number of values is validated against the field cardinality.
|
||||
*/
|
||||
function testCardinalityConstraint() {
|
||||
$cardinality = $this->fieldTestData->field_storage->getCardinality();
|
||||
$entity = $this->entity;
|
||||
|
||||
for ($delta = 0; $delta < $cardinality + 1; $delta++) {
|
||||
$entity->{$this->fieldTestData->field_name}[] = array('value' => 1);
|
||||
}
|
||||
|
||||
// Validate the field.
|
||||
$violations = $entity->{$this->fieldTestData->field_name}->validate();
|
||||
|
||||
// Check that the expected constraint violations are reported.
|
||||
$this->assertEqual(count($violations), 1);
|
||||
$this->assertEqual($violations[0]->getPropertyPath(), '');
|
||||
$this->assertEqual($violations[0]->getMessage(), t('%name: this field cannot hold more than @count values.', array('%name' => $this->fieldTestData->field->getLabel(), '@count' => $cardinality)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that constraints defined by the field type are validated.
|
||||
*/
|
||||
function testFieldConstraints() {
|
||||
$cardinality = $this->fieldTestData->field_storage->getCardinality();
|
||||
$entity = $this->entity;
|
||||
|
||||
// The test is only valid if the field cardinality is greater than 2.
|
||||
$this->assertTrue($cardinality >= 2);
|
||||
|
||||
// Set up values for the field.
|
||||
$expected_violations = array();
|
||||
for ($delta = 0; $delta < $cardinality; $delta++) {
|
||||
// All deltas except '1' have incorrect values.
|
||||
if ($delta == 1) {
|
||||
$value = 1;
|
||||
}
|
||||
else {
|
||||
$value = -1;
|
||||
$expected_violations[$delta . '.value'][] = t('%name does not accept the value -1.', array('%name' => $this->fieldTestData->field->getLabel()));
|
||||
}
|
||||
$entity->{$this->fieldTestData->field_name}[] = $value;
|
||||
}
|
||||
|
||||
// Validate the field.
|
||||
$violations = $entity->{$this->fieldTestData->field_name}->validate();
|
||||
|
||||
// Check that the expected constraint violations are reported.
|
||||
$violations_by_path = array();
|
||||
foreach ($violations as $violation) {
|
||||
$violations_by_path[$violation->getPropertyPath()][] = $violation->getMessage();
|
||||
}
|
||||
$this->assertEqual($violations_by_path, $expected_violations);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\field\Kernel;
|
||||
|
||||
use Drupal\Core\Field\BaseFieldDefinition;
|
||||
|
||||
/**
|
||||
* Tests the field formatter plugin manager.
|
||||
*
|
||||
* @group field
|
||||
*/
|
||||
class FormatterPluginManagerTest extends FieldKernelTestBase {
|
||||
|
||||
/**
|
||||
* Tests that getInstance falls back on default if current is not applicable.
|
||||
*
|
||||
* @see \Drupal\field\Tests\WidgetPluginManagerTest::testNotApplicableFallback()
|
||||
*/
|
||||
public function testNotApplicableFallback() {
|
||||
/** @var \Drupal\Core\Field\FormatterPluginManager $formatter_plugin_manager */
|
||||
$formatter_plugin_manager = \Drupal::service('plugin.manager.field.formatter');
|
||||
|
||||
$base_field_definition = BaseFieldDefinition::create('test_field')
|
||||
// Set a name that will make isApplicable() return TRUE.
|
||||
->setName('field_test_field');
|
||||
|
||||
$formatter_options = array(
|
||||
'field_definition' => $base_field_definition,
|
||||
'view_mode' => 'default',
|
||||
'configuration' => array(
|
||||
'type' => 'field_test_applicable',
|
||||
),
|
||||
);
|
||||
|
||||
$instance = $formatter_plugin_manager->getInstance($formatter_options);
|
||||
$this->assertEqual($instance->getPluginId(), 'field_test_applicable');
|
||||
|
||||
// Now set name to something that makes isApplicable() return FALSE.
|
||||
$base_field_definition->setName('deny_applicable');
|
||||
$instance = $formatter_plugin_manager->getInstance($formatter_options);
|
||||
|
||||
// Instance should be default widget.
|
||||
$this->assertNotEqual($instance->getPluginId(), 'field_test_applicable');
|
||||
$this->assertEqual($instance->getPluginId(), 'field_test_default');
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,181 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\field\Kernel\Migrate\d6;
|
||||
|
||||
use Drupal\Core\Entity\Entity\EntityViewDisplay;
|
||||
use Drupal\Tests\migrate_drupal\Kernel\d6\MigrateDrupal6TestBase;
|
||||
|
||||
/**
|
||||
* Upgrade field formatter settings to entity.display.*.*.yml.
|
||||
*
|
||||
* @group migrate_drupal_6
|
||||
*/
|
||||
class MigrateFieldFormatterSettingsTest extends MigrateDrupal6TestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$this->migrateFields();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that migrated entity display settings can be loaded using D8 API's.
|
||||
*/
|
||||
public function testEntityDisplaySettings() {
|
||||
// Run tests.
|
||||
$field_name = "field_test";
|
||||
$expected = array(
|
||||
'label' => 'above',
|
||||
'weight' => 1,
|
||||
'type' => 'text_trimmed',
|
||||
'settings' => array('trim_length' => 600),
|
||||
'third_party_settings' => array(),
|
||||
);
|
||||
|
||||
// Can we load any entity display.
|
||||
$display = EntityViewDisplay::load('node.story.teaser');
|
||||
$this->assertIdentical($expected, $display->getComponent($field_name));
|
||||
|
||||
// Test migrate worked with multiple bundles.
|
||||
$display = EntityViewDisplay::load('node.test_page.teaser');
|
||||
$expected['weight'] = 35;
|
||||
$this->assertIdentical($expected, $display->getComponent($field_name));
|
||||
|
||||
// Test RSS because that has been converted from 4 to rss.
|
||||
$display = EntityViewDisplay::load('node.story.rss');
|
||||
$expected['weight'] = 1;
|
||||
$this->assertIdentical($expected, $display->getComponent($field_name));
|
||||
|
||||
// Test the default format with text_default which comes from a static map.
|
||||
$expected['type'] = 'text_default';
|
||||
$expected['settings'] = array();
|
||||
$display = EntityViewDisplay::load('node.story.default');
|
||||
$this->assertIdentical($expected, $display->getComponent($field_name));
|
||||
|
||||
// Check that we can migrate multiple fields.
|
||||
$content = $display->get('content');
|
||||
$this->assertTrue(isset($content['field_test']), 'Settings for field_test exist.');
|
||||
$this->assertTrue(isset($content['field_test_two']), "Settings for field_test_two exist.");
|
||||
|
||||
// Check that we can migrate a field where exclude is not set.
|
||||
$this->assertTrue(isset($content['field_test_exclude_unset']), "Settings for field_test_exclude_unset exist.");
|
||||
|
||||
// Test the number field formatter settings are correct.
|
||||
$expected['weight'] = 1;
|
||||
$expected['type'] = 'number_integer';
|
||||
$expected['settings'] = array(
|
||||
'thousand_separator' => ',',
|
||||
'prefix_suffix' => TRUE,
|
||||
);
|
||||
$component = $display->getComponent('field_test_two');
|
||||
$this->assertIdentical($expected, $component);
|
||||
$expected['weight'] = 2;
|
||||
$expected['type'] = 'number_decimal';
|
||||
$expected['settings'] = array(
|
||||
'scale' => 2,
|
||||
'decimal_separator' => '.',
|
||||
'thousand_separator' => ',',
|
||||
'prefix_suffix' => TRUE,
|
||||
);
|
||||
$component = $display->getComponent('field_test_three');
|
||||
$this->assertIdentical($expected, $component);
|
||||
|
||||
// Test the email field formatter settings are correct.
|
||||
$expected['weight'] = 6;
|
||||
$expected['type'] = 'email_mailto';
|
||||
$expected['settings'] = array();
|
||||
$component = $display->getComponent('field_test_email');
|
||||
$this->assertIdentical($expected, $component);
|
||||
|
||||
// Test the link field formatter settings.
|
||||
$expected['weight'] = 7;
|
||||
$expected['type'] = 'link';
|
||||
$expected['settings'] = array(
|
||||
'trim_length' => 80,
|
||||
'url_only' => TRUE,
|
||||
'url_plain' => TRUE,
|
||||
'rel' => '0',
|
||||
'target' => '0',
|
||||
);
|
||||
$component = $display->getComponent('field_test_link');
|
||||
$this->assertIdentical($expected, $component);
|
||||
$expected['settings']['url_only'] = FALSE;
|
||||
$expected['settings']['url_plain'] = FALSE;
|
||||
$display = EntityViewDisplay::load('node.story.teaser');
|
||||
$component = $display->getComponent('field_test_link');
|
||||
$this->assertIdentical($expected, $component);
|
||||
|
||||
// Test the file field formatter settings.
|
||||
$expected['weight'] = 8;
|
||||
$expected['type'] = 'file_default';
|
||||
$expected['settings'] = array();
|
||||
$component = $display->getComponent('field_test_filefield');
|
||||
$this->assertIdentical($expected, $component);
|
||||
$display = EntityViewDisplay::load('node.story.default');
|
||||
$expected['type'] = 'file_url_plain';
|
||||
$component = $display->getComponent('field_test_filefield');
|
||||
$this->assertIdentical($expected, $component);
|
||||
|
||||
// Test the image field formatter settings.
|
||||
$expected['weight'] = 9;
|
||||
$expected['type'] = 'image';
|
||||
$expected['settings'] = array('image_style' => '', 'image_link' => '');
|
||||
$component = $display->getComponent('field_test_imagefield');
|
||||
$this->assertIdentical($expected, $component);
|
||||
$display = EntityViewDisplay::load('node.story.teaser');
|
||||
$expected['settings']['image_link'] = 'file';
|
||||
$component = $display->getComponent('field_test_imagefield');
|
||||
$this->assertIdentical($expected, $component);
|
||||
|
||||
// Test phone field.
|
||||
$expected['weight'] = 13;
|
||||
$expected['type'] = 'basic_string';
|
||||
$expected['settings'] = array();
|
||||
$component = $display->getComponent('field_test_phone');
|
||||
$this->assertIdentical($expected, $component);
|
||||
|
||||
// Test date field.
|
||||
$defaults = array('format_type' => 'fallback', 'timezone_override' => '',);
|
||||
$expected['weight'] = 10;
|
||||
$expected['type'] = 'datetime_default';
|
||||
$expected['settings'] = array('format_type' => 'fallback') + $defaults;
|
||||
$component = $display->getComponent('field_test_date');
|
||||
$this->assertIdentical($expected, $component);
|
||||
$display = EntityViewDisplay::load('node.story.default');
|
||||
$expected['settings']['format_type'] = 'long';
|
||||
$component = $display->getComponent('field_test_date');
|
||||
$this->assertIdentical($expected, $component);
|
||||
|
||||
// Test date stamp field.
|
||||
$expected['weight'] = 11;
|
||||
$expected['settings']['format_type'] = 'fallback';
|
||||
$component = $display->getComponent('field_test_datestamp');
|
||||
$this->assertIdentical($expected, $component);
|
||||
$display = EntityViewDisplay::load('node.story.teaser');
|
||||
$expected['settings'] = array('format_type' => 'medium') + $defaults;
|
||||
$component = $display->getComponent('field_test_datestamp');
|
||||
$this->assertIdentical($expected, $component);
|
||||
|
||||
// Test datetime field.
|
||||
$expected['weight'] = 12;
|
||||
$expected['settings'] = array('format_type' => 'short') + $defaults;
|
||||
$component = $display->getComponent('field_test_datetime');
|
||||
$this->assertIdentical($expected, $component);
|
||||
$display = EntityViewDisplay::load('node.story.default');
|
||||
$expected['settings']['format_type'] = 'fallback';
|
||||
$component = $display->getComponent('field_test_datetime');
|
||||
$this->assertIdentical($expected, $component);
|
||||
|
||||
// Test a date field with a random format which should be mapped
|
||||
// to datetime_default.
|
||||
$display = EntityViewDisplay::load('node.story.rss');
|
||||
$expected['settings']['format_type'] = 'fallback';
|
||||
$component = $display->getComponent('field_test_datetime');
|
||||
$this->assertIdentical($expected, $component);
|
||||
// Test that our Id map has the correct data.
|
||||
$this->assertIdentical(array('node', 'story', 'teaser', 'field_test'), $this->getMigration('d6_field_formatter_settings')->getIdMap()->lookupDestinationID(array('story', 'teaser', 'node', 'field_test')));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,117 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\field\Kernel\Migrate\d6;
|
||||
|
||||
use Drupal\field\Entity\FieldConfig;
|
||||
use Drupal\link\LinkItemInterface;
|
||||
use Drupal\Tests\migrate_drupal\Kernel\d6\MigrateDrupal6TestBase;
|
||||
use Drupal\node\Entity\Node;
|
||||
|
||||
/**
|
||||
* Migrate field instances.
|
||||
*
|
||||
* @group migrate_drupal_6
|
||||
*/
|
||||
class MigrateFieldInstanceTest extends MigrateDrupal6TestBase {
|
||||
|
||||
/**
|
||||
* Tests migration of file variables to file.settings.yml.
|
||||
*/
|
||||
public function testFieldInstanceMigration() {
|
||||
$this->migrateFields();
|
||||
|
||||
$entity = Node::create(['type' => 'story']);
|
||||
// Test a text field.
|
||||
/** @var \Drupal\field\FieldConfigInterface $field */
|
||||
$field = FieldConfig::load('node.story.field_test');
|
||||
$this->assertIdentical('Text Field', $field->label());
|
||||
// field_test is a text_long field, which have no settings.
|
||||
$this->assertIdentical([], $field->getSettings());
|
||||
$this->assertIdentical('text for default value', $entity->field_test->value);
|
||||
|
||||
// Test a number field.
|
||||
$field = FieldConfig::load('node.story.field_test_two');
|
||||
$this->assertIdentical('Integer Field', $field->label());
|
||||
$expected = array(
|
||||
'min' => 10,
|
||||
'max' => 100,
|
||||
'prefix' => 'pref',
|
||||
'suffix' => 'suf',
|
||||
'unsigned' => FALSE,
|
||||
'size' => 'normal',
|
||||
);
|
||||
$this->assertIdentical($expected, $field->getSettings());
|
||||
|
||||
$field = FieldConfig::load('node.story.field_test_four');
|
||||
$this->assertIdentical('Float Field', $field->label());
|
||||
$expected = array(
|
||||
'min' => 100.0,
|
||||
'max' => 200.0,
|
||||
'prefix' => 'id-',
|
||||
'suffix' => '',
|
||||
);
|
||||
$this->assertIdentical($expected, $field->getSettings());
|
||||
|
||||
// Test email field.
|
||||
$field = FieldConfig::load('node.story.field_test_email');
|
||||
$this->assertIdentical('Email Field', $field->label());
|
||||
$this->assertIdentical('benjy@example.com', $entity->field_test_email->value);
|
||||
|
||||
// Test image field.
|
||||
$field = FieldConfig::load('node.story.field_test_imagefield');
|
||||
$this->assertIdentical('Image Field', $field->label());
|
||||
$field_settings = $field->getSettings();
|
||||
$this->assertIdentical('', $field_settings['max_resolution']);
|
||||
$this->assertIdentical('', $field_settings['min_resolution']);
|
||||
$this->assertIdentical('', $field_settings['file_directory']);
|
||||
$this->assertIdentical('png gif jpg jpeg', $field_settings['file_extensions']);
|
||||
$this->assertIdentical('public', $field_settings['uri_scheme']);
|
||||
|
||||
// Test a filefield.
|
||||
$field = FieldConfig::load('node.story.field_test_filefield');
|
||||
$this->assertIdentical('File Field', $field->label());
|
||||
$expected = array(
|
||||
'file_extensions' => 'txt pdf doc',
|
||||
'file_directory' => 'images',
|
||||
'description_field' => TRUE,
|
||||
'max_filesize' => '200KB',
|
||||
'target_type' => 'file',
|
||||
'display_field' => FALSE,
|
||||
'display_default' => FALSE,
|
||||
'uri_scheme' => 'public',
|
||||
'handler' => 'default:file',
|
||||
'handler_settings' => array(),
|
||||
);
|
||||
$field_settings = $field->getSettings();
|
||||
ksort($expected);
|
||||
ksort($field_settings);
|
||||
// This is the only way to compare arrays.
|
||||
$this->assertIdentical($expected, $field_settings);
|
||||
|
||||
// Test a link field.
|
||||
$field = FieldConfig::load('node.story.field_test_link');
|
||||
$this->assertIdentical('Link Field', $field->label());
|
||||
$expected = array('title' => 2, 'link_type' => LinkItemInterface::LINK_GENERIC);
|
||||
$this->assertIdentical($expected, $field->getSettings());
|
||||
$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']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests migrating fields into non-existent content types.
|
||||
*/
|
||||
public function testMigrateFieldIntoUnknownNodeType() {
|
||||
$this->sourceDatabase->delete('node_type')
|
||||
->condition('type', 'test_planet')
|
||||
->execute();
|
||||
// The field migrations use the migration plugin to ensure that the node
|
||||
// types exist, so this should produce no failures...
|
||||
$this->migrateFields();
|
||||
|
||||
// ...and the field instances should not have been migrated.
|
||||
$this->assertNull(FieldConfig::load('node.test_planet.field_multivalue'));
|
||||
$this->assertNull(FieldConfig::load('node.test_planet.field_test_text_single_checkbox'));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,107 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\field\Kernel\Migrate\d6;
|
||||
|
||||
use Drupal\field\Entity\FieldStorageConfig;
|
||||
use Drupal\Tests\migrate_drupal\Kernel\d6\MigrateDrupal6TestBase;
|
||||
|
||||
/**
|
||||
* Migrate fields.
|
||||
*
|
||||
* @group migrate_drupal_6
|
||||
*/
|
||||
class MigrateFieldTest extends MigrateDrupal6TestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$this->executeMigration('d6_field');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the Drupal 6 field to Drupal 8 migration.
|
||||
*/
|
||||
public function testFields() {
|
||||
// Text field.
|
||||
/** @var \Drupal\field\Entity\FieldStorageConfig $field_storage */
|
||||
$field_storage = FieldStorageConfig::load('node.field_test');
|
||||
$this->assertIdentical('text_long', $field_storage->getType());
|
||||
// text_long fields do not have settings.
|
||||
$this->assertIdentical([], $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.', array('@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.', array('@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.', array('@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.', array('@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.', array('@fieldtype' => $field_storage->getType())));
|
||||
$settings = $field_storage->getSettings();
|
||||
$this->assertIdentical('file', $settings['target_type']);
|
||||
$this->assertIdentical('public', $settings['uri_scheme']);
|
||||
$this->assertIdentical(array(), 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.', array('@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.', array('@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.', array('@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'));
|
||||
|
||||
// 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.', array('@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.', array('@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'));
|
||||
|
||||
// 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.', array('@fieldtype' => $field_storage->getType())));
|
||||
|
||||
// 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());
|
||||
|
||||
// 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');
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,100 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\field\Kernel\Migrate\d6;
|
||||
|
||||
use Drupal\Core\Entity\Entity\EntityFormDisplay;
|
||||
use Drupal\Tests\migrate_drupal\Kernel\d6\MigrateDrupal6TestBase;
|
||||
|
||||
/**
|
||||
* Migrate field widget settings.
|
||||
*
|
||||
* @group migrate_drupal_6
|
||||
*/
|
||||
class MigrateFieldWidgetSettingsTest extends MigrateDrupal6TestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$this->migrateFields();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that migrated view modes can be loaded using D8 API's.
|
||||
*/
|
||||
public function testWidgetSettings() {
|
||||
// Test the config can be loaded.
|
||||
$form_display = EntityFormDisplay::load('node.story.default');
|
||||
$this->assertIdentical(FALSE, is_null($form_display), "Form display node.story.default loaded with config.");
|
||||
|
||||
// Text field.
|
||||
$component = $form_display->getComponent('field_test');
|
||||
$expected = array('weight' => 1, 'type' => 'text_textfield');
|
||||
$expected['settings'] = array('size' => 60, 'placeholder' => '');
|
||||
$expected['third_party_settings'] = array();
|
||||
$this->assertIdentical($expected, $component, 'Text field settings are correct.');
|
||||
|
||||
// Integer field.
|
||||
$component = $form_display->getComponent('field_test_two');
|
||||
$expected['type'] = 'number';
|
||||
$expected['weight'] = 1;
|
||||
$expected['settings'] = array('placeholder' => '');
|
||||
$this->assertIdentical($expected, $component);
|
||||
|
||||
// Float field.
|
||||
$component = $form_display->getComponent('field_test_three');
|
||||
$expected['weight'] = 2;
|
||||
$this->assertIdentical($expected, $component);
|
||||
|
||||
// Email field.
|
||||
$component = $form_display->getComponent('field_test_email');
|
||||
$expected['type'] = 'email_default';
|
||||
$expected['weight'] = 6;
|
||||
$expected['settings'] = array('placeholder' => '', 'size' => 60);
|
||||
$this->assertIdentical($expected, $component);
|
||||
|
||||
// Link field.
|
||||
$component = $form_display->getComponent('field_test_link');
|
||||
$this->assertIdentical('link_default', $component['type']);
|
||||
$this->assertIdentical(7, $component['weight']);
|
||||
$this->assertFalse(array_filter($component['settings']));
|
||||
|
||||
// File field.
|
||||
$component = $form_display->getComponent('field_test_filefield');
|
||||
$expected['type'] = 'file_generic';
|
||||
$expected['weight'] = 8;
|
||||
$expected['settings'] = array('progress_indicator' => 'bar');
|
||||
$this->assertIdentical($expected, $component);
|
||||
|
||||
// Image field.
|
||||
$component = $form_display->getComponent('field_test_imagefield');
|
||||
$expected['type'] = 'image_image';
|
||||
$expected['weight'] = 9;
|
||||
$expected['settings'] = array('progress_indicator' => 'bar', 'preview_image_style' => 'thumbnail');
|
||||
$this->assertIdentical($expected, $component);
|
||||
|
||||
// Phone field.
|
||||
$component = $form_display->getComponent('field_test_phone');
|
||||
$expected['type'] = 'telephone_default';
|
||||
$expected['weight'] = 13;
|
||||
$expected['settings'] = array('placeholder' => '');
|
||||
$this->assertIdentical($expected, $component);
|
||||
|
||||
// Date fields.
|
||||
$component = $form_display->getComponent('field_test_date');
|
||||
$expected['type'] = 'datetime_default';
|
||||
$expected['weight'] = 10;
|
||||
$expected['settings'] = array();
|
||||
$this->assertIdentical($expected, $component);
|
||||
|
||||
$component = $form_display->getComponent('field_test_datestamp');
|
||||
$expected['weight'] = 11;
|
||||
$this->assertIdentical($expected, $component);
|
||||
|
||||
$component = $form_display->getComponent('field_test_datetime');
|
||||
$expected['weight'] = 12;
|
||||
$this->assertIdentical($expected, $component);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,289 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\field\Kernel\Migrate\d7;
|
||||
|
||||
use Drupal\comment\Entity\CommentType;
|
||||
use Drupal\Core\Database\Database;
|
||||
use Drupal\Core\Entity\Display\EntityViewDisplayInterface;
|
||||
use Drupal\Core\Entity\Entity\EntityViewDisplay;
|
||||
use Drupal\taxonomy\Entity\Vocabulary;
|
||||
use Drupal\Tests\migrate_drupal\Kernel\d7\MigrateDrupal7TestBase;
|
||||
use Drupal\node\Entity\NodeType;
|
||||
|
||||
/**
|
||||
* Tests migration of D7 field formatter settings.
|
||||
*
|
||||
* @group field
|
||||
*/
|
||||
class MigrateFieldFormatterSettingsTest extends MigrateDrupal7TestBase {
|
||||
|
||||
public static $modules = [
|
||||
'comment',
|
||||
'datetime',
|
||||
'file',
|
||||
'image',
|
||||
'link',
|
||||
'node',
|
||||
'taxonomy',
|
||||
'telephone',
|
||||
'text',
|
||||
];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$this->installEntitySchema('node');
|
||||
$this->installEntitySchema('comment');
|
||||
$this->installEntitySchema('taxonomy_term');
|
||||
|
||||
CommentType::create([
|
||||
'id' => 'comment_node_page',
|
||||
'label' => $this->randomMachineName(),
|
||||
])->save();
|
||||
CommentType::create([
|
||||
'id' => 'comment_node_article',
|
||||
'label' => $this->randomMachineName(),
|
||||
])->save();
|
||||
CommentType::create([
|
||||
'id' => 'comment_node_blog',
|
||||
'label' => $this->randomMachineName(),
|
||||
])->save();
|
||||
CommentType::create([
|
||||
'id' => 'comment_node_book',
|
||||
'label' => $this->randomMachineName(),
|
||||
])->save();
|
||||
CommentType::create([
|
||||
'id' => 'comment_node_forum',
|
||||
'label' => $this->randomMachineName(),
|
||||
])->save();
|
||||
CommentType::create([
|
||||
'id' => 'comment_node_test_content_type',
|
||||
'label' => $this->randomMachineName(),
|
||||
])->save();
|
||||
|
||||
NodeType::create([
|
||||
'type' => 'page',
|
||||
'label' => $this->randomMachineName(),
|
||||
])->save();
|
||||
NodeType::create([
|
||||
'type' => 'article',
|
||||
'label' => $this->randomMachineName(),
|
||||
])->save();
|
||||
NodeType::create([
|
||||
'type' => 'blog',
|
||||
'label' => $this->randomMachineName(),
|
||||
])->save();
|
||||
NodeType::create([
|
||||
'type' => 'book',
|
||||
'label' => $this->randomMachineName(),
|
||||
])->save();
|
||||
NodeType::create([
|
||||
'type' => 'forum',
|
||||
'label' => $this->randomMachineName(),
|
||||
])->save();
|
||||
NodeType::create([
|
||||
'type' => 'test_content_type',
|
||||
'label' => $this->randomMachineName(),
|
||||
])->save();
|
||||
|
||||
Vocabulary::create(['vid' => 'test_vocabulary'])->save();
|
||||
|
||||
// Give one unfortunate field instance invalid display settings to ensure
|
||||
// that the migration provides an empty array as a default (thus avoiding
|
||||
// an "unsupported operand types" fatal).
|
||||
Database::getConnection('default', 'migrate')
|
||||
->update('field_config_instance')
|
||||
->fields(array(
|
||||
'data' => serialize(array (
|
||||
'label' => 'Body',
|
||||
'widget' =>
|
||||
array (
|
||||
'type' => 'text_textarea_with_summary',
|
||||
'settings' =>
|
||||
array (
|
||||
'rows' => 20,
|
||||
'summary_rows' => 5,
|
||||
),
|
||||
'weight' => -4,
|
||||
'module' => 'text',
|
||||
),
|
||||
'settings' =>
|
||||
array (
|
||||
'display_summary' => TRUE,
|
||||
'text_processing' => 1,
|
||||
'user_register_form' => FALSE,
|
||||
),
|
||||
'display' =>
|
||||
array (
|
||||
'default' =>
|
||||
array (
|
||||
'label' => 'hidden',
|
||||
'type' => 'text_default',
|
||||
'settings' =>
|
||||
array (
|
||||
),
|
||||
'module' => 'text',
|
||||
'weight' => 0,
|
||||
),
|
||||
'teaser' =>
|
||||
array (
|
||||
'label' => 'hidden',
|
||||
'type' => 'text_summary_or_trimmed',
|
||||
// settings is always expected to be an array. Making it NULL
|
||||
// causes a fatal.
|
||||
'settings' => NULL,
|
||||
'module' => 'text',
|
||||
'weight' => 0,
|
||||
),
|
||||
),
|
||||
'required' => FALSE,
|
||||
'description' => '',
|
||||
)),
|
||||
))
|
||||
->condition('entity_type', 'node')
|
||||
->condition('bundle', 'article')
|
||||
->condition('field_name', 'body')
|
||||
->execute();
|
||||
|
||||
$this->executeMigrations([
|
||||
'd7_field',
|
||||
'd7_field_instance',
|
||||
'd7_view_modes',
|
||||
'd7_field_formatter_settings',
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts various aspects of a view display.
|
||||
*
|
||||
* @param string $id
|
||||
* The view display ID.
|
||||
*/
|
||||
protected function assertEntity($id) {
|
||||
$display = EntityViewDisplay::load($id);
|
||||
$this->assertTrue($display instanceof EntityViewDisplayInterface);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts various aspects of a particular component of a view display.
|
||||
*
|
||||
* @param string $display_id
|
||||
* The view display ID.
|
||||
* @param string $component_id
|
||||
* The component ID.
|
||||
* @param string $type
|
||||
* The expected component type (formatter plugin ID).
|
||||
* @param string $label
|
||||
* The expected label of the component.
|
||||
* @param int $weight
|
||||
* The expected weight of the component.
|
||||
*/
|
||||
protected function assertComponent($display_id, $component_id, $type, $label, $weight) {
|
||||
$component = EntityViewDisplay::load($display_id)->getComponent($component_id);
|
||||
$this->assertTrue(is_array($component));
|
||||
$this->assertIdentical($type, $component['type']);
|
||||
$this->assertIdentical($label, $component['label']);
|
||||
$this->assertIdentical($weight, $component['weight']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that a particular component is NOT included in a display.
|
||||
*
|
||||
* @param string $display_id
|
||||
* The display ID.
|
||||
* @param string $component_id
|
||||
* The component ID.
|
||||
*/
|
||||
protected function assertComponentNotExists($display_id, $component_id) {
|
||||
$component = EntityViewDisplay::load($display_id)->getComponent($component_id);
|
||||
$this->assertTrue(is_null($component));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests migration of D7 field formatter settings.
|
||||
*/
|
||||
public function testMigration() {
|
||||
$this->assertEntity('comment.comment_node_article.default');
|
||||
$this->assertComponent('comment.comment_node_article.default', 'comment_body', 'text_default', 'hidden', 0);
|
||||
|
||||
$this->assertEntity('comment.comment_node_blog.default');
|
||||
$this->assertComponent('comment.comment_node_blog.default', 'comment_body', 'text_default', 'hidden', 0);
|
||||
|
||||
$this->assertEntity('comment.comment_node_book.default');
|
||||
$this->assertComponent('comment.comment_node_book.default', 'comment_body', 'text_default', 'hidden', 0);
|
||||
|
||||
$this->assertEntity('comment.comment_node_forum.default');
|
||||
$this->assertComponent('comment.comment_node_forum.default', 'comment_body', 'text_default', 'hidden', 0);
|
||||
|
||||
$this->assertEntity('comment.comment_node_page.default');
|
||||
$this->assertComponent('comment.comment_node_page.default', 'comment_body', 'text_default', 'hidden', 0);
|
||||
|
||||
$this->assertEntity('comment.comment_node_test_content_type.default');
|
||||
$this->assertComponent('comment.comment_node_test_content_type.default', 'comment_body', 'text_default', 'hidden', 0);
|
||||
$this->assertComponent('comment.comment_node_test_content_type.default', 'field_integer', 'number_integer', 'above', 1);
|
||||
|
||||
$this->assertEntity('node.article.default');
|
||||
$this->assertComponent('node.article.default', 'body', 'text_default', 'hidden', 0);
|
||||
$this->assertComponent('node.article.default', 'field_tags', 'entity_reference_label', 'above', 10);
|
||||
$this->assertComponent('node.article.default', 'field_image', 'image', 'hidden', -1);
|
||||
|
||||
$this->assertEntity('node.article.teaser');
|
||||
$this->assertComponent('node.article.teaser', 'body', 'text_summary_or_trimmed', 'hidden', 0);
|
||||
$this->assertComponent('node.article.teaser', 'field_tags', 'entity_reference_label', 'above', 10);
|
||||
$this->assertComponent('node.article.teaser', 'field_image', 'image', 'hidden', -1);
|
||||
|
||||
$this->assertEntity('node.blog.default');
|
||||
$this->assertComponent('node.blog.default', 'body', 'text_default', 'hidden', 0);
|
||||
|
||||
$this->assertEntity('node.blog.teaser');
|
||||
$this->assertComponent('node.blog.teaser', 'body', 'text_summary_or_trimmed', 'hidden', 0);
|
||||
|
||||
$this->assertEntity('node.book.default');
|
||||
$this->assertComponent('node.book.default', 'body', 'text_default', 'hidden', 0);
|
||||
|
||||
$this->assertEntity('node.book.teaser');
|
||||
$this->assertComponent('node.book.teaser', 'body', 'text_summary_or_trimmed', 'hidden', 0);
|
||||
|
||||
$this->assertEntity('node.forum.default');
|
||||
$this->assertComponent('node.forum.default', 'body', 'text_default', 'hidden', 11);
|
||||
$this->assertComponent('node.forum.default', 'taxonomy_forums', 'entity_reference_label', 'above', 10);
|
||||
|
||||
$this->assertEntity('node.forum.teaser');
|
||||
$this->assertComponent('node.forum.teaser', 'body', 'text_summary_or_trimmed', 'hidden', 11);
|
||||
$this->assertComponent('node.forum.teaser', 'taxonomy_forums', 'entity_reference_label', 'above', 10);
|
||||
|
||||
$this->assertEntity('node.page.default');
|
||||
$this->assertComponent('node.page.default', 'body', 'text_default', 'hidden', 0);
|
||||
|
||||
$this->assertEntity('node.page.teaser');
|
||||
$this->assertComponent('node.page.teaser', 'body', 'text_summary_or_trimmed', 'hidden', 0);
|
||||
|
||||
$this->assertEntity('node.test_content_type.default');
|
||||
$this->assertComponent('node.test_content_type.default', 'field_boolean', 'list_default', 'above', 0);
|
||||
$this->assertComponent('node.test_content_type.default', 'field_email', 'email_mailto', 'above', 1);
|
||||
// Phone formatters are not mapped and should default to basic_string.
|
||||
$this->assertComponent('node.test_content_type.default', 'field_phone', 'basic_string', 'above', 2);
|
||||
$this->assertComponent('node.test_content_type.default', 'field_date', 'datetime_default', 'above', 3);
|
||||
$this->assertComponent('node.test_content_type.default', 'field_date_with_end_time', 'datetime_default', 'above', 4);
|
||||
$this->assertComponent('node.test_content_type.default', 'field_file', 'file_default', 'above', 5);
|
||||
$this->assertComponent('node.test_content_type.default', 'field_float', 'number_decimal', 'above', 6);
|
||||
$this->assertComponent('node.test_content_type.default', 'field_images', 'image', 'above', 7);
|
||||
$this->assertComponent('node.test_content_type.default', 'field_integer', 'number_integer', 'above', 8);
|
||||
$this->assertComponent('node.test_content_type.default', 'field_link', 'link', 'above', 9);
|
||||
$this->assertComponent('node.test_content_type.default', 'field_text_list', 'list_default', 'above', 10);
|
||||
$this->assertComponent('node.test_content_type.default', 'field_integer_list', 'list_default', 'above', 11);
|
||||
$this->assertComponent('node.test_content_type.default', 'field_long_text', 'text_default', 'above', 12);
|
||||
$this->assertComponent('node.test_content_type.default', 'field_node_entityreference', 'entity_reference_label', 'above', 15);
|
||||
$this->assertComponent('node.test_content_type.default', 'field_user_entityreference', 'entity_reference_label', 'above', 16);
|
||||
$this->assertComponent('node.test_content_type.default', 'field_term_entityreference', 'entity_reference_label', 'above', 17);
|
||||
$this->assertComponentNotExists('node.test_content_type.default', 'field_term_reference');
|
||||
$this->assertComponentNotExists('node.test_content_type.default', 'field_text');
|
||||
|
||||
$this->assertEntity('user.user.default');
|
||||
$this->assertComponent('user.user.default', 'field_file', 'file_default', 'above', 0);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,156 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\field\Kernel\Migrate\d7;
|
||||
|
||||
use Drupal\comment\Entity\CommentType;
|
||||
use Drupal\field\Entity\FieldConfig;
|
||||
use Drupal\field\FieldConfigInterface;
|
||||
use Drupal\taxonomy\Entity\Vocabulary;
|
||||
use Drupal\Tests\migrate_drupal\Kernel\d7\MigrateDrupal7TestBase;
|
||||
use Drupal\node\Entity\NodeType;
|
||||
|
||||
/**
|
||||
* Migrates Drupal 7 field instances.
|
||||
*
|
||||
* @group field
|
||||
*/
|
||||
class MigrateFieldInstanceTest extends MigrateDrupal7TestBase {
|
||||
|
||||
/**
|
||||
* The modules to be enabled during the test.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = array(
|
||||
'comment',
|
||||
'datetime',
|
||||
'file',
|
||||
'image',
|
||||
'link',
|
||||
'node',
|
||||
'system',
|
||||
'taxonomy',
|
||||
'telephone',
|
||||
'text',
|
||||
);
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$this->installConfig(static::$modules);
|
||||
$this->createType('page');
|
||||
$this->createType('article');
|
||||
$this->createType('blog');
|
||||
$this->createType('book');
|
||||
$this->createType('forum');
|
||||
$this->createType('test_content_type');
|
||||
Vocabulary::create(['vid' => 'test_vocabulary'])->save();
|
||||
$this->executeMigrations(['d7_field', 'd7_field_instance']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a node type with a corresponding comment type.
|
||||
*
|
||||
* @param string $id
|
||||
* The node type ID.
|
||||
*/
|
||||
protected function createType($id) {
|
||||
NodeType::create(array(
|
||||
'type' => $id,
|
||||
'label' => $this->randomString(),
|
||||
))->save();
|
||||
|
||||
CommentType::create(array(
|
||||
'id' => 'comment_node_' . $id,
|
||||
'label' => $this->randomString(),
|
||||
'target_entity_type_id' => 'node',
|
||||
))->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts various aspects of a field config entity.
|
||||
*
|
||||
* @param string $id
|
||||
* The entity ID in the form ENTITY_TYPE.BUNDLE.FIELD_NAME.
|
||||
* @param string $expected_label
|
||||
* The expected field label.
|
||||
* @param string $expected_field_type
|
||||
* The expected field type.
|
||||
* @param bool $is_required
|
||||
* Whether or not the field is required.
|
||||
*/
|
||||
protected function assertEntity($id, $expected_label, $expected_field_type, $is_required) {
|
||||
list ($expected_entity_type, $expected_bundle, $expected_name) = explode('.', $id);
|
||||
|
||||
/** @var \Drupal\field\FieldConfigInterface $field */
|
||||
$field = FieldConfig::load($id);
|
||||
$this->assertTrue($field instanceof FieldConfigInterface);
|
||||
$this->assertIdentical($expected_label, $field->label());
|
||||
$this->assertIdentical($expected_field_type, $field->getType());
|
||||
$this->assertIdentical($expected_entity_type, $field->getTargetEntityTypeId());
|
||||
$this->assertIdentical($expected_bundle, $field->getTargetBundle());
|
||||
$this->assertIdentical($expected_name, $field->getName());
|
||||
$this->assertEqual($is_required, $field->isRequired());
|
||||
$this->assertIdentical($expected_entity_type . '.' . $expected_name, $field->getFieldStorageDefinition()->id());
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts the settings of a link field config entity.
|
||||
*
|
||||
* @param $id
|
||||
* The entity ID in the form ENTITY_TYPE.BUNDLE.FIELD_NAME.
|
||||
* @param $title_setting
|
||||
* The expected title setting.
|
||||
*/
|
||||
protected function assertLinkFields($id, $title_setting) {
|
||||
$field = FieldConfig::load($id);
|
||||
$this->assertSame($title_setting, $field->getSetting('title'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests migrating D7 field instances to field_config entities.
|
||||
*/
|
||||
public function testFieldInstances() {
|
||||
$this->assertEntity('comment.comment_node_page.comment_body', 'Comment', 'text_long', TRUE);
|
||||
$this->assertEntity('node.page.body', 'Body', 'text_with_summary', FALSE);
|
||||
$this->assertEntity('comment.comment_node_article.comment_body', 'Comment', 'text_long', TRUE);
|
||||
$this->assertEntity('node.article.body', 'Body', 'text_with_summary', FALSE);
|
||||
$this->assertEntity('node.article.field_tags', 'Tags', 'entity_reference', FALSE);
|
||||
$this->assertEntity('node.article.field_image', 'Image', 'image', FALSE);
|
||||
$this->assertEntity('comment.comment_node_blog.comment_body', 'Comment', 'text_long', TRUE);
|
||||
$this->assertEntity('node.blog.body', 'Body', 'text_with_summary', FALSE);
|
||||
$this->assertEntity('comment.comment_node_book.comment_body', 'Comment', 'text_long', TRUE);
|
||||
$this->assertEntity('node.book.body', 'Body', 'text_with_summary', FALSE);
|
||||
$this->assertEntity('node.forum.taxonomy_forums', 'Forums', 'entity_reference', TRUE);
|
||||
$this->assertEntity('comment.comment_node_forum.comment_body', 'Comment', 'text_long', TRUE);
|
||||
$this->assertEntity('node.forum.body', 'Body', 'text_with_summary', FALSE);
|
||||
$this->assertEntity('comment.comment_node_test_content_type.comment_body', 'Comment', 'text_long', TRUE);
|
||||
$this->assertEntity('node.test_content_type.field_boolean', 'Boolean', 'boolean', FALSE);
|
||||
$this->assertEntity('node.test_content_type.field_email', 'Email', 'email', FALSE);
|
||||
$this->assertEntity('node.test_content_type.field_phone', 'Phone', 'telephone', TRUE);
|
||||
$this->assertEntity('node.test_content_type.field_date', 'Date', 'datetime', FALSE);
|
||||
$this->assertEntity('node.test_content_type.field_date_with_end_time', 'Date With End Time', 'datetime', FALSE);
|
||||
$this->assertEntity('node.test_content_type.field_file', 'File', 'file', FALSE);
|
||||
$this->assertEntity('node.test_content_type.field_float', 'Float', 'float', FALSE);
|
||||
$this->assertEntity('node.test_content_type.field_images', 'Images', 'image', TRUE);
|
||||
$this->assertEntity('node.test_content_type.field_integer', 'Integer', 'integer', TRUE);
|
||||
$this->assertEntity('node.test_content_type.field_link', 'Link', 'link', FALSE);
|
||||
$this->assertEntity('node.test_content_type.field_text_list', 'Text List', 'list_string', FALSE);
|
||||
$this->assertEntity('node.test_content_type.field_integer_list', 'Integer List', 'list_integer', FALSE);
|
||||
$this->assertEntity('node.test_content_type.field_long_text', 'Long text', 'text_with_summary', FALSE);
|
||||
$this->assertEntity('node.test_content_type.field_term_reference', 'Term Reference', 'entity_reference', FALSE);
|
||||
$this->assertEntity('node.test_content_type.field_node_entityreference', 'Node Entity Reference', 'entity_reference', FALSE);
|
||||
$this->assertEntity('node.test_content_type.field_user_entityreference', 'User Entity Reference', 'entity_reference', FALSE);
|
||||
$this->assertEntity('node.test_content_type.field_term_entityreference', 'Term Entity Reference', 'entity_reference', FALSE);
|
||||
$this->assertEntity('node.test_content_type.field_text', 'Text', 'text', FALSE);
|
||||
$this->assertEntity('comment.comment_node_test_content_type.field_integer', 'Integer', 'integer', FALSE);
|
||||
$this->assertEntity('user.user.field_file', 'File', 'file', FALSE);
|
||||
|
||||
$this->assertLinkFields('node.test_content_type.field_link', DRUPAL_OPTIONAL);
|
||||
$this->assertLinkFields('node.article.field_link', DRUPAL_DISABLED);
|
||||
$this->assertLinkFields('node.blog.field_link', DRUPAL_REQUIRED);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,145 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\field\Kernel\Migrate\d7;
|
||||
|
||||
use Drupal\Core\Entity\Display\EntityFormDisplayInterface;
|
||||
use Drupal\Core\Entity\Entity\EntityFormDisplay;
|
||||
use Drupal\Tests\migrate_drupal\Kernel\d7\MigrateDrupal7TestBase;
|
||||
|
||||
/**
|
||||
* Migrate field widget settings.
|
||||
*
|
||||
* @group field
|
||||
*/
|
||||
class MigrateFieldInstanceWidgetSettingsTest extends MigrateDrupal7TestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = array(
|
||||
'comment',
|
||||
'datetime',
|
||||
'field',
|
||||
'file',
|
||||
'image',
|
||||
'link',
|
||||
'node',
|
||||
'taxonomy',
|
||||
'telephone',
|
||||
'text',
|
||||
);
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$this->installEntitySchema('node');
|
||||
$this->installEntitySchema('comment');
|
||||
$this->installEntitySchema('taxonomy_term');
|
||||
$this->installConfig(static::$modules);
|
||||
|
||||
$this->executeMigrations([
|
||||
'd7_node_type',
|
||||
'd7_comment_type',
|
||||
'd7_taxonomy_vocabulary',
|
||||
'd7_field',
|
||||
'd7_field_instance',
|
||||
'd7_field_instance_widget_settings',
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts various aspects of a form display entity.
|
||||
*
|
||||
* @param string $id
|
||||
* The entity ID.
|
||||
* @param string $expected_entity_type
|
||||
* The expected entity type to which the display settings are attached.
|
||||
* @param string $expected_bundle
|
||||
* The expected bundle to which the display settings are attached.
|
||||
*/
|
||||
protected function assertEntity($id, $expected_entity_type, $expected_bundle) {
|
||||
/** @var \Drupal\Core\Entity\Display\EntityFormDisplayInterface $entity */
|
||||
$entity = EntityFormDisplay::load($id);
|
||||
$this->assertTrue($entity instanceof EntityFormDisplayInterface);
|
||||
$this->assertIdentical($expected_entity_type, $entity->getTargetEntityTypeId());
|
||||
$this->assertIdentical($expected_bundle, $entity->getTargetBundle());
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts various aspects of a particular component of a form display.
|
||||
*
|
||||
* @param string $display_id
|
||||
* The form display ID.
|
||||
* @param string $component_id
|
||||
* The component ID.
|
||||
* @param string $widget_type
|
||||
* The expected widget type.
|
||||
* @param string $weight
|
||||
* The expected weight of the component.
|
||||
*/
|
||||
protected function assertComponent($display_id, $component_id, $widget_type, $weight) {
|
||||
$component = EntityFormDisplay::load($display_id)->getComponent($component_id);
|
||||
$this->assertTrue(is_array($component));
|
||||
$this->assertIdentical($widget_type, $component['type']);
|
||||
$this->assertIdentical($weight, $component['weight']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that migrated view modes can be loaded using D8 APIs.
|
||||
*/
|
||||
public function testWidgetSettings() {
|
||||
$this->assertEntity('node.page.default', 'node', 'page');
|
||||
$this->assertComponent('node.page.default', 'body', 'text_textarea_with_summary', -4);
|
||||
|
||||
$this->assertEntity('node.article.default', 'node', 'article');
|
||||
$this->assertComponent('node.article.default', 'body', 'text_textarea_with_summary', -4);
|
||||
$this->assertComponent('node.article.default', 'field_tags', 'entity_reference_autocomplete', -4);
|
||||
$this->assertComponent('node.article.default', 'field_image', 'image_image', -1);
|
||||
|
||||
$this->assertEntity('node.blog.default', 'node', 'blog');
|
||||
$this->assertComponent('node.blog.default', 'body', 'text_textarea_with_summary', -4);
|
||||
|
||||
$this->assertEntity('node.book.default', 'node', 'book');
|
||||
$this->assertComponent('node.book.default', 'body', 'text_textarea_with_summary', -4);
|
||||
|
||||
$this->assertEntity('node.forum.default', 'node', 'forum');
|
||||
$this->assertComponent('node.forum.default', 'body', 'text_textarea_with_summary', 1);
|
||||
$this->assertComponent('node.forum.default', 'taxonomy_forums', 'options_select', 0);
|
||||
|
||||
$this->assertEntity('node.test_content_type.default', 'node', 'test_content_type');
|
||||
$this->assertComponent('node.test_content_type.default', 'field_boolean', 'boolean_checkbox', 1);
|
||||
$this->assertComponent('node.test_content_type.default', 'field_date', 'datetime_default', 2);
|
||||
$this->assertComponent('node.test_content_type.default', 'field_date_with_end_time', 'datetime_default', 3);
|
||||
$this->assertComponent('node.test_content_type.default', 'field_email', 'email_default', 4);
|
||||
$this->assertComponent('node.test_content_type.default', 'field_file', 'file_generic', 5);
|
||||
$this->assertComponent('node.test_content_type.default', 'field_float', 'number', 7);
|
||||
$this->assertComponent('node.test_content_type.default', 'field_images', 'image_image', 8);
|
||||
$this->assertComponent('node.test_content_type.default', 'field_integer', 'number', 9);
|
||||
$this->assertComponent('node.test_content_type.default', 'field_link', 'link_default', 10);
|
||||
$this->assertComponent('node.test_content_type.default', 'field_integer_list', 'options_buttons', 12);
|
||||
$this->assertComponent('node.test_content_type.default', 'field_long_text', 'text_textarea_with_summary', 13);
|
||||
$this->assertComponent('node.test_content_type.default', 'field_phone', 'telephone_default', 6);
|
||||
$this->assertComponent('node.test_content_type.default', 'field_term_reference', 'entity_reference_autocomplete', 14);
|
||||
$this->assertComponent('node.test_content_type.default', 'field_node_entityreference', 'entity_reference_autocomplete', 16);
|
||||
$this->assertComponent('node.test_content_type.default', 'field_user_entityreference', 'options_buttons', 17);
|
||||
$this->assertComponent('node.test_content_type.default', 'field_term_entityreference', 'entity_reference_autocomplete_tags', 18);
|
||||
$this->assertComponent('node.test_content_type.default', 'field_text', 'text_textfield', 15);
|
||||
$this->assertComponent('node.test_content_type.default', 'field_text_list', 'options_select', 11);
|
||||
|
||||
$this->assertEntity('user.user.default', 'user', 'user');
|
||||
$this->assertComponent('user.user.default', 'field_file', 'file_generic', 8);
|
||||
|
||||
$this->assertEntity('comment.comment_node_test_content_type.default', 'comment', 'comment_node_test_content_type');
|
||||
$this->assertComponent('comment.comment_node_test_content_type.default', 'comment_body', 'text_textarea', 0);
|
||||
$this->assertComponent('comment.comment_node_test_content_type.default', 'field_integer', 'number', 2);
|
||||
|
||||
$this->assertEntity('taxonomy_term.test_vocabulary.default', 'taxonomy_term', 'test_vocabulary');
|
||||
$this->assertComponent('comment.comment_node_test_content_type.default', 'field_integer', 'number', 2);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,129 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\field\Kernel\Migrate\d7;
|
||||
|
||||
use Drupal\field\Entity\FieldStorageConfig;
|
||||
use Drupal\field\FieldStorageConfigInterface;
|
||||
use Drupal\Tests\migrate_drupal\Kernel\d7\MigrateDrupal7TestBase;
|
||||
|
||||
/**
|
||||
* Migrates Drupal 7 fields.
|
||||
*
|
||||
* @group field
|
||||
*/
|
||||
class MigrateFieldTest extends MigrateDrupal7TestBase {
|
||||
|
||||
/**
|
||||
* The modules to be enabled during the test.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = array(
|
||||
'comment',
|
||||
'datetime',
|
||||
'file',
|
||||
'image',
|
||||
'link',
|
||||
'node',
|
||||
'system',
|
||||
'taxonomy',
|
||||
'telephone',
|
||||
'text',
|
||||
);
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$this->installConfig(static::$modules);
|
||||
$this->executeMigration('d7_field');
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts various aspects of a field_storage_config entity.
|
||||
*
|
||||
* @param string $id
|
||||
* The entity ID in the form ENTITY_TYPE.FIELD_NAME.
|
||||
* @param string $expected_type
|
||||
* The expected field type.
|
||||
* @param bool $expected_translatable
|
||||
* Whether or not the field is expected to be translatable.
|
||||
* @param int $expected_cardinality
|
||||
* The expected cardinality of the field.
|
||||
*/
|
||||
protected function assertEntity($id, $expected_type, $expected_translatable, $expected_cardinality) {
|
||||
list ($expected_entity_type, $expected_name) = explode('.', $id);
|
||||
|
||||
/** @var \Drupal\field\FieldStorageConfigInterface $field */
|
||||
$field = FieldStorageConfig::load($id);
|
||||
$this->assertTrue($field instanceof FieldStorageConfigInterface);
|
||||
$this->assertIdentical($expected_name, $field->getName());
|
||||
$this->assertIdentical($expected_type, $field->getType());
|
||||
// FieldStorageConfig::$translatable is TRUE by default, so it is useful
|
||||
// to test for FALSE here.
|
||||
$this->assertEqual($expected_translatable, $field->isTranslatable());
|
||||
$this->assertIdentical($expected_entity_type, $field->getTargetEntityTypeId());
|
||||
|
||||
if ($expected_cardinality === 1) {
|
||||
$this->assertFalse($field->isMultiple());
|
||||
}
|
||||
else {
|
||||
$this->assertTrue($field->isMultiple());
|
||||
}
|
||||
$this->assertIdentical($expected_cardinality, $field->getCardinality());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests migrating D7 fields to field_storage_config entities.
|
||||
*/
|
||||
public function testFields() {
|
||||
$this->assertEntity('node.body', 'text_with_summary', FALSE, 1);
|
||||
$this->assertEntity('node.field_long_text', 'text_with_summary', FALSE, 1);
|
||||
$this->assertEntity('comment.comment_body', 'text_long', FALSE, 1);
|
||||
$this->assertEntity('node.field_file', 'file', FALSE, 1);
|
||||
$this->assertEntity('user.field_file', 'file', FALSE, 1);
|
||||
$this->assertEntity('node.field_float', 'float', FALSE, 1);
|
||||
$this->assertEntity('node.field_image', 'image', FALSE, 1);
|
||||
$this->assertEntity('node.field_images', 'image', FALSE, 1);
|
||||
$this->assertEntity('node.field_integer', 'integer', FALSE, 1);
|
||||
$this->assertEntity('comment.field_integer', 'integer', FALSE, 1);
|
||||
$this->assertEntity('node.field_integer_list', 'list_integer', FALSE, 1);
|
||||
$this->assertEntity('node.field_link', 'link', FALSE, 1);
|
||||
$this->assertEntity('node.field_tags', 'entity_reference', FALSE, -1);
|
||||
$this->assertEntity('node.field_term_reference', 'entity_reference', FALSE, 1);
|
||||
$this->assertEntity('node.taxonomy_forums', 'entity_reference', FALSE, 1);
|
||||
$this->assertEntity('node.field_text', 'text', FALSE, 1);
|
||||
$this->assertEntity('node.field_text_list', 'list_string', FALSE, 3);
|
||||
$this->assertEntity('node.field_boolean', 'boolean', FALSE, 1);
|
||||
$this->assertEntity('node.field_email', 'email', FALSE, -1);
|
||||
$this->assertEntity('node.field_phone', 'telephone', FALSE, 1);
|
||||
$this->assertEntity('node.field_date', 'datetime', FALSE, 1);
|
||||
$this->assertEntity('node.field_date_with_end_time', 'datetime', FALSE, 1);
|
||||
$this->assertEntity('node.field_node_entityreference', 'entity_reference', FALSE, -1);
|
||||
$this->assertEntity('node.field_user_entityreference', 'entity_reference', FALSE, 1);
|
||||
$this->assertEntity('node.field_term_entityreference', 'entity_reference', FALSE, -1);
|
||||
|
||||
// Assert that the taxonomy term reference fields are referencing the
|
||||
// correct entity type.
|
||||
$field = FieldStorageConfig::load('node.field_term_reference');
|
||||
$this->assertIdentical('taxonomy_term', $field->getSetting('target_type'));
|
||||
$field = FieldStorageConfig::load('node.taxonomy_forums');
|
||||
$this->assertIdentical('taxonomy_term', $field->getSetting('target_type'));
|
||||
|
||||
// Assert that the entityreference fields are referencing the correct
|
||||
// entity type.
|
||||
$field = FieldStorageConfig::load('node.field_node_entityreference');
|
||||
$this->assertIdentical('node', $field->getSetting('target_type'));
|
||||
$field = FieldStorageConfig::load('node.field_user_entityreference');
|
||||
$this->assertIdentical('user', $field->getSetting('target_type'));
|
||||
$field = FieldStorageConfig::load('node.field_term_entityreference');
|
||||
$this->assertIdentical('taxonomy_term', $field->getSetting('target_type'));
|
||||
|
||||
// Validate that the source count and processed count match up.
|
||||
/** @var \Drupal\migrate\Plugin\MigrationInterface $migration */
|
||||
$migration = $this->getMigration('d7_field');
|
||||
$this->assertIdentical($migration->getSourcePlugin()->count(), $migration->getIdMap()->processedCount());
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\field\Kernel\Migrate\d7;
|
||||
|
||||
use Drupal\Core\Entity\Entity\EntityViewMode;
|
||||
use Drupal\Core\Entity\EntityViewModeInterface;
|
||||
use Drupal\Tests\migrate_drupal\Kernel\d7\MigrateDrupal7TestBase;
|
||||
|
||||
/**
|
||||
* Tests migration of D7 view modes.
|
||||
*
|
||||
* @group field
|
||||
*/
|
||||
class MigrateViewModesTest extends MigrateDrupal7TestBase {
|
||||
|
||||
public static $modules = ['comment', 'node', 'taxonomy'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$this->installEntitySchema('comment');
|
||||
$this->installEntitySchema('node');
|
||||
$this->executeMigration('d7_view_modes');
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts various aspects of a view mode entity.
|
||||
*
|
||||
* @param string $id
|
||||
* The entity ID.
|
||||
* @param string $label
|
||||
* The expected label of the view mode.
|
||||
* @param string $entity_type
|
||||
* The expected entity type ID which owns the view mode.
|
||||
* @param bool $status
|
||||
* The expected status of the view mode.
|
||||
*/
|
||||
protected function assertEntity($id, $label, $entity_type) {
|
||||
/** @var \Drupal\Core\Entity\EntityViewModeInterface $view_mode */
|
||||
$view_mode = EntityViewMode::load($id);
|
||||
$this->assertTrue($view_mode instanceof EntityViewModeInterface);
|
||||
$this->assertIdentical($label, $view_mode->label());
|
||||
$this->assertIdentical($entity_type, $view_mode->getTargetType());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests migration of D7 view mode variables to D8 config entities.
|
||||
*/
|
||||
public function testMigration() {
|
||||
$this->assertEntity('comment.full', 'Full', 'comment');
|
||||
$this->assertEntity('node.teaser', 'Teaser', 'node');
|
||||
$this->assertEntity('node.full', 'Full', 'node');
|
||||
$this->assertEntity('node.custom', 'custom', 'node');
|
||||
$this->assertEntity('user.full', 'Full', 'user');
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,80 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\field\Kernel\Migrate\d7;
|
||||
|
||||
use Drupal\field\Entity\FieldConfig;
|
||||
use Drupal\migrate\MigrateExecutable;
|
||||
|
||||
/**
|
||||
* Migrates and rolls back Drupal 7 fields.
|
||||
*
|
||||
* @group field
|
||||
*/
|
||||
class RollbackFieldInstanceTest extends MigrateFieldInstanceTest {
|
||||
|
||||
/**
|
||||
* Tests migrating D7 fields to field_storage_config entities, then rolling back.
|
||||
*/
|
||||
public function testFieldInstances() {
|
||||
// Test that the field instances have migrated (prior to rollback).
|
||||
parent::testFieldInstances();
|
||||
|
||||
$this->executeRollback('d7_field_instance');
|
||||
$this->executeRollback('d7_field');
|
||||
|
||||
// Check that field instances have been rolled back.
|
||||
$field_instance_ids = [
|
||||
'comment.comment_node_page.comment_body',
|
||||
'node.page.body',
|
||||
'comment.comment_node_article.comment_body',
|
||||
'node.article.body',
|
||||
'node.article.field_tags',
|
||||
'node.article.field_image',
|
||||
'comment.comment_node_blog.comment_body',
|
||||
'node.blog.body',
|
||||
'comment.comment_node_book.comment_body',
|
||||
'node.book.body',
|
||||
'node.forum.taxonomy_forums',
|
||||
'comment.comment_node_forum.comment_body',
|
||||
'node.forum.body',
|
||||
'comment.comment_node_test_content_type.comment_body',
|
||||
'node.test_content_type.field_boolean',
|
||||
'node.test_content_type.field_email',
|
||||
'node.test_content_type.field_phone',
|
||||
'node.test_content_type.field_date',
|
||||
'node.test_content_type.field_date_with_end_time',
|
||||
'node.test_content_type.field_file',
|
||||
'node.test_content_type.field_float',
|
||||
'node.test_content_type.field_images',
|
||||
'node.test_content_type.field_integer',
|
||||
'node.test_content_type.field_link',
|
||||
'node.test_content_type.field_text_list',
|
||||
'node.test_content_type.field_integer_list',
|
||||
'node.test_content_type.field_long_text',
|
||||
'node.test_content_type.field_term_reference',
|
||||
'node.test_content_type.field_text',
|
||||
'comment.comment_node_test_content_type.field_integer',
|
||||
'user.user.field_file',
|
||||
];
|
||||
foreach ($field_instance_ids as $field_instance_id) {
|
||||
$this->assertNull(FieldConfig::load($field_instance_id));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes a single rollback.
|
||||
*
|
||||
* @param string|\Drupal\migrate\Plugin\MigrationInterface $migration
|
||||
* The migration to rollback, or its ID.
|
||||
*/
|
||||
protected function executeRollback($migration) {
|
||||
if (is_string($migration)) {
|
||||
$this->migration = $this->getMigration($migration);
|
||||
}
|
||||
else {
|
||||
$this->migration = $migration;
|
||||
}
|
||||
(new MigrateExecutable($this->migration, $this))->rollback();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,77 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\field\Kernel\Migrate\d7;
|
||||
|
||||
use Drupal\field\Entity\FieldStorageConfig;
|
||||
use Drupal\migrate\MigrateExecutable;
|
||||
|
||||
/**
|
||||
* Migrates and rolls back Drupal 7 fields.
|
||||
*
|
||||
* @group field
|
||||
*/
|
||||
class RollbackFieldTest extends MigrateFieldTest {
|
||||
|
||||
/**
|
||||
* Tests migrating D7 fields to field_storage_config entities, then rolling back.
|
||||
*/
|
||||
public function testFields() {
|
||||
// Test that the fields have migrated (prior to rollback).
|
||||
parent::testFields();
|
||||
|
||||
$this->executeRollback('d7_field');
|
||||
|
||||
// Check that fields have been rolled back.
|
||||
$rolled_back_field_ids = [
|
||||
'comment.field_integer',
|
||||
'node.taxonomy_forums',
|
||||
'node.field_integer',
|
||||
'node.field_tags',
|
||||
'node.field_term_reference',
|
||||
'node.field_text_list',
|
||||
'node.field_text',
|
||||
'node.field_phone',
|
||||
'node.field_file',
|
||||
'node.field_images',
|
||||
'node.field_image',
|
||||
'node.field_long_text',
|
||||
'node.field_date_with_end_time',
|
||||
'node.field_integer_list',
|
||||
'node.field_date',
|
||||
'node.field_link',
|
||||
'node.field_float',
|
||||
'node.field_boolean',
|
||||
'node.field_email',
|
||||
'user.field_file',
|
||||
];
|
||||
foreach ($rolled_back_field_ids as $field_id) {
|
||||
$this->assertNull(FieldStorageConfig::load($field_id));
|
||||
}
|
||||
|
||||
// Check that fields that should persist have not been rolled back.
|
||||
$non_rolled_back_field_ids = [
|
||||
'node.body',
|
||||
'comment.comment_body',
|
||||
];
|
||||
foreach ($non_rolled_back_field_ids as $field_id) {
|
||||
$this->assertNotNull(FieldStorageConfig::load($field_id));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes a single rollback.
|
||||
*
|
||||
* @param string|\Drupal\migrate\Plugin\MigrationInterface $migration
|
||||
* The migration to rollback, or its ID.
|
||||
*/
|
||||
protected function executeRollback($migration) {
|
||||
if (is_string($migration)) {
|
||||
$this->migration = $this->getMigration($migration);
|
||||
}
|
||||
else {
|
||||
$this->migration = $migration;
|
||||
}
|
||||
(new MigrateExecutable($this->migration, $this))->rollback();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\field\Kernel\Migrate\d7;
|
||||
|
||||
use Drupal\Core\Entity\Entity\EntityViewMode;
|
||||
use Drupal\migrate\MigrateExecutable;
|
||||
|
||||
/**
|
||||
* Migrates and rolls back Drupal 7 view modes.
|
||||
*
|
||||
* @group field
|
||||
*/
|
||||
class RollbackViewModesTest extends MigrateViewModesTest {
|
||||
|
||||
/**
|
||||
* Tests migrating D7 view modes, then rolling back.
|
||||
*/
|
||||
public function testMigration() {
|
||||
// Test that the view modes have migrated (prior to rollback).
|
||||
parent::testMigration();
|
||||
|
||||
$this->executeRollback('d7_view_modes');
|
||||
|
||||
// Check that view modes have been rolled back.
|
||||
$view_mode_ids = [
|
||||
'comment.full',
|
||||
'node.teaser',
|
||||
'node.full',
|
||||
'user.full',
|
||||
];
|
||||
foreach ($view_mode_ids as $view_mode_id) {
|
||||
$this->assertNull(EntityViewMode::load($view_mode_id));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes a single rollback.
|
||||
*
|
||||
* @param string|\Drupal\migrate\Plugin\MigrationInterface $migration
|
||||
* The migration to rollback, or its ID.
|
||||
*/
|
||||
protected function executeRollback($migration) {
|
||||
if (is_string($migration)) {
|
||||
$this->migration = $this->getMigration($migration);
|
||||
}
|
||||
else {
|
||||
$this->migration = $migration;
|
||||
}
|
||||
(new MigrateExecutable($this->migration, $this))->rollback();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,104 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\field\Kernel\Number;
|
||||
|
||||
use Drupal\Core\Field\FieldItemInterface;
|
||||
use Drupal\Core\Field\FieldItemListInterface;
|
||||
use Drupal\entity_test\Entity\EntityTest;
|
||||
use Drupal\field\Entity\FieldConfig;
|
||||
use Drupal\Tests\field\Kernel\FieldKernelTestBase;
|
||||
use Drupal\field\Entity\FieldStorageConfig;
|
||||
|
||||
/**
|
||||
* Tests the new entity API for the number field type.
|
||||
*
|
||||
* @group field
|
||||
*/
|
||||
class NumberItemTest extends FieldKernelTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = array();
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
// Create number field storages and fields for validation.
|
||||
foreach (array('integer', 'float', 'decimal') as $type) {
|
||||
FieldStorageConfig::create(array(
|
||||
'entity_type' => 'entity_test',
|
||||
'field_name' => 'field_' . $type,
|
||||
'type' => $type,
|
||||
))->save();
|
||||
FieldConfig::create([
|
||||
'entity_type' => 'entity_test',
|
||||
'field_name' => 'field_' . $type,
|
||||
'bundle' => 'entity_test',
|
||||
])->save();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests using entity fields of the number field type.
|
||||
*/
|
||||
public function testNumberItem() {
|
||||
// Verify entity creation.
|
||||
$entity = EntityTest::create();
|
||||
$integer = rand(0, 10);
|
||||
$entity->field_integer = $integer;
|
||||
$float = 3.14;
|
||||
$entity->field_float = $float;
|
||||
$entity->field_decimal = '20-40';
|
||||
$violations = $entity->validate();
|
||||
$this->assertIdentical(1, count($violations), 'Wrong decimal value causes validation error');
|
||||
$decimal = '31.3';
|
||||
$entity->field_decimal = $decimal;
|
||||
$entity->name->value = $this->randomMachineName();
|
||||
$entity->save();
|
||||
|
||||
// Verify entity has been created properly.
|
||||
$id = $entity->id();
|
||||
$entity = EntityTest::load($id);
|
||||
$this->assertTrue($entity->field_integer instanceof FieldItemListInterface, 'Field implements interface.');
|
||||
$this->assertTrue($entity->field_integer[0] instanceof FieldItemInterface, 'Field item implements interface.');
|
||||
$this->assertEqual($entity->field_integer->value, $integer);
|
||||
$this->assertEqual($entity->field_integer[0]->value, $integer);
|
||||
$this->assertTrue($entity->field_float instanceof FieldItemListInterface, 'Field implements interface.');
|
||||
$this->assertTrue($entity->field_float[0] instanceof FieldItemInterface, 'Field item implements interface.');
|
||||
$this->assertEqual($entity->field_float->value, $float);
|
||||
$this->assertEqual($entity->field_float[0]->value, $float);
|
||||
$this->assertTrue($entity->field_decimal instanceof FieldItemListInterface, 'Field implements interface.');
|
||||
$this->assertTrue($entity->field_decimal[0] instanceof FieldItemInterface, 'Field item implements interface.');
|
||||
$this->assertEqual($entity->field_decimal->value, $decimal);
|
||||
$this->assertEqual($entity->field_decimal[0]->value, $decimal);
|
||||
|
||||
// Verify changing the number value.
|
||||
$new_integer = rand(11, 20);
|
||||
$new_float = rand(1001, 2000) / 100;
|
||||
$new_decimal = '18.2';
|
||||
$entity->field_integer->value = $new_integer;
|
||||
$this->assertEqual($entity->field_integer->value, $new_integer);
|
||||
$entity->field_float->value = $new_float;
|
||||
$this->assertEqual($entity->field_float->value, $new_float);
|
||||
$entity->field_decimal->value = $new_decimal;
|
||||
$this->assertEqual($entity->field_decimal->value, $new_decimal);
|
||||
|
||||
// Read changed entity and assert changed values.
|
||||
$entity->save();
|
||||
$entity = EntityTest::load($id);
|
||||
$this->assertEqual($entity->field_integer->value, $new_integer);
|
||||
$this->assertEqual($entity->field_float->value, $new_float);
|
||||
$this->assertEqual($entity->field_decimal->value, $new_decimal);
|
||||
|
||||
/// Test sample item generation.
|
||||
$entity = EntityTest::create();
|
||||
$entity->field_integer->generateSampleItems();
|
||||
$entity->field_float->generateSampleItems();
|
||||
$entity->field_decimal->generateSampleItems();
|
||||
$this->entityValidateAndSave($entity);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,80 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\field\Kernel\Plugin\migrate\source\d6;
|
||||
|
||||
use Drupal\Tests\migrate\Kernel\MigrateSqlSourceTestBase;
|
||||
|
||||
/**
|
||||
* Tests d6_field_instance_per_form_display source plugin.
|
||||
*
|
||||
* @covers \Drupal\field\Plugin\migrate\source\d6\FieldInstancePerFormDisplay
|
||||
* @group field
|
||||
*/
|
||||
class FieldInstancePerFormDisplayTest extends MigrateSqlSourceTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['field', 'migrate_drupal'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function providerSource() {
|
||||
$tests = [
|
||||
[
|
||||
'source_data' => [],
|
||||
'expected_data' => [],
|
||||
],
|
||||
];
|
||||
|
||||
// The expected results.
|
||||
$tests[0]['expected_data'] = [
|
||||
[
|
||||
'display_settings' => [],
|
||||
'widget_settings' => [],
|
||||
'type_name' => 'story',
|
||||
'widget_active' => TRUE,
|
||||
'field_name' => 'field_test_filefield',
|
||||
'type' => 'filefield',
|
||||
'module' => 'filefield',
|
||||
'weight' => '8',
|
||||
'widget_type' => 'filefield_widget',
|
||||
],
|
||||
];
|
||||
|
||||
// The source data.
|
||||
$empty_array = serialize([]);
|
||||
$tests[0]['source_data']['content_node_field'] = [
|
||||
[
|
||||
'field_name' => 'field_test_filefield',
|
||||
'type' => 'filefield',
|
||||
'global_settings' => $empty_array,
|
||||
'required' => '0',
|
||||
'multiple' => '0',
|
||||
'db_storage' => '1',
|
||||
'module' => 'filefield',
|
||||
'db_columns' => $empty_array,
|
||||
'active' => '1',
|
||||
'locked' => '0',
|
||||
]
|
||||
];
|
||||
$tests[0]['source_data']['content_node_field_instance'] = [
|
||||
[
|
||||
'field_name' => 'field_test_filefield',
|
||||
'type_name' => 'story',
|
||||
'weight' => '8',
|
||||
'label' => 'File Field',
|
||||
'widget_type' => 'filefield_widget',
|
||||
'widget_settings' => $empty_array,
|
||||
'display_settings' => $empty_array,
|
||||
'description' => 'An example image field.',
|
||||
'widget_module' => 'filefield',
|
||||
'widget_active' => '1',
|
||||
],
|
||||
];
|
||||
|
||||
return $tests;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,101 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\field\Kernel\Plugin\migrate\source\d6;
|
||||
|
||||
use Drupal\Tests\migrate\Kernel\MigrateSqlSourceTestBase;
|
||||
|
||||
/**
|
||||
* Tests D6 fields per view mode source plugin.
|
||||
*
|
||||
* @covers \Drupal\field\Plugin\migrate\source\d6\FieldInstancePerViewMode
|
||||
* @group field
|
||||
*/
|
||||
class FieldInstancePerViewModeTest extends MigrateSqlSourceTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['field', 'migrate_drupal', 'node', 'user'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function providerSource() {
|
||||
$tests = [
|
||||
[
|
||||
'source_data' => [],
|
||||
'expected_data' => [],
|
||||
],
|
||||
];
|
||||
|
||||
// The expected results.
|
||||
$tests[0]['expected_data'] = [
|
||||
[
|
||||
'entity_type' => 'node',
|
||||
'view_mode' => 4,
|
||||
'type_name' => 'article',
|
||||
'field_name' => 'field_test',
|
||||
'type' => 'text',
|
||||
'module' => 'text',
|
||||
'weight' => 1,
|
||||
'label' => 'above',
|
||||
'display_settings' => [
|
||||
'weight' => 1,
|
||||
'parent' => '',
|
||||
'label' => [
|
||||
'format' => 'above',
|
||||
],
|
||||
4 => [
|
||||
'format' => 'trimmed',
|
||||
'exclude' => 0,
|
||||
],
|
||||
],
|
||||
'widget_settings' => [],
|
||||
],
|
||||
[
|
||||
'entity_type' => 'node',
|
||||
'view_mode' => 'teaser',
|
||||
'type_name' => 'story',
|
||||
'field_name' => 'field_test',
|
||||
'type' => 'text',
|
||||
'module' => 'text',
|
||||
'weight' => 2,
|
||||
'label' => 'above',
|
||||
'display_settings' => [
|
||||
'weight' => 1,
|
||||
'parent' => '',
|
||||
'label' => [
|
||||
'format' => 'above',
|
||||
],
|
||||
'teaser' => [
|
||||
'format' => 'trimmed',
|
||||
'exclude' => 0,
|
||||
],
|
||||
],
|
||||
'widget_settings' => [],
|
||||
],
|
||||
];
|
||||
|
||||
// The source data.
|
||||
foreach ($tests[0]['expected_data'] as $k => $field_view_mode) {
|
||||
// These are stored as serialized strings.
|
||||
$field_view_mode['display_settings'] = serialize($field_view_mode['display_settings']);
|
||||
$field_view_mode['widget_settings'] = serialize($field_view_mode['widget_settings']);
|
||||
|
||||
$tests[0]['source_data']['content_node_field'][] = [
|
||||
'field_name' => $field_view_mode['field_name'],
|
||||
'type' => $field_view_mode['type'],
|
||||
'module' => $field_view_mode['module'],
|
||||
];
|
||||
unset($field_view_mode['type'], $field_view_mode['module']);
|
||||
|
||||
$tests[0]['source_data']['content_node_field_instance'][] = $field_view_mode;
|
||||
|
||||
// Update the expected display settings.
|
||||
$tests[0]['expected_data'][$k]['display_settings'] = $tests[0]['expected_data'][$k]['display_settings'][$field_view_mode['view_mode']];
|
||||
}
|
||||
|
||||
return $tests;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,96 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\field\Kernel\Plugin\migrate\source\d6;
|
||||
|
||||
use Drupal\Tests\migrate\Kernel\MigrateSqlSourceTestBase;
|
||||
|
||||
/**
|
||||
* Tests D6 field instance source plugin.
|
||||
*
|
||||
* @covers \Drupal\field\Plugin\migrate\source\d6\FieldInstance
|
||||
* @group field
|
||||
*/
|
||||
class FieldInstanceTest extends MigrateSqlSourceTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['field', 'migrate_drupal'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function providerSource() {
|
||||
$tests = [
|
||||
[
|
||||
'source_data' => [],
|
||||
'expected_data' => [],
|
||||
],
|
||||
];
|
||||
|
||||
// The expected results.
|
||||
$tests[0]['expected_data'] = [
|
||||
[
|
||||
'field_name' => 'field_body',
|
||||
'type_name' => 'page',
|
||||
'weight' => 1,
|
||||
'label' => 'body',
|
||||
'widget_type' => 'text_textarea',
|
||||
'description' => '',
|
||||
'widget_module' => 'text',
|
||||
'widget_active' => 1,
|
||||
'required' => 1,
|
||||
'active' => 1,
|
||||
'global_settings' => [],
|
||||
'widget_settings' => [
|
||||
'rows' => 5,
|
||||
'size' => 60,
|
||||
'default_value' => [
|
||||
[
|
||||
'value' => '',
|
||||
'_error_element' => 'default_value_widget][field_body][0][value',
|
||||
'default_value_php' => '',
|
||||
],
|
||||
],
|
||||
],
|
||||
'display_settings' => [
|
||||
'label' => [
|
||||
'format' => 'above',
|
||||
'exclude' => 0,
|
||||
],
|
||||
'teaser' => [
|
||||
'format' => 'default',
|
||||
'exclude' => 0,
|
||||
],
|
||||
'full' => [
|
||||
'format' => 'default',
|
||||
'exclude' => 0,
|
||||
],
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
// The source data.
|
||||
$tests[0]['source_data']['content_node_field_instance'] = array_map(
|
||||
function (array $row) {
|
||||
$row['widget_settings'] = serialize($row['widget_settings']);
|
||||
$row['display_settings'] = serialize($row['display_settings']);
|
||||
$row['global_settings'] = serialize($row['global_settings']);
|
||||
return $row;
|
||||
},
|
||||
$tests[0]['expected_data']
|
||||
);
|
||||
$tests[0]['source_data']['content_node_field'] = [
|
||||
[
|
||||
'field_name' => 'field_body',
|
||||
'required' => 1,
|
||||
'type' => 'text',
|
||||
'active' => 1,
|
||||
'global_settings' => serialize([]),
|
||||
],
|
||||
];
|
||||
|
||||
return $tests;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,79 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\field\Kernel\Plugin\migrate\source\d6;
|
||||
|
||||
use Drupal\Tests\migrate\Kernel\MigrateSqlSourceTestBase;
|
||||
|
||||
/**
|
||||
* Tests D6 field source plugin.
|
||||
*
|
||||
* @covers \Drupal\field\Plugin\migrate\source\d6\Field
|
||||
* @group field
|
||||
*/
|
||||
class FieldTest extends MigrateSqlSourceTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['field', 'migrate_drupal'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function providerSource() {
|
||||
$tests = [
|
||||
[
|
||||
'source_data' => [],
|
||||
'expected_data' => [],
|
||||
],
|
||||
];
|
||||
|
||||
// The expected results.
|
||||
$tests[0]['expected_data'] = [
|
||||
[
|
||||
'field_name' => 'field_body',
|
||||
'type' => 'text',
|
||||
'global_settings' => [
|
||||
'text_processing' => 0,
|
||||
'max_length' => '',
|
||||
'allowed_values' => '',
|
||||
'allowed_values_php' => '',
|
||||
],
|
||||
'required' => 0,
|
||||
'multiple' => 0,
|
||||
'db_storage' => 1,
|
||||
'module' => 'text',
|
||||
'db_columns' => [
|
||||
'value' => [
|
||||
'type' => 'text',
|
||||
'size' => 'big',
|
||||
'not null' => '',
|
||||
'sortable' => 1,
|
||||
'views' => 1,
|
||||
],
|
||||
],
|
||||
'active' => 1,
|
||||
'locked' => 0,
|
||||
],
|
||||
];
|
||||
|
||||
// The source data.
|
||||
$tests[0]['source_data']['content_node_field'] = array_map(
|
||||
function (array $row) {
|
||||
$row['global_settings'] = serialize($row['global_settings']);
|
||||
$row['db_columns'] = serialize($row['db_columns']);
|
||||
return $row;
|
||||
},
|
||||
$tests[0]['expected_data']
|
||||
);
|
||||
$tests[0]['source_data']['content_node_field_instance'] = [
|
||||
[
|
||||
'widget_type' => 'text_textarea',
|
||||
'field_name' => 'field_body',
|
||||
],
|
||||
];
|
||||
|
||||
return $tests;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,169 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\field\Kernel\Plugin\migrate\source\d7;
|
||||
|
||||
use Drupal\Tests\migrate\Kernel\MigrateSqlSourceTestBase;
|
||||
|
||||
/**
|
||||
* Tests D7 field instance per form display source plugin.
|
||||
*
|
||||
* @covers \Drupal\field\Plugin\migrate\source\d7\FieldInstancePerFormDisplay
|
||||
* @group field
|
||||
*/
|
||||
class FieldInstancePerFormDisplayTest extends MigrateSqlSourceTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['field', 'migrate_drupal'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function providerSource() {
|
||||
$tests = [
|
||||
[
|
||||
'source_data' => [],
|
||||
'expected_data' => [],
|
||||
],
|
||||
];
|
||||
|
||||
// The source data.
|
||||
$tests[0]['source_data']['field_config_instance'] = [
|
||||
[
|
||||
'id' => '2',
|
||||
'field_id' => '2',
|
||||
'field_name' => 'body',
|
||||
'entity_type' => 'node',
|
||||
'bundle' => 'page',
|
||||
'data' => 'a:6:{s:5:"label";s:4:"Body";s:6:"widget";a:4:{s:4:"type";s:26:"text_textarea_with_summary";s:8:"settings";a:2:{s:4:"rows";i:20;s:12:"summary_rows";i:5;}s:6:"weight";i:-4;s:6:"module";s:4:"text";}s:8:"settings";a:3:{s:15:"display_summary";b:1;s:15:"text_processing";i:1;s:18:"user_register_form";b:0;}s:7:"display";a:2:{s:7:"default";a:5:{s:5:"label";s:6:"hidden";s:4:"type";s:12:"text_default";s:8:"settings";a:0:{}s:6:"module";s:4:"text";s:6:"weight";i:0;}s:6:"teaser";a:5:{s:5:"label";s:6:"hidden";s:4:"type";s:23:"text_summary_or_trimmed";s:8:"settings";a:1:{s:11:"trim_length";i:600;}s:6:"module";s:4:"text";s:6:"weight";i:0;}}s:8:"required";b:0;s:11:"description";s:0:"";}',
|
||||
'deleted' => '0',
|
||||
],
|
||||
[
|
||||
'id' => '33',
|
||||
'field_id' => '11',
|
||||
'field_name' => 'field_file',
|
||||
'entity_type' => 'user',
|
||||
'bundle' => 'user',
|
||||
'data' => 'a:6:{s:5:"label";s:4:"File";s:6:"widget";a:5:{s:6:"weight";s:1:"8";s:4:"type";s:12:"file_generic";s:6:"module";s:4:"file";s:6:"active";i:1;s:8:"settings";a:1:{s:18:"progress_indicator";s:8:"throbber";}}s:8:"settings";a:5:{s:14:"file_directory";s:0:"";s:15:"file_extensions";s:3:"txt";s:12:"max_filesize";s:0:"";s:17:"description_field";i:0;s:18:"user_register_form";i:0;}s:7:"display";a:1:{s:7:"default";a:5:{s:5:"label";s:5:"above";s:4:"type";s:12:"file_default";s:8:"settings";a:0:{}s:6:"module";s:4:"file";s:6:"weight";i:0;}}s:8:"required";i:0;s:11:"description";s:0:"";}',
|
||||
'deleted' => '0',
|
||||
],
|
||||
[
|
||||
'id' => '32',
|
||||
'field_id' => '14',
|
||||
'field_name' => 'field_integer',
|
||||
'entity_type' => 'comment',
|
||||
'bundle' => 'comment_node_test_content_type',
|
||||
'data' => 'a:7:{s:5:"label";s:7:"Integer";s:6:"widget";a:5:{s:6:"weight";s:1:"2";s:4:"type";s:6:"number";s:6:"module";s:6:"number";s:6:"active";i:0;s:8:"settings";a:0:{}}s:8:"settings";a:5:{s:3:"min";s:0:"";s:3:"max";s:0:"";s:6:"prefix";s:0:"";s:6:"suffix";s:0:"";s:18:"user_register_form";b:0;}s:7:"display";a:1:{s:7:"default";a:5:{s:5:"label";s:5:"above";s:4:"type";s:14:"number_integer";s:8:"settings";a:4:{s:18:"thousand_separator";s:1:" ";s:17:"decimal_separator";s:1:".";s:5:"scale";i:0;s:13:"prefix_suffix";b:1;}s:6:"module";s:6:"number";s:6:"weight";i:1;}}s:8:"required";i:0;s:11:"description";s:0:"";s:13:"default_value";N;}',
|
||||
'deleted' => '0',
|
||||
],
|
||||
[
|
||||
'id' => '25',
|
||||
'field_id' => '15',
|
||||
'field_name' => 'field_link',
|
||||
'entity_type' => 'taxonomy_term',
|
||||
'bundle' => 'test_vocabulary',
|
||||
'data' => 'a:7:{s:5:"label";s:4:"Link";s:6:"widget";a:5:{s:6:"weight";s:2:"10";s:4:"type";s:10:"link_field";s:6:"module";s:4:"link";s:6:"active";i:0;s:8:"settings";a:0:{}}s:8:"settings";a:12:{s:12:"absolute_url";i:1;s:12:"validate_url";i:1;s:3:"url";i:0;s:5:"title";s:8:"optional";s:11:"title_value";s:19:"Unused Static Title";s:27:"title_label_use_field_label";i:0;s:15:"title_maxlength";s:3:"128";s:7:"display";a:1:{s:10:"url_cutoff";s:2:"81";}s:10:"attributes";a:6:{s:6:"target";s:6:"_blank";s:3:"rel";s:8:"nofollow";s:18:"configurable_class";i:0;s:5:"class";s:7:"classes";s:18:"configurable_title";i:1;s:5:"title";s:0:"";}s:10:"rel_remove";s:19:"rel_remove_external";s:13:"enable_tokens";i:1;s:18:"user_register_form";b:0;}s:7:"display";a:1:{s:7:"default";a:5:{s:5:"label";s:5:"above";s:4:"type";s:12:"link_default";s:6:"weight";s:1:"9";s:8:"settings";a:0:{}s:6:"module";s:4:"link";}}s:8:"required";i:0;s:11:"description";s:0:"";s:13:"default_value";N;}',
|
||||
'deleted' => '0',
|
||||
],
|
||||
];
|
||||
$tests[0]['source_data']['field_config'] = [
|
||||
[
|
||||
'id' => '2',
|
||||
'field_name' => 'body',
|
||||
'type' => 'text_with_summary',
|
||||
'module' => 'text',
|
||||
'active' => '1',
|
||||
'storage_type' => 'field_sql_storage',
|
||||
'storage_module' => 'field_sql_storage',
|
||||
'storage_active' => '1',
|
||||
'locked' => '0',
|
||||
'data' => 'a:6:{s:12:"entity_types";a:1:{i:0;s:4:"node";}s:12:"translatable";b:0;s:8:"settings";a:0:{}s:7:"storage";a:4:{s:4:"type";s:17:"field_sql_storage";s:8:"settings";a:0:{}s:6:"module";s:17:"field_sql_storage";s:6:"active";i:1;}s:12:"foreign keys";a:1:{s:6:"format";a:2:{s:5:"table";s:13:"filter_format";s:7:"columns";a:1:{s:6:"format";s:6:"format";}}}s:7:"indexes";a:1:{s:6:"format";a:1:{i:0;s:6:"format";}}}',
|
||||
'cardinality' => '1',
|
||||
'translatable' => '0',
|
||||
'deleted' => '0',
|
||||
],
|
||||
[
|
||||
'id' => '11',
|
||||
'field_name' => 'field_file',
|
||||
'type' => 'file',
|
||||
'module' => 'file',
|
||||
'active' => '1',
|
||||
'storage_type' => 'field_sql_storage',
|
||||
'storage_module' => 'field_sql_storage',
|
||||
'storage_active' => '1',
|
||||
'locked' => '0',
|
||||
'data' => 'a:7:{s:12:"translatable";s:1:"0";s:12:"entity_types";a:0:{}s:8:"settings";a:3:{s:13:"display_field";i:0;s:15:"display_default";i:0;s:10:"uri_scheme";s:6:"public";}s:7:"storage";a:5:{s:4:"type";s:17:"field_sql_storage";s:8:"settings";a:0:{}s:6:"module";s:17:"field_sql_storage";s:6:"active";s:1:"1";s:7:"details";a:1:{s:3:"sql";a:2:{s:18:"FIELD_LOAD_CURRENT";a:1:{s:21:"field_data_field_file";a:3:{s:3:"fid";s:14:"field_file_fid";s:7:"display";s:18:"field_file_display";s:11:"description";s:22:"field_file_description";}}s:19:"FIELD_LOAD_REVISION";a:1:{s:25:"field_revision_field_file";a:3:{s:3:"fid";s:14:"field_file_fid";s:7:"display";s:18:"field_file_display";s:11:"description";s:22:"field_file_description";}}}}}s:12:"foreign keys";a:1:{s:3:"fid";a:2:{s:5:"table";s:12:"file_managed";s:7:"columns";a:1:{s:3:"fid";s:3:"fid";}}}s:7:"indexes";a:1:{s:3:"fid";a:1:{i:0;s:3:"fid";}}s:2:"id";s:2:"11";}',
|
||||
'cardinality' => '1',
|
||||
'translatable' => '0',
|
||||
'deleted' => '0',
|
||||
],
|
||||
[
|
||||
'id' => '14',
|
||||
'field_name' => 'field_integer',
|
||||
'type' => 'number_integer',
|
||||
'module' => 'number',
|
||||
'active' => '1',
|
||||
'storage_type' => 'field_sql_storage',
|
||||
'storage_module' => 'field_sql_storage',
|
||||
'storage_active' => '1',
|
||||
'locked' => '0',
|
||||
'data' => 'a:7:{s:12:"translatable";s:1:"0";s:12:"entity_types";a:0:{}s:8:"settings";a:0:{}s:7:"storage";a:5:{s:4:"type";s:17:"field_sql_storage";s:8:"settings";a:0:{}s:6:"module";s:17:"field_sql_storage";s:6:"active";s:1:"1";s:7:"details";a:1:{s:3:"sql";a:2:{s:18:"FIELD_LOAD_CURRENT";a:1:{s:24:"field_data_field_integer";a:1:{s:5:"value";s:19:"field_integer_value";}}s:19:"FIELD_LOAD_REVISION";a:1:{s:28:"field_revision_field_integer";a:1:{s:5:"value";s:19:"field_integer_value";}}}}}s:12:"foreign keys";a:0:{}s:7:"indexes";a:0:{}s:2:"id";s:2:"14";}',
|
||||
'cardinality' => '1',
|
||||
'translatable' => '0',
|
||||
'deleted' => '0',
|
||||
],
|
||||
[
|
||||
'id' => '15',
|
||||
'field_name' => 'field_link',
|
||||
'type' => 'link_field',
|
||||
'module' => 'link',
|
||||
'active' => '1',
|
||||
'storage_type' => 'field_sql_storage',
|
||||
'storage_module' => 'field_sql_storage',
|
||||
'storage_active' => '1',
|
||||
'locked' => '0',
|
||||
'data' => 'a:7:{s:12:"translatable";s:1:"0";s:12:"entity_types";a:0:{}s:8:"settings";a:7:{s:10:"attributes";a:3:{s:6:"target";s:7:"default";s:5:"class";s:0:"";s:3:"rel";s:0:"";}s:3:"url";i:0;s:5:"title";s:8:"optional";s:11:"title_value";s:0:"";s:15:"title_maxlength";i:128;s:13:"enable_tokens";i:1;s:7:"display";a:1:{s:10:"url_cutoff";i:80;}}s:7:"storage";a:5:{s:4:"type";s:17:"field_sql_storage";s:8:"settings";a:0:{}s:6:"module";s:17:"field_sql_storage";s:6:"active";s:1:"1";s:7:"details";a:1:{s:3:"sql";a:2:{s:18:"FIELD_LOAD_CURRENT";a:1:{s:21:"field_data_field_link";a:3:{s:3:"url";s:14:"field_link_url";s:5:"title";s:16:"field_link_title";s:10:"attributes";s:21:"field_link_attributes";}}s:19:"FIELD_LOAD_REVISION";a:1:{s:25:"field_revision_field_link";a:3:{s:3:"url";s:14:"field_link_url";s:5:"title";s:16:"field_link_title";s:10:"attributes";s:21:"field_link_attributes";}}}}}s:12:"foreign keys";a:0:{}s:7:"indexes";a:0:{}s:2:"id";s:2:"15";}',
|
||||
'cardinality' => '1',
|
||||
'translatable' => '0',
|
||||
'deleted' => '0',
|
||||
],
|
||||
];
|
||||
|
||||
// The expected results.
|
||||
$tests[0]['expected_data'] = [
|
||||
[
|
||||
'field_name' => 'body',
|
||||
'entity_type' => 'node',
|
||||
'bundle' => 'page',
|
||||
'widget_settings' => [
|
||||
'rows' => 20,
|
||||
'summary_rows' => 5,
|
||||
],
|
||||
],
|
||||
[
|
||||
'field_name' => 'field_file',
|
||||
'entity_type' => 'user',
|
||||
'bundle' => 'user',
|
||||
'widget_settings' => [
|
||||
'progress_indicator' => 'throbber',
|
||||
],
|
||||
],
|
||||
[
|
||||
'field_name' => 'field_integer',
|
||||
'entity_type' => 'comment',
|
||||
'bundle' => 'comment_node_test_content_type',
|
||||
'widget_settings' => [],
|
||||
],
|
||||
[
|
||||
'field_name' => 'field_link',
|
||||
'entity_type' => 'taxonomy_term',
|
||||
'bundle' => 'test_vocabulary',
|
||||
'widget_settings' => [],
|
||||
],
|
||||
];
|
||||
|
||||
return $tests;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,95 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\field\Kernel\Plugin\migrate\source\d7;
|
||||
|
||||
use Drupal\Tests\migrate\Kernel\MigrateSqlSourceTestBase;
|
||||
|
||||
/**
|
||||
* Tests D7 field instance per view mode source plugin.
|
||||
*
|
||||
* @covers \Drupal\field\Plugin\migrate\source\d7\FieldInstancePerViewMode
|
||||
* @group field
|
||||
*/
|
||||
class FieldInstancePerViewModeTest extends MigrateSqlSourceTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['field', 'migrate_drupal'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function providerSource() {
|
||||
$tests = [
|
||||
[
|
||||
'source_data' => [],
|
||||
'expected_data' => [],
|
||||
],
|
||||
];
|
||||
|
||||
// The source data.
|
||||
$tests[0]['source_data']['field_config_instance'] = [
|
||||
[
|
||||
'id' => '2',
|
||||
'field_id' => '2',
|
||||
'field_name' => 'body',
|
||||
'entity_type' => 'node',
|
||||
'bundle' => 'page',
|
||||
'data' => 'a:6:{s:5:"label";s:4:"Body";s:6:"widget";a:4:{s:4:"type";s:26:"text_textarea_with_summary";s:8:"settings";a:2:{s:4:"rows";i:20;s:12:"summary_rows";i:5;}s:6:"weight";i:-4;s:6:"module";s:4:"text";}s:8:"settings";a:3:{s:15:"display_summary";b:1;s:15:"text_processing";i:1;s:18:"user_register_form";b:0;}s:7:"display";a:2:{s:7:"default";a:5:{s:5:"label";s:6:"hidden";s:4:"type";s:12:"text_default";s:8:"settings";a:0:{}s:6:"module";s:4:"text";s:6:"weight";i:0;}s:6:"teaser";a:5:{s:5:"label";s:6:"hidden";s:4:"type";s:23:"text_summary_or_trimmed";s:8:"settings";a:1:{s:11:"trim_length";i:600;}s:6:"module";s:4:"text";s:6:"weight";i:0;}}s:8:"required";b:0;s:11:"description";s:0:"";}',
|
||||
'deleted' => '0',
|
||||
],
|
||||
];
|
||||
|
||||
$tests[0]['source_data']['field_config'] = [
|
||||
[
|
||||
'id' => '2',
|
||||
'field_name' => 'body',
|
||||
'type' => 'text_with_summary',
|
||||
'module' => 'text',
|
||||
'active' => '1',
|
||||
'storage_type' => 'field_sql_storage',
|
||||
'storage_module' => 'field_sql_storage',
|
||||
'storage_active' => '1',
|
||||
'locked' => '0',
|
||||
'data' => 'a:7:{s:12:"entity_types";a:1:{i:0;s:4:"node";}s:7:"indexes";a:1:{s:6:"format";a:1:{i:0;s:6:"format";}}s:8:"settings";a:0:{}s:12:"translatable";i:0;s:12:"foreign keys";a:1:{s:6:"format";a:2:{s:5:"table";s:13:"filter_format";s:7:"columns";a:1:{s:6:"format";s:6:"format";}}}s:7:"storage";a:4:{s:4:"type";s:17:"field_sql_storage";s:8:"settings";a:0:{}s:6:"module";s:17:"field_sql_storage";s:6:"active";s:1:"1";}s:2:"id";s:2:"25";}',
|
||||
'cardinality' => '1',
|
||||
'translatable' => '0',
|
||||
'deleted' => '0',
|
||||
],
|
||||
];
|
||||
|
||||
// The expected results.
|
||||
$tests[0]['expected_data'] = [
|
||||
[
|
||||
'entity_type' => 'node',
|
||||
'bundle' => 'page',
|
||||
'field_name' => 'body',
|
||||
'label' => 'hidden',
|
||||
'type' => 'text_with_summary',
|
||||
'formatter_type' => 'text_default',
|
||||
'settings' => [],
|
||||
'module' => 'text',
|
||||
'weight' => 0,
|
||||
'view_mode' => 'default',
|
||||
],
|
||||
[
|
||||
'entity_type' => 'node',
|
||||
'bundle' => 'page',
|
||||
'field_name' => 'body',
|
||||
'label' => 'hidden',
|
||||
'type' => 'text_with_summary',
|
||||
'formatter_type' => 'text_summary_or_trimmed',
|
||||
'settings' => [
|
||||
'trim_length' => 600,
|
||||
],
|
||||
'module' => 'text',
|
||||
'weight' => 0,
|
||||
'view_mode' => 'teaser',
|
||||
],
|
||||
];
|
||||
|
||||
return $tests;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,103 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\field\Kernel\Plugin\migrate\source\d7;
|
||||
|
||||
use Drupal\Tests\migrate\Kernel\MigrateSqlSourceTestBase;
|
||||
|
||||
/**
|
||||
* Tests D7 field instance source plugin.
|
||||
*
|
||||
* @covers \Drupal\field\Plugin\migrate\source\d7\FieldInstance
|
||||
* @group field
|
||||
*/
|
||||
class FieldInstanceTest extends MigrateSqlSourceTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['field', 'migrate_drupal'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function providerSource() {
|
||||
$tests = [
|
||||
[
|
||||
'source_data' => [],
|
||||
'expected_data' => [],
|
||||
],
|
||||
];
|
||||
|
||||
// The source data.
|
||||
$tests[0]['source_data']['field_config_instance'] = [
|
||||
[
|
||||
'id' => '2',
|
||||
'field_id' => '2',
|
||||
'field_name' => 'body',
|
||||
'entity_type' => 'node',
|
||||
'bundle' => 'page',
|
||||
'data' => 'a:6:{s:5:"label";s:4:"Body";s:6:"widget";a:4:{s:4:"type";s:26:"text_textarea_with_summary";s:8:"settings";a:2:{s:4:"rows";i:20;s:12:"summary_rows";i:5;}s:6:"weight";i:-4;s:6:"module";s:4:"text";}s:8:"settings";a:3:{s:15:"display_summary";b:1;s:15:"text_processing";i:1;s:18:"user_register_form";b:0;}s:7:"display";a:2:{s:7:"default";a:5:{s:5:"label";s:6:"hidden";s:4:"type";s:12:"text_default";s:8:"settings";a:0:{}s:6:"module";s:4:"text";s:6:"weight";i:0;}s:6:"teaser";a:5:{s:5:"label";s:6:"hidden";s:4:"type";s:23:"text_summary_or_trimmed";s:8:"settings";a:1:{s:11:"trim_length";i:600;}s:6:"module";s:4:"text";s:6:"weight";i:0;}}s:8:"required";b:0;s:11:"description";s:0:"";}',
|
||||
'deleted' => '0',
|
||||
],
|
||||
];
|
||||
$tests[0]['source_data']['field_config'] = [
|
||||
[
|
||||
'id' => '2',
|
||||
'field_name' => 'body',
|
||||
'type' => 'text_with_summary',
|
||||
'module' => 'text',
|
||||
'active' => '1',
|
||||
'storage_type' => 'field_sql_storage',
|
||||
'storage_module' => 'field_sql_storage',
|
||||
'storage_active' => '1',
|
||||
'locked' => '0',
|
||||
'data' => 'a:6:{s:12:"entity_types";a:1:{i:0;s:4:"node";}s:12:"translatable";b:0;s:8:"settings";a:0:{}s:7:"storage";a:4:{s:4:"type";s:17:"field_sql_storage";s:8:"settings";a:0:{}s:6:"module";s:17:"field_sql_storage";s:6:"active";i:1;}s:12:"foreign keys";a:1:{s:6:"format";a:2:{s:5:"table";s:13:"filter_format";s:7:"columns";a:1:{s:6:"format";s:6:"format";}}}s:7:"indexes";a:1:{s:6:"format";a:1:{i:0;s:6:"format";}}}',
|
||||
'cardinality' => '1',
|
||||
'translatable' => '0',
|
||||
'deleted' => '0',
|
||||
],
|
||||
];
|
||||
|
||||
// The expected results.
|
||||
$tests[0]['expected_data'] = [
|
||||
[
|
||||
'field_name' => 'body',
|
||||
'entity_type' => 'node',
|
||||
'bundle' => 'page',
|
||||
'label' => 'Body',
|
||||
'widget_settings' => [
|
||||
'module' => 'text',
|
||||
'settings' => [
|
||||
'rows' => 20,
|
||||
'summary_rows' => 5,
|
||||
],
|
||||
'type' => 'text_textarea_with_summary',
|
||||
'weight' => -4,
|
||||
],
|
||||
'display_settings' => [
|
||||
'default' => [
|
||||
'label' => 'hidden',
|
||||
'type' => 'text_default',
|
||||
'settings' => [],
|
||||
'module' => 'text',
|
||||
'weight' => 0,
|
||||
],
|
||||
'teaser' => [
|
||||
'label' => 'hidden',
|
||||
'type' => 'text_summary_or_trimmed',
|
||||
'settings' => [
|
||||
'trim_length' => 600,
|
||||
],
|
||||
'module' => 'text',
|
||||
'weight' => 0,
|
||||
],
|
||||
],
|
||||
'description' => '',
|
||||
'required' => FALSE,
|
||||
],
|
||||
];
|
||||
|
||||
return $tests;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,139 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\field\Kernel\Plugin\migrate\source\d7;
|
||||
|
||||
use Drupal\Tests\migrate\Kernel\MigrateSqlSourceTestBase;
|
||||
|
||||
/**
|
||||
* Tests D7 field source plugin.
|
||||
*
|
||||
* @covers \Drupal\field\Plugin\migrate\source\d7\Field
|
||||
* @group field
|
||||
*/
|
||||
class FieldTest extends MigrateSqlSourceTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['field', 'migrate_drupal'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function providerSource() {
|
||||
$tests = [
|
||||
[
|
||||
'source_data' => [],
|
||||
'expected_data' => [],
|
||||
],
|
||||
];
|
||||
|
||||
// The source data.
|
||||
$tests[0]['source_data']['field_config'] = [
|
||||
[
|
||||
'id' => '11',
|
||||
'field_name' => 'field_file',
|
||||
'type' => 'file',
|
||||
'module' => 'file',
|
||||
'active' => '1',
|
||||
'storage_type' => 'field_sql_storage',
|
||||
'storage_module' => 'field_sql_storage',
|
||||
'storage_active' => '1',
|
||||
'locked' => '0',
|
||||
'data' => 'a:7:{s:12:"translatable";s:1:"0";s:12:"entity_types";a:0:{}s:8:"settings";a:3:{s:13:"display_field";i:0;s:15:"display_default";i:0;s:10:"uri_scheme";s:6:"public";}s:7:"storage";a:5:{s:4:"type";s:17:"field_sql_storage";s:8:"settings";a:0:{}s:6:"module";s:17:"field_sql_storage";s:6:"active";s:1:"1";s:7:"details";a:1:{s:3:"sql";a:2:{s:18:"FIELD_LOAD_CURRENT";a:1:{s:21:"field_data_field_file";a:3:{s:3:"fid";s:14:"field_file_fid";s:7:"display";s:18:"field_file_display";s:11:"description";s:22:"field_file_description";}}s:19:"FIELD_LOAD_REVISION";a:1:{s:25:"field_revision_field_file";a:3:{s:3:"fid";s:14:"field_file_fid";s:7:"display";s:18:"field_file_display";s:11:"description";s:22:"field_file_description";}}}}}s:12:"foreign keys";a:1:{s:3:"fid";a:2:{s:5:"table";s:12:"file_managed";s:7:"columns";a:1:{s:3:"fid";s:3:"fid";}}}s:7:"indexes";a:1:{s:3:"fid";a:1:{i:0;s:3:"fid";}}s:2:"id";s:2:"11";}',
|
||||
'cardinality' => '1',
|
||||
'translatable' => '0',
|
||||
'deleted' => '0',
|
||||
],
|
||||
];
|
||||
$tests[0]['source_data']['field_config_instance'] = [
|
||||
[
|
||||
'id' => '33',
|
||||
'field_id' => '11',
|
||||
'field_name' => 'field_file',
|
||||
'entity_type' => 'user',
|
||||
'bundle' => 'user',
|
||||
'data' => 'a:6:{s:5:"label";s:4:"File";s:6:"widget";a:5:{s:6:"weight";s:1:"8";s:4:"type";s:12:"file_generic";s:6:"module";s:4:"file";s:6:"active";i:1;s:8:"settings";a:1:{s:18:"progress_indicator";s:8:"throbber";}}s:8:"settings";a:5:{s:14:"file_directory";s:0:"";s:15:"file_extensions";s:3:"txt";s:12:"max_filesize";s:0:"";s:17:"description_field";i:0;s:18:"user_register_form";i:0;}s:7:"display";a:1:{s:7:"default";a:5:{s:5:"label";s:5:"above";s:4:"type";s:12:"file_default";s:8:"settings";a:0:{}s:6:"module";s:4:"file";s:6:"weight";i:0;}}s:8:"required";i:0;s:11:"description";s:0:"";}',
|
||||
'deleted' => '0',
|
||||
],
|
||||
[
|
||||
'id' => '21',
|
||||
'field_id' => '11',
|
||||
'field_name' => 'field_file',
|
||||
'entity_type' => 'node',
|
||||
'bundle' => 'test_content_type',
|
||||
'data' => 'a:6:{s:5:"label";s:4:"File";s:6:"widget";a:5:{s:6:"weight";s:1:"5";s:4:"type";s:12:"file_generic";s:6:"module";s:4:"file";s:6:"active";i:1;s:8:"settings";a:1:{s:18:"progress_indicator";s:8:"throbber";}}s:8:"settings";a:5:{s:14:"file_directory";s:0:"";s:15:"file_extensions";s:15:"txt pdf ods odf";s:12:"max_filesize";s:5:"10 MB";s:17:"description_field";i:1;s:18:"user_register_form";b:0;}s:7:"display";a:1:{s:7:"default";a:5:{s:5:"label";s:5:"above";s:4:"type";s:12:"file_default";s:6:"weight";s:1:"5";s:8:"settings";a:0:{}s:6:"module";s:4:"file";}}s:8:"required";i:0;s:11:"description";s:0:"";}',
|
||||
'deleted' => '0',
|
||||
],
|
||||
];
|
||||
|
||||
// The expected results.
|
||||
$tests[0]['expected_data'] = [
|
||||
[
|
||||
'field_name' => 'field_file',
|
||||
'type' => 'file',
|
||||
'storage' => [
|
||||
'active' => 1,
|
||||
'details' => [
|
||||
'sql' => [
|
||||
'FIELD_LOAD_CURRENT' => [
|
||||
'field_data_field_file' => [
|
||||
'description' => 'field_file_description',
|
||||
'display' => 'field_file_display',
|
||||
'fid' => 'field_file_fid',
|
||||
],
|
||||
],
|
||||
'FIELD_LOAD_REVISION' => [
|
||||
'field_revision_field_file' => [
|
||||
'description' => 'field_file_description',
|
||||
'display' => 'field_file_display',
|
||||
'fid' => 'field_file_fid',
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
'module' => 'field_sql_storage',
|
||||
'settings' => [],
|
||||
'type' => 'field_sql_storage',
|
||||
],
|
||||
'module' => 'file',
|
||||
'locked' => 0,
|
||||
'entity_type' => 'node',
|
||||
],
|
||||
[
|
||||
'field_name' => 'field_file',
|
||||
'type' => 'file',
|
||||
'storage' => [
|
||||
'active' => 1,
|
||||
'details' => [
|
||||
'sql' => [
|
||||
'FIELD_LOAD_CURRENT' => [
|
||||
'field_data_field_file' => [
|
||||
'description' => 'field_file_description',
|
||||
'display' => 'field_file_display',
|
||||
'fid' => 'field_file_fid',
|
||||
],
|
||||
],
|
||||
'FIELD_LOAD_REVISION' => [
|
||||
'field_revision_field_file' => [
|
||||
'description' => 'field_file_description',
|
||||
'display' => 'field_file_display',
|
||||
'fid' => 'field_file_fid',
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
'module' => 'field_sql_storage',
|
||||
'settings' => [],
|
||||
'type' => 'field_sql_storage',
|
||||
],
|
||||
'module' => 'file',
|
||||
'locked' => 0,
|
||||
'entity_type' => 'user',
|
||||
],
|
||||
];
|
||||
|
||||
return $tests;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,89 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\field\Kernel\Plugin\migrate\source\d7;
|
||||
|
||||
use Drupal\Tests\migrate\Kernel\MigrateSqlSourceTestBase;
|
||||
|
||||
/**
|
||||
* Tests D7 view mode source plugin.
|
||||
*
|
||||
* @covers \Drupal\field\Plugin\migrate\source\d7\ViewMode
|
||||
* @group field
|
||||
*/
|
||||
class ViewModeTest extends MigrateSqlSourceTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['field', 'migrate_drupal'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function providerSource() {
|
||||
$tests = [
|
||||
[
|
||||
'source_data' => [],
|
||||
'expected_data' => [],
|
||||
],
|
||||
];
|
||||
|
||||
// The source data.
|
||||
$tests[0]['source_data']['field_config_instance'] = [
|
||||
[
|
||||
'id' => '13',
|
||||
'field_id' => '2',
|
||||
'field_name' => 'body',
|
||||
'entity_type' => 'node',
|
||||
'bundle' => 'forum',
|
||||
'data' => 'a:6:{s:5:"label";s:4:"Body";s:6:"widget";a:4:{s:4:"type";s:26:"text_textarea_with_summary";s:8:"settings";a:2:{s:4:"rows";i:20;s:12:"summary_rows";i:5;}s:6:"weight";i:1;s:6:"module";s:4:"text";}s:8:"settings";a:3:{s:15:"display_summary";b:1;s:15:"text_processing";i:1;s:18:"user_register_form";b:0;}s:7:"display";a:3:{s:7:"default";a:5:{s:5:"label";s:6:"hidden";s:4:"type";s:12:"text_default";s:8:"settings";a:0:{}s:6:"module";s:4:"text";s:6:"weight";i:11;}s:6:"teaser";a:5:{s:5:"label";s:6:"hidden";s:4:"type";s:23:"text_summary_or_trimmed";s:8:"settings";a:1:{s:11:"trim_length";i:600;}s:6:"module";s:4:"text";s:6:"weight";i:11;}s:6:"custom";a:5:{s:5:"label";s:6:"hidden";s:4:"type";s:23:"text_summary_or_trimmed";s:8:"settings";a:0:{}s:6:"module";s:4:"text";s:6:"weight";i:11;}}s:8:"required";b:0;s:11:"description";s:0:"";}',
|
||||
'deleted' => '0',
|
||||
],
|
||||
[
|
||||
'id' => '33',
|
||||
'field_id' => '11',
|
||||
'field_name' => 'field_file',
|
||||
'entity_type' => 'user',
|
||||
'bundle' => 'user',
|
||||
'data' => 'a:6:{s:5:"label";s:4:"File";s:6:"widget";a:5:{s:6:"weight";s:1:"8";s:4:"type";s:12:"file_generic";s:6:"module";s:4:"file";s:6:"active";i:1;s:8:"settings";a:1:{s:18:"progress_indicator";s:8:"throbber";}}s:8:"settings";a:5:{s:14:"file_directory";s:0:"";s:15:"file_extensions";s:3:"txt";s:12:"max_filesize";s:0:"";s:17:"description_field";i:0;s:18:"user_register_form";i:0;}s:7:"display";a:1:{s:7:"default";a:5:{s:5:"label";s:5:"above";s:4:"type";s:12:"file_default";s:8:"settings";a:0:{}s:6:"module";s:4:"file";s:6:"weight";i:0;}}s:8:"required";i:0;s:11:"description";s:0:"";}',
|
||||
'deleted' => '0',
|
||||
],
|
||||
[
|
||||
'id' => '12',
|
||||
'field_id' => '1',
|
||||
'field_name' => 'comment_body',
|
||||
'entity_type' => 'comment',
|
||||
'bundle' => 'comment_node_forum',
|
||||
'data' => 'a:6:{s:5:"label";s:7:"Comment";s:8:"settings";a:2:{s:15:"text_processing";i:1;s:18:"user_register_form";b:0;}s:8:"required";b:1;s:7:"display";a:1:{s:7:"default";a:5:{s:5:"label";s:6:"hidden";s:4:"type";s:12:"text_default";s:6:"weight";i:0;s:8:"settings";a:0:{}s:6:"module";s:4:"text";}}s:6:"widget";a:4:{s:4:"type";s:13:"text_textarea";s:8:"settings";a:1:{s:4:"rows";i:5;}s:6:"weight";i:0;s:6:"module";s:4:"text";}s:11:"description";s:0:"";}',
|
||||
'deleted' => '0',
|
||||
],
|
||||
];
|
||||
|
||||
// The expected results.
|
||||
$tests[0]['expected_data'] = [
|
||||
[
|
||||
'entity_type' => 'node',
|
||||
'view_mode' => 'default',
|
||||
],
|
||||
[
|
||||
'entity_type' => 'node',
|
||||
'view_mode' => 'teaser',
|
||||
],
|
||||
[
|
||||
'entity_type' => 'node',
|
||||
'view_mode' => 'custom',
|
||||
],
|
||||
[
|
||||
'entity_type' => 'user',
|
||||
'view_mode' => 'default',
|
||||
],
|
||||
[
|
||||
'entity_type' => 'comment',
|
||||
'view_mode' => 'default',
|
||||
],
|
||||
];
|
||||
|
||||
return $tests;
|
||||
}
|
||||
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show more
Reference in a new issue