updated core to 8.6.3
This commit is contained in:
@@ -40,7 +40,7 @@ class GotoAction extends ConfigurableActionBase implements ContainerFactoryPlugi
|
||||
protected $unroutedUrlAssembler;
|
||||
|
||||
/**
|
||||
* Constructs a new DeleteNode object.
|
||||
* Constructs a GotoAction object.
|
||||
*
|
||||
* @param array $configuration
|
||||
* A configuration array containing information about the plugin instance.
|
||||
|
||||
@@ -94,7 +94,7 @@ class ItemsImporter implements ItemsImporterInterface {
|
||||
watchdog_exception('aggregator', $e);
|
||||
}
|
||||
|
||||
// Store instances in an array so we dont have to instantiate new objects.
|
||||
// Store instances in an array so we don't have to instantiate new objects.
|
||||
$processor_instances = [];
|
||||
foreach ($this->config->get('processors') as $processor) {
|
||||
try {
|
||||
|
||||
@@ -33,7 +33,7 @@ class BlockedIP extends DestinationBase implements ContainerFactoryPluginInterfa
|
||||
* @param string $plugin_id
|
||||
* The plugin ID.
|
||||
* @param mixed $plugin_definition
|
||||
* The plugin definiiton.
|
||||
* The plugin definition.
|
||||
* @param \Drupal\migrate\Plugin\MigrationInterface $migration
|
||||
* The current migration.
|
||||
* @param \Drupal\ban\BanIpManagerInterface $ban_manager
|
||||
|
||||
@@ -2,8 +2,7 @@
|
||||
|
||||
namespace Drupal\block_content\Plugin\migrate\source\d6;
|
||||
|
||||
use Drupal\migrate\Row;
|
||||
use Drupal\migrate_drupal\Plugin\migrate\source\DrupalSqlBase;
|
||||
use Drupal\block_content\Plugin\migrate\source\d7\BlockCustomTranslation as D7BlockCustomTranslation;
|
||||
|
||||
/**
|
||||
* Gets Drupal 6 i18n custom block translations from database.
|
||||
@@ -13,97 +12,12 @@ use Drupal\migrate_drupal\Plugin\migrate\source\DrupalSqlBase;
|
||||
* source_module = "i18nblocks"
|
||||
* )
|
||||
*/
|
||||
class BoxTranslation extends DrupalSqlBase {
|
||||
class BoxTranslation extends D7BlockCustomTranslation {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* Drupal 6 table names.
|
||||
*/
|
||||
public function query() {
|
||||
// Build a query based on i18n_strings table where each row has the
|
||||
// translation for only one property, either title or description. The
|
||||
// method prepareRow() is then used to obtain the translation for the
|
||||
// other property.
|
||||
$query = $this->select('boxes', 'b')
|
||||
->fields('b', ['bid', 'format', 'body'])
|
||||
->fields('i18n', ['property'])
|
||||
->fields('lt', ['lid', 'translation', 'language'])
|
||||
->orderBy('b.bid')
|
||||
->isNotNull('lt.lid');
|
||||
|
||||
// Use 'title' for the info field to match the property name in the
|
||||
// i18n_strings table.
|
||||
$query->addField('b', 'info', 'title');
|
||||
|
||||
// Add in the property, which is either title or body. Cast the bid to text
|
||||
// so PostgreSQL can make the join.
|
||||
$query->leftJoin('i18n_strings', 'i18n', 'i18n.objectid = CAST(b.bid as CHAR(255))');
|
||||
$query->condition('i18n.type', 'block');
|
||||
|
||||
// Add in the translation for the property.
|
||||
$query->leftJoin('locales_target', 'lt', 'lt.lid = i18n.lid');
|
||||
return $query;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function prepareRow(Row $row) {
|
||||
$language = $row->getSourceProperty('language');
|
||||
$bid = $row->getSourceProperty('bid');
|
||||
|
||||
// If this row has been migrated it is a duplicate then skip it.
|
||||
if ($this->idMap->lookupDestinationIds(['bid' => $bid, 'language' => $language])) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Save the translation for this property.
|
||||
$property = $row->getSourceProperty('property');
|
||||
$row->setSourceProperty($property . '_translated', $row->getSourceProperty('translation'));
|
||||
|
||||
// Get the translation for the property not already in the row.
|
||||
$translation = ($property === 'title') ? 'body' : 'title';
|
||||
$query = $this->select('i18n_strings', 'i18n')
|
||||
->fields('i18n', ['lid'])
|
||||
->condition('i18n.property', $translation)
|
||||
->condition('i18n.objectid', $bid);
|
||||
$query->leftJoin('locales_target', 'lt', 'i18n.lid = lt.lid');
|
||||
$query->condition('lt.language', $language)
|
||||
->addField('lt', 'translation');
|
||||
$results = $query->execute()->fetchAssoc();
|
||||
if (!$results) {
|
||||
$row->setSourceProperty($translation . '_translated', NULL);
|
||||
}
|
||||
else {
|
||||
$row->setSourceProperty($translation . '_translated', $results['translation']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function fields() {
|
||||
return [
|
||||
'bid' => $this->t('The block numeric identifier.'),
|
||||
'format' => $this->t('Input format of the custom block/box content.'),
|
||||
'lid' => $this->t('i18n_string table id'),
|
||||
'language' => $this->t('Language for this field.'),
|
||||
'property' => $this->t('Block property'),
|
||||
'translation' => $this->t('The translation of the value of "property".'),
|
||||
'title' => $this->t('Block title.'),
|
||||
'title_translated' => $this->t('Block title translation.'),
|
||||
'body' => $this->t('Block body.'),
|
||||
'body_translated' => $this->t('Block body translation.'),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getIds() {
|
||||
$ids['bid']['type'] = 'integer';
|
||||
$ids['bid']['alias'] = 'b';
|
||||
$ids['language']['type'] = 'string';
|
||||
return $ids;
|
||||
}
|
||||
const CUSTOM_BLOCK_TABLE = 'boxes';
|
||||
const I18N_STRING_TABLE = 'i18n_strings';
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\block_content\Plugin\migrate\source\d7;
|
||||
|
||||
use Drupal\migrate\Row;
|
||||
use Drupal\migrate_drupal\Plugin\migrate\source\DrupalSqlBase;
|
||||
use Drupal\content_translation\Plugin\migrate\source\I18nQueryTrait;
|
||||
|
||||
/**
|
||||
* Gets Drupal 7 custom block translation from database.
|
||||
*
|
||||
* @MigrateSource(
|
||||
* id = "d7_block_custom_translation",
|
||||
* source_module = "block"
|
||||
* )
|
||||
*/
|
||||
class BlockCustomTranslation extends DrupalSqlBase {
|
||||
|
||||
use I18nQueryTrait;
|
||||
|
||||
/**
|
||||
* Drupal 7 table names.
|
||||
*/
|
||||
const CUSTOM_BLOCK_TABLE = 'block_custom';
|
||||
const I18N_STRING_TABLE = 'i18n_string';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function query() {
|
||||
// Build a query based on blockCustomTable table where each row has the
|
||||
// translation for only one property, either title or description. The
|
||||
// method prepareRow() is then used to obtain the translation for the
|
||||
// other property.
|
||||
$query = $this->select(static::CUSTOM_BLOCK_TABLE, 'b')
|
||||
->fields('b', ['bid', 'format', 'body'])
|
||||
->fields('i18n', ['property'])
|
||||
->fields('lt', ['lid', 'translation', 'language'])
|
||||
->orderBy('b.bid')
|
||||
->isNotNull('lt.lid');
|
||||
|
||||
// Use 'title' for the info field to match the property name in
|
||||
// i18nStringTable.
|
||||
$query->addField('b', 'info', 'title');
|
||||
|
||||
// Add in the property, which is either title or body. Cast the bid to text
|
||||
// so PostgreSQL can make the join.
|
||||
$query->leftJoin(static::I18N_STRING_TABLE, 'i18n', 'i18n.objectid = CAST(b.bid as CHAR(255))');
|
||||
$query->condition('i18n.type', 'block');
|
||||
|
||||
// Add in the translation for the property.
|
||||
$query->leftJoin('locales_target', 'lt', 'lt.lid = i18n.lid');
|
||||
return $query;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function prepareRow(Row $row) {
|
||||
parent::prepareRow($row);
|
||||
// Set the i18n string table for use in I18nQueryTrait.
|
||||
$this->i18nStringTable = static::I18N_STRING_TABLE;
|
||||
// Save the translation for this property.
|
||||
$property_in_row = $row->getSourceProperty('property');
|
||||
// Get the translation for the property not already in the row and save it
|
||||
// in the row.
|
||||
$property_not_in_row = ($property_in_row === 'title') ? 'body' : 'title';
|
||||
return $this->getPropertyNotInRowTranslation($row, $property_not_in_row, 'bid', $this->idMap);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function fields() {
|
||||
return [
|
||||
'bid' => $this->t('The block numeric identifier.'),
|
||||
'format' => $this->t('Input format of the custom block/box content.'),
|
||||
'lid' => $this->t('i18n_string table id'),
|
||||
'language' => $this->t('Language for this field.'),
|
||||
'property' => $this->t('Block property'),
|
||||
'translation' => $this->t('The translation of the value of "property".'),
|
||||
'title' => $this->t('Block title.'),
|
||||
'title_translated' => $this->t('Block title translation.'),
|
||||
'body' => $this->t('Block body.'),
|
||||
'body_translated' => $this->t('Block body translation.'),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getIds() {
|
||||
$ids['bid']['type'] = 'integer';
|
||||
$ids['bid']['alias'] = 'b';
|
||||
$ids['language']['type'] = 'string';
|
||||
return $ids;
|
||||
}
|
||||
|
||||
}
|
||||
+69
@@ -0,0 +1,69 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\block_content\Kernel\Migrate\d7;
|
||||
|
||||
use Drupal\block_content\Entity\BlockContent;
|
||||
use Drupal\Tests\migrate_drupal\Kernel\d7\MigrateDrupal7TestBase;
|
||||
|
||||
/**
|
||||
* Tests migration of i18n custom block strings.
|
||||
*
|
||||
* @group migrate_drupal_7
|
||||
*/
|
||||
class MigrateCustomBlockContentTranslationTest extends MigrateDrupal7TestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = [
|
||||
'block_content',
|
||||
'content_translation',
|
||||
'filter',
|
||||
'language',
|
||||
'text',
|
||||
// Required for translation migrations.
|
||||
'migrate_drupal_multilingual',
|
||||
];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$this->installConfig(['block_content']);
|
||||
$this->installEntitySchema('block_content');
|
||||
$this->executeMigrations([
|
||||
'language',
|
||||
'd7_filter_format',
|
||||
'block_content_type',
|
||||
'block_content_body_field',
|
||||
'd7_custom_block',
|
||||
'd7_custom_block_translation',
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the Drupal 7 i18n custom block strings to Drupal 8 migration.
|
||||
*/
|
||||
public function testCustomBlockContentTranslation() {
|
||||
/** @var \Drupal\block_content\Entity\BlockContent $block */
|
||||
$block = BlockContent::load(1)->getTranslation('fr');
|
||||
$this->assertSame('fr - Mildly amusing limerick of the day', $block->label());
|
||||
$this->assertGreaterThanOrEqual($block->getChangedTime(), \Drupal::time()->getRequestTime());
|
||||
$this->assertLessThanOrEqual(time(), $block->getChangedTime());
|
||||
$this->assertSame('fr', $block->language()->getId());
|
||||
$translation = "fr - A fellow jumped off a high wall\r\nAnd had a most terrible fall\r\nHe went back to bed\r\nWith a bump on his head\r\nThat's why you don't jump off a wall";
|
||||
$this->assertSame($translation, $block->body->value);
|
||||
$this->assertSame('filtered_html', $block->body->format);
|
||||
|
||||
$block = $block->getTranslation('is');
|
||||
$this->assertSame('is - Mildly amusing limerick of the day', $block->label());
|
||||
$this->assertGreaterThanOrEqual($block->getChangedTime(), \Drupal::time()->getRequestTime());
|
||||
$this->assertLessThanOrEqual(time(), $block->getChangedTime());
|
||||
$this->assertSame('is', $block->language()->getId());
|
||||
$text = "A fellow jumped off a high wall\r\nAnd had a most terrible fall\r\nHe went back to bed\r\nWith a bump on his head\r\nThat's why you don't jump off a wall";
|
||||
$this->assertSame($text, $block->body->value);
|
||||
$this->assertSame('filtered_html', $block->body->format);
|
||||
}
|
||||
|
||||
}
|
||||
+148
@@ -0,0 +1,148 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\block_content\Kernel\Plugin\migrate\source\d7;
|
||||
|
||||
use Drupal\Tests\migrate\Kernel\MigrateSqlSourceTestBase;
|
||||
|
||||
/**
|
||||
* Tests i18n custom block translations source plugin.
|
||||
*
|
||||
* @covers \Drupal\block_content\Plugin\migrate\source\d7\BlockCustomTranslation
|
||||
*
|
||||
* @group content_translation
|
||||
*/
|
||||
class BlockCustomTranslationTest extends MigrateSqlSourceTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['block_content', 'migrate_drupal'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function providerSource() {
|
||||
$tests = [];
|
||||
|
||||
// The source data.
|
||||
$tests[0]['database']['block_custom'] = [
|
||||
[
|
||||
'bid' => 1,
|
||||
'body' => 'box 1 body',
|
||||
'info' => 'box 1 title',
|
||||
'format' => '2',
|
||||
],
|
||||
[
|
||||
'bid' => 2,
|
||||
'body' => 'box 2 body',
|
||||
'info' => 'box 2 title',
|
||||
'format' => '2',
|
||||
],
|
||||
];
|
||||
|
||||
$tests[0]['database']['i18n_string'] = [
|
||||
[
|
||||
'lid' => 1,
|
||||
'objectid' => 1,
|
||||
'type' => 'block',
|
||||
'property' => 'title',
|
||||
'objectindex' => 1,
|
||||
'format' => 0,
|
||||
],
|
||||
[
|
||||
'lid' => 2,
|
||||
'objectid' => 1,
|
||||
'type' => 'block',
|
||||
'property' => 'body',
|
||||
'objectindex' => 1,
|
||||
'format' => 0,
|
||||
],
|
||||
[
|
||||
'lid' => 3,
|
||||
'objectid' => 2,
|
||||
'type' => 'block',
|
||||
'property' => 'body',
|
||||
'objectindex' => 2,
|
||||
'format' => 2,
|
||||
],
|
||||
];
|
||||
|
||||
$tests[0]['database']['locales_target'] = [
|
||||
[
|
||||
'lid' => 1,
|
||||
'language' => 'fr',
|
||||
'translation' => 'fr - title translation',
|
||||
'plid' => 0,
|
||||
'plural' => 0,
|
||||
'i18n_status' => 0,
|
||||
],
|
||||
[
|
||||
'lid' => 2,
|
||||
'language' => 'fr',
|
||||
'translation' => 'fr - body translation',
|
||||
'plid' => 0,
|
||||
'plural' => 0,
|
||||
'i18n_status' => 0,
|
||||
],
|
||||
[
|
||||
'lid' => 3,
|
||||
'language' => 'zu',
|
||||
'translation' => 'zu - body translation',
|
||||
'plid' => 0,
|
||||
'plural' => 0,
|
||||
'i18n_status' => 0,
|
||||
],
|
||||
];
|
||||
|
||||
$tests[0]['database']['system'] = [
|
||||
[
|
||||
'type' => 'module',
|
||||
'name' => 'system',
|
||||
'schema_version' => '7001',
|
||||
'status' => '1',
|
||||
],
|
||||
];
|
||||
|
||||
$tests[0]['expected_results'] = [
|
||||
[
|
||||
'lid' => '1',
|
||||
'property' => 'title',
|
||||
'language' => 'fr',
|
||||
'translation' => 'fr - title translation',
|
||||
'bid' => '1',
|
||||
'format' => '2',
|
||||
'title_translated' => 'fr - title translation',
|
||||
'body_translated' => 'fr - body translation',
|
||||
'title' => 'box 1 title',
|
||||
'body' => 'box 1 body',
|
||||
],
|
||||
[
|
||||
'lid' => '2',
|
||||
'property' => 'body',
|
||||
'language' => 'fr',
|
||||
'translation' => 'fr - body translation',
|
||||
'bid' => '1',
|
||||
'format' => '2',
|
||||
'title_translated' => 'fr - title translation',
|
||||
'body_translated' => 'fr - body translation',
|
||||
'title' => 'box 1 title',
|
||||
'body' => 'box 1 body',
|
||||
],
|
||||
[
|
||||
'lid' => '3',
|
||||
'property' => 'body',
|
||||
'language' => 'zu',
|
||||
'translation' => 'zu - body translation',
|
||||
'bid' => '2',
|
||||
'format' => '2',
|
||||
'title_translated' => NULL,
|
||||
'body_translated' => 'zu - body translation',
|
||||
'title' => 'box 2 title',
|
||||
'body' => 'box 2 body',
|
||||
],
|
||||
];
|
||||
|
||||
return $tests;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -177,7 +177,7 @@ class BookTest extends BrowserTestBase {
|
||||
$this->checkBookNode($other_book, [$node], FALSE, FALSE, $node, []);
|
||||
$this->checkBookNode($node, NULL, $other_book, $other_book, FALSE, [$other_book]);
|
||||
|
||||
// Test that we can save a book programatically.
|
||||
// Test that we can save a book programmatically.
|
||||
$this->drupalLogin($this->bookAuthor);
|
||||
$book = $this->createBookNode('new');
|
||||
$book->save();
|
||||
@@ -282,7 +282,7 @@ class BookTest extends BrowserTestBase {
|
||||
$nodes[$child] = $this->createBookNode($book->id(), $nodes[$parent]->id());
|
||||
}
|
||||
$this->drupalGet($nodes[0]->toUrl('edit-form'));
|
||||
// Snice Node 0 has children 2 levels deep, nodes 10 and 11 should not
|
||||
// Since Node 0 has children 2 levels deep, nodes 10 and 11 should not
|
||||
// appear in the selector.
|
||||
$this->assertNoOption('edit-book-pid', $nodes[10]->id());
|
||||
$this->assertNoOption('edit-book-pid', $nodes[11]->id());
|
||||
|
||||
@@ -68,7 +68,7 @@
|
||||
* Reacts on a change in the editor element.
|
||||
*
|
||||
* @param {HTMLElement} element
|
||||
* The element where the change occured.
|
||||
* The element where the change occurred.
|
||||
* @param {function} callback
|
||||
* Callback called with the value of the editor.
|
||||
*
|
||||
|
||||
@@ -24,6 +24,10 @@ class CKEditorPlugin extends Plugin {
|
||||
/**
|
||||
* The plugin ID.
|
||||
*
|
||||
* This MUST match the name of the CKEditor plugin itself (written in
|
||||
* JavaScript). Otherwise CKEditor will throw JavaScript errors when it runs,
|
||||
* because it fails to load this CKEditor plugin.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $id;
|
||||
|
||||
+1
-1
@@ -9,7 +9,7 @@ use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\editor\Entity\Editor;
|
||||
|
||||
/**
|
||||
* Defines a "LlamaContextualAndbutton" plugin, with a contextually OR toolbar
|
||||
* Defines a "LlamaContextualAndButton" plugin, with a contextually OR toolbar
|
||||
* builder-enabled "llama" feature.
|
||||
*
|
||||
* @CKEditorPlugin(
|
||||
|
||||
@@ -24,6 +24,13 @@ class CKEditorIntegrationTest extends WebDriverTestBase {
|
||||
*/
|
||||
protected $account;
|
||||
|
||||
/**
|
||||
* The FilterFormat config entity used for testing.
|
||||
*
|
||||
* @var \Drupal\filter\FilterFormatInterface
|
||||
*/
|
||||
protected $filterFormat;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
@@ -36,12 +43,12 @@ class CKEditorIntegrationTest extends WebDriverTestBase {
|
||||
parent::setUp();
|
||||
|
||||
// Create a text format and associate CKEditor.
|
||||
$filtered_html_format = FilterFormat::create([
|
||||
$this->filterFormat = FilterFormat::create([
|
||||
'format' => 'filtered_html',
|
||||
'name' => 'Filtered HTML',
|
||||
'weight' => 0,
|
||||
]);
|
||||
$filtered_html_format->save();
|
||||
$this->filterFormat->save();
|
||||
|
||||
Editor::create([
|
||||
'format' => 'filtered_html',
|
||||
@@ -119,4 +126,55 @@ class CKEditorIntegrationTest extends WebDriverTestBase {
|
||||
self::assertEquals($before_url, $after_url, 'History back works.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests if the Image button appears and works as expected.
|
||||
*/
|
||||
public function testDrupalImageDialog() {
|
||||
$session = $this->getSession();
|
||||
$web_assert = $this->assertSession();
|
||||
|
||||
$this->drupalGet('node/add/page');
|
||||
$session->getPage();
|
||||
|
||||
// Asserts the Image button is present in the toolbar.
|
||||
$web_assert->elementExists('css', '#cke_edit-body-0-value .cke_button__drupalimage');
|
||||
|
||||
// Asserts the image dialog opens when clicking the Image button.
|
||||
$this->click('.cke_button__drupalimage');
|
||||
$this->assertNotEmpty($web_assert->waitForElement('css', '.ui-dialog'));
|
||||
|
||||
$web_assert->elementContains('css', '.ui-dialog .ui-dialog-titlebar', 'Insert Image');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests if the Drupal Image Caption plugin appears and works as expected.
|
||||
*/
|
||||
public function testDrupalImageCaptionDialog() {
|
||||
$web_assert = $this->assertSession();
|
||||
|
||||
// Disable the caption filter.
|
||||
$this->filterFormat->setFilterConfig('filter_caption', [
|
||||
'status' => FALSE,
|
||||
]);
|
||||
$this->filterFormat->save();
|
||||
|
||||
// If the caption filter is disabled, its checkbox should be absent.
|
||||
$this->drupalGet('node/add/page');
|
||||
$this->click('.cke_button__drupalimage');
|
||||
$this->assertNotEmpty($web_assert->waitForElement('css', '.ui-dialog'));
|
||||
$web_assert->elementNotExists('css', '.ui-dialog input[name="attributes[hasCaption]"]');
|
||||
|
||||
// Enable the caption filter again.
|
||||
$this->filterFormat->setFilterConfig('filter_caption', [
|
||||
'status' => TRUE,
|
||||
]);
|
||||
$this->filterFormat->save();
|
||||
|
||||
// If the caption filter is enabled, its checkbox should be present.
|
||||
$this->drupalGet('node/add/page');
|
||||
$this->click('.cke_button__drupalimage');
|
||||
$this->assertNotEmpty($web_assert->waitForElement('css', '.ui-dialog'));
|
||||
$web_assert->elementExists('css', '.ui-dialog input[name="attributes[hasCaption]"]');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ use Drupal\field\FieldConfigInterface;
|
||||
use Drupal\field\FieldStorageConfigInterface;
|
||||
use Drupal\node\NodeInterface;
|
||||
use Drupal\user\RoleInterface;
|
||||
use Drupal\user\UserInterface;
|
||||
|
||||
/**
|
||||
* Anonymous posters cannot enter their contact information.
|
||||
@@ -518,7 +519,7 @@ function comment_node_search_result(EntityInterface $node) {
|
||||
/**
|
||||
* Implements hook_user_cancel().
|
||||
*/
|
||||
function comment_user_cancel($edit, $account, $method) {
|
||||
function comment_user_cancel($edit, UserInterface $account, $method) {
|
||||
switch ($method) {
|
||||
case 'user_cancel_block_unpublish':
|
||||
$comments = entity_load_multiple_by_properties('comment', ['uid' => $account->id()]);
|
||||
|
||||
@@ -16,7 +16,16 @@ process:
|
||||
plugin: migration_lookup
|
||||
migration: d6_comment
|
||||
source: pid
|
||||
entity_id: nid
|
||||
entity_id:
|
||||
-
|
||||
plugin: migration_lookup
|
||||
migration:
|
||||
- d6_node
|
||||
- d6_node_translation
|
||||
source: nid
|
||||
-
|
||||
plugin: skip_on_empty
|
||||
method: row
|
||||
entity_type: 'constants/entity_type'
|
||||
comment_type:
|
||||
-
|
||||
@@ -26,6 +35,7 @@ process:
|
||||
-
|
||||
plugin: skip_on_empty
|
||||
method: row
|
||||
langcode: language
|
||||
field_name: '@comment_type'
|
||||
subject: subject
|
||||
uid: uid
|
||||
@@ -52,3 +62,5 @@ migration_dependencies:
|
||||
- d6_comment_entity_form_display
|
||||
- d6_user
|
||||
- d6_filter_format
|
||||
optional:
|
||||
- d6_node_translation
|
||||
|
||||
@@ -17,7 +17,16 @@ process:
|
||||
plugin: migration_lookup
|
||||
migration: d7_comment
|
||||
source: pid
|
||||
entity_id: nid
|
||||
entity_id:
|
||||
-
|
||||
plugin: migration_lookup
|
||||
migration:
|
||||
- d7_node
|
||||
- d7_node_translation
|
||||
source: nid
|
||||
-
|
||||
plugin: skip_on_empty
|
||||
method: row
|
||||
entity_type: 'constants/entity_type'
|
||||
comment_type:
|
||||
-
|
||||
@@ -27,6 +36,7 @@ process:
|
||||
-
|
||||
plugin: skip_on_empty
|
||||
method: row
|
||||
langcode: language
|
||||
field_name: '@comment_type'
|
||||
subject: subject
|
||||
uid: uid
|
||||
@@ -45,3 +55,5 @@ migration_dependencies:
|
||||
required:
|
||||
- d7_node
|
||||
- d7_comment_type
|
||||
optional:
|
||||
- d7_node_translation
|
||||
|
||||
@@ -50,7 +50,7 @@ class CommentFieldItemList extends FieldItemList {
|
||||
return $return_as_object ? $result : $result->isAllowed();
|
||||
}
|
||||
if ($operation === 'view') {
|
||||
// Only users with either post comments or access comments permisison can
|
||||
// Only users with "post comments" or "access comments" permission can
|
||||
// view the field value. The formatter,
|
||||
// Drupal\comment\Plugin\Field\FieldFormatter\CommentDefaultFormatter,
|
||||
// takes care of showing the thread and form based on individual
|
||||
|
||||
@@ -56,8 +56,9 @@ interface CommentInterface extends ContentEntityInterface, EntityChangedInterfac
|
||||
/**
|
||||
* Returns the entity to which the comment is attached.
|
||||
*
|
||||
* @return \Drupal\Core\Entity\FieldableEntityInterface
|
||||
* The entity on which the comment is attached.
|
||||
* @return \Drupal\Core\Entity\FieldableEntityInterface|null
|
||||
* The entity on which the comment is attached or NULL if the comment is an
|
||||
* orphan.
|
||||
*/
|
||||
public function getCommentedEntity();
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ class Comment extends DrupalSqlBase {
|
||||
'mail', 'homepage', 'format',
|
||||
]);
|
||||
$query->innerJoin('node', 'n', 'c.nid = n.nid');
|
||||
$query->fields('n', ['type']);
|
||||
$query->fields('n', ['type', 'language']);
|
||||
$query->orderBy('c.timestamp');
|
||||
return $query;
|
||||
}
|
||||
@@ -61,6 +61,13 @@ class Comment extends DrupalSqlBase {
|
||||
// In D6, status=0 means published, while in D8 means the opposite.
|
||||
// See https://www.drupal.org/node/237636.
|
||||
$row->setSourceProperty('status', !$row->getSourceProperty('status'));
|
||||
|
||||
// If node did not have a language, use site default language as a fallback.
|
||||
if (!$row->getSourceProperty('language')) {
|
||||
$language_default = $this->variableGet('language_default', NULL);
|
||||
$language = $language_default ? $language_default->language : 'en';
|
||||
$row->setSourceProperty('language', $language);
|
||||
}
|
||||
return $row;
|
||||
}
|
||||
|
||||
@@ -84,6 +91,7 @@ class Comment extends DrupalSqlBase {
|
||||
'mail' => $this->t("The comment author's email address from the comment form, if user is anonymous, and the 'Anonymous users may/must leave their contact information' setting is turned on."),
|
||||
'homepage' => $this->t("The comment author's home page address from the comment form, if user is anonymous, and the 'Anonymous users may/must leave their contact information' setting is turned on."),
|
||||
'type' => $this->t("The {node}.type to which this comment is a reply."),
|
||||
'language' => $this->t("The {node}.language to which this comment is a reply. Site default language is used as a fallback if node does not have a language."),
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
@@ -36,8 +36,20 @@ class Comment extends FieldableEntity {
|
||||
$comment_type = 'comment_node_' . $node_type;
|
||||
$row->setSourceProperty('comment_type', 'comment_node_' . $node_type);
|
||||
|
||||
foreach (array_keys($this->getFields('comment', $comment_type)) as $field) {
|
||||
$row->setSourceProperty($field, $this->getFieldValues('comment', $field, $cid));
|
||||
// If this entity was translated using Entity Translation, we need to get
|
||||
// its source language to get the field values in the right language.
|
||||
// The translations will be migrated by the d7_comment_entity_translation
|
||||
// migration.
|
||||
$entity_translatable = $this->isEntityTranslatable('comment') && (int) $this->variableGet('language_content_type_' . $node_type, 0) === 4;
|
||||
$source_language = $this->getEntityTranslationSourceLanguage('comment', $cid);
|
||||
$language = $entity_translatable && $source_language ? $source_language : $row->getSourceProperty('language');
|
||||
|
||||
// Get Field API field values.
|
||||
foreach ($this->getFields('comment', $comment_type) as $field_name => $field) {
|
||||
// Ensure we're using the right language if the entity and the field are
|
||||
// translatable.
|
||||
$field_language = $entity_translatable && $field['translatable'] ? $language : NULL;
|
||||
$row->setSourceProperty($field_name, $this->getFieldValues('comment', $field_name, $cid, NULL, $field_language));
|
||||
}
|
||||
|
||||
// If the comment subject was replaced by a real field using the Drupal 7
|
||||
@@ -72,6 +84,7 @@ class Comment extends FieldableEntity {
|
||||
'name' => $this->t("The comment author's name. Uses {users}.name if the user is logged in, otherwise uses the value typed into the comment form."),
|
||||
'mail' => $this->t("The comment author's email address from the comment form, if user is anonymous, and the 'Anonymous users may/must leave their contact information' setting is turned on."),
|
||||
'homepage' => $this->t("The comment author's home page address from the comment form, if user is anonymous, and the 'Anonymous users may/must leave their contact information' setting is turned on."),
|
||||
'language' => $this->t('The comment language.'),
|
||||
'type' => $this->t("The {node}.type to which this comment is a reply."),
|
||||
];
|
||||
}
|
||||
|
||||
@@ -0,0 +1,103 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\comment\Plugin\migrate\source\d7;
|
||||
|
||||
use Drupal\migrate\Row;
|
||||
use Drupal\migrate_drupal\Plugin\migrate\source\d7\FieldableEntity;
|
||||
|
||||
/**
|
||||
* Provides Drupal 7 comment entity translation source plugin.
|
||||
*
|
||||
* @MigrateSource(
|
||||
* id = "d7_comment_entity_translation",
|
||||
* source_module = "entity_translation"
|
||||
* )
|
||||
*/
|
||||
class CommentEntityTranslation extends FieldableEntity {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function query() {
|
||||
$query = $this->select('entity_translation', 'et')
|
||||
->fields('et')
|
||||
->fields('c', [
|
||||
'subject',
|
||||
])
|
||||
->condition('et.entity_type', 'comment')
|
||||
->condition('et.source', '', '<>');
|
||||
|
||||
$query->innerJoin('comment', 'c', 'c.cid = et.entity_id');
|
||||
$query->innerJoin('node', 'n', 'n.nid = c.nid');
|
||||
|
||||
$query->addField('n', 'type', 'node_type');
|
||||
|
||||
$query->orderBy('et.created');
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function prepareRow(Row $row) {
|
||||
$cid = $row->getSourceProperty('entity_id');
|
||||
$language = $row->getSourceProperty('language');
|
||||
$node_type = $row->getSourceProperty('node_type');
|
||||
$comment_type = 'comment_node_' . $node_type;
|
||||
|
||||
// Get Field API field values.
|
||||
foreach ($this->getFields('comment', $comment_type) as $field_name => $field) {
|
||||
// Ensure we're using the right language if the entity is translatable.
|
||||
$field_language = $field['translatable'] ? $language : NULL;
|
||||
$row->setSourceProperty($field_name, $this->getFieldValues('comment', $field_name, $cid, NULL, $field_language));
|
||||
}
|
||||
|
||||
// If the comment subject was replaced by a real field using the Drupal 7
|
||||
// Title module, use the field value instead of the comment subject.
|
||||
if ($this->moduleExists('title')) {
|
||||
$subject_field = $row->getSourceProperty('subject_field');
|
||||
if (isset($subject_field[0]['value'])) {
|
||||
$row->setSourceProperty('subject', $subject_field[0]['value']);
|
||||
}
|
||||
}
|
||||
|
||||
return parent::prepareRow($row);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function fields() {
|
||||
return [
|
||||
'entity_type' => $this->t('The entity type this translation relates to'),
|
||||
'entity_id' => $this->t('The entity ID this translation relates to'),
|
||||
'revision_id' => $this->t('The entity revision ID this translation relates to'),
|
||||
'language' => $this->t('The target language for this translation.'),
|
||||
'source' => $this->t('The source language from which this translation was created.'),
|
||||
'uid' => $this->t('The author of this translation.'),
|
||||
'status' => $this->t('Boolean indicating whether the translation is published (visible to non-administrators).'),
|
||||
'translate' => $this->t('A boolean indicating whether this translation needs to be updated.'),
|
||||
'created' => $this->t('The Unix timestamp when the translation was created.'),
|
||||
'changed' => $this->t('The Unix timestamp when the translation was most recently saved.'),
|
||||
'subject' => $this->t('The comment title.'),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getIds() {
|
||||
return [
|
||||
'entity_id' => [
|
||||
'type' => 'integer',
|
||||
'alias' => 'et',
|
||||
],
|
||||
'language' => [
|
||||
'type' => 'string',
|
||||
'alias' => 'et',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
}
|
||||
@@ -10,9 +10,9 @@ use Drupal\comment\Tests\CommentTestTrait;
|
||||
use Drupal\entity_test\Entity\EntityTest;
|
||||
use Drupal\field\Entity\FieldConfig;
|
||||
use Drupal\field\Entity\FieldStorageConfig;
|
||||
use Drupal\field_ui\Tests\FieldUiTestTrait;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
use Drupal\Core\Entity\EntityInterface;
|
||||
use Drupal\Tests\field_ui\Traits\FieldUiTestTrait;
|
||||
use Drupal\user\RoleInterface;
|
||||
|
||||
/**
|
||||
|
||||
@@ -14,7 +14,7 @@ class CommentHalJsonAnonTest extends CommentHalJsonTestBase {
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* Anononymous users cannot edit their own comments.
|
||||
* Anonymous users cannot edit their own comments.
|
||||
*
|
||||
* @see \Drupal\comment\CommentAccessControlHandler::checkAccess
|
||||
*
|
||||
|
||||
@@ -24,7 +24,7 @@ class CommentJsonAnonTest extends CommentResourceTestBase {
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* Anononymous users cannot edit their own comments.
|
||||
* Anonymous users cannot edit their own comments.
|
||||
*
|
||||
* @see \Drupal\comment\CommentAccessControlHandler::checkAccess
|
||||
*
|
||||
|
||||
@@ -60,7 +60,7 @@ abstract class CommentResourceTestBase extends EntityResourceTestBase {
|
||||
$this->grantPermissionsToTestedRole(['post comments']);
|
||||
break;
|
||||
case 'PATCH':
|
||||
// Anononymous users are not ever allowed to edit their own comments. To
|
||||
// Anonymous users are not ever allowed to edit their own comments. To
|
||||
// be able to test PATCHing comments as the anonymous user, the more
|
||||
// permissive 'administer comments' permission must be granted.
|
||||
// @see \Drupal\comment\CommentAccessControlHandler::checkAccess
|
||||
|
||||
@@ -26,7 +26,7 @@ class CommentXmlAnonTest extends CommentResourceTestBase {
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* Anononymous users cannot edit their own comments.
|
||||
* Anonymous users cannot edit their own comments.
|
||||
*
|
||||
* @see \Drupal\comment\CommentAccessControlHandler::checkAccess
|
||||
*
|
||||
|
||||
@@ -20,7 +20,12 @@ class MigrateCommentTest extends MigrateDrupal6TestBase {
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['comment', 'menu_ui'];
|
||||
public static $modules = [
|
||||
'comment',
|
||||
'content_translation',
|
||||
'language',
|
||||
'menu_ui',
|
||||
];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
@@ -31,6 +36,7 @@ class MigrateCommentTest extends MigrateDrupal6TestBase {
|
||||
$this->installEntitySchema('node');
|
||||
$this->installEntitySchema('comment');
|
||||
$this->installSchema('comment', ['comment_entity_statistics']);
|
||||
$this->installSchema('node', ['node_access']);
|
||||
$this->installConfig(['comment']);
|
||||
|
||||
// The entity.node.canonical route must exist when the RDF hook is called.
|
||||
@@ -38,7 +44,10 @@ class MigrateCommentTest extends MigrateDrupal6TestBase {
|
||||
|
||||
$this->migrateContent();
|
||||
$this->executeMigrations([
|
||||
'language',
|
||||
'd6_language_content_settings',
|
||||
'd6_node',
|
||||
'd6_node_translation',
|
||||
'd6_comment_type',
|
||||
'd6_comment_field',
|
||||
'd6_comment_field_instance',
|
||||
@@ -84,6 +93,31 @@ class MigrateCommentTest extends MigrateDrupal6TestBase {
|
||||
$node = $comment->getCommentedEntity();
|
||||
$this->assertInstanceOf(NodeInterface::class, $node);
|
||||
$this->assertSame('1', $node->id());
|
||||
|
||||
// Tests that the language of the comment is migrated from the node.
|
||||
$comment = Comment::load(7);
|
||||
$this->assertSame('Comment to John Smith - EN', $comment->subject->value);
|
||||
$this->assertSame('This is an English comment.', $comment->comment_body->value);
|
||||
$this->assertSame('21', $comment->getCommentedEntityId());
|
||||
$this->assertSame('node', $comment->getCommentedEntityTypeId());
|
||||
$this->assertSame('en', $comment->language()->getId());
|
||||
|
||||
$node = $comment->getCommentedEntity();
|
||||
$this->assertInstanceOf(NodeInterface::class, $node);
|
||||
$this->assertSame('21', $node->id());
|
||||
|
||||
// Tests that the comment language is correct and that the commented entity
|
||||
// is correctly migrated when the comment was posted to a node translation.
|
||||
$comment = Comment::load(8);
|
||||
$this->assertSame('Comment to John Smith - FR', $comment->subject->value);
|
||||
$this->assertSame('This is a French comment.', $comment->comment_body->value);
|
||||
$this->assertSame('21', $comment->getCommentedEntityId());
|
||||
$this->assertSame('node', $comment->getCommentedEntityTypeId());
|
||||
$this->assertSame('fr', $comment->language()->getId());
|
||||
|
||||
$node = $comment->getCommentedEntity();
|
||||
$this->assertInstanceOf(NodeInterface::class, $node);
|
||||
$this->assertSame('21', $node->id());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -19,11 +19,15 @@ class MigrateCommentTest extends MigrateDrupal7TestBase {
|
||||
*/
|
||||
public static $modules = [
|
||||
'comment',
|
||||
'content_translation',
|
||||
'datetime',
|
||||
'filter',
|
||||
'image',
|
||||
'language',
|
||||
'link',
|
||||
'menu_ui',
|
||||
// Required for translation migrations.
|
||||
'migrate_drupal_multilingual',
|
||||
'node',
|
||||
'taxonomy',
|
||||
'telephone',
|
||||
@@ -38,14 +42,19 @@ class MigrateCommentTest extends MigrateDrupal7TestBase {
|
||||
|
||||
$this->installEntitySchema('node');
|
||||
$this->installEntitySchema('comment');
|
||||
$this->installEntitySchema('taxonomy_term');
|
||||
$this->installConfig(['comment', 'node']);
|
||||
$this->installSchema('comment', ['comment_entity_statistics']);
|
||||
|
||||
$this->installSchema('node', ['node_access']);
|
||||
$this->executeMigrations([
|
||||
'language',
|
||||
'd7_node_type',
|
||||
'd7_language_content_settings',
|
||||
'd7_user_role',
|
||||
'd7_user',
|
||||
'd7_node_type',
|
||||
'd7_node',
|
||||
'd7_node_translation',
|
||||
'd7_comment_type',
|
||||
'd7_comment_field',
|
||||
'd7_comment_field_instance',
|
||||
@@ -55,6 +64,8 @@ class MigrateCommentTest extends MigrateDrupal7TestBase {
|
||||
'd7_field',
|
||||
'd7_field_instance',
|
||||
'd7_comment',
|
||||
'd7_entity_translation_settings',
|
||||
'd7_comment_entity_translation',
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -64,7 +75,7 @@ class MigrateCommentTest extends MigrateDrupal7TestBase {
|
||||
public function testMigration() {
|
||||
$comment = Comment::load(1);
|
||||
$this->assertInstanceOf(Comment::class, $comment);
|
||||
$this->assertSame('A comment', $comment->getSubject());
|
||||
$this->assertSame('Subject field in English', $comment->getSubject());
|
||||
$this->assertSame('1421727536', $comment->getCreatedTime());
|
||||
$this->assertSame('1421727536', $comment->getChangedTime());
|
||||
$this->assertTrue($comment->getStatus());
|
||||
@@ -73,6 +84,7 @@ class MigrateCommentTest extends MigrateDrupal7TestBase {
|
||||
$this->assertSame('This is a comment', $comment->comment_body->value);
|
||||
$this->assertSame('filtered_html', $comment->comment_body->format);
|
||||
$this->assertSame('2001:db8:ffff:ffff:ffff:ffff:ffff:ffff', $comment->getHostname());
|
||||
$this->assertSame('en', $comment->language()->getId());
|
||||
$this->assertSame('1000000', $comment->field_integer->value);
|
||||
|
||||
$node = $comment->getCommentedEntity();
|
||||
@@ -85,6 +97,59 @@ class MigrateCommentTest extends MigrateDrupal7TestBase {
|
||||
$this->assertInstanceOf(Comment::class, $comment);
|
||||
$this->assertSame('TNG for the win!', $comment->getSubject());
|
||||
$this->assertSame('TNG is better than DS9.', $comment->comment_body->value);
|
||||
$this->assertSame('en', $comment->language()->getId());
|
||||
|
||||
// Tests that the commented entity is correctly migrated when the comment
|
||||
// was posted to a node translation.
|
||||
$comment = Comment::load(3);
|
||||
$this->assertInstanceOf(Comment::class, $comment);
|
||||
$this->assertSame('Comment to IS translation', $comment->getSubject());
|
||||
$this->assertSame('This is a comment to an Icelandic translation.', $comment->comment_body->value);
|
||||
$this->assertSame('2', $comment->getCommentedEntityId());
|
||||
$this->assertSame('node', $comment->getCommentedEntityTypeId());
|
||||
$this->assertSame('is', $comment->language()->getId());
|
||||
|
||||
$node = $comment->getCommentedEntity();
|
||||
$this->assertInstanceOf(NodeInterface::class, $node);
|
||||
$this->assertSame('2', $node->id());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the migration of comment entity translations.
|
||||
*/
|
||||
public function testCommentEntityTranslations() {
|
||||
$manager = $this->container->get('content_translation.manager');
|
||||
|
||||
// Get the comment and its translations.
|
||||
$comment = Comment::load(1);
|
||||
$comment_fr = $comment->getTranslation('fr');
|
||||
$comment_is = $comment->getTranslation('is');
|
||||
|
||||
// Test that fields translated with Entity Translation are migrated.
|
||||
$this->assertSame('Subject field in English', $comment->getSubject());
|
||||
$this->assertSame('Subject field in French', $comment_fr->getSubject());
|
||||
$this->assertSame('Subject field in Icelandic', $comment_is->getSubject());
|
||||
$this->assertSame('1000000', $comment->field_integer->value);
|
||||
$this->assertSame('2000000', $comment_fr->field_integer->value);
|
||||
$this->assertSame('3000000', $comment_is->field_integer->value);
|
||||
|
||||
// Test that the French translation metadata is correctly migrated.
|
||||
$metadata_fr = $manager->getTranslationMetadata($comment_fr);
|
||||
$this->assertFalse($metadata_fr->isPublished());
|
||||
$this->assertSame('en', $metadata_fr->getSource());
|
||||
$this->assertSame('1', $metadata_fr->getAuthor()->uid->value);
|
||||
$this->assertSame('1531837764', $metadata_fr->getCreatedTime());
|
||||
$this->assertSame('1531837764', $metadata_fr->getChangedTime());
|
||||
$this->assertFalse($metadata_fr->isOutdated());
|
||||
|
||||
// Test that the Icelandic translation metadata is correctly migrated.
|
||||
$metadata_is = $manager->getTranslationMetadata($comment_is);
|
||||
$this->assertTrue($metadata_is->isPublished());
|
||||
$this->assertSame('en', $metadata_is->getSource());
|
||||
$this->assertSame('2', $metadata_is->getAuthor()->uid->value);
|
||||
$this->assertSame('1531838064', $metadata_is->getCreatedTime());
|
||||
$this->assertSame('1531838064', $metadata_is->getChangedTime());
|
||||
$this->assertTrue($metadata_is->isOutdated());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+3
@@ -66,10 +66,12 @@ class CommentSourceWithHighWaterTest extends MigrateSqlSourceTestBase {
|
||||
[
|
||||
'nid' => 2,
|
||||
'type' => 'story',
|
||||
'language' => 'en',
|
||||
],
|
||||
[
|
||||
'nid' => 3,
|
||||
'type' => 'page',
|
||||
'language' => 'fr',
|
||||
],
|
||||
];
|
||||
|
||||
@@ -91,6 +93,7 @@ class CommentSourceWithHighWaterTest extends MigrateSqlSourceTestBase {
|
||||
'homepage' => '',
|
||||
'format' => 'testformat2',
|
||||
'type' => 'page',
|
||||
'language' => 'fr',
|
||||
],
|
||||
];
|
||||
|
||||
|
||||
@@ -65,10 +65,12 @@ class CommentTest extends MigrateSqlSourceTestBase {
|
||||
[
|
||||
'nid' => 2,
|
||||
'type' => 'story',
|
||||
'language' => 'en',
|
||||
],
|
||||
[
|
||||
'nid' => 3,
|
||||
'type' => 'page',
|
||||
'language' => 'fr',
|
||||
],
|
||||
];
|
||||
|
||||
@@ -90,6 +92,7 @@ class CommentTest extends MigrateSqlSourceTestBase {
|
||||
'homepage' => '',
|
||||
'format' => 'testformat1',
|
||||
'type' => 'story',
|
||||
'language' => 'en',
|
||||
],
|
||||
[
|
||||
'cid' => 2,
|
||||
@@ -107,6 +110,7 @@ class CommentTest extends MigrateSqlSourceTestBase {
|
||||
'homepage' => '',
|
||||
'format' => 'testformat2',
|
||||
'type' => 'page',
|
||||
'language' => 'fr',
|
||||
],
|
||||
];
|
||||
|
||||
|
||||
+281
@@ -0,0 +1,281 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\comment\Kernel\Plugin\migrate\source\d7;
|
||||
|
||||
use Drupal\Tests\migrate\Kernel\MigrateSqlSourceTestBase;
|
||||
|
||||
/**
|
||||
* Tests D7 comment entity translation source plugin.
|
||||
*
|
||||
* @covers \Drupal\comment\Plugin\migrate\source\d7\CommentEntityTranslation
|
||||
* @group comment
|
||||
*/
|
||||
class CommentEntityTranslationTest extends MigrateSqlSourceTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['comment', 'migrate_drupal'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function providerSource() {
|
||||
$tests = [];
|
||||
|
||||
// The source data.
|
||||
$tests[0]['source_data']['comment'] = [
|
||||
[
|
||||
'cid' => '1',
|
||||
'pid' => '0',
|
||||
'nid' => '1',
|
||||
'uid' => '1',
|
||||
'subject' => 'A comment',
|
||||
'hostname' => '::1',
|
||||
'created' => '1421727536',
|
||||
'changed' => '1421727536',
|
||||
'status' => '1',
|
||||
'thread' => '01/',
|
||||
'name' => 'admin',
|
||||
'mail' => '',
|
||||
'homepage' => '',
|
||||
'language' => 'en',
|
||||
],
|
||||
];
|
||||
$tests[0]['source_data']['entity_translation'] = [
|
||||
[
|
||||
'entity_type' => 'comment',
|
||||
'entity_id' => 1,
|
||||
'revision_id' => 1,
|
||||
'language' => 'en',
|
||||
'source' => '',
|
||||
'uid' => 1,
|
||||
'status' => 1,
|
||||
'translate' => 0,
|
||||
'created' => '1421727536',
|
||||
'changed' => '1421727536',
|
||||
],
|
||||
[
|
||||
'entity_type' => 'comment',
|
||||
'entity_id' => 1,
|
||||
'revision_id' => 1,
|
||||
'language' => 'fr',
|
||||
'source' => 'en',
|
||||
'uid' => 1,
|
||||
'status' => 0,
|
||||
'translate' => 0,
|
||||
'created' => 1531343508,
|
||||
'changed' => 1531343508,
|
||||
],
|
||||
[
|
||||
'entity_type' => 'comment',
|
||||
'entity_id' => 1,
|
||||
'revision_id' => 1,
|
||||
'language' => 'es',
|
||||
'source' => 'en',
|
||||
'uid' => 2,
|
||||
'status' => 1,
|
||||
'translate' => 1,
|
||||
'created' => 1531343528,
|
||||
'changed' => 1531343528,
|
||||
],
|
||||
];
|
||||
$tests[0]['source_data']['field_config'] = [
|
||||
[
|
||||
'id' => 1,
|
||||
'field_name' => 'field_test',
|
||||
'type' => 'text',
|
||||
'module' => 'text',
|
||||
'active' => 1,
|
||||
'storage_type' => 'field_sql_storage',
|
||||
'storage_module' => 'field_sql_storage',
|
||||
'storage_active' => 1,
|
||||
'locked' => 1,
|
||||
'data' => 'a:0:{}',
|
||||
'cardinality' => 1,
|
||||
'translatable' => 1,
|
||||
'deleted' => 0,
|
||||
],
|
||||
[
|
||||
'id' => 2,
|
||||
'field_name' => 'subject_field',
|
||||
'type' => 'text',
|
||||
'module' => 'text',
|
||||
'active' => 1,
|
||||
'storage_type' => 'field_sql_storage',
|
||||
'storage_module' => 'field_sql_storage',
|
||||
'storage_active' => 1,
|
||||
'locked' => 1,
|
||||
'data' => 'a:0:{}',
|
||||
'cardinality' => 1,
|
||||
'translatable' => 1,
|
||||
'deleted' => 0,
|
||||
],
|
||||
];
|
||||
$tests[0]['source_data']['field_config_instance'] = [
|
||||
[
|
||||
'id' => '1',
|
||||
'field_id' => '1',
|
||||
'field_name' => 'field_test',
|
||||
'entity_type' => 'comment',
|
||||
'bundle' => 'comment_node_test_content_type',
|
||||
'data' => 'a:0:{}',
|
||||
'deleted' => '0',
|
||||
],
|
||||
[
|
||||
'id' => '2',
|
||||
'field_id' => '2',
|
||||
'field_name' => 'subject_field',
|
||||
'entity_type' => 'comment',
|
||||
'bundle' => 'comment_node_test_content_type',
|
||||
'data' => 'a:0:{}',
|
||||
'deleted' => '0',
|
||||
],
|
||||
];
|
||||
$tests[0]['source_data']['field_data_field_test'] = [
|
||||
[
|
||||
'entity_type' => 'comment',
|
||||
'bundle' => 'comment_node_test_content_type',
|
||||
'deleted' => '0',
|
||||
'entity_id' => '1',
|
||||
'revision_id' => '1',
|
||||
'language' => 'en',
|
||||
'delta' => '0',
|
||||
'field_test_value' => 'This is an English comment',
|
||||
'field_test_format' => NULL,
|
||||
],
|
||||
[
|
||||
'entity_type' => 'comment',
|
||||
'bundle' => 'comment_node_test_content_type',
|
||||
'deleted' => '0',
|
||||
'entity_id' => '1',
|
||||
'revision_id' => '1',
|
||||
'language' => 'fr',
|
||||
'delta' => '0',
|
||||
'field_test_value' => 'This is a French comment',
|
||||
'field_test_format' => NULL,
|
||||
],
|
||||
[
|
||||
'entity_type' => 'comment',
|
||||
'bundle' => 'comment_node_test_content_type',
|
||||
'deleted' => '0',
|
||||
'entity_id' => '1',
|
||||
'revision_id' => '1',
|
||||
'language' => 'es',
|
||||
'delta' => '0',
|
||||
'field_test_value' => 'This is a Spanish comment',
|
||||
'field_test_format' => NULL,
|
||||
],
|
||||
];
|
||||
$tests[0]['source_data']['field_data_subject_field'] = [
|
||||
[
|
||||
'entity_type' => 'comment',
|
||||
'bundle' => 'comment_node_test_content_type',
|
||||
'deleted' => '0',
|
||||
'entity_id' => '1',
|
||||
'revision_id' => '1',
|
||||
'language' => 'en',
|
||||
'delta' => '0',
|
||||
'subject_field_value' => 'Comment subject in English',
|
||||
'subject_field_format' => NULL,
|
||||
],
|
||||
[
|
||||
'entity_type' => 'comment',
|
||||
'bundle' => 'comment_node_test_content_type',
|
||||
'deleted' => '0',
|
||||
'entity_id' => '1',
|
||||
'revision_id' => '1',
|
||||
'language' => 'fr',
|
||||
'delta' => '0',
|
||||
'subject_field_value' => 'Comment subject in French',
|
||||
'subject_field_format' => NULL,
|
||||
],
|
||||
[
|
||||
'entity_type' => 'comment',
|
||||
'bundle' => 'comment_node_test_content_type',
|
||||
'deleted' => '0',
|
||||
'entity_id' => '1',
|
||||
'revision_id' => '1',
|
||||
'language' => 'es',
|
||||
'delta' => '0',
|
||||
'subject_field_value' => 'Comment subject in Spanish',
|
||||
'subject_field_format' => NULL,
|
||||
],
|
||||
];
|
||||
$tests[0]['source_data']['node'] = [
|
||||
[
|
||||
'nid' => '1',
|
||||
'vid' => '1',
|
||||
'type' => 'test_content_type',
|
||||
'language' => 'en',
|
||||
'title' => 'A Node',
|
||||
'uid' => '1',
|
||||
'status' => '1',
|
||||
'created' => '1421727515',
|
||||
'changed' => '1421727515',
|
||||
'comment' => '2',
|
||||
'promote' => '1',
|
||||
'sticky' => '0',
|
||||
'tnid' => '0',
|
||||
'translate' => '0',
|
||||
],
|
||||
];
|
||||
|
||||
// The expected results.
|
||||
$tests[0]['expected_data'] = [
|
||||
[
|
||||
'subject' => 'A comment',
|
||||
'entity_type' => 'comment',
|
||||
'entity_id' => '1',
|
||||
'revision_id' => '1',
|
||||
'language' => 'fr',
|
||||
'source' => 'en',
|
||||
'uid' => '1',
|
||||
'status' => '0',
|
||||
'translate' => '0',
|
||||
'created' => '1531343508',
|
||||
'changed' => '1531343508',
|
||||
'field_test' => [
|
||||
[
|
||||
'value' => 'This is a French comment',
|
||||
'format' => NULL,
|
||||
],
|
||||
],
|
||||
'subject_field' => [
|
||||
[
|
||||
'value' => 'Comment subject in French',
|
||||
'format' => NULL,
|
||||
],
|
||||
],
|
||||
],
|
||||
[
|
||||
'subject' => 'A comment',
|
||||
'entity_type' => 'comment',
|
||||
'entity_id' => '1',
|
||||
'revision_id' => '1',
|
||||
'language' => 'es',
|
||||
'source' => 'en',
|
||||
'uid' => '2',
|
||||
'status' => '1',
|
||||
'translate' => '1',
|
||||
'created' => '1531343528',
|
||||
'changed' => '1531343528',
|
||||
'field_test' => [
|
||||
[
|
||||
'value' => 'This is a Spanish comment',
|
||||
'format' => NULL,
|
||||
],
|
||||
],
|
||||
'subject_field' => [
|
||||
[
|
||||
'value' => 'Comment subject in Spanish',
|
||||
'format' => NULL,
|
||||
],
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
return $tests;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -107,7 +107,16 @@ class ConfigInstallProfileOverrideTest extends BrowserTestBase {
|
||||
$this->container->get('module_installer')->install(['dblog']);
|
||||
$this->rebuildContainer();
|
||||
$this->assertEqual($config_test_storage->load('override_unmet')->label(), 'Override', 'The optional config_test entity is overridden by the profile optional configuration and is installed when its dependencies are met.');
|
||||
$this->assertEqual($config_test_storage->load('completely_new')->label(), 'Completely new optional configuration', 'The optional config_test entity is provided by the profile optional configuration and is installed when its dependencies are met.');
|
||||
$config_test_new = $config_test_storage->load('completely_new');
|
||||
$this->assertEqual($config_test_new->label(), 'Completely new optional configuration', 'The optional config_test entity is provided by the profile optional configuration and is installed when its dependencies are met.');
|
||||
$config_test_new->delete();
|
||||
|
||||
// Install another module that provides optional configuration and ensure
|
||||
// that deleted profile configuration is not re-created.
|
||||
$this->container->get('module_installer')->install(['config_other_module_config_test']);
|
||||
$this->rebuildContainer();
|
||||
$config_test_storage = \Drupal::entityManager()->getStorage('config_test');
|
||||
$this->assertNull($config_test_storage->load('completely_new'));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ class ConfigUninstallViaCliImportTest extends KernelTestBase {
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that the config mopdule can be uninstalled via CLI config import.
|
||||
* Tests that the config module can be uninstalled via CLI config import.
|
||||
*
|
||||
* @see \Drupal\config\ConfigSubscriber
|
||||
*/
|
||||
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
id: d6_field_instance_label_description_translation
|
||||
label: Field label and description translation
|
||||
migration_tags:
|
||||
- Drupal 6
|
||||
- Configuration
|
||||
- Multilingual
|
||||
source:
|
||||
plugin: d6_field_instance_label_description_translation
|
||||
constants:
|
||||
entity_type: node
|
||||
process:
|
||||
langcode:
|
||||
plugin: skip_on_empty
|
||||
source: language
|
||||
method: row
|
||||
translation:
|
||||
plugin: skip_on_empty
|
||||
source: translation
|
||||
method: row
|
||||
field_name_parts:
|
||||
plugin: explode
|
||||
source: objectid
|
||||
delimiter: '-'
|
||||
field_name:
|
||||
plugin: extract
|
||||
source: '@field_name_parts'
|
||||
index:
|
||||
- 1
|
||||
bundle:
|
||||
plugin: extract
|
||||
source: '@field_name_parts'
|
||||
index:
|
||||
- 0
|
||||
exists:
|
||||
-
|
||||
plugin: migration_lookup
|
||||
migration: d6_field_instance
|
||||
source:
|
||||
- '@field_name'
|
||||
- '@bundle'
|
||||
-
|
||||
plugin: skip_on_empty
|
||||
method: row
|
||||
entity_type: 'constants/entity_type'
|
||||
property:
|
||||
plugin: static_map
|
||||
source: property
|
||||
bypass: true
|
||||
map:
|
||||
widget_label: label
|
||||
widget_description: description
|
||||
destination:
|
||||
plugin: entity:field_config
|
||||
translations: true
|
||||
migration_dependencies:
|
||||
required:
|
||||
- d6_field_instance
|
||||
@@ -0,0 +1,178 @@
|
||||
id: d6_field_instance_option_translation
|
||||
label: Field instance option configuration translation
|
||||
migration_tags:
|
||||
- Drupal 6
|
||||
- Configuration
|
||||
- Multilingual
|
||||
source:
|
||||
plugin: d6_field_instance_option_translation
|
||||
skip_count: true
|
||||
constants:
|
||||
entity_type: node
|
||||
property: settings
|
||||
process:
|
||||
# We skip field types that don't exist because they weren't migrated by the
|
||||
# field migration.
|
||||
field_type_exists:
|
||||
-
|
||||
plugin: migration_lookup
|
||||
migration: d6_field
|
||||
source:
|
||||
- objectid
|
||||
-
|
||||
plugin: extract
|
||||
index:
|
||||
- 1
|
||||
-
|
||||
plugin: skip_on_empty
|
||||
method: row
|
||||
# Use the process from d6_field to determine the field type.
|
||||
type:
|
||||
plugin: field_type
|
||||
source:
|
||||
- type
|
||||
- widget_type
|
||||
map:
|
||||
userreference:
|
||||
userreference_select: entity_reference
|
||||
userreference_buttons: entity_reference
|
||||
userreference_autocomplete: entity_reference
|
||||
nodereference:
|
||||
nodereference_select: entity_reference
|
||||
number_integer:
|
||||
number: integer
|
||||
optionwidgets_select: list_integer
|
||||
optionwidgets_buttons: list_integer
|
||||
optionwidgets_onoff: boolean
|
||||
number_decimal:
|
||||
number: decimal
|
||||
optionwidgets_select: list_float
|
||||
optionwidgets_buttons: list_float
|
||||
optionwidgets_onoff: boolean
|
||||
number_float:
|
||||
number: float
|
||||
optionwidgets_select: list_float
|
||||
optionwidgets_buttons: list_float
|
||||
optionwidgets_onoff: boolean
|
||||
email:
|
||||
email_textfield: email
|
||||
filefield:
|
||||
imagefield_widget: image
|
||||
filefield_widget: file
|
||||
fr_phone:
|
||||
phone_textfield: telephone
|
||||
be_phone:
|
||||
phone_textfield: telephone
|
||||
it_phone:
|
||||
phone_textfield: telephone
|
||||
el_phone:
|
||||
phone_textfield: telephone
|
||||
ch_phone:
|
||||
phone_textfield: telephone
|
||||
ca_phone:
|
||||
phone_textfield: telephone
|
||||
cr_phone:
|
||||
phone_textfield: telephone
|
||||
pa_phone:
|
||||
phone_textfield: telephone
|
||||
gb_phone:
|
||||
phone_textfield: telephone
|
||||
ru_phone:
|
||||
phone_textfield: telephone
|
||||
ua_phone:
|
||||
phone_textfield: telephone
|
||||
es_phone:
|
||||
phone_textfield: telephone
|
||||
au_phone:
|
||||
phone_textfield: telephone
|
||||
cs_phone:
|
||||
phone_textfield: telephone
|
||||
hu_phone:
|
||||
phone_textfield: telephone
|
||||
pl_phone:
|
||||
phone_textfield: telephone
|
||||
nl_phone:
|
||||
phone_textfield: telephone
|
||||
se_phone:
|
||||
phone_textfield: telephone
|
||||
za_phone:
|
||||
phone_textfield: telephone
|
||||
il_phone:
|
||||
phone_textfield: telephone
|
||||
nz_phone:
|
||||
phone_textfield: telephone
|
||||
br_phone:
|
||||
phone_textfield: telephone
|
||||
cl_phone:
|
||||
phone_textfield: telephone
|
||||
cn_phone:
|
||||
phone_textfield: telephone
|
||||
hk_phone:
|
||||
phone_textfield: telephone
|
||||
mo_phone:
|
||||
phone_textfield: telephone
|
||||
ph_phone:
|
||||
phone_textfield: telephone
|
||||
sg_phone:
|
||||
phone_textfield: telephone
|
||||
jo_phone:
|
||||
phone_textfield: telephone
|
||||
eg_phone:
|
||||
phone_textfield: telephone
|
||||
pk_phone:
|
||||
phone_textfield: telephone
|
||||
int_phone:
|
||||
phone_textfield: telephone
|
||||
boolean_type:
|
||||
-
|
||||
plugin: static_map
|
||||
source: '@type'
|
||||
map:
|
||||
boolean: boolean
|
||||
default_value: false
|
||||
-
|
||||
plugin: skip_on_empty
|
||||
method: row
|
||||
bundle:
|
||||
-
|
||||
plugin: migration_lookup
|
||||
migration: d6_node_type
|
||||
source: type_name
|
||||
-
|
||||
plugin: skip_on_empty
|
||||
method: row
|
||||
langcode:
|
||||
plugin: skip_on_empty
|
||||
source: language
|
||||
method: row
|
||||
field_name: objectid
|
||||
entity_type: 'constants/entity_type'
|
||||
results:
|
||||
plugin: d6_field_instance_option_translation
|
||||
source:
|
||||
- '@type'
|
||||
- global_settings
|
||||
translation:
|
||||
-
|
||||
plugin: extract
|
||||
source: '@results'
|
||||
index: [1]
|
||||
-
|
||||
plugin: skip_on_empty
|
||||
method: row
|
||||
property:
|
||||
-
|
||||
plugin: extract
|
||||
source: '@results'
|
||||
index: [0]
|
||||
-
|
||||
plugin: skip_on_empty
|
||||
method: row
|
||||
destination:
|
||||
plugin: entity:field_config
|
||||
translations: true
|
||||
migration_dependencies:
|
||||
required:
|
||||
- d6_node_type
|
||||
- d6_field_instance
|
||||
- d6_field_option_translation
|
||||
@@ -0,0 +1,144 @@
|
||||
id: d6_field_option_translation
|
||||
label: Field option configuration translation
|
||||
migration_tags:
|
||||
- Drupal 6
|
||||
- Configuration
|
||||
- Multilingual
|
||||
source:
|
||||
plugin: d6_field_option_translation
|
||||
skip_count: true
|
||||
constants:
|
||||
entity_type: node
|
||||
allowed_values: settings
|
||||
process:
|
||||
entity_type: 'constants/entity_type'
|
||||
status: active
|
||||
langcode:
|
||||
plugin: skip_on_empty
|
||||
source: language
|
||||
method: row
|
||||
field_name: objectid
|
||||
# Use the process from d6_field to determine the field type.
|
||||
type:
|
||||
plugin: field_type
|
||||
source:
|
||||
- type
|
||||
- widget_type
|
||||
map:
|
||||
userreference:
|
||||
userreference_select: entity_reference
|
||||
userreference_buttons: entity_reference
|
||||
userreference_autocomplete: entity_reference
|
||||
nodereference:
|
||||
nodereference_select: entity_reference
|
||||
number_integer:
|
||||
number: integer
|
||||
optionwidgets_select: list_integer
|
||||
optionwidgets_buttons: list_integer
|
||||
optionwidgets_onoff: boolean
|
||||
number_decimal:
|
||||
number: decimal
|
||||
optionwidgets_select: list_float
|
||||
optionwidgets_buttons: list_float
|
||||
optionwidgets_onoff: boolean
|
||||
number_float:
|
||||
number: float
|
||||
optionwidgets_select: list_float
|
||||
optionwidgets_buttons: list_float
|
||||
optionwidgets_onoff: boolean
|
||||
email:
|
||||
email_textfield: email
|
||||
filefield:
|
||||
imagefield_widget: image
|
||||
filefield_widget: file
|
||||
fr_phone:
|
||||
phone_textfield: telephone
|
||||
be_phone:
|
||||
phone_textfield: telephone
|
||||
it_phone:
|
||||
phone_textfield: telephone
|
||||
el_phone:
|
||||
phone_textfield: telephone
|
||||
ch_phone:
|
||||
phone_textfield: telephone
|
||||
ca_phone:
|
||||
phone_textfield: telephone
|
||||
cr_phone:
|
||||
phone_textfield: telephone
|
||||
pa_phone:
|
||||
phone_textfield: telephone
|
||||
gb_phone:
|
||||
phone_textfield: telephone
|
||||
ru_phone:
|
||||
phone_textfield: telephone
|
||||
ua_phone:
|
||||
phone_textfield: telephone
|
||||
es_phone:
|
||||
phone_textfield: telephone
|
||||
au_phone:
|
||||
phone_textfield: telephone
|
||||
cs_phone:
|
||||
phone_textfield: telephone
|
||||
hu_phone:
|
||||
phone_textfield: telephone
|
||||
pl_phone:
|
||||
phone_textfield: telephone
|
||||
nl_phone:
|
||||
phone_textfield: telephone
|
||||
se_phone:
|
||||
phone_textfield: telephone
|
||||
za_phone:
|
||||
phone_textfield: telephone
|
||||
il_phone:
|
||||
phone_textfield: telephone
|
||||
nz_phone:
|
||||
phone_textfield: telephone
|
||||
br_phone:
|
||||
phone_textfield: telephone
|
||||
cl_phone:
|
||||
phone_textfield: telephone
|
||||
cn_phone:
|
||||
phone_textfield: telephone
|
||||
hk_phone:
|
||||
phone_textfield: telephone
|
||||
mo_phone:
|
||||
phone_textfield: telephone
|
||||
ph_phone:
|
||||
phone_textfield: telephone
|
||||
sg_phone:
|
||||
phone_textfield: telephone
|
||||
jo_phone:
|
||||
phone_textfield: telephone
|
||||
eg_phone:
|
||||
phone_textfield: telephone
|
||||
pk_phone:
|
||||
phone_textfield: telephone
|
||||
int_phone:
|
||||
phone_textfield: telephone
|
||||
results:
|
||||
plugin: d6_field_option_translation
|
||||
source:
|
||||
- '@type'
|
||||
- global_settings
|
||||
translation:
|
||||
-
|
||||
plugin: extract
|
||||
source: '@results'
|
||||
index: [1]
|
||||
-
|
||||
plugin: skip_on_empty
|
||||
method: row
|
||||
property:
|
||||
-
|
||||
plugin: extract
|
||||
source: '@results'
|
||||
index: [0]
|
||||
-
|
||||
plugin: skip_on_empty
|
||||
method: row
|
||||
destination:
|
||||
plugin: entity:field_storage_config
|
||||
translations: true
|
||||
migration_dependencies:
|
||||
required:
|
||||
- d6_field
|
||||
@@ -5,7 +5,7 @@ migration_tags:
|
||||
- Configuration
|
||||
- Multilingual
|
||||
source:
|
||||
plugin: variable_translation
|
||||
plugin: d6_variable_translation
|
||||
variables:
|
||||
- site_offline_message
|
||||
source_module: i18n
|
||||
|
||||
@@ -5,7 +5,7 @@ migration_tags:
|
||||
- Configuration
|
||||
- Multilingual
|
||||
source:
|
||||
plugin: variable_translation
|
||||
plugin: d6_variable_translation
|
||||
constants:
|
||||
slash: '/'
|
||||
variables:
|
||||
|
||||
@@ -5,7 +5,7 @@ migration_tags:
|
||||
- Configuration
|
||||
- Multilingual
|
||||
source:
|
||||
plugin: variable_translation
|
||||
plugin: d6_variable_translation
|
||||
variables:
|
||||
- user_mail_status_activated_subject
|
||||
- user_mail_status_activated_body
|
||||
|
||||
@@ -5,7 +5,7 @@ migration_tags:
|
||||
- Configuration
|
||||
- Multilingual
|
||||
source:
|
||||
plugin: variable_translation
|
||||
plugin: d6_variable_translation
|
||||
variables:
|
||||
- user_mail_status_blocked_notify
|
||||
- user_mail_status_activated_notify
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
id: d7_system_maintenance_translation
|
||||
label: Maintenance page configuration
|
||||
migration_tags:
|
||||
- Drupal 7
|
||||
- Configuration
|
||||
- Multilingual
|
||||
source:
|
||||
plugin: d7_variable_translation
|
||||
variables:
|
||||
- maintenance_mode_message
|
||||
process:
|
||||
langcode: language
|
||||
message: maintenance_mode_message
|
||||
destination:
|
||||
plugin: config
|
||||
config_name: system.maintenance
|
||||
translations: true
|
||||
@@ -0,0 +1,27 @@
|
||||
id: d7_system_site_translation
|
||||
label: Site configuration translation
|
||||
migration_tags:
|
||||
- Drupal 7
|
||||
- Configuration
|
||||
- Multilingual
|
||||
source:
|
||||
plugin: d7_variable_translation
|
||||
variables:
|
||||
- site_name
|
||||
- site_mail
|
||||
- site_slogan
|
||||
- site_frontpage
|
||||
- site_403
|
||||
- site_404
|
||||
process:
|
||||
langcode: language
|
||||
name: site_name
|
||||
mail: site_mail
|
||||
slogan: site_slogan
|
||||
'page/front': site_frontpage
|
||||
'page/403': site_403
|
||||
'page/404': site_404
|
||||
destination:
|
||||
plugin: config
|
||||
config_name: system.site
|
||||
translations: true
|
||||
@@ -0,0 +1,79 @@
|
||||
id: d7_user_mail_translation
|
||||
label: User mail configuration translation
|
||||
migration_tags:
|
||||
- Drupal 7
|
||||
- Configuration
|
||||
- Multilingual
|
||||
source:
|
||||
plugin: d7_variable_translation
|
||||
variables:
|
||||
- user_mail_cancel_confirm_subject
|
||||
- user_mail_cancel_confirm_body
|
||||
- user_mail_password_reset_subject
|
||||
- user_mail_password_reset_body
|
||||
- user_mail_register_admin_created_subject
|
||||
- user_mail_register_admin_created_body
|
||||
- user_mail_register_no_approval_required_subject
|
||||
- user_mail_register_no_approval_required_body
|
||||
- user_mail_register_pending_approval_subject
|
||||
- user_mail_register_pending_approval_body
|
||||
- user_mail_status_activated_subject
|
||||
- user_mail_status_activated_body
|
||||
- user_mail_status_blocked_subject
|
||||
- user_mail_status_blocked_body
|
||||
- user_mail_status_canceled_subject
|
||||
- user_mail_status_canceled_body
|
||||
process:
|
||||
langcode: language
|
||||
'cancel_confirm/subject':
|
||||
plugin: convert_tokens
|
||||
source: user_mail_cancel_confirm_subject
|
||||
'cancel_confirm/body':
|
||||
plugin: convert_tokens
|
||||
source: user_mail_cancel_confirm_body
|
||||
'password_reset/subject':
|
||||
plugin: convert_tokens
|
||||
source: user_mail_password_reset_subject
|
||||
'password_reset/body':
|
||||
plugin: convert_tokens
|
||||
source: user_mail_password_reset_body
|
||||
'register_admin_created/subject':
|
||||
plugin: convert_tokens
|
||||
source: user_mail_register_admin_created_subject
|
||||
'register_admin_created/body':
|
||||
plugin: convert_tokens
|
||||
source: user_mail_register_admin_created_body
|
||||
'register_no_approval_required/subject':
|
||||
plugin: convert_tokens
|
||||
source: user_mail_register_no_approval_required_subject
|
||||
'register_no_approval_required/body':
|
||||
plugin: convert_tokens
|
||||
source: user_mail_register_no_approval_required_body
|
||||
'register_pending_approval/subject':
|
||||
plugin: convert_tokens
|
||||
source: user_mail_register_pending_approval_subject
|
||||
'register_pending_approval/body':
|
||||
plugin: convert_tokens
|
||||
source: user_mail_register_pending_approval_body
|
||||
'status_activated/subject':
|
||||
plugin: convert_tokens
|
||||
source: user_mail_status_activated_subject
|
||||
'status_activated/body':
|
||||
plugin: convert_tokens
|
||||
source: user_mail_status_activated_body
|
||||
'status_blocked/subject':
|
||||
plugin: convert_tokens
|
||||
source: user_mail_status_blocked_subject
|
||||
'status_blocked/body':
|
||||
plugin: convert_tokens
|
||||
source: user_mail_status_blocked_body
|
||||
'status_canceled/subject':
|
||||
plugin: convert_tokens
|
||||
source: user_mail_status_canceled_subject
|
||||
'status_canceled/body':
|
||||
plugin: convert_tokens
|
||||
source: user_mail_status_canceled_body
|
||||
destination:
|
||||
plugin: config
|
||||
config_name: user.mail
|
||||
translations: true
|
||||
@@ -0,0 +1,17 @@
|
||||
id: d7_user_settings_translation
|
||||
label: User settings configuration translation
|
||||
migration_tags:
|
||||
- Drupal 7
|
||||
- Configuration
|
||||
- Multilingual
|
||||
source:
|
||||
plugin: d7_variable_translation
|
||||
variables:
|
||||
- anonymous
|
||||
process:
|
||||
langcode: language
|
||||
anonymous: anonymous
|
||||
destination:
|
||||
plugin: config
|
||||
config_name: user.settings
|
||||
translations: true
|
||||
@@ -23,7 +23,7 @@ interface ElementInterface {
|
||||
public static function create(TypedDataInterface $schema);
|
||||
|
||||
/**
|
||||
* Builds a render array containg the source and translation form elements.
|
||||
* Builds a render array containing the source and translation form elements.
|
||||
*
|
||||
* @param \Drupal\Core\Language\LanguageInterface $source_language
|
||||
* The source language of the configuration object.
|
||||
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\config_translation\Kernel\Migrate\d7;
|
||||
|
||||
use Drupal\Tests\migrate_drupal\Kernel\d7\MigrateDrupal7TestBase;
|
||||
|
||||
/**
|
||||
* Tests migrations of i18n maintenance variable.
|
||||
*
|
||||
* @group migrate_drupal_7
|
||||
*/
|
||||
class MigrateSystemMaintenanceTranslationTest extends MigrateDrupal7TestBase {
|
||||
|
||||
public static $modules = [
|
||||
'language',
|
||||
'config_translation',
|
||||
// Required for translation migrations.
|
||||
'migrate_drupal_multilingual',
|
||||
];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$this->executeMigration('d7_system_maintenance_translation');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests migrations of i18n maintenance variable.
|
||||
*/
|
||||
public function testSystemMaintenance() {
|
||||
$config = \Drupal::service('language_manager')->getLanguageConfigOverride('is', 'system.maintenance');
|
||||
$this->assertSame('is - This is a custom maintenance mode message.', $config->get('message'));
|
||||
}
|
||||
|
||||
}
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\config_translation\Kernel\Migrate\d7;
|
||||
|
||||
use Drupal\Tests\migrate_drupal\Kernel\d7\MigrateDrupal7TestBase;
|
||||
|
||||
/**
|
||||
* Migrate multilingual site variables.
|
||||
*
|
||||
* @group migrate_drupal_7
|
||||
*/
|
||||
class MigrateSystemSiteTranslationTest extends MigrateDrupal7TestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = [
|
||||
'language',
|
||||
'config_translation',
|
||||
// Required for translation migrations.
|
||||
'migrate_drupal_multilingual',
|
||||
];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$this->executeMigration('d7_system_site_translation');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests migration of system (site) variables to system.site.yml.
|
||||
*/
|
||||
public function testSystemSite() {
|
||||
$language_manager = \Drupal::service('language_manager');
|
||||
$config_translation = $language_manager->getLanguageConfigOverride('fr', 'system.site');
|
||||
$this->assertSame('The Site Name', $config_translation->get('name'));
|
||||
$this->assertSame('fr - The Slogan', $config_translation->get('slogan'));
|
||||
$this->assertSame('node', $config_translation->get('page.403'));
|
||||
$this->assertSame('node', $config_translation->get('page.404'));
|
||||
$this->assertSame('node', $config_translation->get('page.front'));
|
||||
$this->assertSame(NULL, $config_translation->get('admin_compact_mode'));
|
||||
|
||||
$config_translation = $language_manager->getLanguageConfigOverride('is', 'system.site');
|
||||
$this->assertSame('is - The Site Name', $config_translation->get('name'));
|
||||
$this->assertSame('is - The Slogan', $config_translation->get('slogan'));
|
||||
$this->assertSame('node/1', $config_translation->get('page.403'));
|
||||
$this->assertSame('node/6', $config_translation->get('page.404'));
|
||||
$this->assertSame('node/4', $config_translation->get('page.front'));
|
||||
$this->assertNULL($config_translation->get('admin_compact_mode'));
|
||||
}
|
||||
|
||||
}
|
||||
+74
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\config_translation\Kernel\Migrate\d7;
|
||||
|
||||
use Drupal\Tests\SchemaCheckTestTrait;
|
||||
use Drupal\Tests\migrate_drupal\Kernel\d7\MigrateDrupal7TestBase;
|
||||
|
||||
/**
|
||||
* Test migration of i18n user variables.
|
||||
*
|
||||
* @group migrate_drupal_7
|
||||
*/
|
||||
class MigrateUserConfigsTranslationTest extends MigrateDrupal7TestBase {
|
||||
|
||||
use SchemaCheckTestTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = [
|
||||
'language',
|
||||
'locale',
|
||||
'config_translation',
|
||||
// Required for translation migrations.
|
||||
'migrate_drupal_multilingual',
|
||||
];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$this->installSchema('locale', [
|
||||
'locales_source',
|
||||
'locales_target',
|
||||
'locales_location',
|
||||
]);
|
||||
$this->executeMigrations([
|
||||
'd7_user_mail_translation',
|
||||
'd7_user_settings_translation',
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests migration of i18n user variables to user.mail and user.settings.
|
||||
*/
|
||||
public function testUserConfig() {
|
||||
// Tests migration of i18n user variables to user.mail.yml.
|
||||
$language_manager = \Drupal::service('language_manager');
|
||||
$config = $language_manager->getLanguageConfigOverride('is', 'user.mail');
|
||||
$this->assertSame('is - Are you sure?', $config->get('cancel_confirm.subject'));
|
||||
$this->assertSame('is - A little birdie said you wanted to cancel your account.', $config->get('cancel_confirm.body'));
|
||||
$this->assertSame('is - Fix your password', $config->get('password_reset.subject'));
|
||||
$this->assertSame("is - Nope! You're locked out forever.", $config->get('password_reset.body'));
|
||||
$this->assertSame('is - Gawd made you an account', $config->get('register_admin_created.subject'));
|
||||
$this->assertSame("is - ...and she could take it away.\r\n[site:name], [site:url]", $config->get('register_admin_created.body'));
|
||||
$this->assertSame('is - Welcome!', $config->get('register_no_approval_required.subject'));
|
||||
$this->assertSame('is - You can now log in if you can figure out how to use Drupal!', $config->get('register_no_approval_required.body'));
|
||||
$this->assertSame('is - Soon...', $config->get('register_pending_approval.subject'));
|
||||
$this->assertSame('is - ...you will join our Circle. Let the Drupal flow through you.', $config->get('register_pending_approval.body'));
|
||||
$this->assertSame('is - Your account is approved!', $config->get('status_activated.subject'));
|
||||
$this->assertSame('is - Your account was activated, and there was much rejoicing.', $config->get('status_activated.body'));
|
||||
$this->assertSame('is - BEGONE!', $config->get('status_blocked.subject'));
|
||||
$this->assertSame('is - You no longer please the robot overlords. Go to your room and chill out.', $config->get('status_blocked.body'));
|
||||
$this->assertSame('is - So long, bub', $config->get('status_canceled.subject'));
|
||||
$this->assertSame('is - The gates of Drupal are closed to you. Now you will work in the salt mines.', $config->get('status_canceled.body'));
|
||||
$this->assertConfigSchema(\Drupal::service('config.typed'), 'user.mail', $config->get());
|
||||
|
||||
// Tests migration of i18n user variables to user.settings.yml.
|
||||
$config = $language_manager->getLanguageConfigOverride('is', 'user.settings');
|
||||
$this->assertSame('is - anonymous', $config->get('anonymous'));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -5,9 +5,9 @@ namespace Drupal\Tests\contact\Functional;
|
||||
use Drupal\contact\Entity\ContactForm;
|
||||
use Drupal\Core\Mail\MailFormatHelper;
|
||||
use Drupal\Core\Test\AssertMailTrait;
|
||||
use Drupal\field_ui\Tests\FieldUiTestTrait;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
use Drupal\Core\Entity\EntityTypeInterface;
|
||||
use Drupal\Tests\field_ui\Traits\FieldUiTestTrait;
|
||||
use Drupal\user\RoleInterface;
|
||||
|
||||
/**
|
||||
|
||||
+1
-1
@@ -127,7 +127,7 @@ class ModerationStateWidget extends OptionsSelectWidget implements ContainerFact
|
||||
$transitions = $this->validator->getValidTransitions($entity, $this->currentUser);
|
||||
|
||||
$transition_labels = [];
|
||||
$default_value = NULL;
|
||||
$default_value = $items->value;
|
||||
foreach ($transitions as $transition) {
|
||||
$transition_to_state = $transition->to();
|
||||
$transition_labels[$transition_to_state->id()] = $transition_to_state->label();
|
||||
|
||||
@@ -16,7 +16,6 @@ use Drupal\Core\TypedData\ComputedItemListTrait;
|
||||
class ModerationStateFieldItemList extends FieldItemList {
|
||||
|
||||
use ComputedItemListTrait {
|
||||
ensureComputedValue as traitEnsureComputedValue;
|
||||
get as traitGet;
|
||||
}
|
||||
|
||||
@@ -34,19 +33,6 @@ class ModerationStateFieldItemList extends FieldItemList {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function ensureComputedValue() {
|
||||
// If the moderation state field is set to an empty value, always recompute
|
||||
// the state. Empty is not a valid moderation state value, when none is
|
||||
// present the default state is used.
|
||||
if (!isset($this->list[0]) || $this->list[0]->isEmpty()) {
|
||||
$this->valueComputed = FALSE;
|
||||
}
|
||||
$this->traitEnsureComputedValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the moderation state ID linked to a content entity revision.
|
||||
*
|
||||
@@ -140,10 +126,8 @@ class ModerationStateFieldItemList extends FieldItemList {
|
||||
*/
|
||||
public function setValue($values, $notify = TRUE) {
|
||||
parent::setValue($values, $notify);
|
||||
$this->valueComputed = TRUE;
|
||||
|
||||
if (isset($this->list[0])) {
|
||||
$this->valueComputed = TRUE;
|
||||
}
|
||||
// If the parent created a field item and if the parent should be notified
|
||||
// about the change (e.g. this is not initialized with the current value),
|
||||
// update the moderated entity.
|
||||
|
||||
+8
@@ -9,6 +9,7 @@ use Drupal\Core\Entity\EntityInterface;
|
||||
use Drupal\Core\Entity\EntityTypeManagerInterface;
|
||||
use Drupal\content_moderation\ModerationInformationInterface;
|
||||
use Drupal\Core\Session\AccountInterface;
|
||||
use Drupal\Core\Validation\Plugin\Validation\Constraint\NotNullConstraint;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Symfony\Component\Validator\Constraint;
|
||||
use Symfony\Component\Validator\ConstraintValidator;
|
||||
@@ -89,6 +90,13 @@ class ModerationStateConstraintValidator extends ConstraintValidator implements
|
||||
return;
|
||||
}
|
||||
|
||||
// If the entity is moderated and the item list is empty, ensure users see
|
||||
// the same required message as typical NotNull constraints.
|
||||
if ($value->isEmpty()) {
|
||||
$this->context->addViolation((new NotNullConstraint())->message);
|
||||
return;
|
||||
}
|
||||
|
||||
$workflow = $this->moderationInformation->getWorkflowForEntity($entity);
|
||||
|
||||
if (!$workflow->getTypePlugin()->hasState($entity->moderation_state->value)) {
|
||||
|
||||
+57
-6
@@ -102,20 +102,70 @@ class ModerationStateFieldItemListTest extends KernelTestBase {
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the computed field when it is unset or set to an empty value.
|
||||
* Tests the item list when it is emptied and appended to.
|
||||
*/
|
||||
public function testSetEmptyState() {
|
||||
public function testEmptyStateAndAppend() {
|
||||
// This test case mimics the lifecycle of an entity that is being patched in
|
||||
// a rest resource.
|
||||
$this->testNode->moderation_state->setValue([]);
|
||||
$this->assertTrue($this->testNode->moderation_state->isEmpty());
|
||||
$this->assertEmptiedModerationFieldItemList();
|
||||
|
||||
$this->testNode->moderation_state->appendItem();
|
||||
$this->assertEquals(1, $this->testNode->moderation_state->count());
|
||||
$this->assertEquals(NULL, $this->testNode->moderation_state->value);
|
||||
$this->assertEmptiedModerationFieldItemList();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test an empty value assigned to the field item.
|
||||
*/
|
||||
public function testEmptyFieldItem() {
|
||||
$this->testNode->moderation_state->value = '';
|
||||
$this->assertEquals('draft', $this->testNode->moderation_state->value);
|
||||
$this->assertEquals('', $this->testNode->moderation_state->value);
|
||||
$this->assertEmptiedModerationFieldItemList();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test an empty value assigned to the field item list.
|
||||
*/
|
||||
public function testEmptyFieldItemList() {
|
||||
$this->testNode->moderation_state = '';
|
||||
$this->assertEquals('draft', $this->testNode->moderation_state->value);
|
||||
$this->assertEquals('', $this->testNode->moderation_state->value);
|
||||
$this->assertEmptiedModerationFieldItemList();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the field item when it is unset.
|
||||
*/
|
||||
public function testUnsetItemList() {
|
||||
unset($this->testNode->moderation_state);
|
||||
$this->assertEquals('draft', $this->testNode->moderation_state->value);
|
||||
$this->assertEquals(NULL, $this->testNode->moderation_state->value);
|
||||
$this->assertEmptiedModerationFieldItemList();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the field item when it is assigned NULL.
|
||||
*/
|
||||
public function testAssignNullItemList() {
|
||||
$this->testNode->moderation_state = NULL;
|
||||
$this->assertEquals('draft', $this->testNode->moderation_state->value);
|
||||
$this->assertEquals(NULL, $this->testNode->moderation_state->value);
|
||||
$this->assertEmptiedModerationFieldItemList();
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert the set of expectations when the moderation state field is emptied.
|
||||
*/
|
||||
protected function assertEmptiedModerationFieldItemList() {
|
||||
$this->assertTrue($this->testNode->moderation_state->isEmpty());
|
||||
// Test the empty value causes a violation in the entity.
|
||||
$violations = $this->testNode->validate();
|
||||
$this->assertCount(1, $violations);
|
||||
$this->assertEquals('This value should not be null.', $violations->get(0)->getMessage());
|
||||
// Test that incorrectly saving the entity regardless will not produce a
|
||||
// change in the moderation state.
|
||||
$this->testNode->save();
|
||||
$this->assertEquals('draft', Node::load($this->testNode->id())->moderation_state->value);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -131,6 +181,7 @@ class ModerationStateFieldItemListTest extends KernelTestBase {
|
||||
|
||||
$unmoderated_node->moderation_state = NULL;
|
||||
$this->assertEquals(0, $unmoderated_node->moderation_state->count());
|
||||
$this->assertCount(0, $unmoderated_node->validate());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
id: d7_comment_entity_translation
|
||||
label: Comment entity translations
|
||||
migration_tags:
|
||||
- Drupal 7
|
||||
- translation
|
||||
- Content
|
||||
class: Drupal\comment\Plugin\migrate\D7Comment
|
||||
source:
|
||||
plugin: d7_comment_entity_translation
|
||||
process:
|
||||
cid: entity_id
|
||||
subject: subject
|
||||
langcode: language
|
||||
uid: uid
|
||||
status: status
|
||||
created: created
|
||||
changed: changed
|
||||
content_translation_source: source
|
||||
content_translation_outdated: translate
|
||||
destination:
|
||||
plugin: entity:comment
|
||||
translations: true
|
||||
destination_module: content_translation
|
||||
migration_dependencies:
|
||||
required:
|
||||
- language
|
||||
- d7_entity_translation_settings
|
||||
- d7_comment
|
||||
@@ -0,0 +1,50 @@
|
||||
id: d7_custom_block_translation
|
||||
label: Custom block translations
|
||||
migration_tags:
|
||||
- Drupal 7
|
||||
- Content
|
||||
- Multilingual
|
||||
source:
|
||||
plugin: d7_block_custom_translation
|
||||
process:
|
||||
id:
|
||||
plugin: migration_lookup
|
||||
migration: d7_custom_block
|
||||
source:
|
||||
- bid
|
||||
langcode: language
|
||||
info:
|
||||
-
|
||||
plugin: callback
|
||||
source:
|
||||
- title_translated
|
||||
- title
|
||||
callable: array_filter
|
||||
-
|
||||
plugin: callback
|
||||
callable: current
|
||||
'body/value':
|
||||
-
|
||||
plugin: callback
|
||||
source:
|
||||
- body_translated
|
||||
- body
|
||||
callable: array_filter
|
||||
-
|
||||
plugin: callback
|
||||
callable: current
|
||||
'body/format':
|
||||
plugin: migration_lookup
|
||||
migration: d7_filter_format
|
||||
source: format
|
||||
destination:
|
||||
plugin: entity:block_content
|
||||
no_stub: true
|
||||
translations: true
|
||||
destination_module: content_translation
|
||||
migration_dependencies:
|
||||
required:
|
||||
- d7_filter_format
|
||||
- block_content_body_field
|
||||
- d7_custom_block
|
||||
- language
|
||||
+4
@@ -23,10 +23,14 @@ process:
|
||||
revision_log: log
|
||||
revision_timestamp: timestamp
|
||||
content_translation_source: source
|
||||
# Boolean indicating whether this translation needs to be updated.
|
||||
content_translation_outdated: translate
|
||||
destination:
|
||||
plugin: entity:node
|
||||
translations: true
|
||||
destination_module: content_translation
|
||||
migration_dependencies:
|
||||
required:
|
||||
- language
|
||||
- d7_entity_translation_settings
|
||||
- d7_node
|
||||
@@ -0,0 +1,32 @@
|
||||
id: d7_taxonomy_term_entity_translation
|
||||
label: Taxonomy term entity translations
|
||||
migration_tags:
|
||||
- Drupal 7
|
||||
- translation
|
||||
- Content
|
||||
- Multilingual
|
||||
deriver: Drupal\taxonomy\Plugin\migrate\D7TaxonomyTermDeriver
|
||||
source:
|
||||
plugin: d7_taxonomy_term_entity_translation
|
||||
process:
|
||||
tid: entity_id
|
||||
name: name
|
||||
description/value: description
|
||||
description/format: format
|
||||
langcode: language
|
||||
status: status
|
||||
content_translation_source: source
|
||||
content_translation_outdated: translate
|
||||
content_translation_uid: uid
|
||||
content_translation_created: created
|
||||
changed: changed
|
||||
forum_container: is_container
|
||||
destination:
|
||||
plugin: entity:taxonomy_term
|
||||
translations: true
|
||||
destination_module: content_translation
|
||||
migration_dependencies:
|
||||
required:
|
||||
- language
|
||||
- d7_entity_translation_settings
|
||||
- d7_taxonomy_term
|
||||
@@ -145,37 +145,14 @@ class ContentTranslationController extends ControllerBase {
|
||||
$translations = $entity->getTranslationLanguages();
|
||||
}
|
||||
|
||||
$add_url = new Url(
|
||||
"entity.$entity_type_id.content_translation_add",
|
||||
[
|
||||
'source' => $original,
|
||||
'target' => $language->getId(),
|
||||
$entity_type_id => $entity->id(),
|
||||
],
|
||||
[
|
||||
'language' => $language,
|
||||
]
|
||||
);
|
||||
$edit_url = new Url(
|
||||
"entity.$entity_type_id.content_translation_edit",
|
||||
[
|
||||
'language' => $language->getId(),
|
||||
$entity_type_id => $entity->id(),
|
||||
],
|
||||
[
|
||||
'language' => $language,
|
||||
]
|
||||
);
|
||||
$delete_url = new Url(
|
||||
"entity.$entity_type_id.content_translation_delete",
|
||||
[
|
||||
'language' => $language->getId(),
|
||||
$entity_type_id => $entity->id(),
|
||||
],
|
||||
[
|
||||
'language' => $language,
|
||||
]
|
||||
);
|
||||
$options = ['language' => $language];
|
||||
$add_url = $entity->toUrl('drupal:content-translation-add', $options)
|
||||
->setRouteParameter('source', $original)
|
||||
->setRouteParameter('target', $language->getId());
|
||||
$edit_url = $entity->toUrl('drupal:content-translation-edit', $options)
|
||||
->setRouteParameter('language', $language->getId());
|
||||
$delete_url = $entity->toUrl('drupal:content-translation-delete', $options)
|
||||
->setRouteParameter('language', $language->getId());
|
||||
$operations = [
|
||||
'data' => [
|
||||
'#type' => 'operations',
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\content_translation\Plugin\migrate\source;
|
||||
|
||||
use Drupal\migrate\Plugin\MigrateIdMapInterface;
|
||||
use Drupal\migrate\MigrateException;
|
||||
use Drupal\migrate\Row;
|
||||
|
||||
/**
|
||||
* Gets an i18n translation from the source database.
|
||||
*/
|
||||
trait I18nQueryTrait {
|
||||
|
||||
/**
|
||||
* The i18n string table name.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $i18nStringTable;
|
||||
|
||||
/**
|
||||
* Gets the translation for the property not already in the row.
|
||||
*
|
||||
* For some i18n migrations there are two translation values, such as a
|
||||
* translated title and a translated description, that need to be retrieved.
|
||||
* Since these values are stored in separate rows of the i18nStringTable
|
||||
* table we get them individually, one in the source plugin query() and the
|
||||
* other in prepareRow(). The names of the properties varies, for example,
|
||||
* in BoxTranslation they are 'body' and 'title' whereas in
|
||||
* MenuLinkTranslation they are 'title' and 'description'. This will save both
|
||||
* translations to the row.
|
||||
*
|
||||
* @param \Drupal\migrate\Row $row
|
||||
* The current migration row which must include both a 'language' property
|
||||
* and an 'objectid' property. The 'objectid' is the value for the
|
||||
* 'objectid' field in the i18n_string table.
|
||||
* @param string $property_not_in_row
|
||||
* The name of the property to get the translation for.
|
||||
* @param string $object_id_name
|
||||
* The value of the objectid in the i18n table.
|
||||
* @param \Drupal\migrate\Plugin\MigrateIdMapInterface $id_map
|
||||
* The ID map.
|
||||
*
|
||||
* @return bool
|
||||
* FALSE if the property has already been migrated.
|
||||
*
|
||||
* @throws \Drupal\migrate\MigrateException
|
||||
*/
|
||||
protected function getPropertyNotInRowTranslation(Row $row, $property_not_in_row, $object_id_name, MigrateIdMapInterface $id_map) {
|
||||
$language = $row->getSourceProperty('language');
|
||||
if (!$language) {
|
||||
throw new MigrateException('No language found.');
|
||||
}
|
||||
$object_id = $row->getSourceProperty($object_id_name);
|
||||
if (!$object_id) {
|
||||
throw new MigrateException('No objectid found.');
|
||||
}
|
||||
|
||||
// If this row has been migrated it is a duplicate so skip it.
|
||||
if ($id_map->lookupDestinationIds([$object_id_name => $object_id, 'language' => $language])) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Save the translation for the property already in the row.
|
||||
$property_in_row = $row->getSourceProperty('property');
|
||||
$row->setSourceProperty($property_in_row . '_translated', $row->getSourceProperty('translation'));
|
||||
|
||||
// Get the translation, if one exists, for the property not already in the
|
||||
// row.
|
||||
$query = $this->select($this->i18nStringTable, 'i18n')
|
||||
->fields('i18n', ['lid'])
|
||||
->condition('i18n.property', $property_not_in_row)
|
||||
->condition('i18n.objectid', $object_id);
|
||||
$query->leftJoin('locales_target', 'lt', 'i18n.lid = lt.lid');
|
||||
$query->condition('lt.language', $language);
|
||||
$query->addField('lt', 'translation');
|
||||
$results = $query->execute()->fetchAssoc();
|
||||
if (!$results) {
|
||||
$row->setSourceProperty($property_not_in_row . '_translated', NULL);
|
||||
}
|
||||
else {
|
||||
$row->setSourceProperty($property_not_in_row . '_translated', $results['translation']);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
}
|
||||
+109
-114
@@ -36,18 +36,6 @@ class ContentTranslationRouteSubscriber extends RouteSubscriberBase {
|
||||
*/
|
||||
protected function alterRoutes(RouteCollection $collection) {
|
||||
foreach ($this->contentTranslationManager->getSupportedEntityTypes() as $entity_type_id => $entity_type) {
|
||||
// Try to get the route from the current collection.
|
||||
$link_template = $entity_type->getLinkTemplate('canonical');
|
||||
if (strpos($link_template, '/') !== FALSE) {
|
||||
$base_path = '/' . $link_template;
|
||||
}
|
||||
else {
|
||||
if (!$entity_route = $collection->get("entity.$entity_type_id.canonical")) {
|
||||
continue;
|
||||
}
|
||||
$base_path = $entity_route->getPath();
|
||||
}
|
||||
|
||||
// Inherit admin route status from edit route, if exists.
|
||||
$is_admin = FALSE;
|
||||
$route_name = "entity.$entity_type_id.edit_form";
|
||||
@@ -55,115 +43,122 @@ class ContentTranslationRouteSubscriber extends RouteSubscriberBase {
|
||||
$is_admin = (bool) $edit_route->getOption('_admin_route');
|
||||
}
|
||||
|
||||
$path = $base_path . '/translations';
|
||||
$load_latest_revision = ContentTranslationManager::isPendingRevisionSupportEnabled($entity_type_id);
|
||||
|
||||
$route = new Route(
|
||||
$path,
|
||||
[
|
||||
'_controller' => '\Drupal\content_translation\Controller\ContentTranslationController::overview',
|
||||
'entity_type_id' => $entity_type_id,
|
||||
],
|
||||
[
|
||||
'_entity_access' => $entity_type_id . '.view',
|
||||
'_access_content_translation_overview' => $entity_type_id,
|
||||
],
|
||||
[
|
||||
'parameters' => [
|
||||
$entity_type_id => [
|
||||
'type' => 'entity:' . $entity_type_id,
|
||||
'load_latest_revision' => $load_latest_revision,
|
||||
],
|
||||
if ($entity_type->hasLinkTemplate('drupal:content-translation-overview')) {
|
||||
$route = new Route(
|
||||
$entity_type->getLinkTemplate('drupal:content-translation-overview'),
|
||||
[
|
||||
'_controller' => '\Drupal\content_translation\Controller\ContentTranslationController::overview',
|
||||
'entity_type_id' => $entity_type_id,
|
||||
],
|
||||
'_admin_route' => $is_admin,
|
||||
]
|
||||
);
|
||||
$route_name = "entity.$entity_type_id.content_translation_overview";
|
||||
$collection->add($route_name, $route);
|
||||
|
||||
$route = new Route(
|
||||
$path . '/add/{source}/{target}',
|
||||
[
|
||||
'_controller' => '\Drupal\content_translation\Controller\ContentTranslationController::add',
|
||||
'source' => NULL,
|
||||
'target' => NULL,
|
||||
'_title' => 'Add',
|
||||
'entity_type_id' => $entity_type_id,
|
||||
|
||||
],
|
||||
[
|
||||
'_entity_access' => $entity_type_id . '.view',
|
||||
'_access_content_translation_manage' => 'create',
|
||||
],
|
||||
[
|
||||
'parameters' => [
|
||||
'source' => [
|
||||
'type' => 'language',
|
||||
],
|
||||
'target' => [
|
||||
'type' => 'language',
|
||||
],
|
||||
$entity_type_id => [
|
||||
'type' => 'entity:' . $entity_type_id,
|
||||
'load_latest_revision' => $load_latest_revision,
|
||||
],
|
||||
[
|
||||
'_entity_access' => $entity_type_id . '.view',
|
||||
'_access_content_translation_overview' => $entity_type_id,
|
||||
],
|
||||
'_admin_route' => $is_admin,
|
||||
]
|
||||
);
|
||||
$collection->add("entity.$entity_type_id.content_translation_add", $route);
|
||||
[
|
||||
'parameters' => [
|
||||
$entity_type_id => [
|
||||
'type' => 'entity:' . $entity_type_id,
|
||||
'load_latest_revision' => $load_latest_revision,
|
||||
],
|
||||
],
|
||||
'_admin_route' => $is_admin,
|
||||
]
|
||||
);
|
||||
$route_name = "entity.$entity_type_id.content_translation_overview";
|
||||
$collection->add($route_name, $route);
|
||||
}
|
||||
|
||||
$route = new Route(
|
||||
$path . '/edit/{language}',
|
||||
[
|
||||
'_controller' => '\Drupal\content_translation\Controller\ContentTranslationController::edit',
|
||||
'language' => NULL,
|
||||
'_title' => 'Edit',
|
||||
'entity_type_id' => $entity_type_id,
|
||||
],
|
||||
[
|
||||
'_access_content_translation_manage' => 'update',
|
||||
],
|
||||
[
|
||||
'parameters' => [
|
||||
'language' => [
|
||||
'type' => 'language',
|
||||
],
|
||||
$entity_type_id => [
|
||||
'type' => 'entity:' . $entity_type_id,
|
||||
'load_latest_revision' => $load_latest_revision,
|
||||
],
|
||||
],
|
||||
'_admin_route' => $is_admin,
|
||||
]
|
||||
);
|
||||
$collection->add("entity.$entity_type_id.content_translation_edit", $route);
|
||||
if ($entity_type->hasLinkTemplate('drupal:content-translation-add')) {
|
||||
$route = new Route(
|
||||
$entity_type->getLinkTemplate('drupal:content-translation-add'),
|
||||
[
|
||||
'_controller' => '\Drupal\content_translation\Controller\ContentTranslationController::add',
|
||||
'source' => NULL,
|
||||
'target' => NULL,
|
||||
'_title' => 'Add',
|
||||
'entity_type_id' => $entity_type_id,
|
||||
|
||||
$route = new Route(
|
||||
$path . '/delete/{language}',
|
||||
[
|
||||
'_entity_form' => $entity_type_id . '.content_translation_deletion',
|
||||
'language' => NULL,
|
||||
'_title' => 'Delete',
|
||||
'entity_type_id' => $entity_type_id,
|
||||
],
|
||||
[
|
||||
'_access_content_translation_manage' => 'delete',
|
||||
],
|
||||
[
|
||||
'parameters' => [
|
||||
'language' => [
|
||||
'type' => 'language',
|
||||
],
|
||||
$entity_type_id => [
|
||||
'type' => 'entity:' . $entity_type_id,
|
||||
'load_latest_revision' => $load_latest_revision,
|
||||
],
|
||||
],
|
||||
'_admin_route' => $is_admin,
|
||||
]
|
||||
);
|
||||
$collection->add("entity.$entity_type_id.content_translation_delete", $route);
|
||||
[
|
||||
'_entity_access' => $entity_type_id . '.view',
|
||||
'_access_content_translation_manage' => 'create',
|
||||
],
|
||||
[
|
||||
'parameters' => [
|
||||
'source' => [
|
||||
'type' => 'language',
|
||||
],
|
||||
'target' => [
|
||||
'type' => 'language',
|
||||
],
|
||||
$entity_type_id => [
|
||||
'type' => 'entity:' . $entity_type_id,
|
||||
'load_latest_revision' => $load_latest_revision,
|
||||
],
|
||||
],
|
||||
'_admin_route' => $is_admin,
|
||||
]
|
||||
);
|
||||
$collection->add("entity.$entity_type_id.content_translation_add", $route);
|
||||
}
|
||||
|
||||
if ($entity_type->hasLinkTemplate('drupal:content-translation-edit')) {
|
||||
$route = new Route(
|
||||
$entity_type->getLinkTemplate('drupal:content-translation-edit'),
|
||||
[
|
||||
'_controller' => '\Drupal\content_translation\Controller\ContentTranslationController::edit',
|
||||
'language' => NULL,
|
||||
'_title' => 'Edit',
|
||||
'entity_type_id' => $entity_type_id,
|
||||
],
|
||||
[
|
||||
'_access_content_translation_manage' => 'update',
|
||||
],
|
||||
[
|
||||
'parameters' => [
|
||||
'language' => [
|
||||
'type' => 'language',
|
||||
],
|
||||
$entity_type_id => [
|
||||
'type' => 'entity:' . $entity_type_id,
|
||||
'load_latest_revision' => $load_latest_revision,
|
||||
],
|
||||
],
|
||||
'_admin_route' => $is_admin,
|
||||
]
|
||||
);
|
||||
$collection->add("entity.$entity_type_id.content_translation_edit", $route);
|
||||
}
|
||||
|
||||
if ($entity_type->hasLinkTemplate('drupal:content-translation-delete')) {
|
||||
$route = new Route(
|
||||
$entity_type->getLinkTemplate('drupal:content-translation-delete'),
|
||||
[
|
||||
'_entity_form' => $entity_type_id . '.content_translation_deletion',
|
||||
'language' => NULL,
|
||||
'_title' => 'Delete',
|
||||
'entity_type_id' => $entity_type_id,
|
||||
],
|
||||
[
|
||||
'_access_content_translation_manage' => 'delete',
|
||||
],
|
||||
[
|
||||
'parameters' => [
|
||||
'language' => [
|
||||
'type' => 'language',
|
||||
],
|
||||
$entity_type_id => [
|
||||
'type' => 'entity:' . $entity_type_id,
|
||||
'load_latest_revision' => $load_latest_revision,
|
||||
],
|
||||
],
|
||||
'_admin_route' => $is_admin,
|
||||
]
|
||||
);
|
||||
$collection->add("entity.$entity_type_id.content_translation_delete", $route);
|
||||
}
|
||||
|
||||
// Add our custom translation deletion access checker.
|
||||
if ($load_latest_revision) {
|
||||
|
||||
+1
-1
@@ -249,7 +249,7 @@ class ContentTranslationSyncUnitTest extends KernelTestBase {
|
||||
for ($delta = 0; $delta < $this->cardinality; $delta++) {
|
||||
foreach ($this->columns as $column) {
|
||||
// If the column is synchronized, the value should have been synced,
|
||||
// for unsychronized columns, the value must not change.
|
||||
// for unsynchronized columns, the value must not change.
|
||||
$expected_value = in_array($column, $this->synchronized) ? $changed_items[$delta][$column] : $this->unchangedFieldValues[$langcode][$delta][$column];
|
||||
$this->assertEqual($field_values[$langcode][$delta][$column], $expected_value, "Differing Item $delta column $column for langcode $langcode synced correctly");
|
||||
}
|
||||
|
||||
@@ -99,7 +99,7 @@
|
||||
|
||||
// Set the destination parameter on each of the contextual links.
|
||||
const destination = `destination=${Drupal.encodePath(
|
||||
drupalSettings.path.currentPath,
|
||||
Drupal.url(drupalSettings.path.currentPath),
|
||||
)}`;
|
||||
$contextual.find('.contextual-links a').each(function() {
|
||||
const url = this.getAttribute('href');
|
||||
|
||||
@@ -55,7 +55,7 @@
|
||||
|
||||
$contextual.html(html).addClass('contextual').prepend(Drupal.theme('contextualTrigger'));
|
||||
|
||||
var destination = 'destination=' + Drupal.encodePath(drupalSettings.path.currentPath);
|
||||
var destination = 'destination=' + Drupal.encodePath(Drupal.url(drupalSettings.path.currentPath));
|
||||
$contextual.find('.contextual-links a').each(function () {
|
||||
var url = this.getAttribute('href');
|
||||
var glue = url.indexOf('?') === -1 ? '?' : '&';
|
||||
|
||||
@@ -96,9 +96,9 @@
|
||||
* The keypress event.
|
||||
*/
|
||||
onKeypress(event) {
|
||||
// The first tab key press is tracked so that an annoucement about tabbing
|
||||
// constraints can be raised if edit mode is enabled when the page is
|
||||
// loaded.
|
||||
// The first tab key press is tracked so that an announcement about
|
||||
// tabbing constraints can be raised if edit mode is enabled when the page
|
||||
// is loaded.
|
||||
if (
|
||||
!this.announcedOnce &&
|
||||
event.keyCode === 9 &&
|
||||
|
||||
@@ -92,4 +92,19 @@ class ContextualLinksTest extends WebDriverTestBase {
|
||||
$this->assertSession()->pageTextContains('Everything is contextual!');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the contextual links destination.
|
||||
*/
|
||||
public function testContextualLinksDestination() {
|
||||
$this->grantPermissions(Role::load(Role::AUTHENTICATED_ID), [
|
||||
'access contextual links',
|
||||
'administer blocks',
|
||||
]);
|
||||
$this->drupalGet('user');
|
||||
$this->assertSession()->waitForElement('css', '.contextual button');
|
||||
$expected_destination_value = (string) $this->loggedInUser->toUrl()->toString();
|
||||
$contextual_link_url_parsed = parse_url($this->getSession()->getPage()->findLink('Configure block')->getAttribute('href'));
|
||||
$this->assertEquals("destination=$expected_destination_value", $contextual_link_url_parsed['query']);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+3
-148
@@ -2,17 +2,9 @@
|
||||
|
||||
namespace Drupal\datetime\Plugin\Field\FieldFormatter;
|
||||
|
||||
use Drupal\Component\Render\FormattableMarkup;
|
||||
use Drupal\Core\Cache\CacheableMetadata;
|
||||
use Drupal\Core\Datetime\DateFormatterInterface;
|
||||
use Drupal\Core\Datetime\DrupalDateTime;
|
||||
use Drupal\Core\Field\FieldDefinitionInterface;
|
||||
use Drupal\Core\Field\FieldItemListInterface;
|
||||
use Drupal\Core\Field\FormatterBase;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Drupal\Core\Field\Plugin\Field\FieldFormatter\TimestampAgoFormatter;
|
||||
|
||||
/**
|
||||
* Plugin implementation of the 'Time ago' formatter for 'datetime' fields.
|
||||
@@ -25,80 +17,7 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
* }
|
||||
* )
|
||||
*/
|
||||
class DateTimeTimeAgoFormatter extends FormatterBase implements ContainerFactoryPluginInterface {
|
||||
|
||||
/**
|
||||
* The date formatter service.
|
||||
*
|
||||
* @var \Drupal\Core\Datetime\DateFormatterInterface
|
||||
*/
|
||||
protected $dateFormatter;
|
||||
|
||||
/**
|
||||
* The current Request object.
|
||||
*
|
||||
* @var \Symfony\Component\HttpFoundation\Request
|
||||
*/
|
||||
protected $request;
|
||||
|
||||
/**
|
||||
* Constructs a DateTimeTimeAgoFormatter object.
|
||||
*
|
||||
* @param string $plugin_id
|
||||
* The plugin_id for the formatter.
|
||||
* @param mixed $plugin_definition
|
||||
* The plugin implementation definition.
|
||||
* @param \Drupal\Core\Field\FieldDefinitionInterface $field_definition
|
||||
* The definition of the field to which the formatter is associated.
|
||||
* @param array $settings
|
||||
* The formatter settings.
|
||||
* @param string $label
|
||||
* The formatter label display setting.
|
||||
* @param string $view_mode
|
||||
* The view mode.
|
||||
* @param array $third_party_settings
|
||||
* Third party settings.
|
||||
* @param \Drupal\Core\Datetime\DateFormatterInterface $date_formatter
|
||||
* The date formatter service.
|
||||
* @param \Symfony\Component\HttpFoundation\Request $request
|
||||
* The current request.
|
||||
*/
|
||||
public function __construct($plugin_id, $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, $label, $view_mode, array $third_party_settings, DateFormatterInterface $date_formatter, Request $request) {
|
||||
parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings, $label, $view_mode, $third_party_settings);
|
||||
|
||||
$this->dateFormatter = $date_formatter;
|
||||
$this->request = $request;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function defaultSettings() {
|
||||
$settings = [
|
||||
'future_format' => '@interval hence',
|
||||
'past_format' => '@interval ago',
|
||||
'granularity' => 2,
|
||||
] + parent::defaultSettings();
|
||||
|
||||
return $settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
|
||||
return new static(
|
||||
$plugin_id,
|
||||
$plugin_definition,
|
||||
$configuration['field_definition'],
|
||||
$configuration['settings'],
|
||||
$configuration['label'],
|
||||
$configuration['view_mode'],
|
||||
$configuration['third_party_settings'],
|
||||
$container->get('date.formatter'),
|
||||
$container->get('request_stack')->getCurrentRequest()
|
||||
);
|
||||
}
|
||||
class DateTimeTimeAgoFormatter extends TimestampAgoFormatter {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
@@ -118,50 +37,6 @@ class DateTimeTimeAgoFormatter extends FormatterBase implements ContainerFactory
|
||||
return $elements;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function settingsForm(array $form, FormStateInterface $form_state) {
|
||||
$form = parent::settingsForm($form, $form_state);
|
||||
|
||||
$form['future_format'] = [
|
||||
'#type' => 'textfield',
|
||||
'#title' => $this->t('Future format'),
|
||||
'#default_value' => $this->getSetting('future_format'),
|
||||
'#description' => $this->t('Use <em>@interval</em> where you want the formatted interval text to appear.'),
|
||||
];
|
||||
|
||||
$form['past_format'] = [
|
||||
'#type' => 'textfield',
|
||||
'#title' => $this->t('Past format'),
|
||||
'#default_value' => $this->getSetting('past_format'),
|
||||
'#description' => $this->t('Use <em>@interval</em> where you want the formatted interval text to appear.'),
|
||||
];
|
||||
|
||||
$form['granularity'] = [
|
||||
'#type' => 'number',
|
||||
'#title' => $this->t('Granularity'),
|
||||
'#default_value' => $this->getSetting('granularity'),
|
||||
'#description' => $this->t('How many time units should be shown in the formatted output.'),
|
||||
];
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function settingsSummary() {
|
||||
$summary = parent::settingsSummary();
|
||||
|
||||
$future_date = new DrupalDateTime('1 year 1 month 1 week 1 day 1 hour 1 minute');
|
||||
$past_date = new DrupalDateTime('-1 year -1 month -1 week -1 day -1 hour -1 minute');
|
||||
$summary[] = t('Future date: %display', ['%display' => $this->formatDate($future_date)]);
|
||||
$summary[] = t('Past date: %display', ['%display' => $this->formatDate($past_date)]);
|
||||
|
||||
return $summary;
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats a date/time as a time interval.
|
||||
*
|
||||
@@ -172,27 +47,7 @@ class DateTimeTimeAgoFormatter extends FormatterBase implements ContainerFactory
|
||||
* The formatted date/time string using the past or future format setting.
|
||||
*/
|
||||
protected function formatDate(DrupalDateTime $date) {
|
||||
$granularity = $this->getSetting('granularity');
|
||||
$timestamp = $date->getTimestamp();
|
||||
$options = [
|
||||
'granularity' => $granularity,
|
||||
'return_as_object' => TRUE,
|
||||
];
|
||||
|
||||
if ($this->request->server->get('REQUEST_TIME') > $timestamp) {
|
||||
$result = $this->dateFormatter->formatTimeDiffSince($timestamp, $options);
|
||||
$build = [
|
||||
'#markup' => new FormattableMarkup($this->getSetting('past_format'), ['@interval' => $result->getString()]),
|
||||
];
|
||||
}
|
||||
else {
|
||||
$result = $this->dateFormatter->formatTimeDiffUntil($timestamp, $options);
|
||||
$build = [
|
||||
'#markup' => new FormattableMarkup($this->getSetting('future_format'), ['@interval' => $result->getString()]),
|
||||
];
|
||||
}
|
||||
CacheableMetadata::createFromObject($result)->applyTo($build);
|
||||
return $build;
|
||||
return parent::formatTimestamp($date->getTimestamp());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ class Date extends NumericDate implements ContainerFactoryPluginInterface {
|
||||
protected $calculateOffset = TRUE;
|
||||
|
||||
/**
|
||||
* The request stack used to determin current time.
|
||||
* The request stack used to determine current time.
|
||||
*
|
||||
* @var \Symfony\Component\HttpFoundation\RequestStack
|
||||
*/
|
||||
|
||||
@@ -171,7 +171,7 @@ class DateTimeFieldTest extends DateTestBase {
|
||||
// past. First update the test entity so that the date difference always
|
||||
// has the same interval. Since the database always stores UTC, and the
|
||||
// interval will use this, force the test date to use UTC and not the local
|
||||
// or user timezome.
|
||||
// or user timezone.
|
||||
$timestamp = REQUEST_TIME - 87654321;
|
||||
$entity = EntityTest::load($id);
|
||||
$field_name = $this->fieldStorage->getName();
|
||||
@@ -201,7 +201,7 @@ class DateTimeFieldTest extends DateTestBase {
|
||||
// future. First update the test entity so that the date difference always
|
||||
// has the same interval. Since the database always stores UTC, and the
|
||||
// interval will use this, force the test date to use UTC and not the local
|
||||
// or user timezome.
|
||||
// or user timezone.
|
||||
$timestamp = REQUEST_TIME + 87654321;
|
||||
$entity = EntityTest::load($id);
|
||||
$field_name = $this->fieldStorage->getName();
|
||||
@@ -323,7 +323,7 @@ class DateTimeFieldTest extends DateTestBase {
|
||||
// past. First update the test entity so that the date difference always
|
||||
// has the same interval. Since the database always stores UTC, and the
|
||||
// interval will use this, force the test date to use UTC and not the local
|
||||
// or user timezome.
|
||||
// or user timezone.
|
||||
$timestamp = REQUEST_TIME - 87654321;
|
||||
$entity = EntityTest::load($id);
|
||||
$field_name = $this->fieldStorage->getName();
|
||||
@@ -350,7 +350,7 @@ class DateTimeFieldTest extends DateTestBase {
|
||||
// future. First update the test entity so that the date difference always
|
||||
// has the same interval. Since the database always stores UTC, and the
|
||||
// interval will use this, force the test date to use UTC and not the local
|
||||
// or user timezome.
|
||||
// or user timezone.
|
||||
$timestamp = REQUEST_TIME + 87654321;
|
||||
$entity = EntityTest::load($id);
|
||||
$field_name = $this->fieldStorage->getName();
|
||||
|
||||
@@ -0,0 +1,122 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\datetime\Functional;
|
||||
|
||||
use Drupal\Core\Entity\Entity\EntityFormDisplay;
|
||||
use Drupal\Core\Entity\Entity\EntityViewDisplay;
|
||||
use Drupal\field\Entity\FieldConfig;
|
||||
use Drupal\field\Entity\FieldStorageConfig;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
|
||||
/**
|
||||
* Tests the functionality of DateTimeTimeAgoFormatter field formatter.
|
||||
*
|
||||
* @group field
|
||||
*/
|
||||
class DateTimeTimeAgoFormatterTest extends BrowserTestBase {
|
||||
|
||||
/**
|
||||
* An array of display options to pass to entity_get_display().
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $displayOptions;
|
||||
|
||||
/**
|
||||
* A field storage to use in this test class.
|
||||
*
|
||||
* @var \Drupal\field\Entity\FieldStorageConfig
|
||||
*/
|
||||
protected $fieldStorage;
|
||||
|
||||
/**
|
||||
* The field used in this test class.
|
||||
*
|
||||
* @var \Drupal\field\Entity\FieldConfig
|
||||
*/
|
||||
protected $field;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['datetime', 'entity_test', 'field_ui'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$web_user = $this->drupalCreateUser([
|
||||
'access administration pages',
|
||||
'view test entity',
|
||||
'administer entity_test content',
|
||||
'administer entity_test fields',
|
||||
'administer entity_test display',
|
||||
'administer entity_test form display',
|
||||
'view the administration theme',
|
||||
]);
|
||||
$this->drupalLogin($web_user);
|
||||
|
||||
$field_name = 'field_datetime';
|
||||
$type = 'datetime';
|
||||
$widget_type = 'datetime_default';
|
||||
$formatter_type = 'datetime_time_ago';
|
||||
|
||||
$this->fieldStorage = FieldStorageConfig::create([
|
||||
'field_name' => $field_name,
|
||||
'entity_type' => 'entity_test',
|
||||
'type' => $type,
|
||||
]);
|
||||
$this->fieldStorage->save();
|
||||
$this->field = FieldConfig::create([
|
||||
'field_storage' => $this->fieldStorage,
|
||||
'bundle' => 'entity_test',
|
||||
'required' => TRUE,
|
||||
]);
|
||||
$this->field->save();
|
||||
|
||||
EntityFormDisplay::load('entity_test.entity_test.default')
|
||||
->setComponent($field_name, ['type' => $widget_type])
|
||||
->save();
|
||||
|
||||
$this->displayOptions = [
|
||||
'type' => $formatter_type,
|
||||
'label' => 'hidden',
|
||||
];
|
||||
|
||||
EntityViewDisplay::create([
|
||||
'targetEntityType' => $this->field->getTargetEntityTypeId(),
|
||||
'bundle' => $this->field->getTargetBundle(),
|
||||
'mode' => 'full',
|
||||
'status' => TRUE,
|
||||
])->setComponent($field_name, $this->displayOptions)
|
||||
->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the formatter settings.
|
||||
*/
|
||||
public function testSettings() {
|
||||
$this->drupalGet('entity_test/structure/entity_test/display');
|
||||
|
||||
$edit = [
|
||||
'fields[field_datetime][region]' => 'content',
|
||||
'fields[field_datetime][type]' => 'datetime_time_ago',
|
||||
];
|
||||
$this->drupalPostForm(NULL, $edit, t('Save'));
|
||||
|
||||
$this->drupalPostForm(NULL, [], 'field_datetime_settings_edit');
|
||||
$edit = [
|
||||
'fields[field_datetime][settings_edit_form][settings][future_format]' => 'ends in @interval',
|
||||
'fields[field_datetime][settings_edit_form][settings][past_format]' => 'started @interval ago',
|
||||
'fields[field_datetime][settings_edit_form][settings][granularity]' => 3,
|
||||
];
|
||||
$this->drupalPostForm(NULL, $edit, 'Update');
|
||||
$this->drupalPostForm(NULL, [], 'Save');
|
||||
|
||||
$this->assertSession()->pageTextContains('ends in 1 year 1 month 1 week');
|
||||
$this->assertSession()->pageTextContains('started 1 year 1 month 1 week ago');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -53,9 +53,13 @@ function datetime_range_view_presave(ViewEntityInterface $view) {
|
||||
if (isset($display['display_options']['filters'])) {
|
||||
foreach ($display['display_options']['filters'] as $field_name => &$filter) {
|
||||
if ($filter['plugin_id'] === 'string') {
|
||||
$table_data = Views::viewsData()->get($filter['table']);
|
||||
if (!$table_data) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Get field config.
|
||||
$filter_views_data = Views::viewsData()->get($filter['table'])[$filter['field']]['filter'];
|
||||
$filter_views_data = $table_data[$filter['field']]['filter'];
|
||||
if (!isset($filter_views_data['entity_type']) || !isset($filter_views_data['field_name'])) {
|
||||
continue;
|
||||
}
|
||||
@@ -128,9 +132,13 @@ function datetime_range_view_presave(ViewEntityInterface $view) {
|
||||
if (isset($display['display_options']['sorts'])) {
|
||||
foreach ($display['display_options']['sorts'] as $field_name => &$sort) {
|
||||
if ($sort['plugin_id'] === 'standard') {
|
||||
$table_data = Views::viewsData()->get($sort['table']);
|
||||
if (!$table_data) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Get field config.
|
||||
$sort_views_data = Views::viewsData()->get($sort['table'])[$sort['field']]['sort'];
|
||||
$sort_views_data = $table_data[$sort['field']]['sort'];
|
||||
if (!isset($sort_views_data['entity_type']) || !isset($sort_views_data['field_name'])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
name: 'Datetime range test'
|
||||
type: module
|
||||
description: 'Provides a testing module for datetime_range.'
|
||||
package: Testing
|
||||
version: VERSION
|
||||
core: 8.x
|
||||
dependencies:
|
||||
- drupal:taxonomy
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains datetime_range_test.module
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements hook_entity_type_alter().
|
||||
*/
|
||||
function datetime_range_test_entity_type_alter(array &$entity_types) {
|
||||
// Inhibit views data for the 'taxonomy_term' entity type in order to cover
|
||||
// the case when an entity type provides no views data.
|
||||
// @see https://www.drupal.org/project/drupal/issues/2995578
|
||||
// @see \Drupal\Tests\datetime_range\Kernel\Views\EntityTypeWithoutViewsDataTest
|
||||
$entity_types['taxonomy_term']->setHandlerClass('views_data', NULL);
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\datetime_range\Kernel\Views;
|
||||
|
||||
use Drupal\Core\Config\InstallStorage;
|
||||
use Drupal\Core\Serialization\Yaml;
|
||||
use Drupal\KernelTests\KernelTestBase;
|
||||
use Drupal\views\Entity\View;
|
||||
|
||||
/**
|
||||
* Tests datetime_range.module when an entity type provides no views data.
|
||||
*
|
||||
* @group datetime
|
||||
*/
|
||||
class EntityTypeWithoutViewsDataTest extends KernelTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $modules = [
|
||||
'datetime_range',
|
||||
'datetime_range_test',
|
||||
'node',
|
||||
'system',
|
||||
'taxonomy',
|
||||
'text',
|
||||
'user',
|
||||
'views',
|
||||
];
|
||||
|
||||
/**
|
||||
* Tests the case when an entity type provides no views data.
|
||||
*
|
||||
* @see datetime_test_entity_type_alter()
|
||||
* @see datetime_range_view_presave()
|
||||
*/
|
||||
public function testEntityTypeWithoutViewsData() {
|
||||
$view_yaml = drupal_get_path('module', 'taxonomy') . '/' . InstallStorage::CONFIG_OPTIONAL_DIRECTORY . '/views.view.taxonomy_term.yml';
|
||||
$values = Yaml::decode(file_get_contents($view_yaml));
|
||||
$this->assertEquals(SAVED_NEW, View::create($values)->save());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -8,7 +8,6 @@ use Drupal\Core\Logger\RfcLogLevel;
|
||||
use Drupal\Core\Url;
|
||||
use Drupal\dblog\Controller\DbLogController;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
use Drupal\Tests\Traits\Core\CronRunTrait;
|
||||
|
||||
/**
|
||||
* Generate events and verify dblog entries; verify user access to log reports
|
||||
@@ -17,7 +16,6 @@ use Drupal\Tests\Traits\Core\CronRunTrait;
|
||||
* @group dblog
|
||||
*/
|
||||
class DbLogTest extends BrowserTestBase {
|
||||
use CronRunTrait;
|
||||
use FakeLogEntries;
|
||||
|
||||
/**
|
||||
@@ -67,7 +65,6 @@ class DbLogTest extends BrowserTestBase {
|
||||
|
||||
$row_limit = 100;
|
||||
$this->verifyRowLimit($row_limit);
|
||||
$this->verifyCron($row_limit);
|
||||
$this->verifyEvents();
|
||||
$this->verifyReports();
|
||||
$this->verifyBreadcrumbs();
|
||||
@@ -137,52 +134,6 @@ class DbLogTest extends BrowserTestBase {
|
||||
$this->assertTrue($current_limit == $row_limit, format_string('[Cache] Row limit variable of @count equals row limit of @limit', ['@count' => $current_limit, '@limit' => $row_limit]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that cron correctly applies the database log row limit.
|
||||
*
|
||||
* @param int $row_limit
|
||||
* The row limit.
|
||||
*/
|
||||
private function verifyCron($row_limit) {
|
||||
// Generate additional log entries.
|
||||
$this->generateLogEntries($row_limit + 10);
|
||||
// Verify that the database log row count exceeds the row limit.
|
||||
$count = db_query('SELECT COUNT(wid) FROM {watchdog}')->fetchField();
|
||||
$this->assertTrue($count > $row_limit, format_string('Dblog row count of @count exceeds row limit of @limit', ['@count' => $count, '@limit' => $row_limit]));
|
||||
|
||||
// Get the number of enabled modules. Cron adds a log entry for each module.
|
||||
$list = \Drupal::moduleHandler()->getImplementations('cron');
|
||||
$module_count = count($list);
|
||||
$cron_detailed_count = $this->runCron();
|
||||
$this->assertTrue($cron_detailed_count == $module_count + 2, format_string('Cron added @count of @expected new log entries', ['@count' => $cron_detailed_count, '@expected' => $module_count + 2]));
|
||||
|
||||
// Test disabling of detailed cron logging.
|
||||
$this->config('system.cron')->set('logging', 0)->save();
|
||||
$cron_count = $this->runCron();
|
||||
$this->assertTrue($cron_count = 1, format_string('Cron added @count of @expected new log entries', ['@count' => $cron_count, '@expected' => 1]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs cron and returns number of new log entries.
|
||||
*
|
||||
* @return int
|
||||
* Number of new watchdog entries.
|
||||
*/
|
||||
private function runCron() {
|
||||
// Get last ID to compare against; log entries get deleted, so we can't
|
||||
// reliably add the number of newly created log entries to the current count
|
||||
// to measure number of log entries created by cron.
|
||||
$last_id = db_query('SELECT MAX(wid) FROM {watchdog}')->fetchField();
|
||||
|
||||
// Run a cron job.
|
||||
$this->cronRun();
|
||||
|
||||
// Get last ID after cron was run.
|
||||
$current_id = db_query('SELECT MAX(wid) FROM {watchdog}')->fetchField();
|
||||
|
||||
return $current_id - $last_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the entry logs by clicking on 'Clear log messages' button.
|
||||
*/
|
||||
|
||||
@@ -65,7 +65,7 @@ class DblogFiltersAndFieldsUpgradeTest extends UpdatePathTestBase {
|
||||
// Now save the view. This trigger dblog_view_presave().
|
||||
$view->save();
|
||||
|
||||
// Finally check the same convertion proccess ran.
|
||||
// Finally check the same conversion process ran.
|
||||
$data = $view->storage->toArray();
|
||||
$fields = $data['display']['default']['display_options']['fields'];
|
||||
$filters = $data['display']['default']['display_options']['filters'];
|
||||
|
||||
@@ -6,7 +6,7 @@ use Drupal\FunctionalTests\Update\UpdatePathTestBase;
|
||||
use Drupal\views\Views;
|
||||
|
||||
/**
|
||||
* Test the upgrade path of changing the emtpy text area for watchdog view.
|
||||
* Test the upgrade path of changing the empty text area for watchdog view.
|
||||
*
|
||||
* @see dblog_update_8600()
|
||||
*
|
||||
|
||||
+2
-2
@@ -5,7 +5,7 @@ namespace Drupal\Tests\dblog\Functional\Update;
|
||||
use Drupal\FunctionalTests\Update\UpdatePathTestBase;
|
||||
|
||||
/**
|
||||
* Ensures that update hook that creates the watchdog view ran sucessfully.
|
||||
* Ensures that update hook that creates the watchdog view ran successfully.
|
||||
*
|
||||
* @group Update
|
||||
* @group legacy
|
||||
@@ -25,7 +25,7 @@ class DblogRecentLogsUsingViewsUpdateTest extends UpdatePathTestBase {
|
||||
* Ensures that update hook is run for dblog module.
|
||||
*/
|
||||
public function testUpdate() {
|
||||
// Make sure the watchog view doesn't exist before the updates.
|
||||
// Make sure the watchdog view doesn't exist before the updates.
|
||||
$view = \Drupal::entityTypeManager()->getStorage('view')->load('watchdog');
|
||||
$this->assertNull($view);
|
||||
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\dblog\Kernel;
|
||||
|
||||
use Drupal\KernelTests\KernelTestBase;
|
||||
use Drupal\Tests\dblog\Functional\FakeLogEntries;
|
||||
|
||||
/**
|
||||
* Generate events and verify dblog entries.
|
||||
*
|
||||
* @group dblog
|
||||
*/
|
||||
class DbLogTest extends KernelTestBase {
|
||||
|
||||
use FakeLogEntries;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $modules = ['dblog', 'system'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$this->installSchema('dblog', ['watchdog']);
|
||||
$this->installSchema('system', ['key_value_expire', 'sequences']);
|
||||
$this->installConfig(['system']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that cron correctly applies the database log row limit.
|
||||
*/
|
||||
public function testDbLogCron() {
|
||||
$row_limit = 100;
|
||||
// Generate additional log entries.
|
||||
$this->generateLogEntries($row_limit + 10);
|
||||
// Verify that the database log row count exceeds the row limit.
|
||||
$count = db_query('SELECT COUNT(wid) FROM {watchdog}')->fetchField();
|
||||
$this->assertGreaterThan($row_limit, $count, format_string('Dblog row count of @count exceeds row limit of @limit', ['@count' => $count, '@limit' => $row_limit]));
|
||||
|
||||
// Get the number of enabled modules. Cron adds a log entry for each module.
|
||||
$list = $this->container->get('module_handler')->getImplementations('cron');
|
||||
$module_count = count($list);
|
||||
$cron_detailed_count = $this->runCron();
|
||||
$this->assertEquals($module_count + 2, $cron_detailed_count, format_string('Cron added @count of @expected new log entries', ['@count' => $cron_detailed_count, '@expected' => $module_count + 2]));
|
||||
|
||||
// Test disabling of detailed cron logging.
|
||||
$this->config('system.cron')->set('logging', 0)->save();
|
||||
$cron_count = $this->runCron();
|
||||
$this->assertEquals(1, $cron_count, format_string('Cron added @count of @expected new log entries', ['@count' => $cron_count, '@expected' => 1]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs cron and returns number of new log entries.
|
||||
*
|
||||
* @return int
|
||||
* Number of new watchdog entries.
|
||||
*/
|
||||
private function runCron() {
|
||||
// Get last ID to compare against; log entries get deleted, so we can't
|
||||
// reliably add the number of newly created log entries to the current count
|
||||
// to measure number of log entries created by cron.
|
||||
$last_id = db_query('SELECT MAX(wid) FROM {watchdog}')->fetchField();
|
||||
|
||||
// Run a cron job.
|
||||
$this->container->get('cron')->run();
|
||||
|
||||
// Get last ID after cron was run.
|
||||
$current_id = db_query('SELECT MAX(wid) FROM {watchdog}')->fetchField();
|
||||
|
||||
return $current_id - $last_id;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -292,7 +292,7 @@ function hook_field_widget_multivalue_WIDGET_TYPE_form_alter(array &$elements, \
|
||||
// Code here will only act on widgets of type WIDGET_TYPE. For example,
|
||||
// hook_field_widget_multivalue_mymodule_autocomplete_form_alter() will only
|
||||
// act on widgets of type 'mymodule_autocomplete'.
|
||||
// Change the autcomplete route for each autocomplete element within the
|
||||
// Change the autocomplete route for each autocomplete element within the
|
||||
// multivalue widget.
|
||||
foreach (Element::children($elements) as $delta => $element) {
|
||||
$elements[$delta]['#autocomplete_route_name'] = 'mymodule.autocomplete_route';
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\field\Plugin\migrate\process\d6;
|
||||
|
||||
use Drupal\migrate\MigrateExecutableInterface;
|
||||
use Drupal\migrate\ProcessPluginBase;
|
||||
use Drupal\migrate\Row;
|
||||
|
||||
/**
|
||||
* Determines the settings property and translation for boolean fields.
|
||||
*
|
||||
* @MigrateProcessPlugin(
|
||||
* id = "d6_field_instance_option_translation",
|
||||
* handle_multiples = TRUE
|
||||
* )
|
||||
*/
|
||||
class FieldInstanceOptionTranslation extends ProcessPluginBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) {
|
||||
list($field_type, $global_settings) = $value;
|
||||
|
||||
$option_key = 0;
|
||||
$translation = '';
|
||||
if (isset($global_settings['allowed_values'])) {
|
||||
$list = explode("\n", $global_settings['allowed_values']);
|
||||
$list = array_map('trim', $list);
|
||||
$list = array_filter($list, 'strlen');
|
||||
switch ($field_type) {
|
||||
case 'boolean';
|
||||
$option = preg_replace('/^option_/', '', $row->getSourceProperty('property'));
|
||||
for ($i = 0; $i < 2; $i++) {
|
||||
$value = $list[$i];
|
||||
$tmp = explode("|", $value);
|
||||
$original_option_key = isset($tmp[0]) ? $tmp[0] : NULL;
|
||||
$option_key = ($i === 0) ? 'off_label' : 'on_label';
|
||||
// Find property with name matching the original option.
|
||||
if ($option == $original_option_key) {
|
||||
$translation = $row->getSourceProperty('translation');
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
}
|
||||
}
|
||||
return ['settings.' . $option_key, $translation];
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\field\Plugin\migrate\process\d6;
|
||||
|
||||
use Drupal\migrate\MigrateExecutableInterface;
|
||||
use Drupal\migrate\ProcessPluginBase;
|
||||
use Drupal\migrate\Row;
|
||||
|
||||
/**
|
||||
* Determines the allowed values translation for select lists.
|
||||
*
|
||||
* @MigrateProcessPlugin(
|
||||
* id = "d6_field_option_translation",
|
||||
* handle_multiples = TRUE
|
||||
* )
|
||||
*/
|
||||
class FieldOptionTranslation extends ProcessPluginBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* Get the field default/mapped settings.
|
||||
*/
|
||||
public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) {
|
||||
list($field_type, $global_settings) = $value;
|
||||
|
||||
$allowed_values = '';
|
||||
$i = 0;
|
||||
if (isset($global_settings['allowed_values'])) {
|
||||
$list = explode("\n", $global_settings['allowed_values']);
|
||||
$list = array_map('trim', $list);
|
||||
$list = array_filter($list, 'strlen');
|
||||
switch ($field_type) {
|
||||
case 'list_string':
|
||||
case 'list_integer':
|
||||
case 'list_float':
|
||||
// Remove the prefix used in the i18n_strings table for field options
|
||||
// to get the option value.
|
||||
$option = preg_replace('/^option_/', '', $row->getSourceProperty('property'));
|
||||
$i = 0;
|
||||
foreach ($list as $allowed_value) {
|
||||
// Get the key for this allowed value which may be a key|label pair
|
||||
// or or just key.
|
||||
$value = explode("|", $allowed_value);
|
||||
if (isset($value[0]) && ($value[0] == $option)) {
|
||||
$allowed_values = ['label' => $row->getSourceProperty('translation')];
|
||||
break;
|
||||
}
|
||||
$i++;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
}
|
||||
}
|
||||
return ["settings.allowed_values.$i", $allowed_values];
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\field\Plugin\migrate\source\d6;
|
||||
|
||||
/**
|
||||
* Gets field instance option label translations.
|
||||
*
|
||||
* @MigrateSource(
|
||||
* id = "d6_field_instance_option_translation",
|
||||
* source_module = "i18ncck"
|
||||
* )
|
||||
*/
|
||||
class FieldInstanceOptionTranslation extends FieldOptionTranslation {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function query() {
|
||||
$query = parent::query();
|
||||
$query->join('content_node_field_instance', 'cnfi', 'cnf.field_name = cnfi.field_name');
|
||||
$query->addField('cnfi', 'type_name');
|
||||
return $query;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function fields() {
|
||||
$fields = [
|
||||
'type_name' => $this->t('Type (article, page, ....)'),
|
||||
];
|
||||
return parent::fields() + $fields;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\field\Plugin\migrate\source\d6;
|
||||
|
||||
use Drupal\migrate_drupal\Plugin\migrate\source\DrupalSqlBase;
|
||||
|
||||
/**
|
||||
* Gets field label and description translations.
|
||||
*
|
||||
* @MigrateSource(
|
||||
* id = "d6_field_instance_label_description_translation",
|
||||
* source_module = "i18ncck"
|
||||
* )
|
||||
*/
|
||||
class FieldLabelDescriptionTranslation extends DrupalSqlBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function query() {
|
||||
// Get translations for field labels and descriptions.
|
||||
$query = $this->select('i18n_strings', 'i18n')
|
||||
->fields('i18n', ['property', 'objectid', 'type'])
|
||||
->fields('lt', ['lid', 'translation', 'language'])
|
||||
->condition('i18n.type', 'field')
|
||||
->isNotNull('language')
|
||||
->isNotNull('translation');
|
||||
$condition = $query->orConditionGroup()
|
||||
->condition('property', 'widget_label')
|
||||
->condition('property', 'widget_description');
|
||||
$query->condition($condition);
|
||||
$query->leftJoin('locales_target', 'lt', 'lt.lid = i18n.lid');
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function fields() {
|
||||
return [
|
||||
'property' => $this->t('Profile field ID.'),
|
||||
'lid' => $this->t('Locales target language ID.'),
|
||||
'language' => $this->t('Language for this field.'),
|
||||
'translation' => $this->t('Translation of either the title or explanation.'),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getIds() {
|
||||
$ids['property']['type'] = 'string';
|
||||
$ids['language']['type'] = 'string';
|
||||
$ids['lid']['type'] = 'integer';
|
||||
$ids['lid']['alias'] = 'lt';
|
||||
return $ids;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\field\Plugin\migrate\source\d6;
|
||||
|
||||
/**
|
||||
* Gets field option label translations.
|
||||
*
|
||||
* @MigrateSource(
|
||||
* id = "d6_field_option_translation",
|
||||
* source_module = "i18ncck"
|
||||
* )
|
||||
*/
|
||||
class FieldOptionTranslation extends Field {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function query() {
|
||||
// Get the fields that have field options translations.
|
||||
$query = $this->select('i18n_strings', 'i18n')
|
||||
->fields('i18n')
|
||||
->fields('lt', [
|
||||
'translation',
|
||||
'language',
|
||||
'plid',
|
||||
'plural',
|
||||
'i18n_status',
|
||||
])
|
||||
->condition('i18n.type', 'field')
|
||||
->condition('property', 'option\_%', 'LIKE')
|
||||
->isNotNull('translation');
|
||||
$query->leftJoin('locales_target', 'lt', 'lt.lid = i18n.lid');
|
||||
$query->leftjoin('content_node_field', 'cnf', 'cnf.field_name = i18n.objectid');
|
||||
$query->addField('cnf', 'field_name');
|
||||
$query->addField('cnf', 'global_settings');
|
||||
// Minimise changes to the d6_field_option_translation.yml, which is copied
|
||||
// from d6_field.yml, by ensuring the 'type' property is from
|
||||
// content_node_field table.
|
||||
$query->addField('cnf', 'type');
|
||||
$query->addField('i18n', 'type', 'i18n_type');
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function fields() {
|
||||
$fields = [
|
||||
'property' => $this->t('Option ID.'),
|
||||
'objectid' => $this->t('Object ID'),
|
||||
'objectindex' => $this->t('Integer value of Object ID'),
|
||||
'format' => $this->t('The input format used by this string'),
|
||||
'lid' => $this->t('Source string ID'),
|
||||
'language' => $this->t('Language code'),
|
||||
'translation' => $this->t('Translation of the option'),
|
||||
'plid' => $this->t('Parent lid'),
|
||||
'plural' => $this->t('Plural index number in case of plural strings'),
|
||||
];
|
||||
return parent::fields() + $fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getIds() {
|
||||
return parent::getIds() +
|
||||
[
|
||||
'language' => ['type' => 'string'],
|
||||
'property' => ['type' => 'string'],
|
||||
];
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2,63 +2,18 @@
|
||||
|
||||
namespace Drupal\field\Tests\EntityReference;
|
||||
|
||||
use Drupal\field\Entity\FieldConfig;
|
||||
use Drupal\field\Entity\FieldStorageConfig;
|
||||
use Drupal\Tests\field\Traits\EntityReferenceTestTrait as nonDeprecatedEntityReferenceTestTrait;
|
||||
|
||||
/**
|
||||
* Provides common functionality for the EntityReference test classes.
|
||||
*
|
||||
* @deprecated in Drupal 8.6.2 for removal before 9.0.0. Use
|
||||
* Drupal\Tests\field\Traits\EntityReferenceTestTrait instead.
|
||||
*
|
||||
* @see https://www.drupal.org/node/2998888
|
||||
*/
|
||||
trait EntityReferenceTestTrait {
|
||||
|
||||
/**
|
||||
* Creates a field of an entity reference field storage on the specified bundle.
|
||||
*
|
||||
* @param string $entity_type
|
||||
* The type of entity the field will be attached to.
|
||||
* @param string $bundle
|
||||
* The bundle name of the entity the field will be attached to.
|
||||
* @param string $field_name
|
||||
* The name of the field; if it already exists, a new instance of the existing
|
||||
* field will be created.
|
||||
* @param string $field_label
|
||||
* The label of the field.
|
||||
* @param string $target_entity_type
|
||||
* The type of the referenced entity.
|
||||
* @param string $selection_handler
|
||||
* The selection handler used by this field.
|
||||
* @param array $selection_handler_settings
|
||||
* An array of settings supported by the selection handler specified above.
|
||||
* (e.g. 'target_bundles', 'sort', 'auto_create', etc).
|
||||
* @param int $cardinality
|
||||
* The cardinality of the field.
|
||||
*
|
||||
* @see \Drupal\Core\Entity\Plugin\EntityReferenceSelection\SelectionBase::buildConfigurationForm()
|
||||
*/
|
||||
protected function createEntityReferenceField($entity_type, $bundle, $field_name, $field_label, $target_entity_type, $selection_handler = 'default', $selection_handler_settings = [], $cardinality = 1) {
|
||||
// Look for or add the specified field to the requested entity bundle.
|
||||
if (!FieldStorageConfig::loadByName($entity_type, $field_name)) {
|
||||
FieldStorageConfig::create([
|
||||
'field_name' => $field_name,
|
||||
'type' => 'entity_reference',
|
||||
'entity_type' => $entity_type,
|
||||
'cardinality' => $cardinality,
|
||||
'settings' => [
|
||||
'target_type' => $target_entity_type,
|
||||
],
|
||||
])->save();
|
||||
}
|
||||
if (!FieldConfig::loadByName($entity_type, $bundle, $field_name)) {
|
||||
FieldConfig::create([
|
||||
'field_name' => $field_name,
|
||||
'entity_type' => $entity_type,
|
||||
'bundle' => $bundle,
|
||||
'label' => $field_label,
|
||||
'settings' => [
|
||||
'handler' => $selection_handler,
|
||||
'handler_settings' => $selection_handler_settings,
|
||||
],
|
||||
])->save();
|
||||
}
|
||||
}
|
||||
use nonDeprecatedEntityReferenceTestTrait;
|
||||
|
||||
}
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@ namespace Drupal\Tests\field\Functional\EntityReference;
|
||||
use Drupal\Core\Field\FieldStorageDefinitionInterface;
|
||||
use Drupal\field\Entity\FieldConfig;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
use Drupal\field\Tests\EntityReference\EntityReferenceTestTrait;
|
||||
use Drupal\Tests\field\Traits\EntityReferenceTestTrait;
|
||||
use Drupal\taxonomy\Entity\Vocabulary;
|
||||
use Drupal\node\Entity\Node;
|
||||
use Drupal\field\Entity\FieldStorageConfig;
|
||||
|
||||
+1
-1
@@ -6,8 +6,8 @@ use Drupal\Component\Render\FormattableMarkup;
|
||||
use Drupal\entity_test\Entity\EntityTest;
|
||||
use Drupal\field\Entity\FieldConfig;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
use Drupal\field\Tests\EntityReference\EntityReferenceTestTrait;
|
||||
use Drupal\Tests\config\Traits\AssertConfigEntityImportTrait;
|
||||
use Drupal\Tests\field\Traits\EntityReferenceTestTrait;
|
||||
|
||||
/**
|
||||
* Tests various Entity reference UI components.
|
||||
|
||||
@@ -5,7 +5,7 @@ namespace Drupal\Tests\field\Functional\EntityReference;
|
||||
use Drupal\Core\Entity\Entity\EntityFormDisplay;
|
||||
use Drupal\Core\Entity\Entity\EntityViewDisplay;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
use Drupal\field\Tests\EntityReference\EntityReferenceTestTrait;
|
||||
use Drupal\Tests\field\Traits\EntityReferenceTestTrait;
|
||||
|
||||
/**
|
||||
* Tests possible XSS security issues in entity references.
|
||||
|
||||
@@ -31,7 +31,7 @@ class DisplayApiTest extends FieldKernelTestBase {
|
||||
/**
|
||||
* The field cardinality to use in this test.
|
||||
*
|
||||
* @var number
|
||||
* @var int
|
||||
*/
|
||||
protected $cardinality;
|
||||
|
||||
|
||||
+1
-1
@@ -8,12 +8,12 @@ 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;
|
||||
use Drupal\Tests\field\Traits\EntityReferenceTestTrait;
|
||||
|
||||
/**
|
||||
* Tests the formatters functionality.
|
||||
|
||||
@@ -14,7 +14,6 @@ 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\node\Entity\NodeType;
|
||||
use Drupal\node\NodeInterface;
|
||||
use Drupal\taxonomy\TermInterface;
|
||||
@@ -24,6 +23,7 @@ use Drupal\node\Entity\Node;
|
||||
use Drupal\taxonomy\Entity\Term;
|
||||
use Drupal\taxonomy\Entity\Vocabulary;
|
||||
use Drupal\user\Entity\User;
|
||||
use Drupal\Tests\field\Traits\EntityReferenceTestTrait;
|
||||
|
||||
/**
|
||||
* Tests the new entity API for the entity reference field type.
|
||||
|
||||
@@ -5,10 +5,10 @@ namespace Drupal\Tests\field\Kernel\EntityReference;
|
||||
use Drupal\Core\DependencyInjection\ContainerBuilder;
|
||||
use Drupal\Core\Logger\RfcLogLevel;
|
||||
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;
|
||||
use Drupal\Tests\field\Traits\EntityReferenceTestTrait;
|
||||
use Symfony\Component\Debug\BufferingLogger;
|
||||
|
||||
/**
|
||||
|
||||
+10
-1
@@ -4,9 +4,9 @@ namespace Drupal\Tests\field\Kernel\EntityReference\Views;
|
||||
|
||||
use Drupal\entity_test\Entity\EntityTestMulChanged;
|
||||
use Drupal\field\Entity\FieldStorageConfig;
|
||||
use Drupal\field\Tests\EntityReference\EntityReferenceTestTrait;
|
||||
use Drupal\entity_test\Entity\EntityTest;
|
||||
use Drupal\entity_test\Entity\EntityTestMul;
|
||||
use Drupal\Tests\field\Traits\EntityReferenceTestTrait;
|
||||
use Drupal\Tests\views\Kernel\ViewsKernelTestBase;
|
||||
use Drupal\views\Tests\ViewTestData;
|
||||
use Drupal\views\Views;
|
||||
@@ -331,6 +331,15 @@ class EntityReferenceRelationshipTest extends ViewsKernelTestBase {
|
||||
// Fourth result has no reference from EntityTestMul hence the output for
|
||||
// should be empty.
|
||||
$this->assertEqual('', $view->getStyle()->getField(3, 'name_2'));
|
||||
|
||||
$fields = $view->field;
|
||||
// Check getValue for reference with a value. The first 3 rows reference
|
||||
// EntityTestMul, so have value 'name1'.
|
||||
$this->assertEquals('name1', $fields['name_2']->getValue($view->result[0]));
|
||||
$this->assertEquals('name1', $fields['name_2']->getValue($view->result[1]));
|
||||
$this->assertEquals('name1', $fields['name_2']->getValue($view->result[2]));
|
||||
// Ensure getValue works on empty references.
|
||||
$this->assertNull($fields['name_2']->getValue($view->result[3]));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+134
@@ -0,0 +1,134 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\field\Kernel\Migrate\d6;
|
||||
|
||||
use Drupal\KernelTests\KernelTestBase;
|
||||
use Drupal\Core\Database\Database;
|
||||
use Drupal\Tests\migrate\Kernel\MigrateDumpAlterInterface;
|
||||
use Drupal\Tests\migrate_drupal\Kernel\d6\MigrateDrupal6TestBase;
|
||||
|
||||
/**
|
||||
* Tests migration field label and description i18n translations.
|
||||
*
|
||||
* @group migrate_drupal_6
|
||||
* @group legacy
|
||||
*/
|
||||
class MigrateFieldInstanceLabelDescriptionTest extends MigrateDrupal6TestBase implements MigrateDumpAlterInterface {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = [
|
||||
'config_translation',
|
||||
'locale',
|
||||
'language',
|
||||
'menu_ui',
|
||||
'node',
|
||||
'field',
|
||||
];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setUp() {
|
||||
parent::setUp();
|
||||
$this->migrateFields();
|
||||
|
||||
$this->installEntitySchema('node');
|
||||
$this->installConfig(['node']);
|
||||
$this->installSchema('node', ['node_access']);
|
||||
$this->installSchema('system', ['sequences']);
|
||||
$this->executeMigration('language');
|
||||
$this->executeMigration('d6_field_instance_label_description_translation');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function migrateDumpAlter(KernelTestBase $test) {
|
||||
$db = Database::getConnection('default', 'migrate');
|
||||
// Alter the database to test the migration is successful when a translated
|
||||
// field is deleted but the translation data for that field remains in both
|
||||
// the i18n_strings and locales_target tables.
|
||||
$db->delete('content_node_field_instance')
|
||||
->condition('field_name', 'field_test')
|
||||
->condition('type_name', 'story')
|
||||
->execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests migration of file variables to file.settings.yml.
|
||||
*/
|
||||
public function testFieldInstanceLabelDescriptionTranslationMigration() {
|
||||
$language_manager = $this->container->get('language_manager');
|
||||
|
||||
// Tests fields on 'story' node type.
|
||||
// Check that the deleted field with translations was skipped.
|
||||
$config_translation = $language_manager->getLanguageConfigOverride('fr', 'field.field.node.story.field_test');
|
||||
$this->assertNull($config_translation->get('label'));
|
||||
$this->assertNull($config_translation->get('description'));
|
||||
|
||||
$config_translation = $language_manager->getLanguageConfigOverride('fr', 'field.field.node.story.field_test_two');
|
||||
$this->assertSame("fr - Integer Field", $config_translation->get('label'));
|
||||
$this->assertSame("fr - An example integer field.", $config_translation->get('description'));
|
||||
|
||||
$config_translation = $language_manager->getLanguageConfigOverride('fr', 'field.field.node.story.field_test_four');
|
||||
$this->assertSame("fr - Float Field", $config_translation->get('label'));
|
||||
$this->assertSame("fr - An example float field.", $config_translation->get('description'));
|
||||
|
||||
$config_translation = $language_manager->getLanguageConfigOverride('fr', 'field.field.node.story.field_test_email');
|
||||
$this->assertSame("fr - Email Field", $config_translation->get('label'));
|
||||
$this->assertSame("fr - An example email field.", $config_translation->get('description'));
|
||||
|
||||
$config_translation = $language_manager->getLanguageConfigOverride('fr', 'field.field.node.story.field_test_imagefield');
|
||||
$this->assertSame("fr - Image Field", $config_translation->get('label'));
|
||||
$this->assertSame("fr - An example image field.", $config_translation->get('description'));
|
||||
|
||||
$config_translation = $language_manager->getLanguageConfigOverride('zu', 'field.field.node.story.field_test_imagefield');
|
||||
$this->assertSame("zu - Image Field", $config_translation->get('label'));
|
||||
$this->assertSame("zu - An example image field.", $config_translation->get('description'));
|
||||
|
||||
$config_translation = $language_manager->getLanguageConfigOverride('fr', 'field.field.node.story.field_test_filefield');
|
||||
$this->assertSame("fr - File Field", $config_translation->get('label'));
|
||||
$this->assertSame("fr - An example file field.", $config_translation->get('description'));
|
||||
|
||||
$config_translation = $language_manager->getLanguageConfigOverride('fr', 'field.field.node.story.field_test_link');
|
||||
$this->assertSame("fr - Link Field", $config_translation->get('label'));
|
||||
$this->assertSame("fr - An example link field.", $config_translation->get('description'));
|
||||
|
||||
$config_translation = $language_manager->getLanguageConfigOverride('fr', 'field.field.node.story.field_test_date');
|
||||
$this->assertSame("fr - Date Field", $config_translation->get('label'));
|
||||
$this->assertSame("fr - An example date field.", $config_translation->get('description'));
|
||||
|
||||
$config_translation = $language_manager->getLanguageConfigOverride('fr', 'field.field.node.story.field_test_datetime');
|
||||
$this->assertSame("fr - Datetime Field", $config_translation->get('label'));
|
||||
$this->assertSame("fr - An example datetime field.", $config_translation->get('description'));
|
||||
|
||||
$config_translation = $language_manager->getLanguageConfigOverride('fr', 'field.field.node.story.field_test_datestamp');
|
||||
$this->assertSame("fr - Date Stamp Field", $config_translation->get('label'));
|
||||
$this->assertSame("fr - An example date stamp field.", $config_translation->get('description'));
|
||||
|
||||
$config_translation = $language_manager->getLanguageConfigOverride('fr', 'field.field.node.story.field_test_date');
|
||||
$this->assertSame("fr - Date Field", $config_translation->get('label'));
|
||||
$this->assertSame("fr - An example date field.", $config_translation->get('description'));
|
||||
|
||||
$config_translation = $language_manager->getLanguageConfigOverride('fr', 'field.field.node.story.field_test_phone');
|
||||
$this->assertSame("fr - Phone Field", $config_translation->get('label'));
|
||||
$this->assertSame("fr - An example phone field.", $config_translation->get('description'));
|
||||
|
||||
// Tests fields on 'test_page' node type.
|
||||
$config_translation = $language_manager->getLanguageConfigOverride('fr', 'field.field.node.test_page.field_test');
|
||||
$this->assertSame("Champ de texte", $config_translation->get('label'));
|
||||
$this->assertSame("fr - An example text field.", $config_translation->get('description'));
|
||||
|
||||
// Tests fields on 'test_planet' node type.
|
||||
$config_translation = $language_manager->getLanguageConfigOverride('fr', 'field.field.node.test_planet.field_multivalue');
|
||||
$this->assertSame("fr - Decimal Field", $config_translation->get('label'));
|
||||
$this->assertSame("Un exemple plusieurs valeurs champ décimal.", $config_translation->get('description'));
|
||||
|
||||
$config_translation = $language_manager->getLanguageConfigOverride('fr', 'field.field.node.test_planet.field_test_text_single_checkbox');
|
||||
$this->assertNull($config_translation->get('label'));
|
||||
$this->assertSame('fr - An example text field using a single on/off checkbox.', $config_translation->get('description'));
|
||||
}
|
||||
|
||||
}
|
||||
+75
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\field\Kernel\Migrate\d6;
|
||||
|
||||
use Drupal\Tests\migrate_drupal\Kernel\d6\MigrateDrupal6TestBase;
|
||||
|
||||
/**
|
||||
* Migrate field instance option translations.
|
||||
*
|
||||
* @group migrate_drupal_6
|
||||
*/
|
||||
class MigrateFieldInstanceOptionTranslationTest extends MigrateDrupal6TestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules =
|
||||
[
|
||||
'config_translation',
|
||||
'language',
|
||||
'locale',
|
||||
'menu_ui',
|
||||
];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$this->installConfig(['node']);
|
||||
$this->executeMigrations([
|
||||
'language',
|
||||
'd6_node_type',
|
||||
'd6_field',
|
||||
'd6_field_instance',
|
||||
'd6_field_option_translation',
|
||||
'd6_field_instance_option_translation',
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests migration of file variables to file.settings.yml.
|
||||
*/
|
||||
public function testFieldInstanceOptionTranslation() {
|
||||
$language_manager = $this->container->get('language_manager');
|
||||
|
||||
/** @var \Drupal\language\Config\LanguageConfigOverride $config_translation */
|
||||
$config_translation = $language_manager->getLanguageConfigOverride('fr', 'field.field.node.story.field_test_float_single_checkbox');
|
||||
$option_translation = ['on_label' => 'fr - 1.234'];
|
||||
$this->assertSame($option_translation, $config_translation->get('settings'));
|
||||
|
||||
$config_translation = $language_manager->getLanguageConfigOverride('zu', 'field.field.node.story.field_test_float_single_checkbox');
|
||||
$option_translation = ['on_label' => 'zu - 1.234'];
|
||||
$this->assertSame($option_translation, $config_translation->get('settings'));
|
||||
|
||||
$config_translation = $language_manager->getLanguageConfigOverride('fr', 'field.field.node.story.field_test_text_single_checkbox');
|
||||
$option_translation = [
|
||||
'off_label' => 'fr - Hello',
|
||||
'on_label' => 'fr - Goodbye',
|
||||
];
|
||||
$this->assertSame($option_translation, $config_translation->get('settings'));
|
||||
|
||||
$config_translation = $language_manager->getLanguageConfigOverride('fr', 'field.field.node.story.field_test_text_single_checkbox2');
|
||||
$option_translation = [
|
||||
'off_label' => 'fr - Off',
|
||||
'on_label' => 'fr - Hello',
|
||||
];
|
||||
$this->assertSame($option_translation, $config_translation->get('settings'));
|
||||
|
||||
$config_translation = $language_manager->getLanguageConfigOverride('zu', 'field.field.node.story.field_test_text_single_checkbox2');
|
||||
$option_translation = ['on_label' => 'zu - Hello'];
|
||||
$this->assertSame($option_translation, $config_translation->get('settings'));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\field\Kernel\Migrate\d6;
|
||||
|
||||
use Drupal\Tests\migrate_drupal\Kernel\d6\MigrateDrupal6TestBase;
|
||||
|
||||
/**
|
||||
* Migrate field option translations.
|
||||
*
|
||||
* @group migrate_drupal_6
|
||||
*/
|
||||
class MigrateFieldOptionTranslationTest extends MigrateDrupal6TestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = [
|
||||
'config_translation',
|
||||
'language',
|
||||
'locale',
|
||||
'menu_ui',
|
||||
];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$this->executeMigrations([
|
||||
'language',
|
||||
'd6_field',
|
||||
'd6_field_option_translation',
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the Drupal 6 field to Drupal 8 migration.
|
||||
*/
|
||||
public function testFieldOptionTranslation() {
|
||||
$language_manager = $this->container->get('language_manager');
|
||||
|
||||
// Test a select list with allowed values of key only.
|
||||
/** @var \Drupal\language\Config\LanguageConfigOverride $config_translation */
|
||||
$config_translation = $language_manager->getLanguageConfigOverride('fr', 'field.storage.node.field_test_integer_selectlist');
|
||||
$allowed_values = [
|
||||
1 => [
|
||||
'label' => 'fr - 2341',
|
||||
],
|
||||
3 => [
|
||||
'label' => 'fr - 4123',
|
||||
],
|
||||
];
|
||||
$this->assertSame($allowed_values, $config_translation->get('settings.allowed_values'));
|
||||
|
||||
$config_translation = $language_manager->getLanguageConfigOverride('zu', 'field.storage.node.field_test_integer_selectlist');
|
||||
$allowed_values = [
|
||||
1 => [
|
||||
'label' => 'zu - 2341',
|
||||
],
|
||||
];
|
||||
$this->assertSame($allowed_values, $config_translation->get('settings.allowed_values'));
|
||||
|
||||
// Test a select list with allowed values of key|label.
|
||||
$config_translation = $language_manager->getLanguageConfigOverride('fr', 'field.storage.node.field_test_string_selectlist');
|
||||
$allowed_values = [
|
||||
0 => [
|
||||
'label' => 'Noir',
|
||||
],
|
||||
];
|
||||
$this->assertSame($allowed_values, $config_translation->get('settings.allowed_values'));
|
||||
|
||||
$config_translation = $language_manager->getLanguageConfigOverride('zu', 'field.storage.node.field_test_string_selectlist');
|
||||
$allowed_values = [
|
||||
0 => [
|
||||
'label' => 'Okumnyama',
|
||||
],
|
||||
1 => [
|
||||
'label' => 'Mhlophe',
|
||||
],
|
||||
];
|
||||
$this->assertSame($allowed_values, $config_translation->get('settings.allowed_values'));
|
||||
}
|
||||
|
||||
}
|
||||
+79
@@ -0,0 +1,79 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\field\Kernel\Plugin\migrate\source\d6;
|
||||
|
||||
use Drupal\Tests\migrate\Kernel\MigrateSqlSourceTestBase;
|
||||
|
||||
/**
|
||||
* Tests the field label and description translation source plugin.
|
||||
*
|
||||
* @covers \Drupal\field\Plugin\migrate\source\d6\FieldLabelDescriptionTranslation
|
||||
* @group migrate_drupal
|
||||
*/
|
||||
class FieldInstanceLabelDescriptionTranslationTest extends MigrateSqlSourceTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['config_translation', 'migrate_drupal', 'field'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function providerSource() {
|
||||
$test = [];
|
||||
|
||||
// The source data.
|
||||
$test[0]['source_data'] = [
|
||||
'i18n_strings' => [
|
||||
[
|
||||
'lid' => 10,
|
||||
'objectid' => 'story-field_test_two',
|
||||
'type' => 'field',
|
||||
'property' => 'widget_label',
|
||||
],
|
||||
[
|
||||
'lid' => 11,
|
||||
'objectid' => 'story-field_test_two',
|
||||
'type' => 'field',
|
||||
'property' => 'widget_description',
|
||||
],
|
||||
[
|
||||
'lid' => 12,
|
||||
'objectid' => 'story-field_test_two',
|
||||
'type' => 'field',
|
||||
'property' => 'widget_description',
|
||||
],
|
||||
],
|
||||
'locales_target' => [
|
||||
[
|
||||
'lid' => 10,
|
||||
'translation' => "fr - Integer Field",
|
||||
'language' => 'fr',
|
||||
],
|
||||
[
|
||||
'lid' => 11,
|
||||
'translation' => 'fr - An example integer field.',
|
||||
'language' => 'fr',
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
$test[0]['expected_results'] = [
|
||||
[
|
||||
'property' => 'widget_label',
|
||||
'translation' => "fr - Integer Field",
|
||||
'language' => 'fr',
|
||||
'lid' => '10',
|
||||
],
|
||||
[
|
||||
'property' => 'widget_description',
|
||||
'translation' => 'fr - An example integer field.',
|
||||
'language' => 'fr',
|
||||
'lid' => '11',
|
||||
],
|
||||
];
|
||||
return $test;
|
||||
}
|
||||
|
||||
}
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\field\Kernel\Plugin\migrate\source\d6;
|
||||
|
||||
/**
|
||||
* Tests the field instance option translation source plugin.
|
||||
*
|
||||
* @covers \Drupal\field\Plugin\migrate\source\d6\FieldInstanceOptionTranslation
|
||||
* @group migrate_drupal
|
||||
*/
|
||||
class FieldInstanceOptionTranslationTest extends FieldOptionTranslationTest {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['field', 'migrate_drupal'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function providerSource() {
|
||||
$test = parent::providerSource();
|
||||
|
||||
// FieldInstanceOptionTranslation extends FieldOptionTranslation so the
|
||||
// same test can be used with the addition of the 'type' field to the
|
||||
// output.
|
||||
$test[0]['expected_results'][0]['type'] = 'text';
|
||||
$test[0]['expected_results'][1]['type'] = 'text';
|
||||
$test[0]['expected_results'][2]['type'] = 'number_integer';
|
||||
$test[0]['expected_results'][3]['type'] = 'number_integer';
|
||||
return $test;
|
||||
}
|
||||
|
||||
}
|
||||
+242
@@ -0,0 +1,242 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\field\Kernel\Plugin\migrate\source\d6;
|
||||
|
||||
use Drupal\Tests\migrate\Kernel\MigrateSqlSourceTestBase;
|
||||
|
||||
/**
|
||||
* Tests the field option translation source plugin.
|
||||
*
|
||||
* @covers \Drupal\field\Plugin\migrate\source\d6\FieldOptionTranslation
|
||||
* @group migrate_drupal
|
||||
*/
|
||||
class FieldOptionTranslationTest extends MigrateSqlSourceTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['field', 'migrate_drupal'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function providerSource() {
|
||||
$test = [];
|
||||
|
||||
// The source data.
|
||||
$test[0]['source_data']['content_node_field'] = [
|
||||
[
|
||||
'field_name' => 'field_test_text_single_checkbox',
|
||||
'type' => 'text',
|
||||
'global_settings' => 'a:4:{s:15:"text_processing";s:1:"0";s:10:"max_length";s:0:"";s:14:"allowed_values";s:10:"Off\\nHello";s:18:"allowed_values_php";s:0:"";}',
|
||||
'required' => 0,
|
||||
'multiple' => 0,
|
||||
'db_storage' => 1,
|
||||
'module' => 'text',
|
||||
],
|
||||
[
|
||||
'field_name' => 'field_test_integer_selectlist',
|
||||
'type' => 'number_integer',
|
||||
'global_settings' => 'a:6:{s:6:"prefix";s:0:"";s:6:"suffix";s:0:"";s:3:"min";s:0:"";s:3:"max";s:0:"";s:14:"allowed_values";s:22:"1234\\n2341\\n3412\\n4123";s:18:"allowed_values_php";s:0:"";}',
|
||||
'required' => 0,
|
||||
'multiple' => 0,
|
||||
'db_storage' => 1,
|
||||
'module' => 'text',
|
||||
],
|
||||
];
|
||||
$test[0]['source_data']['content_node_field_instance'] = [
|
||||
[
|
||||
'field_name' => 'field_test_text_single_checkbox',
|
||||
'type_name' => 'story',
|
||||
'weight' => 1,
|
||||
'label' => 'Text Single Checkbox Field',
|
||||
'widget_type' => 'optionwidgets_onoff',
|
||||
'description' => 'An example text field using a single on/off checkbox.',
|
||||
'widget_module' => 'optionwidgets',
|
||||
'widget_active' => 1,
|
||||
'required' => 1,
|
||||
'active' => 1,
|
||||
'global_settings' => 'a:0;',
|
||||
'widget_settings' => 'a:0;',
|
||||
'display_settings' => 'a:0;',
|
||||
],
|
||||
[
|
||||
'field_name' => 'field_test_integer_selectlist',
|
||||
'type_name' => 'story',
|
||||
'weight' => 1,
|
||||
'label' => 'Integer Select List Field',
|
||||
'widget_type' => 'optionwidgets_select',
|
||||
'description' => 'An example integer field using a select list.',
|
||||
'widget_module' => 'optionwidgets',
|
||||
'widget_active' => 1,
|
||||
'required' => 1,
|
||||
'active' => 1,
|
||||
'global_settings' => 'a:0;',
|
||||
'widget_settings' => 'a:0;',
|
||||
'display_settings' => 'a:0;',
|
||||
],
|
||||
];
|
||||
|
||||
$test[0]['source_data']['i18n_strings'] = [
|
||||
[
|
||||
'lid' => 10,
|
||||
'objectid' => 'field_test_text_single_checkbox',
|
||||
'type' => 'field',
|
||||
'property' => 'option_0',
|
||||
'objectindex' => 0,
|
||||
'format' => 0,
|
||||
],
|
||||
[
|
||||
'lid' => 11,
|
||||
'objectid' => 'field_test_text_single_checkbox',
|
||||
'type' => 'field',
|
||||
'property' => 'option_1',
|
||||
'objectindex' => 0,
|
||||
'format' => 0,
|
||||
],
|
||||
[
|
||||
'lid' => 20,
|
||||
'objectid' => 'field_test_integer_selectlist',
|
||||
'type' => 'field',
|
||||
'property' => 'option_1234',
|
||||
'objectindex' => 0,
|
||||
'format' => 0,
|
||||
],
|
||||
[
|
||||
'lid' => 21,
|
||||
'objectid' => 'field_test_integer_selectlist',
|
||||
'type' => 'field',
|
||||
'property' => 'option_4123',
|
||||
'objectindex' => 0,
|
||||
'format' => 0,
|
||||
],
|
||||
];
|
||||
$test[0]['source_data']['locales_target'] = [
|
||||
[
|
||||
'lid' => 10,
|
||||
'translation' => "fr - Hello",
|
||||
'language' => 'fr',
|
||||
'plid' => 0,
|
||||
'plural' => 0,
|
||||
'i18n_status' => 0,
|
||||
],
|
||||
[
|
||||
'lid' => 11,
|
||||
'translation' => 'fr - Goodbye',
|
||||
'language' => 'fr',
|
||||
'plid' => 0,
|
||||
'plural' => 0,
|
||||
'i18n_status' => 0,
|
||||
],
|
||||
[
|
||||
'lid' => 20,
|
||||
'translation' => "fr - 4444",
|
||||
'language' => 'fr',
|
||||
'plid' => 0,
|
||||
'plural' => 0,
|
||||
'i18n_status' => 0,
|
||||
],
|
||||
[
|
||||
'lid' => 21,
|
||||
'translation' => 'fr - 5555',
|
||||
'language' => 'fr',
|
||||
'plid' => 0,
|
||||
'plural' => 0,
|
||||
'i18n_status' => 0,
|
||||
],
|
||||
];
|
||||
|
||||
$test[0]['expected_results'] = [
|
||||
[
|
||||
'field_name' => 'field_test_text_single_checkbox',
|
||||
'type' => 'text',
|
||||
'widget_type' => 'optionwidgets_onoff',
|
||||
'global_settings' => [
|
||||
'allowed_values' => 'Off\nHello',
|
||||
'allowed_values_php' => '',
|
||||
'max_length' => '',
|
||||
'text_processing' => '0',
|
||||
],
|
||||
'db_columns' => '',
|
||||
'property' => 'option_0',
|
||||
'objectid' => 'field_test_text_single_checkbox',
|
||||
'language' => 'fr',
|
||||
'translation' => 'fr - Hello',
|
||||
'objectindex' => 0,
|
||||
'format' => 0,
|
||||
'plid' => 0,
|
||||
'plural' => 0,
|
||||
'i18n_status' => 0,
|
||||
],
|
||||
[
|
||||
'field_name' => 'field_test_text_single_checkbox',
|
||||
'type' => 'text',
|
||||
'widget_type' => 'optionwidgets_onoff',
|
||||
'global_settings' => [
|
||||
'allowed_values' => 'Off\nHello',
|
||||
'allowed_values_php' => '',
|
||||
'max_length' => '',
|
||||
'text_processing' => '0',
|
||||
],
|
||||
'db_columns' => '',
|
||||
'property' => 'option_1',
|
||||
'objectid' => 'field_test_text_single_checkbox',
|
||||
'language' => 'fr',
|
||||
'translation' => 'fr - Goodbye',
|
||||
'objectindex' => 0,
|
||||
'format' => 0,
|
||||
'plid' => 0,
|
||||
'plural' => 0,
|
||||
'i18n_status' => 0,
|
||||
],
|
||||
[
|
||||
'field_name' => 'field_test_integer_selectlist',
|
||||
'type' => 'number_integer',
|
||||
'widget_type' => 'optionwidgets_select',
|
||||
'global_settings' => [
|
||||
'allowed_values' => '1234\n2341\n3412\n4123',
|
||||
'max' => '',
|
||||
'min' => '',
|
||||
'prefix' => '',
|
||||
'suffix' => '',
|
||||
'allowed_values_php' => '',
|
||||
],
|
||||
'db_columns' => '',
|
||||
'property' => 'option_1234',
|
||||
'objectid' => 'field_test_integer_selectlist',
|
||||
'language' => 'fr',
|
||||
'translation' => 'fr - 4444',
|
||||
'objectindex' => 0,
|
||||
'format' => 0,
|
||||
'plid' => 0,
|
||||
'plural' => 0,
|
||||
'i18n_status' => 0,
|
||||
],
|
||||
[
|
||||
'field_name' => 'field_test_integer_selectlist',
|
||||
'type' => 'number_integer',
|
||||
'widget_type' => 'optionwidgets_select',
|
||||
'global_settings' => [
|
||||
'allowed_values' => '1234\n2341\n3412\n4123',
|
||||
'max' => '',
|
||||
'min' => '',
|
||||
'prefix' => '',
|
||||
'suffix' => '',
|
||||
'allowed_values_php' => '',
|
||||
],
|
||||
'db_columns' => '',
|
||||
'property' => 'option_4123',
|
||||
'objectid' => 'field_test_integer_selectlist',
|
||||
'language' => 'fr',
|
||||
'translation' => 'fr - 5555',
|
||||
'objectindex' => 0,
|
||||
'format' => 0,
|
||||
'plid' => 0,
|
||||
'plural' => 0,
|
||||
'i18n_status' => 0,
|
||||
],
|
||||
];
|
||||
return $test;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\field\Traits;
|
||||
|
||||
use Drupal\field\Entity\FieldConfig;
|
||||
use Drupal\field\Entity\FieldStorageConfig;
|
||||
|
||||
/**
|
||||
* Provides common functionality for the EntityReference test classes.
|
||||
*/
|
||||
trait EntityReferenceTestTrait {
|
||||
|
||||
/**
|
||||
* Creates a field of an entity reference field storage on the specified bundle.
|
||||
*
|
||||
* @param string $entity_type
|
||||
* The type of entity the field will be attached to.
|
||||
* @param string $bundle
|
||||
* The bundle name of the entity the field will be attached to.
|
||||
* @param string $field_name
|
||||
* The name of the field; if it already exists, a new instance of the existing
|
||||
* field will be created.
|
||||
* @param string $field_label
|
||||
* The label of the field.
|
||||
* @param string $target_entity_type
|
||||
* The type of the referenced entity.
|
||||
* @param string $selection_handler
|
||||
* The selection handler used by this field.
|
||||
* @param array $selection_handler_settings
|
||||
* An array of settings supported by the selection handler specified above.
|
||||
* (e.g. 'target_bundles', 'sort', 'auto_create', etc).
|
||||
* @param int $cardinality
|
||||
* The cardinality of the field.
|
||||
*
|
||||
* @see \Drupal\Core\Entity\Plugin\EntityReferenceSelection\SelectionBase::buildConfigurationForm()
|
||||
*/
|
||||
protected function createEntityReferenceField($entity_type, $bundle, $field_name, $field_label, $target_entity_type, $selection_handler = 'default', $selection_handler_settings = [], $cardinality = 1) {
|
||||
// Look for or add the specified field to the requested entity bundle.
|
||||
if (!FieldStorageConfig::loadByName($entity_type, $field_name)) {
|
||||
FieldStorageConfig::create([
|
||||
'field_name' => $field_name,
|
||||
'type' => 'entity_reference',
|
||||
'entity_type' => $entity_type,
|
||||
'cardinality' => $cardinality,
|
||||
'settings' => [
|
||||
'target_type' => $target_entity_type,
|
||||
],
|
||||
])->save();
|
||||
}
|
||||
if (!FieldConfig::loadByName($entity_type, $bundle, $field_name)) {
|
||||
FieldConfig::create([
|
||||
'field_name' => $field_name,
|
||||
'entity_type' => $entity_type,
|
||||
'bundle' => $bundle,
|
||||
'label' => $field_label,
|
||||
'settings' => [
|
||||
'handler' => $selection_handler,
|
||||
'handler_settings' => $selection_handler_settings,
|
||||
],
|
||||
])->save();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -6,6 +6,7 @@
|
||||
*/
|
||||
|
||||
use Drupal\Core\Cache\Cache;
|
||||
use Drupal\Core\Entity\Display\EntityDisplayInterface;
|
||||
use Drupal\Core\Entity\Entity\EntityFormDisplay;
|
||||
use Drupal\Core\Entity\Entity\EntityViewDisplay;
|
||||
use Drupal\field_layout\Display\EntityDisplayWithLayoutInterface;
|
||||
@@ -15,8 +16,10 @@ use Drupal\field_layout\Display\EntityDisplayWithLayoutInterface;
|
||||
*/
|
||||
function field_layout_install() {
|
||||
// Ensure each entity display has a layout.
|
||||
$entity_save = function (EntityDisplayWithLayoutInterface $entity) {
|
||||
$entity->ensureLayout()->save();
|
||||
$entity_save = function (EntityDisplayInterface $entity) {
|
||||
if ($entity instanceof EntityDisplayWithLayoutInterface) {
|
||||
$entity->ensureLayout()->save();
|
||||
}
|
||||
};
|
||||
array_map($entity_save, EntityViewDisplay::loadMultiple());
|
||||
array_map($entity_save, EntityFormDisplay::loadMultiple());
|
||||
@@ -31,8 +34,10 @@ function field_layout_install() {
|
||||
function field_layout_uninstall() {
|
||||
// Reset each entity display to use the one-column layout to best approximate
|
||||
// the absence of layouts.
|
||||
$entity_save = function (EntityDisplayWithLayoutInterface $entity) {
|
||||
$entity->setLayoutId('layout_onecol')->save();
|
||||
$entity_save = function (EntityDisplayInterface $entity) {
|
||||
if ($entity instanceof EntityDisplayWithLayoutInterface) {
|
||||
$entity->setLayoutId('layout_onecol')->save();
|
||||
}
|
||||
};
|
||||
array_map($entity_save, EntityViewDisplay::loadMultiple());
|
||||
array_map($entity_save, EntityFormDisplay::loadMultiple());
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user