Update to Drupal 8.1.5. For more information, see https://www.drupal.org/project/drupal/releases/8.1.5
This commit is contained in:
parent
13b6ca7cc2
commit
38ba7c357d
342 changed files with 7814 additions and 1534 deletions
|
@ -1,8 +1,8 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\action\Tests;
|
||||
namespace Drupal\Tests\action\Functional;
|
||||
|
||||
use Drupal\simpletest\WebTestBase;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
|
||||
/**
|
||||
* Tests that uninstalling actions does not remove other module's actions.
|
||||
|
@ -10,7 +10,7 @@ use Drupal\simpletest\WebTestBase;
|
|||
* @group action
|
||||
* @see \Drupal\action\Plugin\views\field\BulkForm
|
||||
*/
|
||||
class ActionUninstallTest extends WebTestBase {
|
||||
class ActionUninstallTest extends BrowserTestBase {
|
||||
|
||||
/**
|
||||
* Modules to install.
|
|
@ -1,8 +1,8 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\action\Tests;
|
||||
namespace Drupal\Tests\action\Functional;
|
||||
|
||||
use Drupal\simpletest\WebTestBase;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
use Drupal\views\Views;
|
||||
|
||||
/**
|
||||
|
@ -11,7 +11,7 @@ use Drupal\views\Views;
|
|||
* @group action
|
||||
* @see \Drupal\action\Plugin\views\field\BulkForm
|
||||
*/
|
||||
class BulkFormTest extends WebTestBase {
|
||||
class BulkFormTest extends BrowserTestBase {
|
||||
|
||||
/**
|
||||
* Modules to install.
|
||||
|
@ -123,7 +123,7 @@ class BulkFormTest extends WebTestBase {
|
|||
// Check the default title.
|
||||
$this->drupalGet('test_bulk_form');
|
||||
$result = $this->xpath('//label[@for="edit-action"]');
|
||||
$this->assertEqual('With selection', (string) $result[0]);
|
||||
$this->assertEqual('With selection', $result[0]->getText());
|
||||
|
||||
// Setup up a different bulk form title.
|
||||
$view = Views::getView('test_bulk_form');
|
||||
|
@ -133,7 +133,7 @@ class BulkFormTest extends WebTestBase {
|
|||
|
||||
$this->drupalGet('test_bulk_form');
|
||||
$result = $this->xpath('//label[@for="edit-action"]');
|
||||
$this->assertEqual('Test title', (string) $result[0]);
|
||||
$this->assertEqual('Test title', $result[0]->getText());
|
||||
|
||||
$this->drupalGet('test_bulk_form');
|
||||
// Call the node delete action.
|
|
@ -1,9 +1,9 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\action\Tests;
|
||||
namespace Drupal\Tests\action\Functional;
|
||||
|
||||
use Drupal\Component\Utility\Crypt;
|
||||
use Drupal\simpletest\WebTestBase;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
|
||||
/**
|
||||
* Tests complex actions configuration by adding, editing, and deleting a
|
||||
|
@ -11,7 +11,7 @@ use Drupal\simpletest\WebTestBase;
|
|||
*
|
||||
* @group action
|
||||
*/
|
||||
class ConfigurationTest extends WebTestBase {
|
||||
class ConfigurationTest extends BrowserTestBase {
|
||||
|
||||
/**
|
||||
* Modules to install.
|
|
@ -20,7 +20,7 @@ class AggregatorItem extends DrupalSqlBase {
|
|||
public function query() {
|
||||
return $this->select('aggregator_item', 'ai')
|
||||
->fields('ai')
|
||||
->orderBy('iid');
|
||||
->orderBy('ai.iid');
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\ban\Tests;
|
||||
namespace Drupal\Tests\ban\Functional;
|
||||
|
||||
use Drupal\simpletest\WebTestBase;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
|
||||
/**
|
||||
* Tests IP address banning.
|
||||
*
|
||||
* @group ban
|
||||
*/
|
||||
class IpAddressBlockingTest extends WebTestBase {
|
||||
class IpAddressBlockingTest extends BrowserTestBase {
|
||||
|
||||
/**
|
||||
* Modules to install.
|
||||
|
@ -61,7 +61,7 @@ class IpAddressBlockingTest extends WebTestBase {
|
|||
|
||||
// Pass an IP address as a URL parameter and submit it.
|
||||
$submit_ip = '1.2.3.4';
|
||||
$this->drupalPostForm('admin/config/people/ban/' . $submit_ip, NULL, t('Add'));
|
||||
$this->drupalPostForm('admin/config/people/ban/' . $submit_ip, array(), t('Add'));
|
||||
$ip = db_query("SELECT iid from {ban_ip} WHERE ip = :ip", array(':ip' => $submit_ip))->fetchField();
|
||||
$this->assertTrue($ip, 'IP address found in database');
|
||||
$this->assertRaw(t('The IP address %ip has been banned.', array('%ip' => $submit_ip)), 'IP address was banned.');
|
|
@ -226,6 +226,13 @@ class BigPipe implements BigPipeInterface {
|
|||
$preg_placeholder_strings = array_map($prepare_for_preg_split, array_keys($no_js_placeholders));
|
||||
$fragments = preg_split('/' . implode('|', $preg_placeholder_strings) . '/', $html, NULL, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
|
||||
|
||||
// Determine how many occurrences there are of each no-JS placeholder.
|
||||
$placeholder_occurrences = array_count_values(array_intersect($fragments, array_keys($no_js_placeholders)));
|
||||
|
||||
// Set up a variable to store the content of placeholders that have multiple
|
||||
// occurrences.
|
||||
$multi_occurrence_placeholders_content = [];
|
||||
|
||||
foreach ($fragments as $fragment) {
|
||||
// If the fragment isn't one of the no-JS placeholders, it is the HTML in
|
||||
// between placeholders and it must be printed & flushed immediately. The
|
||||
|
@ -236,6 +243,15 @@ class BigPipe implements BigPipeInterface {
|
|||
continue;
|
||||
}
|
||||
|
||||
// If there are multiple occurrences of this particular placeholder, and
|
||||
// this is the second occurrence, we can skip all calculations and just
|
||||
// send the same content.
|
||||
if ($placeholder_occurrences[$fragment] > 1 && isset($multi_occurrence_placeholders_content[$fragment])) {
|
||||
print $multi_occurrence_placeholders_content[$fragment];
|
||||
flush();
|
||||
continue;
|
||||
}
|
||||
|
||||
$placeholder = $fragment;
|
||||
assert('isset($no_js_placeholders[$placeholder])');
|
||||
$token = Crypt::randomBytesBase64(55);
|
||||
|
@ -310,6 +326,13 @@ class BigPipe implements BigPipeInterface {
|
|||
// they can be sent in ::sendPreBody().
|
||||
$cumulative_assets->setAlreadyLoadedLibraries(array_merge($cumulative_assets->getAlreadyLoadedLibraries(), $html_response->getAttachments()['library']));
|
||||
$cumulative_assets->setSettings($html_response->getAttachments()['drupalSettings']);
|
||||
|
||||
// If there are multiple occurrences of this particular placeholder, track
|
||||
// the content that was sent, so we can skip all calculations for the next
|
||||
// occurrence.
|
||||
if ($placeholder_occurrences[$fragment] > 1) {
|
||||
$multi_occurrence_placeholders_content[$fragment] = $html_response->getContent();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -508,7 +531,9 @@ EOF;
|
|||
*
|
||||
* @return array
|
||||
* Indexed array; the order in which the BigPipe placeholders must be sent.
|
||||
* Values are the BigPipe placeholder IDs.
|
||||
* Values are the BigPipe placeholder IDs. Note that only unique
|
||||
* placeholders are kept: if the same placeholder occurs multiple times, we
|
||||
* only keep the first occurrence.
|
||||
*/
|
||||
protected function getPlaceholderOrder($html) {
|
||||
$fragments = explode('<div data-big-pipe-placeholder-id="', $html);
|
||||
|
@ -521,7 +546,7 @@ EOF;
|
|||
$order[] = $placeholder;
|
||||
}
|
||||
|
||||
return $order;
|
||||
return array_unique($order);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -269,6 +269,42 @@ class BigPipeTest extends WebTestBase {
|
|||
unlink(\Drupal::root() . '/' . $this->siteDirectory . '/error.log');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests BigPipe with a multi-occurrence placeholder.
|
||||
*/
|
||||
public function testBigPipeMultiOccurrencePlaceholders() {
|
||||
$this->drupalLogin($this->rootUser);
|
||||
$this->assertSessionCookieExists(TRUE);
|
||||
$this->assertBigPipeNoJsCookieExists(FALSE);
|
||||
|
||||
// By not calling performMetaRefresh() here, we simulate JavaScript being
|
||||
// enabled, because as far as the BigPipe module is concerned, JavaScript is
|
||||
// enabled in the browser as long as the BigPipe no-JS cookie is *not* set.
|
||||
// @see setUp()
|
||||
// @see performMetaRefresh()
|
||||
|
||||
$this->drupalGet(Url::fromRoute('big_pipe_test_multi_occurrence'));
|
||||
$big_pipe_placeholder_id = 'callback=Drupal%5CCore%5CRender%5CElement%5CStatusMessages%3A%3ArenderMessages&args[0]&token=a8c34b5e';
|
||||
$expected_placeholder_replacement = '<script type="application/vnd.drupal-ajax" data-big-pipe-replacement-for-placeholder-with-id="' . $big_pipe_placeholder_id . '">';
|
||||
$this->assertRaw('The count is 1.');
|
||||
$this->assertNoRaw('The count is 2.');
|
||||
$this->assertNoRaw('The count is 3.');
|
||||
$raw_content = $this->getRawContent();
|
||||
$this->assertTrue(substr_count($raw_content, $expected_placeholder_replacement) == 1, 'Only one placeholder replacement was found for the duplicate #lazy_builder arrays.');
|
||||
|
||||
// By calling performMetaRefresh() here, we simulate JavaScript being
|
||||
// disabled, because as far as the BigPipe module is concerned, it is
|
||||
// enabled in the browser when the BigPipe no-JS cookie is set.
|
||||
// @see setUp()
|
||||
// @see performMetaRefresh()
|
||||
$this->performMetaRefresh();
|
||||
$this->assertBigPipeNoJsCookieExists(TRUE);
|
||||
$this->drupalGet(Url::fromRoute('big_pipe_test_multi_occurrence'));
|
||||
$this->assertRaw('The count is 1.');
|
||||
$this->assertNoRaw('The count is 2.');
|
||||
$this->assertNoRaw('The count is 3.');
|
||||
}
|
||||
|
||||
protected function assertBigPipeResponseHeadersPresent() {
|
||||
$this->pass('Verifying BigPipe response headers…', 'Debug');
|
||||
$this->assertTrue(FALSE !== strpos($this->drupalGetHeader('Cache-Control'), 'private'), 'Cache-Control header set to "private".');
|
||||
|
|
|
@ -15,3 +15,12 @@ no_big_pipe:
|
|||
_no_big_pipe: TRUE
|
||||
requirements:
|
||||
_access: 'TRUE'
|
||||
|
||||
big_pipe_test_multi_occurrence:
|
||||
path: '/big_pipe_test_multi_occurrence'
|
||||
defaults:
|
||||
_controller: '\Drupal\big_pipe_test\BigPipeTestController::multiOccurrence'
|
||||
_title: 'BigPipe test multiple occurrences of the same placeholder'
|
||||
requirements:
|
||||
_access: 'TRUE'
|
||||
|
||||
|
|
|
@ -52,6 +52,30 @@ class BigPipeTestController {
|
|||
return ['#markup' => '<p>Nope.</p>'];
|
||||
}
|
||||
|
||||
/**
|
||||
* A page with multiple occurrences of the same placeholder.
|
||||
*
|
||||
* @see \Drupal\big_pipe\Tests\BigPipeTest::testBigPipeMultipleOccurrencePlaceholders()
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function multiOccurrence() {
|
||||
return [
|
||||
'item1' => [
|
||||
'#lazy_builder' => [static::class . '::counter', []],
|
||||
'#create_placeholder' => TRUE,
|
||||
],
|
||||
'item2' => [
|
||||
'#lazy_builder' => [static::class . '::counter', []],
|
||||
'#create_placeholder' => TRUE,
|
||||
],
|
||||
'item3' => [
|
||||
'#lazy_builder' => [static::class . '::counter', []],
|
||||
'#create_placeholder' => TRUE,
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* #lazy_builder callback; builds <time> markup with current time.
|
||||
*
|
||||
|
@ -98,4 +122,31 @@ class BigPipeTestController {
|
|||
return ['#plain_text' => BigPipeTestSubscriber::CONTENT_TRIGGER_EXCEPTION];
|
||||
}
|
||||
|
||||
/**
|
||||
* #lazy_builder callback; returns the current count.
|
||||
*
|
||||
* @see \Drupal\big_pipe\Tests\BigPipeTest::testBigPipeMultipleOccurrencePlaceholders()
|
||||
*
|
||||
* @return array
|
||||
* The render array.
|
||||
*/
|
||||
public static function counter() {
|
||||
// Lazy builders are not allowed to build their own state like this function
|
||||
// does, but in this case we're intentionally doing that for testing
|
||||
// purposes: so we can ensure that each lazy builder is only ever called
|
||||
// once with the same parameters.
|
||||
static $count;
|
||||
|
||||
if (!isset($count)) {
|
||||
$count = 0;
|
||||
}
|
||||
|
||||
$count++;
|
||||
|
||||
return [
|
||||
'#markup' => BigPipeMarkup::create("<p>The count is $count.</p>"),
|
||||
'#cache' => ['max-age' => 0],
|
||||
];
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,117 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\big_pipe\FunctionalJavascript;
|
||||
|
||||
use Drupal\comment\CommentInterface;
|
||||
use Drupal\comment\Entity\Comment;
|
||||
use Drupal\comment\Plugin\Field\FieldType\CommentItemInterface;
|
||||
use Drupal\comment\Tests\CommentTestTrait;
|
||||
use Drupal\editor\Entity\Editor;
|
||||
use Drupal\filter\Entity\FilterFormat;
|
||||
use Drupal\FunctionalJavascriptTests\JavascriptTestBase;
|
||||
use Drupal\simpletest\ContentTypeCreationTrait;
|
||||
use Drupal\simpletest\NodeCreationTrait;
|
||||
|
||||
/**
|
||||
* BigPipe regression tests.
|
||||
*
|
||||
* @group big_pipe
|
||||
*/
|
||||
class BigPipeRegressionTest extends JavascriptTestBase {
|
||||
|
||||
use CommentTestTrait;
|
||||
use ContentTypeCreationTrait;
|
||||
use NodeCreationTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = [
|
||||
'node',
|
||||
'comment',
|
||||
'big_pipe',
|
||||
'history',
|
||||
'editor',
|
||||
'ckeditor',
|
||||
'filter',
|
||||
];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
// Use the big_pipe_test_theme theme.
|
||||
$this->container->get('theme_installer')->install(['big_pipe_test_theme']);
|
||||
$this->container->get('config.factory')->getEditable('system.theme')->set('default', 'big_pipe_test_theme')->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure comment form works with history and big_pipe modules.
|
||||
*
|
||||
* @see https://www.drupal.org/node/2698811
|
||||
*/
|
||||
public function testCommentForm_2698811() {
|
||||
// Ensure an `article` node type exists.
|
||||
$this->createContentType(['type' => 'article']);
|
||||
$this->addDefaultCommentField('node', 'article');
|
||||
|
||||
// Enable CKEditor.
|
||||
$format = $this->randomMachineName();
|
||||
FilterFormat::create([
|
||||
'format' => $format,
|
||||
'name' => $this->randomString(),
|
||||
'weight' => 1,
|
||||
'filters' => [],
|
||||
])->save();
|
||||
$settings['toolbar']['rows'] = [
|
||||
[
|
||||
[
|
||||
'name' => 'Links',
|
||||
'items' => [
|
||||
'DrupalLink',
|
||||
'DrupalUnlink',
|
||||
],
|
||||
],
|
||||
],
|
||||
];
|
||||
$editor = Editor::create([
|
||||
'format' => $format,
|
||||
'editor' => 'ckeditor',
|
||||
]);
|
||||
$editor->setSettings($settings);
|
||||
$editor->save();
|
||||
|
||||
$admin_user = $this->drupalCreateUser([
|
||||
'access comments',
|
||||
'post comments',
|
||||
'use text format ' . $format,
|
||||
]);
|
||||
$this->drupalLogin($admin_user);
|
||||
|
||||
$node = $this->createNode([
|
||||
'type' => 'article',
|
||||
'comment' => CommentItemInterface::OPEN,
|
||||
]);
|
||||
// Create some comments.
|
||||
foreach (range(1, 5) as $i) {
|
||||
$comment = Comment::create([
|
||||
'status' => CommentInterface::PUBLISHED,
|
||||
'field_name' => 'comment',
|
||||
'entity_type' => 'node',
|
||||
'entity_id' => $node->id(),
|
||||
]);
|
||||
$comment->save();
|
||||
}
|
||||
$this->drupalGet($node->toUrl()->toString());
|
||||
// Confirm that CKEditor loaded.
|
||||
$javascript = <<<JS
|
||||
(function(){
|
||||
return Object.keys(CKEDITOR.instances).length > 0;
|
||||
}());
|
||||
JS;
|
||||
$this->assertJsCondition($javascript);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
name: 'BigPipe test theme'
|
||||
type: theme
|
||||
description: 'Theme for testing BigPipe edge cases.'
|
||||
version: VERSION
|
||||
core: 8.x
|
|
@ -0,0 +1,13 @@
|
|||
{#
|
||||
/**
|
||||
* @file
|
||||
* Test that comments still work with the form above instead of below.
|
||||
*
|
||||
* @see \Drupal\Tests\big_pipe\FunctionalJavascript\BigPipeRegressionTest::testCommentForm_2698811()
|
||||
*/
|
||||
#}
|
||||
<section{{ attributes }}>
|
||||
{{ comment_form }}
|
||||
|
||||
{{ comments }}
|
||||
</section>
|
|
@ -19,6 +19,9 @@ process:
|
|||
- module
|
||||
- delta
|
||||
delimiter: _
|
||||
-
|
||||
plugin: machine_name
|
||||
field: id
|
||||
plugin:
|
||||
-
|
||||
plugin: static_map
|
||||
|
|
|
@ -291,7 +291,6 @@ class Block extends ConfigEntityBase implements BlockInterface, EntityWithPlugin
|
|||
* The condition plugin manager.
|
||||
*/
|
||||
protected function conditionPluginManager() {
|
||||
$this->conditionPluginManager;
|
||||
if (!isset($this->conditionPluginManager)) {
|
||||
$this->conditionPluginManager = \Drupal::service('plugin.manager.condition');
|
||||
}
|
||||
|
|
|
@ -43,6 +43,13 @@ class Block extends DrupalSqlBase {
|
|||
*/
|
||||
protected $blockRoleTable;
|
||||
|
||||
/**
|
||||
* Table listing user roles.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $userRoleTable;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
@ -55,6 +62,9 @@ class Block extends DrupalSqlBase {
|
|||
$this->blockTable = 'blocks';
|
||||
$this->blockRoleTable = 'blocks_roles';
|
||||
}
|
||||
// Drupal 6 & 7 both use the same name for the user roles table.
|
||||
$this->userRoleTable = 'role';
|
||||
|
||||
return $this->select($this->blockTable, 'b')->fields('b');
|
||||
}
|
||||
|
||||
|
@ -106,11 +116,12 @@ class Block extends DrupalSqlBase {
|
|||
$module = $row->getSourceProperty('module');
|
||||
$delta = $row->getSourceProperty('delta');
|
||||
|
||||
$roles = $this->select($this->blockRoleTable, 'br')
|
||||
$query = $this->select($this->blockRoleTable, 'br')
|
||||
->fields('br', array('rid'))
|
||||
->condition('module', $module)
|
||||
->condition('delta', $delta)
|
||||
->execute()
|
||||
->condition('delta', $delta);
|
||||
$query->join($this->userRoleTable, 'ur', 'br.rid = ur.rid');
|
||||
$roles = $query->execute()
|
||||
->fetchCol();
|
||||
$row->setSourceProperty('roles', $roles);
|
||||
|
||||
|
|
|
@ -108,7 +108,7 @@ class MigrateBlockTest extends MigrateDrupal7TestBase {
|
|||
$this->assertEntity('bartik_system_main', 'system_main_block', [], '', 'content', 'bartik', 0, '', '0');
|
||||
$this->assertEntity('bartik_search_form', 'search_form_block', [], '', 'sidebar_first', 'bartik', -1, '', '0');
|
||||
$this->assertEntity('bartik_user_login', 'user_login_block', [], '', 'sidebar_first', 'bartik', 0, '', '0');
|
||||
$this->assertEntity('bartik_system_powered-by', 'system_powered_by_block', [], '', 'footer', 'bartik', 10, '', '0');
|
||||
$this->assertEntity('bartik_system_powered_by', 'system_powered_by_block', [], '', 'footer', 'bartik', 10, '', '0');
|
||||
$this->assertEntity('seven_system_main', 'system_main_block', [], '', 'content', 'seven', 0, '', '0');
|
||||
$this->assertEntity('seven_user_login', 'user_login_block', [], '', 'content', 'seven', 10, '', '0');
|
||||
|
||||
|
|
|
@ -25,6 +25,39 @@ class BlockTest extends MigrateSqlSourceTestCase {
|
|||
* Sample block instance query results from the source.
|
||||
*/
|
||||
protected $expectedResults = array(
|
||||
array(
|
||||
'bid' => 1,
|
||||
'module' => 'block',
|
||||
'delta' => '1',
|
||||
'theme' => 'garland',
|
||||
'status' => 1,
|
||||
'weight' => 0,
|
||||
'region' => 'left',
|
||||
'visibility' => 0,
|
||||
'pages' => '',
|
||||
'title' => 'Test Title 01',
|
||||
'cache' => -1,
|
||||
'roles' => [2]
|
||||
),
|
||||
array(
|
||||
'bid' => 2,
|
||||
'module' => 'block',
|
||||
'delta' => '2',
|
||||
'theme' => 'garland',
|
||||
'status' => 1,
|
||||
'weight' => 5,
|
||||
'region' => 'right',
|
||||
'visibility' => 0,
|
||||
'pages' => '<front>',
|
||||
'title' => 'Test Title 02',
|
||||
'cache' => -1,
|
||||
'roles' => [2]
|
||||
),
|
||||
);
|
||||
/**
|
||||
* Sample block table.
|
||||
*/
|
||||
protected $expectedBlocks = array(
|
||||
array(
|
||||
'bid' => 1,
|
||||
'module' => 'block',
|
||||
|
@ -62,14 +95,35 @@ class BlockTest extends MigrateSqlSourceTestCase {
|
|||
'delta' => 1,
|
||||
'rid' => 2,
|
||||
),
|
||||
array(
|
||||
'module' => 'block',
|
||||
'delta' => 2,
|
||||
'rid' => 2,
|
||||
),
|
||||
array(
|
||||
'module' => 'block',
|
||||
'delta' => 2,
|
||||
'rid' => 100,
|
||||
),
|
||||
);
|
||||
|
||||
/**
|
||||
* Sample role table.
|
||||
*/
|
||||
protected $expectedRole = array(
|
||||
array(
|
||||
'rid' => 2,
|
||||
'name' => 'authenticated user',
|
||||
),
|
||||
);
|
||||
|
||||
/**
|
||||
* Prepopulate database contents.
|
||||
*/
|
||||
protected function setUp() {
|
||||
$this->databaseContents['blocks'] = $this->expectedResults;
|
||||
$this->databaseContents['blocks'] = $this->expectedBlocks;
|
||||
$this->databaseContents['blocks_roles'] = $this->expectedBlocksRoles;
|
||||
$this->databaseContents['role'] = $this->expectedRole;
|
||||
$this->databaseContents['system'] = array(
|
||||
array(
|
||||
'filename' => 'modules/system/system.module',
|
||||
|
|
|
@ -392,7 +392,7 @@ display:
|
|||
plugin_id: string
|
||||
type:
|
||||
id: type
|
||||
table: block_content
|
||||
table: block_content_field_data
|
||||
field: type
|
||||
relationship: none
|
||||
group_type: group
|
||||
|
|
|
@ -4,11 +4,8 @@ migration_tags:
|
|||
- Drupal 6
|
||||
source:
|
||||
plugin: d6_box
|
||||
constants:
|
||||
type: basic
|
||||
process:
|
||||
id: bid
|
||||
type: 'constants/type'
|
||||
info: info
|
||||
'body/format':
|
||||
plugin: migration
|
||||
|
@ -17,6 +14,7 @@ process:
|
|||
'body/value': body
|
||||
destination:
|
||||
plugin: entity:block_content
|
||||
default_bundle: basic
|
||||
no_stub: true
|
||||
migration_dependencies:
|
||||
required:
|
||||
|
|
|
@ -4,11 +4,8 @@ migration_tags:
|
|||
- Drupal 7
|
||||
source:
|
||||
plugin: d7_block_custom
|
||||
constants:
|
||||
type: basic
|
||||
process:
|
||||
id: bid
|
||||
type: 'constants/type'
|
||||
info: info
|
||||
'body/format':
|
||||
plugin: migration
|
||||
|
@ -17,6 +14,7 @@ process:
|
|||
'body/value': body
|
||||
destination:
|
||||
plugin: entity:block_content
|
||||
default_bundle: basic
|
||||
no_stub: true
|
||||
migration_dependencies:
|
||||
required:
|
||||
|
|
|
@ -19,7 +19,7 @@ class Box extends DrupalSqlBase {
|
|||
public function query() {
|
||||
$query = $this->select('boxes', 'b')
|
||||
->fields('b', array('bid', 'body', 'info', 'format'));
|
||||
$query->orderBy('bid');
|
||||
$query->orderBy('b.bid');
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
|
|
@ -28,6 +28,10 @@ class BlockContentListViewsTest extends BlockContentTestBase {
|
|||
// Test for the page title.
|
||||
$this->assertTitle(t('Custom block library') . ' | Drupal');
|
||||
|
||||
// Test for the exposed filters.
|
||||
$this->assertFieldByName('info');
|
||||
$this->assertFieldByName('type');
|
||||
|
||||
// Test for the table.
|
||||
$element = $this->xpath('//div[@class="layout-content"]//table');
|
||||
$this->assertTrue($element, 'Views table found.');
|
||||
|
|
|
@ -18,6 +18,8 @@ interface BookManagerInterface {
|
|||
* Since this can be the full tree including hidden items, the data returned
|
||||
* may be used for generating an an admin interface or a select.
|
||||
*
|
||||
* Note: based on menu_tree_all_data().
|
||||
*
|
||||
* @param int $bid
|
||||
* The Book ID to find links for.
|
||||
* @param array|null $link
|
||||
|
@ -31,8 +33,6 @@ interface BookManagerInterface {
|
|||
*
|
||||
* @return array
|
||||
* An tree of menu links in an array, in the order they should be rendered.
|
||||
*
|
||||
* Note: based on menu_tree_all_data().
|
||||
*/
|
||||
public function bookTreeAllData($bid, $link = NULL, $max_depth = NULL);
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ class Book extends DrupalSqlBase {
|
|||
for ($i = 1; $i <= 9; $i++) {
|
||||
$field = "p$i";
|
||||
$ml_fields[] = $field;
|
||||
$query->orderBy($field);
|
||||
$query->orderBy('ml.' . $field);
|
||||
}
|
||||
$query->fields('ml', $ml_fields);
|
||||
return $query;
|
||||
|
|
|
@ -30,7 +30,7 @@ class CommentType extends DrupalSqlBase {
|
|||
return $this->select('field_config_instance', 'fci')
|
||||
->distinct()
|
||||
->fields('fci', array('bundle'))
|
||||
->condition('entity_type', 'comment');
|
||||
->condition('fci.entity_type', 'comment');
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
id: d6_i18n_system_maintenance
|
||||
label: Maintenance page configuration
|
||||
migration_tags:
|
||||
- Drupal 6
|
||||
source:
|
||||
plugin: i18n_variable
|
||||
variables:
|
||||
- site_offline_message
|
||||
process:
|
||||
langcode: language
|
||||
message: site_offline_message
|
||||
destination:
|
||||
plugin: config
|
||||
config_name: system.maintenance
|
|
@ -0,0 +1,38 @@
|
|||
id: d6_i18n_system_site
|
||||
label: Site configuration
|
||||
migration_tags:
|
||||
- Drupal 6
|
||||
source:
|
||||
plugin: i18n_variable
|
||||
constants:
|
||||
slash: '/'
|
||||
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':
|
||||
plugin: concat
|
||||
source:
|
||||
- constants/slash
|
||||
- site_frontpage
|
||||
'page/403':
|
||||
plugin: concat
|
||||
source:
|
||||
- constants/slash
|
||||
- site_403
|
||||
'page/404':
|
||||
plugin: concat
|
||||
source:
|
||||
- constants/slash
|
||||
- site_404
|
||||
destination:
|
||||
plugin: config
|
||||
config_name: system.site
|
|
@ -0,0 +1,68 @@
|
|||
id: d6_i18n_user_mail
|
||||
label: User mail configuration
|
||||
migration_tags:
|
||||
- Drupal 6
|
||||
source:
|
||||
plugin: i18n_variable
|
||||
variables:
|
||||
- user_mail_status_activated_subject
|
||||
- user_mail_status_activated_body
|
||||
- user_mail_password_reset_subject
|
||||
- user_mail_password_reset_body
|
||||
- user_mail_status_deleted_subject
|
||||
- user_mail_status_deleted_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_blocked_subject
|
||||
- user_mail_status_blocked_body
|
||||
process:
|
||||
langcode: language
|
||||
'status_activated/subject':
|
||||
plugin: convert_tokens
|
||||
source: user_mail_status_activated_subject
|
||||
'status_activated/body':
|
||||
plugin: convert_tokens
|
||||
source: user_mail_status_activated_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
|
||||
'cancel_confirm/subject':
|
||||
plugin: convert_tokens
|
||||
source: user_mail_status_deleted_subject
|
||||
'cancel_confirm/body':
|
||||
plugin: convert_tokens
|
||||
source: user_mail_status_deleted_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_blocked/subject':
|
||||
plugin: convert_tokens
|
||||
source: user_mail_status_blocked_subject
|
||||
'status_blocked/body':
|
||||
plugin: convert_tokens
|
||||
source: user_mail_status_blocked_body
|
||||
destination:
|
||||
plugin: config
|
||||
config_name: user.mail
|
|
@ -0,0 +1,29 @@
|
|||
id: d6_i18n_user_settings
|
||||
label: User configuration
|
||||
migration_tags:
|
||||
- Drupal 6
|
||||
source:
|
||||
plugin: i18n_variable
|
||||
variables:
|
||||
- user_mail_status_blocked_notify
|
||||
- user_mail_status_activated_notify
|
||||
- user_email_verification
|
||||
- user_register
|
||||
- anonymous
|
||||
process:
|
||||
langcode: language
|
||||
'notify/status_blocked': user_mail_status_blocked_notify
|
||||
'notify/status_activated': user_mail_status_activated_notify
|
||||
verify_mail: user_email_verification
|
||||
register:
|
||||
plugin: static_map
|
||||
source: user_register
|
||||
default_value: visitors_admin_approval
|
||||
map:
|
||||
2: visitors_admin_approval
|
||||
1: visitors
|
||||
0: admin_only
|
||||
anonymous: anonymous
|
||||
destination:
|
||||
plugin: config
|
||||
config_name: user.settings
|
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\config_translation\Kernel\Migrate\d6;
|
||||
|
||||
use Drupal\Tests\migrate_drupal\Kernel\d6\MigrateDrupal6TestBase;
|
||||
|
||||
/**
|
||||
* Upgrade i18n maintenance variables to system.*.yml.
|
||||
*
|
||||
* @group migrate_drupal_6
|
||||
*/
|
||||
class MigrateI18nSystemMaintenanceTest extends MigrateDrupal6TestBase {
|
||||
|
||||
public static $modules = ['language', 'config_translation'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$this->executeMigration('d6_i18n_system_maintenance');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests migration of system (maintenance) variables to system.maintenance.yml.
|
||||
*/
|
||||
public function testSystemMaintenance() {
|
||||
$config = \Drupal::service('language_manager')->getLanguageConfigOverride('fr', 'system.maintenance');
|
||||
$this->assertIdentical('fr - Drupal is currently under maintenance. We should be back shortly. Thank you for your patience.', $config->get('message'));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\config_translation\Kernel\Migrate\d6;
|
||||
|
||||
use Drupal\Tests\migrate_drupal\Kernel\d6\MigrateDrupal6TestBase;
|
||||
|
||||
/**
|
||||
* Upgrade i18n_strings site variables to system.*.yml.
|
||||
*
|
||||
* @group migrate_drupal_6
|
||||
*/
|
||||
class MigrateI18nSystemSiteTest extends MigrateDrupal6TestBase {
|
||||
|
||||
public static $modules = ['language', 'config_translation'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$this->executeMigration('d6_i18n_system_site');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests migration of system (site) variables to system.site.yml.
|
||||
*/
|
||||
public function testSystemSite() {
|
||||
$config_translation = \Drupal::service('language_manager')->getLanguageConfigOverride('fr', 'system.site');
|
||||
$this->assertIdentical('fr site name', $config_translation->get('name'));
|
||||
$this->assertIdentical('fr_site_mail@example.com', $config_translation->get('mail'));
|
||||
$this->assertIdentical('fr Migrate rocks', $config_translation->get('slogan'));
|
||||
$this->assertIdentical('/fr-user', $config_translation->get('page.403'));
|
||||
$this->assertIdentical('/fr-page-not-found', $config_translation->get('page.404'));
|
||||
$this->assertIdentical('/node', $config_translation->get('page.front'));
|
||||
$this->assertIdentical(NULL, $config_translation->get('admin_compact_mode'));
|
||||
|
||||
$config_translation = \Drupal::service('language_manager')->getLanguageConfigOverride('zu', 'system.site');
|
||||
$this->assertIdentical('zu - site_name', $config_translation->get('name'));
|
||||
$this->assertIdentical('site_mail@example.com', $config_translation->get('mail'));
|
||||
$this->assertIdentical('Migrate rocks', $config_translation->get('slogan'));
|
||||
$this->assertIdentical('/zu-user', $config_translation->get('page.403'));
|
||||
$this->assertIdentical('/zu-page-not-found', $config_translation->get('page.404'));
|
||||
$this->assertIdentical('/node', $config_translation->get('page.front'));
|
||||
$this->assertIdentical(NULL, $config_translation->get('admin_compact_mode'));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\config_translation\Kernel\Migrate\d6;
|
||||
|
||||
use Drupal\config\Tests\SchemaCheckTestTrait;
|
||||
use Drupal\Tests\migrate_drupal\Kernel\d6\MigrateDrupal6TestBase;
|
||||
|
||||
/**
|
||||
* Upgrade i18n variables to user.*.yml.
|
||||
*
|
||||
* @group migrate_drupal_6
|
||||
*/
|
||||
class MigrateI18nUserConfigsTest extends MigrateDrupal6TestBase {
|
||||
|
||||
use SchemaCheckTestTrait;
|
||||
|
||||
public static $modules = ['language', 'locale', 'config_translation'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$this->installSchema('locale',
|
||||
['locales_source', 'locales_target', 'locales_location']);
|
||||
$this->executeMigrations(['d6_i18n_user_mail', 'd6_i18n_user_settings']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests migration of i18n user variables to user.mail.yml.
|
||||
*/
|
||||
public function testUserMail() {
|
||||
$config = \Drupal::service('language_manager')->getLanguageConfigOverride('fr', 'user.mail');
|
||||
$this->assertIdentical('fr - Account details for [user:name] at [site:name] (approved)', $config->get('status_activated.subject'));
|
||||
$this->assertIdentical("fr - [user:name],\r\n\r\nYour account at [site:name] has been activated.\r\n\r\nYou may now log in by clicking on this link or copying and pasting it in your browser:\r\n\r\n[user:one-time-login-url]\r\n\r\nThis is a one-time login, so it can be used only once.\r\n\r\nAfter logging in, you will be redirected to [user:edit-url] so you can change your password.\r\n\r\nOnce you have set your own password, you will be able to log in to [site:login-url] in the future using:\r\n\r\nusername: [user:name]\r\n", $config->get('status_activated.body'));
|
||||
$this->assertIdentical('fr - Replacement login information for [user:name] at [site:name]', $config->get('password_reset.subject'));
|
||||
$this->assertIdentical("fr - [user:name],\r\n\r\nA request to reset the password for your account has been made at [site:name].\r\n\r\nYou may now log in to [site:url-brief] by clicking on this link or copying and pasting it in your browser:\r\n\r\n[user:one-time-login-url]\r\n\r\nThis is a one-time login, so it can be used only once. It expires after one day and nothing will happen if it's not used.\r\n\r\nAfter logging in, you will be redirected to [user:edit-url] so you can change your password.", $config->get('password_reset.body'));
|
||||
$this->assertIdentical('fr - Account details for [user:name] at [site:name] (deleted)', $config->get('cancel_confirm.subject'));
|
||||
$this->assertIdentical("fr - [user:name],\r\n\r\nYour account on [site:name] has been deleted.", $config->get('cancel_confirm.body'));
|
||||
$this->assertIdentical('fr - An administrator created an account for you at [site:name]', $config->get('register_admin_created.subject'));
|
||||
$this->assertIdentical("fr - [user:name],\r\n\r\nA site administrator at [site:name] has created an account for you. You may now log in to [site:login-url] using the following username and password:\r\n\r\nusername: [user:name]\r\npassword: \r\n\r\nYou may also log in by clicking on this link or copying and pasting it in your browser:\r\n\r\n[user:one-time-login-url]\r\n\r\nThis is a one-time login, so it can be used only once.\r\n\r\nAfter logging in, you will be redirected to [user:edit-url] so you can change your password.\r\n\r\n\r\n-- [site:name] team", $config->get('register_admin_created.body'));
|
||||
$this->assertIdentical('fr - Account details for [user:name] at [site:name]', $config->get('register_no_approval_required.subject'));
|
||||
$this->assertIdentical("fr - [user:name],\r\n\r\nThank you for registering at [site:name]. You may now log in to [site:login-url] using the following username and password:\r\n\r\nusername: [user:name]\r\npassword: \r\n\r\nYou may also log in by clicking on this link or copying and pasting it in your browser:\r\n\r\n[user:one-time-login-url]\r\n\r\nThis is a one-time login, so it can be used only once.\r\n\r\nAfter logging in, you will be redirected to [user:edit-url] so you can change your password.\r\n\r\n\r\n-- [site:name] team", $config->get('register_no_approval_required.body'));
|
||||
$this->assertIdentical('fr - Account details for [user:name] at [site:name] (pending admin approval)', $config->get('register_pending_approval.subject'));
|
||||
$this->assertIdentical("fr - [user:name],\r\n\r\nThank you for registering at [site:name]. Your application for an account is currently pending approval. Once it has been approved, you will receive another email containing information about how to log in, set your password, and other details.\r\n\r\n\r\n-- [site:name] team", $config->get('register_pending_approval.body'));
|
||||
$this->assertIdentical('fr - Account details for [user:name] at [site:name] (blocked)', $config->get('status_blocked.subject'));
|
||||
$this->assertIdentical("fr - [user:name],\r\n\r\nYour account on [site:name] has been blocked.", $config->get('status_blocked.body'));
|
||||
$this->assertConfigSchema(\Drupal::service('config.typed'), 'user.mail', $config->get());
|
||||
|
||||
$config = \Drupal::service('language_manager')->getLanguageConfigOverride('zu', 'user.mail');
|
||||
$this->assertIdentical('zu - An administrator created an account for you at [site:name]', $config->get('register_admin_created.subject'));
|
||||
$this->assertIdentical("zu - [user:name],\r\n\r\nA site administrator at [site:name] has created an account for you. You may now log in to [site:login-url] using the following username and password:\r\n\r\nusername: [user:name]\r\npassword: \r\n\r\nYou may also log in by clicking on this link or copying and pasting it in your browser:\r\n\r\n[user:one-time-login-url]\r\n\r\nThis is a one-time login, so it can be used only once.\r\n\r\nAfter logging in, you will be redirected to [user:edit-url] so you can change your password.\r\n\r\n\r\n-- [site:name] team", $config->get('register_admin_created.body'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests migration of i18n user variables to user.settings.yml.
|
||||
*/
|
||||
public function testUserSettings() {
|
||||
$config = \Drupal::service('language_manager')->getLanguageConfigOverride('fr', 'user.settings');
|
||||
$this->assertIdentical(1, $config->get('notify.status_blocked'));
|
||||
$this->assertIdentical(0, $config->get('notify.status_activated'));
|
||||
$this->assertIdentical(0, $config->get('verify_mail'));
|
||||
$this->assertIdentical('admin_only', $config->get('register'));
|
||||
$this->assertIdentical('fr Guest', $config->get('anonymous'));
|
||||
|
||||
$config = \Drupal::service('language_manager')->getLanguageConfigOverride('zu', 'user.settings');
|
||||
$this->assertIdentical(1, $config->get('notify.status_blocked'));
|
||||
$this->assertIdentical(0, $config->get('notify.status_activated'));
|
||||
$this->assertIdentical(0, $config->get('verify_mail'));
|
||||
$this->assertIdentical('admin_only', $config->get('register'));
|
||||
$this->assertIdentical('Guest', $config->get('anonymous'));
|
||||
}
|
||||
|
||||
}
|
|
@ -21,7 +21,7 @@ interface ContactFormInterface extends ConfigEntityInterface {
|
|||
* Returns an auto-reply message to send to the message author.
|
||||
*
|
||||
* @return string
|
||||
* An auto-reply message
|
||||
* An auto-reply message
|
||||
*/
|
||||
public function getReply();
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ class ContactCategory extends DrupalSqlBase {
|
|||
'selected',
|
||||
)
|
||||
);
|
||||
$query->orderBy('cid');
|
||||
$query->orderBy('c.cid');
|
||||
return $query;
|
||||
}
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ class ContactSettings extends Variable {
|
|||
protected function initializeIterator() {
|
||||
$default_category = $this->select('contact', 'c')
|
||||
->fields('c', ['cid'])
|
||||
->condition('selected', 1)
|
||||
->condition('c.selected', 1)
|
||||
->execute()
|
||||
->fetchField();
|
||||
return new \ArrayIterator([$this->values() + ['default_category' => $default_category]]);
|
||||
|
|
|
@ -77,8 +77,8 @@ class ContentTranslationController extends ControllerBase {
|
|||
* The route match.
|
||||
* @param string $entity_type_id
|
||||
* (optional) The entity type ID.
|
||||
* @return array Array of page elements to render.
|
||||
* Array of page elements to render.
|
||||
* @return array
|
||||
* Array of page elements to render.
|
||||
*/
|
||||
public function overview(RouteMatchInterface $route_match, $entity_type_id = NULL) {
|
||||
/** @var \Drupal\Core\Entity\ContentEntityInterface $entity */
|
||||
|
|
|
@ -446,17 +446,23 @@ class DateTimeFieldTest extends WebTestBase {
|
|||
|
||||
$this->assertFieldByXPath("//*[@id=\"edit-$field_name-0-value-year\"]", NULL, 'Year element found.');
|
||||
$this->assertOptionSelected("edit-$field_name-0-value-year", '', 'No year selected.');
|
||||
$this->assertOptionByText("edit-$field_name-0-value-year", t('Year'));
|
||||
$this->assertFieldByXPath("//*[@id=\"edit-$field_name-0-value-month\"]", NULL, 'Month element found.');
|
||||
$this->assertOptionSelected("edit-$field_name-0-value-month", '', 'No month selected.');
|
||||
$this->assertOptionByText("edit-$field_name-0-value-month", t('Month'));
|
||||
$this->assertFieldByXPath("//*[@id=\"edit-$field_name-0-value-day\"]", NULL, 'Day element found.');
|
||||
$this->assertOptionSelected("edit-$field_name-0-value-day", '', 'No day selected.');
|
||||
$this->assertOptionByText("edit-$field_name-0-value-day", t('Day'));
|
||||
$this->assertFieldByXPath("//*[@id=\"edit-$field_name-0-value-hour\"]", NULL, 'Hour element found.');
|
||||
$this->assertOptionSelected("edit-$field_name-0-value-hour", '', 'No hour selected.');
|
||||
$this->assertOptionByText("edit-$field_name-0-value-hour", t('Hour'));
|
||||
$this->assertFieldByXPath("//*[@id=\"edit-$field_name-0-value-minute\"]", NULL, 'Minute element found.');
|
||||
$this->assertOptionSelected("edit-$field_name-0-value-minute", '', 'No minute selected.');
|
||||
$this->assertOptionByText("edit-$field_name-0-value-minute", t('Minute'));
|
||||
$this->assertNoFieldByXPath("//*[@id=\"edit-$field_name-0-value-second\"]", NULL, 'Second element not found.');
|
||||
$this->assertFieldByXPath("//*[@id=\"edit-$field_name-0-value-ampm\"]", NULL, 'AMPM element found.');
|
||||
$this->assertOptionSelected("edit-$field_name-0-value-ampm", '', 'No ampm selected.');
|
||||
$this->assertOptionByText("edit-$field_name-0-value-ampm", t('AM/PM'));
|
||||
|
||||
// Submit a valid date and ensure it is accepted.
|
||||
$date_value = array('year' => 2012, 'month' => 12, 'day' => 31, 'hour' => 5, 'minute' => 15);
|
||||
|
|
|
@ -173,13 +173,13 @@ class DynamicPageCacheSubscriber implements EventSubscriberInterface {
|
|||
|
||||
// Don't cache the response if Dynamic Page Cache's request subscriber did
|
||||
// not fire, because that means it is impossible to have a Dynamic Page
|
||||
// Cache hit. (This can happen when the master request is for example a 403
|
||||
// Cache hit. This can happen when the master request is for example a 403
|
||||
// or 404, in which case a subrequest is performed by the router. In that
|
||||
// case, it is the subrequest's response that is cached by Dynamic Page
|
||||
// Cache, because the routing happens in a request subscriber earlier than
|
||||
// Dynamic Page Cache's and immediately sets a response, i.e. the one
|
||||
// returned by the subrequest, and thus causes Dynamic Page Cache's request
|
||||
// subscriber to not fire for the master request.)
|
||||
// subscriber to not fire for the master request.
|
||||
// @see \Drupal\Core\Routing\AccessAwareRouter::checkAccess()
|
||||
// @see \Drupal\Core\EventSubscriber\DefaultExceptionHtmlSubscriber::on403()
|
||||
$request = $event->getRequest();
|
||||
|
@ -218,7 +218,7 @@ class DynamicPageCacheSubscriber implements EventSubscriberInterface {
|
|||
* is automatically placeholdered, and consequently the cacheability metadata
|
||||
* of the placeholdered content does not bubble up to the response level.
|
||||
*
|
||||
* @param \Drupal\Core\Cache\CacheableResponseInterface
|
||||
* @param \Drupal\Core\Cache\CacheableResponseInterface $response
|
||||
* The response whose cacheability to analyze.
|
||||
*
|
||||
* @return bool
|
||||
|
|
|
@ -2,6 +2,8 @@ id: d7_field
|
|||
label: Field configuration
|
||||
migration_tags:
|
||||
- Drupal 7
|
||||
class: Drupal\migrate_drupal\Plugin\migrate\CckMigration
|
||||
cck_plugin_method: processField
|
||||
source:
|
||||
plugin: d7_field
|
||||
constants:
|
||||
|
@ -13,7 +15,7 @@ process:
|
|||
langcode: 'constants/langcode'
|
||||
field_name: field_name
|
||||
type:
|
||||
plugin: static_map
|
||||
plugin: field_type
|
||||
source: type
|
||||
map:
|
||||
date: datetime
|
||||
|
@ -30,8 +32,6 @@ process:
|
|||
number_decimal: decimal
|
||||
number_float: float
|
||||
phone: telephone
|
||||
taxonomy_term_reference: entity_reference
|
||||
text: text
|
||||
text_long: text_long
|
||||
text_with_summary: text_with_summary
|
||||
translatable: translatable
|
||||
|
|
|
@ -2,6 +2,8 @@ id: d7_field_formatter_settings
|
|||
label: Field formatter configuration
|
||||
migration_tags:
|
||||
- Drupal 7
|
||||
class: Drupal\migrate_drupal\Plugin\migrate\CckMigration
|
||||
cck_plugin_method: processFieldFormatter
|
||||
source:
|
||||
plugin: d7_field_instance_per_view_mode
|
||||
constants:
|
||||
|
|
|
@ -2,6 +2,8 @@ id: d7_field_instance
|
|||
label: Field instance configuration
|
||||
migration_tags:
|
||||
- Drupal 7
|
||||
class: Drupal\migrate_drupal\Plugin\migrate\CckMigration
|
||||
cck_plugin_method: processFieldInstance
|
||||
source:
|
||||
plugin: d7_field_instance
|
||||
constants:
|
||||
|
|
|
@ -2,6 +2,8 @@ id: d7_field_instance_widget_settings
|
|||
label: Field instance widget configuration
|
||||
migration_tags:
|
||||
- Drupal 7
|
||||
class: Drupal\migrate_drupal\Plugin\migrate\CckMigration
|
||||
cck_plugin_method: processFieldWidget
|
||||
source:
|
||||
plugin: d7_field_instance_per_form_display
|
||||
constants:
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\field\Plugin\migrate\process\d6;
|
||||
namespace Drupal\field\Plugin\migrate\process;
|
||||
|
||||
use Drupal\Component\Plugin\Exception\PluginNotFoundException;
|
||||
use Drupal\Component\Plugin\PluginManagerInterface;
|
||||
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
|
||||
use Drupal\migrate\MigrateExecutableInterface;
|
||||
use Drupal\migrate\Plugin\MigrationInterface;
|
||||
use Drupal\migrate\Plugin\migrate\process\StaticMap;
|
||||
use Drupal\migrate\Row;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
@ -24,6 +25,13 @@ class FieldType extends StaticMap implements ContainerFactoryPluginInterface {
|
|||
*/
|
||||
protected $cckPluginManager;
|
||||
|
||||
/**
|
||||
* The migration object.
|
||||
*
|
||||
* @var \Drupal\migrate\Plugin\MigrationInterface
|
||||
*/
|
||||
protected $migration;
|
||||
|
||||
/**
|
||||
* Constructs a FieldType plugin.
|
||||
*
|
||||
|
@ -35,21 +43,25 @@ class FieldType extends StaticMap implements ContainerFactoryPluginInterface {
|
|||
* The plugin definition.
|
||||
* @param \Drupal\Component\Plugin\PluginManagerInterface $cck_plugin_manager
|
||||
* The cckfield plugin manager.
|
||||
* @param \Drupal\migrate\Plugin\MigrationInterface $migration
|
||||
* The migration being run.
|
||||
*/
|
||||
public function __construct(array $configuration, $plugin_id, $plugin_definition, PluginManagerInterface $cck_plugin_manager) {
|
||||
public function __construct(array $configuration, $plugin_id, $plugin_definition, PluginManagerInterface $cck_plugin_manager, MigrationInterface $migration = NULL) {
|
||||
parent::__construct($configuration, $plugin_id, $plugin_definition);
|
||||
$this->cckPluginManager = $cck_plugin_manager;
|
||||
$this->migration = $migration;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
|
||||
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration = NULL) {
|
||||
return new static(
|
||||
$configuration,
|
||||
$plugin_id,
|
||||
$plugin_definition,
|
||||
$container->get('plugin.manager.migrate.cckfield')
|
||||
$container->get('plugin.manager.migrate.cckfield'),
|
||||
$migration
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -57,11 +69,10 @@ class FieldType extends StaticMap implements ContainerFactoryPluginInterface {
|
|||
* {@inheritdoc}
|
||||
*/
|
||||
public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) {
|
||||
list ($field_type, $widget_type) = $value;
|
||||
$field_type = is_array($value) ? $value[0] : $value;
|
||||
|
||||
try {
|
||||
return $this->cckPluginManager->createInstance($field_type)
|
||||
->getFieldType($row);
|
||||
return $this->cckPluginManager->createInstance($field_type, [], $this->migration)->getFieldType($row);
|
||||
}
|
||||
catch (PluginNotFoundException $e) {
|
||||
return parent::transform($value, $migrate_executable, $row, $destination_property);
|
|
@ -62,7 +62,7 @@ class FieldInstancePerFormDisplay extends DrupalSqlBase {
|
|||
'module',
|
||||
));
|
||||
$query->join('content_node_field', 'cnf', 'cnfi.field_name = cnf.field_name');
|
||||
$query->orderBy('weight');
|
||||
$query->orderBy('cnfi.weight');
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
|
|
@ -65,7 +65,7 @@ class FieldInstancePerViewMode extends ViewModeBase {
|
|||
'module',
|
||||
));
|
||||
$query->join('content_node_field', 'cnf', 'cnfi.field_name = cnf.field_name');
|
||||
$query->orderBy('weight');
|
||||
$query->orderBy('cnfi.weight');
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
|
|
@ -31,10 +31,10 @@ class FieldInstance extends DrupalSqlBase {
|
|||
|
||||
// Optionally filter by entity type and bundle.
|
||||
if (isset($this->configuration['entity_type'])) {
|
||||
$query->condition('entity_type', $this->configuration['entity_type']);
|
||||
$query->condition('fci.entity_type', $this->configuration['entity_type']);
|
||||
|
||||
if (isset($this->configuration['bundle'])) {
|
||||
$query->condition('bundle', $this->configuration['bundle']);
|
||||
$query->condition('fci.bundle', $this->configuration['bundle']);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ abstract class FieldTestBase extends WebTestBase {
|
|||
* @param $cardinality
|
||||
* Number of values to generate.
|
||||
* @return
|
||||
* An array of random values, in the format expected for field values.
|
||||
* An array of random values, in the format expected for field values.
|
||||
*/
|
||||
function _generateTestFieldValues($cardinality) {
|
||||
$values = array();
|
||||
|
|
|
@ -142,8 +142,6 @@ abstract class FieldUnitTestBase extends KernelTestBase {
|
|||
*
|
||||
* @param \Drupal\Core\Entity\EntityInterface $entity
|
||||
* The entity to save.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function entityValidateAndSave(EntityInterface $entity) {
|
||||
$violations = $entity->validate();
|
||||
|
@ -161,7 +159,7 @@ abstract class FieldUnitTestBase extends KernelTestBase {
|
|||
* @param $cardinality
|
||||
* Number of values to generate.
|
||||
* @return
|
||||
* An array of random values, in the format expected for field values.
|
||||
* An array of random values, in the format expected for field values.
|
||||
*/
|
||||
protected function _generateTestFieldValues($cardinality) {
|
||||
$values = array();
|
||||
|
|
|
@ -81,6 +81,16 @@ class FieldUITest extends FieldTestBase {
|
|||
$this->assertEqual($view->field['field_name_0']->options['type'], 'text_trimmed');
|
||||
$this->assertEqual($view->field['field_name_0']->options['settings']['trim_length'], $random_number);
|
||||
|
||||
// Now change the formatter back to 'default' which doesn't have any
|
||||
// settings. We want to ensure that the settings are empty then.
|
||||
$edit['options[type]'] = 'text_default';
|
||||
$this->drupalPostForm('admin/structure/views/nojs/handler/test_view_fieldapi/default/field/field_name_0', $edit, t('Apply'));
|
||||
$this->drupalPostForm('admin/structure/views/view/test_view_fieldapi', [], t('Save'));
|
||||
$view = Views::getView('test_view_fieldapi');
|
||||
$view->initHandlers();
|
||||
$this->assertEqual($view->field['field_name_0']->options['type'], 'text_default');
|
||||
$this->assertEqual($view->field['field_name_0']->options['settings'], []);
|
||||
|
||||
// Ensure that the view depends on the field storage.
|
||||
$dependencies = \Drupal::service('config.manager')->findConfigEntityDependents('config', [$this->fieldStorages[0]->getConfigDependencyName()]);
|
||||
$this->assertTrue(isset($dependencies['views.view.test_view_fieldapi']), 'The view is dependent on the field storage.');
|
||||
|
|
|
@ -139,8 +139,6 @@ abstract class FieldKernelTestBase extends KernelTestBase {
|
|||
*
|
||||
* @param \Drupal\Core\Entity\EntityInterface $entity
|
||||
* The entity to save.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function entityValidateAndSave(EntityInterface $entity) {
|
||||
$violations = $entity->validate();
|
||||
|
@ -158,7 +156,7 @@ abstract class FieldKernelTestBase extends KernelTestBase {
|
|||
* @param $cardinality
|
||||
* Number of values to generate.
|
||||
* @return
|
||||
* An array of random values, in the format expected for field values.
|
||||
* An array of random values, in the format expected for field values.
|
||||
*/
|
||||
protected function _generateTestFieldValues($cardinality) {
|
||||
$values = array();
|
||||
|
|
|
@ -27,7 +27,13 @@ class FieldInstanceTest extends MigrateSqlSourceTestCase {
|
|||
'bundle' => 'page',
|
||||
'label' => 'Body',
|
||||
'widget_settings' => array(
|
||||
'module' => 'text',
|
||||
'settings' => array(
|
||||
'rows' => 20,
|
||||
'summary_rows' => 5,
|
||||
),
|
||||
'type' => 'text_textarea_with_summary',
|
||||
'weight' => -4,
|
||||
),
|
||||
'display_settings' => array(
|
||||
),
|
||||
|
|
|
@ -26,8 +26,28 @@ class FieldTest extends MigrateSqlSourceTestCase {
|
|||
'type' => 'file',
|
||||
'global_settings' => '',
|
||||
'storage' => array(
|
||||
'type' => 'field_sql_storage',
|
||||
'active' => 1,
|
||||
'details' => array(
|
||||
'sql' => array(
|
||||
'FIELD_LOAD_CURRENT' => array(
|
||||
'field_data_field_file' => array(
|
||||
'description' => 'field_file_description',
|
||||
'display' => 'field_file_display',
|
||||
'fid' => 'field_file_fid',
|
||||
),
|
||||
),
|
||||
'FIELD_LOAD_REVISION' => array(
|
||||
'field_revision_field_file' => array(
|
||||
'description' => 'field_file_description',
|
||||
'display' => 'field_file_display',
|
||||
'fid' => 'field_file_fid',
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
'module' => 'field_sql_storage',
|
||||
'settings' => array(),
|
||||
'type' => 'field_sql_storage',
|
||||
),
|
||||
'module' => 'file',
|
||||
'db_columns' => '',
|
||||
|
@ -39,8 +59,28 @@ class FieldTest extends MigrateSqlSourceTestCase {
|
|||
'type' => 'file',
|
||||
'global_settings' => '',
|
||||
'storage' => array(
|
||||
'type' => 'field_sql_storage',
|
||||
'active' => 1,
|
||||
'details' => array(
|
||||
'sql' => array(
|
||||
'FIELD_LOAD_CURRENT' => array(
|
||||
'field_data_field_file' => array(
|
||||
'description' => 'field_file_description',
|
||||
'display' => 'field_file_display',
|
||||
'fid' => 'field_file_fid',
|
||||
),
|
||||
),
|
||||
'FIELD_LOAD_REVISION' => array(
|
||||
'field_revision_field_file' => array(
|
||||
'description' => 'field_file_description',
|
||||
'display' => 'field_file_display',
|
||||
'fid' => 'field_file_fid',
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
'module' => 'field_sql_storage',
|
||||
'settings' => array(),
|
||||
'type' => 'field_sql_storage',
|
||||
),
|
||||
'module' => 'file',
|
||||
'db_columns' => '',
|
||||
|
|
|
@ -148,10 +148,27 @@ class FieldStorageConfigEditForm extends EntityForm {
|
|||
public function validateForm(array &$form, FormStateInterface $form_state) {
|
||||
parent::validateForm($form, $form_state);
|
||||
|
||||
$field_storage_definitions = \Drupal::service('entity_field.manager')->getFieldStorageDefinitions($this->entity->getTargetEntityTypeId());
|
||||
|
||||
// Validate field cardinality.
|
||||
if ($form_state->getValue('cardinality') === 'number' && !$form_state->getValue('cardinality_number')) {
|
||||
$form_state->setErrorByName('cardinality_number', $this->t('Number of values is required.'));
|
||||
}
|
||||
// If a specific cardinality is used, validate that there are no entities
|
||||
// with a higher delta.
|
||||
elseif (!$this->entity->isNew() && isset($field_storage_definitions[$this->entity->getName()]) && $form_state->getValue('cardinality') != FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED) {
|
||||
|
||||
// Get a count of entities that have a value in a delta higher than the
|
||||
// one selected. Deltas start with 0, so the selected value does not
|
||||
// need to be incremented.
|
||||
$entities_with_higher_delta = \Drupal::entityQuery($this->entity->getTargetEntityTypeId())
|
||||
->condition($this->entity->getName() . '.%delta', $form_state->getValue('cardinality'))
|
||||
->count()
|
||||
->execute();
|
||||
if ($entities_with_higher_delta) {
|
||||
$form_state->setErrorByName('cardinality_number', $this->formatPlural($entities_with_higher_delta, 'There is @count entity with @delta or more values in this field.', 'There are @count entities with @delta or more values in this field.', ['@delta' => $form_state->getValue('cardinality') + 1]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -267,6 +267,23 @@ class ManageFieldsTest extends WebTestBase {
|
|||
$this->assertLink(t('Field settings'));
|
||||
$this->assertLinkByHref($field_edit_path);
|
||||
|
||||
// Add two entries in the body.
|
||||
$edit = ['title[0][value]' => 'Cardinality', 'body[0][value]' => 'Body 1', 'body[1][value]' => 'Body 2'];
|
||||
$this->drupalPostForm('node/add/article', $edit, 'Save');
|
||||
|
||||
// Assert that you can't set the cardinality to a lower number than the
|
||||
// highest delta of this field.
|
||||
$edit = [
|
||||
'cardinality' => 'number',
|
||||
'cardinality_number' => 1,
|
||||
];
|
||||
$this->drupalPostForm($field_edit_path, $edit, t('Save field settings'));
|
||||
$this->assertRaw(t('There is @count entity with @delta or more values in this field.', ['@count' => 1, '@delta' => 2]), 'Correctly failed to set cardinality lower than highest delta.');
|
||||
|
||||
// Create a second entity with three values.
|
||||
$edit = ['title[0][value]' => 'Cardinality 3', 'body[0][value]' => 'Body 1', 'body[1][value]' => 'Body 2', 'body[2][value]' => 'Body 3'];
|
||||
$this->drupalPostForm('node/add/article', $edit, 'Save');
|
||||
|
||||
// Set to unlimited.
|
||||
$edit = array(
|
||||
'cardinality' => FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED,
|
||||
|
@ -276,6 +293,28 @@ class ManageFieldsTest extends WebTestBase {
|
|||
$this->drupalGet($field_edit_path);
|
||||
$this->assertFieldByXPath("//select[@name='cardinality']", FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED);
|
||||
$this->assertFieldByXPath("//input[@name='cardinality_number']", 1);
|
||||
|
||||
// Assert that you can't set the cardinality to a lower number then the
|
||||
// highest delta of this field but can set it to the same.
|
||||
$edit = [
|
||||
'cardinality' => 'number',
|
||||
'cardinality_number' => 1,
|
||||
];
|
||||
$this->drupalPostForm($field_edit_path, $edit, t('Save field settings'));
|
||||
$this->assertRaw(t('There are @count entities with @delta or more values in this field.', ['@count' => 2, '@delta' => 2]), 'Correctly failed to set cardinality lower than highest delta.');
|
||||
|
||||
$edit = [
|
||||
'cardinality' => 'number',
|
||||
'cardinality_number' => 2,
|
||||
];
|
||||
$this->drupalPostForm($field_edit_path, $edit, t('Save field settings'));
|
||||
$this->assertRaw(t('There is @count entity with @delta or more values in this field.', ['@count' => 1, '@delta' => 3]), 'Correctly failed to set cardinality lower than highest delta.');
|
||||
|
||||
$edit = [
|
||||
'cardinality' => 'number',
|
||||
'cardinality_number' => 3,
|
||||
];
|
||||
$this->drupalPostForm($field_edit_path, $edit, t('Save field settings'));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -185,8 +185,6 @@ function file_copy(FileInterface $source, $destination = NULL, $replace = FILE_E
|
|||
/**
|
||||
* Moves a file to a new location and update the file's database entry.
|
||||
*
|
||||
* Moving a file is performed by copying the file to the new location and then
|
||||
* deleting the original.
|
||||
* - Checks if $source and $destination are valid and readable/writable.
|
||||
* - Performs a file move if $source is not equal to $destination.
|
||||
* - If file already exists in $destination either the call will error out,
|
||||
|
@ -1177,7 +1175,7 @@ function file_managed_file_save_upload($element, FormStateInterface $form_state)
|
|||
|
||||
$destination = isset($element['#upload_location']) ? $element['#upload_location'] : NULL;
|
||||
if (isset($destination) && !file_prepare_directory($destination, FILE_CREATE_DIRECTORY)) {
|
||||
\Drupal::logger('file')->notice('The upload directory %directory for the file field !name could not be created or is not accessible. A newly uploaded file could not be saved in this directory as a consequence, and the upload was canceled.', array('%directory' => $destination, '!name' => $element['#field_name']));
|
||||
\Drupal::logger('file')->notice('The upload directory %directory for the file field %name could not be created or is not accessible. A newly uploaded file could not be saved in this directory as a consequence, and the upload was canceled.', array('%directory' => $destination, '%name' => $element['#field_name']));
|
||||
$form_state->setError($element, t('The file could not be uploaded.'));
|
||||
return FALSE;
|
||||
}
|
||||
|
|
|
@ -8,7 +8,8 @@ use Drupal\migrate_drupal\Plugin\migrate\cckfield\CckFieldPluginBase;
|
|||
|
||||
/**
|
||||
* @MigrateCckField(
|
||||
* id = "filefield"
|
||||
* id = "filefield",
|
||||
* core = {6}
|
||||
* )
|
||||
*/
|
||||
class FileField extends CckFieldPluginBase {
|
||||
|
|
|
@ -9,6 +9,7 @@ use Drupal\migrate_drupal\Plugin\migrate\cckfield\CckFieldPluginBase;
|
|||
/**
|
||||
* @MigrateCckField(
|
||||
* id = "file",
|
||||
* core = {7}
|
||||
* )
|
||||
*/
|
||||
class FileField extends CckFieldPluginBase {
|
||||
|
|
|
@ -7,7 +7,8 @@ use Drupal\migrate_drupal\Plugin\migrate\cckfield\CckFieldPluginBase;
|
|||
|
||||
/**
|
||||
* @MigrateCckField(
|
||||
* id = "image"
|
||||
* id = "image",
|
||||
* core = {7}
|
||||
* )
|
||||
*/
|
||||
class ImageField extends CckFieldPluginBase {
|
||||
|
|
|
@ -147,7 +147,7 @@ class EntityFile extends EntityContentBase {
|
|||
* (optional) FILE_EXISTS_REPLACE (default) or FILE_EXISTS_RENAME.
|
||||
*
|
||||
* @return bool
|
||||
* TRUE on success, FALSE on failure.
|
||||
* TRUE on success, FALSE on failure.
|
||||
*/
|
||||
protected function writeFile($source, $destination, $replace = FILE_EXISTS_REPLACE) {
|
||||
if ($this->configuration['move']) {
|
||||
|
@ -190,8 +190,8 @@ class EntityFile extends EntityContentBase {
|
|||
* The URI or path.
|
||||
*
|
||||
* @return string|false
|
||||
* The directory component of the path or URI, or FALSE if it could not
|
||||
* be determined.
|
||||
* The directory component of the path or URI, or FALSE if it could not
|
||||
* be determined.
|
||||
*/
|
||||
protected function getDirectory($uri) {
|
||||
$dir = $this->fileSystem->dirname($uri);
|
||||
|
@ -213,8 +213,8 @@ class EntityFile extends EntityContentBase {
|
|||
* The destination URI.
|
||||
*
|
||||
* @return bool
|
||||
* TRUE if the source and destination URIs refer to the same physical path,
|
||||
* otherwise FALSE.
|
||||
* TRUE if the source and destination URIs refer to the same physical path,
|
||||
* otherwise FALSE.
|
||||
*/
|
||||
protected function isLocationUnchanged($source, $destination) {
|
||||
if ($this->isLocalUri($source) && $this->isLocalUri($destination)) {
|
||||
|
|
|
@ -45,7 +45,7 @@ class File extends DrupalSqlBase {
|
|||
// If two or more files have the same timestamp, they'll end up in a
|
||||
// non-deterministic order. Ordering by fid (or any other unique field)
|
||||
// will prevent this.
|
||||
->orderBy('fid');
|
||||
->orderBy('f.fid');
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -33,7 +33,7 @@ class UploadInstance extends DrupalSqlBase {
|
|||
$return = array();
|
||||
$values = $this->select('variable', 'v')
|
||||
->fields('v', ['name', 'value'])
|
||||
->condition('name', $variables, 'IN')
|
||||
->condition('v.name', $variables, 'IN')
|
||||
->execute()
|
||||
->fetchAllKeyed();
|
||||
foreach ($node_types as $node_type) {
|
||||
|
|
|
@ -42,7 +42,7 @@ class File extends DrupalSqlBase {
|
|||
public function query() {
|
||||
$query = $this->select('file_managed', 'f')
|
||||
->fields('f')
|
||||
->orderBy('timestamp');
|
||||
->orderBy('f.timestamp');
|
||||
|
||||
// Filter by scheme(s), if configured.
|
||||
if (isset($this->configuration['scheme'])) {
|
||||
|
|
|
@ -4,6 +4,7 @@ namespace Drupal\file\Tests;
|
|||
|
||||
use Drupal\node\Entity\Node;
|
||||
use Drupal\file\Entity\File;
|
||||
use Drupal\entity_test\Entity\EntityTestConstraints;
|
||||
|
||||
/**
|
||||
* Tests file listing page functionality.
|
||||
|
@ -17,7 +18,7 @@ class FileListingTest extends FileFieldTestBase {
|
|||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = array('views', 'file', 'image');
|
||||
public static $modules = array('views', 'file', 'image', 'entity_test');
|
||||
|
||||
/**
|
||||
* An authenticated user.
|
||||
|
@ -144,11 +145,60 @@ class FileListingTest extends FileFieldTestBase {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests file listing usage page for entities with no canonical link template.
|
||||
*/
|
||||
function testFileListingUsageNoLink() {
|
||||
// Login with user with right permissions and test listing.
|
||||
$this->drupalLogin($this->adminUser);
|
||||
|
||||
// Create a bundle and attach a File field to the bundle.
|
||||
$bundle = $this->randomMachineName();
|
||||
entity_test_create_bundle($bundle, NULL, 'entity_test_constraints');
|
||||
$this->createFileField('field_test_file', 'entity_test_constraints', $bundle, array(), array('file_extensions' => 'txt png'));
|
||||
|
||||
// Create file to attach to entity.
|
||||
$file = File::create([
|
||||
'filename' => 'druplicon.txt',
|
||||
'uri' => 'public://druplicon.txt',
|
||||
'filemime' => 'text/plain',
|
||||
]);
|
||||
$file->setPermanent();
|
||||
file_put_contents($file->getFileUri(), 'hello world');
|
||||
$file->save();
|
||||
|
||||
// Create entity and attach the created file.
|
||||
$entity_name = $this->randomMachineName();
|
||||
$entity = EntityTestConstraints::create(array(
|
||||
'uid' => 1,
|
||||
'name' => $entity_name,
|
||||
'type' => $bundle,
|
||||
'field_test_file' => array(
|
||||
'target_id' => $file->id(),
|
||||
),
|
||||
));
|
||||
$entity->save();
|
||||
|
||||
// Create node entity and attach the created file.
|
||||
$node = $this->drupalCreateNode(array('type' => 'article', 'file' => $file));
|
||||
$node->save();
|
||||
|
||||
// Load the file usage page for the created and attached file.
|
||||
$this->drupalGet('admin/content/files/usage/' . $file->id());
|
||||
|
||||
$this->assertResponse(200);
|
||||
// Entity name should be displayed, but not linked if Entity::toUrl
|
||||
// throws an exception
|
||||
$this->assertText($entity_name, 'Entity name is added to file usage listing.');
|
||||
$this->assertNoLink($entity_name, 'Linked entity name not added to file usage listing.');
|
||||
$this->assertLink($node->getTitle());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and saves a test file.
|
||||
*
|
||||
* @return \Drupal\Core\Entity\EntityInterface
|
||||
* A file entity.
|
||||
* A file entity.
|
||||
*/
|
||||
protected function createFile() {
|
||||
// Create a new file entity.
|
||||
|
|
|
@ -8,6 +8,7 @@ process:
|
|||
format: format
|
||||
name: name
|
||||
cache: cache
|
||||
weight: weight
|
||||
filters:
|
||||
plugin: iterator
|
||||
source: filters
|
||||
|
@ -25,5 +26,6 @@ process:
|
|||
status:
|
||||
plugin: default_value
|
||||
default_value: true
|
||||
weight: weight
|
||||
destination:
|
||||
plugin: entity:filter_format
|
||||
|
|
|
@ -35,25 +35,31 @@ class MigrateFilterFormatTest extends MigrateDrupal7TestBase {
|
|||
* @param string $label
|
||||
* The expected label of the format.
|
||||
* @param array $enabled_filters
|
||||
* The expected filters in the format, keyed by ID.
|
||||
* The expected filters in the format, keyed by ID with weight as values.
|
||||
* @param int $weight
|
||||
* The weight of the filter.
|
||||
*/
|
||||
protected function assertEntity($id, $label, array $enabled_filters) {
|
||||
protected function assertEntity($id, $label, array $enabled_filters, $weight) {
|
||||
/** @var \Drupal\filter\FilterFormatInterface $entity */
|
||||
$entity = FilterFormat::load($id);
|
||||
$this->assertTrue($entity instanceof FilterFormatInterface);
|
||||
$this->assertIdentical($label, $entity->label());
|
||||
// get('filters') will return enabled filters only, not all of them.
|
||||
$this->assertIdentical($enabled_filters, array_keys($entity->get('filters')));
|
||||
$this->assertIdentical(array_keys($enabled_filters), array_keys($entity->get('filters')));
|
||||
$this->assertIdentical($weight, $entity->get('weight'));
|
||||
foreach ($entity->get('filters') as $filter_id => $filter) {
|
||||
$this->assertIdentical($filter['weight'], $enabled_filters[$filter_id]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the Drupal 7 filter format to Drupal 8 migration.
|
||||
*/
|
||||
public function testFilterFormat() {
|
||||
$this->assertEntity('custom_text_format', 'Custom Text format', ['filter_autop', 'filter_html']);
|
||||
$this->assertEntity('filtered_html', 'Filtered HTML', ['filter_autop', 'filter_html', 'filter_htmlcorrector', 'filter_url']);
|
||||
$this->assertEntity('full_html', 'Full HTML', ['filter_autop', 'filter_htmlcorrector', 'filter_url']);
|
||||
$this->assertEntity('plain_text', 'Plain text', ['filter_html_escape', 'filter_url', 'filter_autop']);
|
||||
$this->assertEntity('custom_text_format', 'Custom Text format', ['filter_autop' => 0, 'filter_html' => -10], 0);
|
||||
$this->assertEntity('filtered_html', 'Filtered HTML', ['filter_autop' => 2, 'filter_html' => 1, 'filter_htmlcorrector' => 10, 'filter_url' => 0], 0);
|
||||
$this->assertEntity('full_html', 'Full HTML', ['filter_autop' => 1, 'filter_htmlcorrector' => 10, 'filter_url' => 0], 1);
|
||||
$this->assertEntity('plain_text', 'Plain text', ['filter_html_escape' => 0, 'filter_url' => 1, 'filter_autop' => 2], 10);
|
||||
// This assertion covers issue #2555089. Drupal 7 formats are identified
|
||||
// by machine names, so migrated formats should be merged into existing
|
||||
// ones.
|
||||
|
|
|
@ -32,16 +32,19 @@ class FilterFormatTest extends MigrateSqlSourceTestCase {
|
|||
'module' => 'filter',
|
||||
'delta' => 2,
|
||||
'weight' => 0,
|
||||
'settings' => array(),
|
||||
),
|
||||
array(
|
||||
'module' => 'filter',
|
||||
'delta' => 0,
|
||||
'weight' => 1,
|
||||
'settings' => array(),
|
||||
),
|
||||
array(
|
||||
'module' => 'filter',
|
||||
'delta' => 1,
|
||||
'weight' => 2,
|
||||
'settings' => array(),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
@ -55,16 +58,19 @@ class FilterFormatTest extends MigrateSqlSourceTestCase {
|
|||
'module' => 'filter',
|
||||
'delta' => 2,
|
||||
'weight' => 0,
|
||||
'settings' => array(),
|
||||
),
|
||||
array(
|
||||
'module' => 'filter',
|
||||
'delta' => 1,
|
||||
'weight' => 1,
|
||||
'settings' => array(),
|
||||
),
|
||||
array(
|
||||
'module' => 'filter',
|
||||
'delta' => 3,
|
||||
'weight' => 10,
|
||||
'settings' => array(),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
@ -79,6 +85,7 @@ class FilterFormatTest extends MigrateSqlSourceTestCase {
|
|||
'module' => 'markdown',
|
||||
'delta' => 1,
|
||||
'weight' => 10,
|
||||
'settings' => array(),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
@ -89,9 +96,11 @@ class FilterFormatTest extends MigrateSqlSourceTestCase {
|
|||
*/
|
||||
protected function setUp() {
|
||||
$fid = 1;
|
||||
$empty_array = serialize(array());
|
||||
foreach ($this->expectedResults as $k => $row) {
|
||||
$row['roles'] = ',' . implode(',', $row['roles']) . ',';
|
||||
foreach ($row['filters'] as $filter) {
|
||||
$filter['settings'] = $empty_array;
|
||||
$this->databaseContents['filters'][$fid] = $filter;
|
||||
$this->databaseContents['filters'][$fid]['format'] = $row['format'];
|
||||
$this->databaseContents['filters'][$fid]['fid'] = $fid;
|
||||
|
|
|
@ -29,6 +29,7 @@ class FilterFormatTest extends MigrateSqlSourceTestCase {
|
|||
'weight' => 0,
|
||||
'filters' => array(
|
||||
'filter_autop' => array(
|
||||
'format' => 'custom_text_format',
|
||||
'module' => 'filter',
|
||||
'name' => 'filter_autop',
|
||||
'weight' => 0,
|
||||
|
@ -36,6 +37,7 @@ class FilterFormatTest extends MigrateSqlSourceTestCase {
|
|||
'settings' => array(),
|
||||
),
|
||||
'filter_html' => array(
|
||||
'format' => 'custom_text_format',
|
||||
'module' => 'filter',
|
||||
'name' => 'filter_html',
|
||||
'weight' => 1,
|
||||
|
@ -52,6 +54,7 @@ class FilterFormatTest extends MigrateSqlSourceTestCase {
|
|||
'weight' => 1,
|
||||
'filters' => array(
|
||||
'filter_url' => array(
|
||||
'format' => 'full_html',
|
||||
'module' => 'filter',
|
||||
'name' => 'filter_url',
|
||||
'weight' => 0,
|
||||
|
|
|
@ -2,6 +2,7 @@ langcode: en
|
|||
status: true
|
||||
dependencies:
|
||||
config:
|
||||
- field.field.taxonomy_term.forums.forum_container
|
||||
- taxonomy.vocabulary.forums
|
||||
module:
|
||||
- text
|
||||
|
|
|
@ -2,6 +2,7 @@ langcode: en
|
|||
status: true
|
||||
dependencies:
|
||||
config:
|
||||
- field.field.taxonomy_term.forums.forum_container
|
||||
- taxonomy.vocabulary.forums
|
||||
module:
|
||||
- text
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\help\Tests;
|
||||
namespace Drupal\Tests\help\Functional;
|
||||
|
||||
use Drupal\simpletest\WebTestBase;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
|
||||
/**
|
||||
* Verifies help for experimental modules.
|
||||
*
|
||||
* @group help
|
||||
*/
|
||||
class ExperimentalHelpTest extends WebTestBase {
|
||||
class ExperimentalHelpTest extends BrowserTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
|
@ -1,15 +1,15 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\help\Tests;
|
||||
namespace Drupal\Tests\help\Functional;
|
||||
|
||||
use Drupal\simpletest\WebTestBase;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
|
||||
/**
|
||||
* Tests display of help block.
|
||||
*
|
||||
* @group help
|
||||
*/
|
||||
class HelpBlockTest extends WebTestBase {
|
||||
class HelpBlockTest extends BrowserTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
|
@ -1,15 +1,15 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\help\Tests;
|
||||
namespace Drupal\Tests\help\Functional;
|
||||
|
||||
use Drupal\simpletest\WebTestBase;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
|
||||
/**
|
||||
* Verify help display and user access to help based on permissions.
|
||||
*
|
||||
* @group help
|
||||
*/
|
||||
class HelpTest extends WebTestBase {
|
||||
class HelpTest extends BrowserTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
|
@ -40,8 +40,6 @@ class HelpTest extends WebTestBase {
|
|||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$this->getModuleList();
|
||||
|
||||
// Create users.
|
||||
$this->adminUser = $this->drupalCreateUser(array('access administration pages', 'view the administration theme', 'administer permissions'));
|
||||
$this->anyUser = $this->drupalCreateUser(array());
|
||||
|
@ -122,7 +120,7 @@ class HelpTest extends WebTestBase {
|
|||
$this->assertResponse($response);
|
||||
if ($response == 200) {
|
||||
$this->assertTitle($name . ' | Drupal', format_string('%module title was displayed', array('%module' => $module)));
|
||||
$this->assertEqual($this->cssSelect('h1.page-title')[0], t($name), format_string('%module heading was displayed', array('%module' => $module)));
|
||||
$this->assertEquals($name, $this->cssSelect('h1.page-title')[0]->getText(), "$module heading was displayed");
|
||||
$admin_tasks = system_get_module_admin_tasks($module, system_get_info('module', $module));
|
||||
if (!empty($admin_tasks)) {
|
||||
$this->assertText(t('@module administration pages', array('@module' => $name)));
|
|
@ -1,15 +1,15 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\help\Tests;
|
||||
namespace Drupal\Tests\help\Functional;
|
||||
|
||||
use Drupal\simpletest\WebTestBase;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
|
||||
/**
|
||||
* Verify no help is displayed for modules not providing any help.
|
||||
*
|
||||
* @group help
|
||||
*/
|
||||
class NoHelpTest extends WebTestBase {
|
||||
class NoHelpTest extends BrowserTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
|
@ -188,14 +188,14 @@ class ImageFormatter extends ImageFormatterBase implements ContainerFactoryPlugi
|
|||
$image_style_setting = $this->getSetting('image_style');
|
||||
|
||||
// Collect cache tags to be added for each item in the field.
|
||||
$cache_tags = array();
|
||||
$base_cache_tags = [];
|
||||
if (!empty($image_style_setting)) {
|
||||
$image_style = $this->imageStyleStorage->load($image_style_setting);
|
||||
$cache_tags = $image_style->getCacheTags();
|
||||
$base_cache_tags = $image_style->getCacheTags();
|
||||
}
|
||||
|
||||
foreach ($files as $delta => $file) {
|
||||
$cache_contexts = array();
|
||||
$cache_contexts = [];
|
||||
if (isset($link_file)) {
|
||||
$image_uri = $file->getFileUri();
|
||||
// @todo Wrap in file_url_transform_relative(). This is currently
|
||||
|
@ -206,7 +206,7 @@ class ImageFormatter extends ImageFormatterBase implements ContainerFactoryPlugi
|
|||
$url = Url::fromUri(file_create_url($image_uri));
|
||||
$cache_contexts[] = 'url.site';
|
||||
}
|
||||
$cache_tags = Cache::mergeTags($cache_tags, $file->getCacheTags());
|
||||
$cache_tags = Cache::mergeTags($base_cache_tags, $file->getCacheTags());
|
||||
|
||||
// Extract field item attributes for the theme function, and unset them
|
||||
// from the $item so that the field template does not re-render them.
|
||||
|
|
|
@ -343,7 +343,7 @@ class ImageItem extends FileItem {
|
|||
$image = File::create();
|
||||
$image->setFileUri($path);
|
||||
$image->setOwnerId(\Drupal::currentUser()->id());
|
||||
$image->setMimeType('image/' . pathinfo($path, PATHINFO_EXTENSION));
|
||||
$image->setMimeType(\Drupal::service('file.mime_type.guesser')->guess($path));
|
||||
$image->setFileName(drupal_basename($path));
|
||||
$destination_dir = static::doGetUploadLocation($settings);
|
||||
file_prepare_directory($destination_dir, FILE_CREATE_DIRECTORY);
|
||||
|
|
102
core/modules/image/tests/src/Kernel/ImageFormatterTest.php
Normal file
102
core/modules/image/tests/src/Kernel/ImageFormatterTest.php
Normal file
|
@ -0,0 +1,102 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\image\Kernel;
|
||||
|
||||
use Drupal\Component\Utility\Unicode;
|
||||
use Drupal\Core\Field\FieldStorageDefinitionInterface;
|
||||
use Drupal\entity_test\Entity\EntityTest;
|
||||
use Drupal\field\Entity\FieldConfig;
|
||||
use Drupal\field\Entity\FieldStorageConfig;
|
||||
use Drupal\Tests\field\Kernel\FieldKernelTestBase;
|
||||
|
||||
/**
|
||||
* Tests the image field rendering using entity fields of the image field type.
|
||||
*
|
||||
* @group image
|
||||
*/
|
||||
class ImageFormatterTest extends FieldKernelTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = array('file', 'image');
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $entityType;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $bundle;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $fieldName;
|
||||
|
||||
/**
|
||||
* @var \Drupal\Core\Entity\Display\EntityViewDisplayInterface
|
||||
*/
|
||||
protected $display;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$this->installConfig(['field']);
|
||||
$this->installEntitySchema('entity_test');
|
||||
$this->installEntitySchema('file');
|
||||
$this->installSchema('file', array('file_usage'));
|
||||
|
||||
$this->entityType = 'entity_test';
|
||||
$this->bundle = $this->entityType;
|
||||
$this->fieldName = Unicode::strtolower($this->randomMachineName());
|
||||
|
||||
FieldStorageConfig::create(array(
|
||||
'entity_type' => $this->entityType,
|
||||
'field_name' => $this->fieldName,
|
||||
'type' => 'image',
|
||||
'cardinality' => FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED,
|
||||
))->save();
|
||||
FieldConfig::create([
|
||||
'entity_type' => $this->entityType,
|
||||
'field_name' => $this->fieldName,
|
||||
'bundle' => $this->bundle,
|
||||
'settings' => [
|
||||
'file_extensions' => 'jpg',
|
||||
],
|
||||
])->save();
|
||||
|
||||
$this->display = entity_get_display($this->entityType, $this->bundle, 'default')
|
||||
->setComponent($this->fieldName, [
|
||||
'type' => 'image',
|
||||
'label' => 'hidden',
|
||||
]);
|
||||
$this->display->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the cache tags from image formatters.
|
||||
*/
|
||||
function testImageFormatterCacheTags() {
|
||||
// Create a test entity with the image field set.
|
||||
$entity = EntityTest::create([
|
||||
'name' => $this->randomMachineName(),
|
||||
]);
|
||||
$entity->{$this->fieldName}->generateSampleItems(2);
|
||||
$entity->save();
|
||||
|
||||
// Generate the render array to verify if the cache tags are as expected.
|
||||
$build = $this->display->build($entity);
|
||||
|
||||
$this->assertEquals($entity->{$this->fieldName}[0]->entity->getCacheTags(), $build[$this->fieldName][0]['#cache']['tags'], 'First image cache tags is as expected');
|
||||
$this->assertEquals($entity->{$this->fieldName}[1]->entity->getCacheTags(), $build[$this->fieldName][1]['#cache']['tags'], 'Second image cache tags is as expected');
|
||||
}
|
||||
|
||||
}
|
|
@ -53,6 +53,9 @@ class ImageItemTest extends FieldKernelTestBase {
|
|||
'entity_type' => 'entity_test',
|
||||
'field_name' => 'image_test',
|
||||
'bundle' => 'entity_test',
|
||||
'settings' => [
|
||||
'file_extensions' => 'jpg',
|
||||
],
|
||||
])->save();
|
||||
file_unmanaged_copy(\Drupal::root() . '/core/misc/druplicon.png', 'public://example.jpg');
|
||||
$this->image = File::create([
|
||||
|
@ -123,6 +126,7 @@ class ImageItemTest extends FieldKernelTestBase {
|
|||
$entity = EntityTest::create();
|
||||
$entity->image_test->generateSampleItems();
|
||||
$this->entityValidateAndSave($entity);
|
||||
$this->assertEqual($entity->image_test->entity->get('filemime')->value, 'image/jpeg');
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -41,7 +41,7 @@ class ImageStyleTest extends UnitTestCase {
|
|||
* @param \Drupal\image\ImageEffectInterface|\PHPUnit_Framework_MockObject_MockObject $image_effect
|
||||
* The image effect used for testing.
|
||||
*
|
||||
* @return \Drupal\image\ImageStyleInterface|\Drupal\image\ImageStyleInterface
|
||||
* @return \Drupal\image\ImageStyleInterface
|
||||
* The mocked image style.
|
||||
*/
|
||||
protected function getImageStyleMock($image_effect_id, $image_effect, $stubs = array()) {
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
id: d6_language_content_settings
|
||||
label: Drupal 6 language content settings
|
||||
migration_tags:
|
||||
- Drupal 6
|
||||
source:
|
||||
plugin: d6_language_content_settings
|
||||
constants:
|
||||
target_type: 'node'
|
||||
process:
|
||||
# Ignore i18n_node_options_[node_type] options not available in Drupal 8,
|
||||
# i18n_required_node and i18n_newnode_current
|
||||
target_bundle: type
|
||||
target_entity_type_id: 'constants/target_type'
|
||||
default_langcode:
|
||||
-
|
||||
plugin: static_map
|
||||
source: language_content_type
|
||||
map:
|
||||
0: NULL
|
||||
1: 'current_interface'
|
||||
2: 'current_interface'
|
||||
-
|
||||
plugin: skip_on_empty
|
||||
method: row
|
||||
language_alterable:
|
||||
plugin: static_map
|
||||
source: i18n_lock_node
|
||||
map:
|
||||
0: true
|
||||
1: false
|
||||
'third_party_settings/content_translation/enabled':
|
||||
plugin: static_map
|
||||
source: language_content_type
|
||||
map:
|
||||
# In the case of being 0, it will be skipped. We are not actually setting
|
||||
# a null value.
|
||||
0: NULL
|
||||
1: false
|
||||
2: true
|
||||
destination:
|
||||
plugin: entity:language_content_settings
|
||||
migration_dependencies:
|
||||
required:
|
||||
- d6_node_type
|
|
@ -0,0 +1,44 @@
|
|||
id: d7_language_content_settings
|
||||
label: Drupal 7 language content settings
|
||||
migration_tags:
|
||||
- Drupal 7
|
||||
source:
|
||||
plugin: d7_language_content_settings
|
||||
constants:
|
||||
target_type: 'node'
|
||||
process:
|
||||
# Ignore i18n_node_options_[node_type] options not available in Drupal 8,
|
||||
# i18n_required_node and i18n_newnode_current
|
||||
target_bundle: type
|
||||
target_entity_type_id: 'constants/target_type'
|
||||
default_langcode:
|
||||
-
|
||||
plugin: static_map
|
||||
source: language_content_type
|
||||
map:
|
||||
0: NULL
|
||||
1: 'current_interface'
|
||||
2: 'current_interface'
|
||||
-
|
||||
plugin: skip_on_empty
|
||||
method: row
|
||||
language_alterable:
|
||||
plugin: static_map
|
||||
source: i18n_lock_node
|
||||
map:
|
||||
0: true
|
||||
1: false
|
||||
'third_party_settings/content_translation/enabled':
|
||||
plugin: static_map
|
||||
source: language_content_type
|
||||
map:
|
||||
# In the case of being 0, it will be skipped. We are not actually setting
|
||||
# a null value.
|
||||
0: NULL
|
||||
1: false
|
||||
2: true
|
||||
destination:
|
||||
plugin: entity:language_content_settings
|
||||
migration_dependencies:
|
||||
required:
|
||||
- d7_node_type
|
|
@ -40,7 +40,7 @@ class DefaultLanguageItem extends LanguageItem {
|
|||
* The entity whose language code to be loaded.
|
||||
*
|
||||
* @return string
|
||||
* A string language code.
|
||||
* A string language code.
|
||||
*/
|
||||
public function getDefaultLangcode(EntityInterface $entity) {
|
||||
return language_get_default_langcode($entity->getEntityTypeId(), $entity->bundle());
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\language\Plugin\migrate\source\d6;
|
||||
|
||||
use Drupal\migrate\Row;
|
||||
use Drupal\migrate_drupal\Plugin\migrate\source\DrupalSqlBase;
|
||||
|
||||
/**
|
||||
* Drupal multilingual node settings from database.
|
||||
*
|
||||
* @MigrateSource(
|
||||
* id = "d6_language_content_settings",
|
||||
* )
|
||||
*/
|
||||
class LanguageContentSettings extends DrupalSqlBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function query() {
|
||||
return $this->select('node_type', 't')
|
||||
->fields('t', array(
|
||||
'type',
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function fields() {
|
||||
$fields = array(
|
||||
'type' => $this->t('Type'),
|
||||
'language_content_type' => $this->t('Multilingual support.'),
|
||||
'i18n_lock_node' => $this->t('Lock language.'),
|
||||
);
|
||||
return $fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function prepareRow(Row $row) {
|
||||
$type = $row->getSourceProperty('type');
|
||||
$row->setSourceProperty('language_content_type', $this->variableGet('language_content_type_' . $type, NULL));
|
||||
$row->setSourceProperty('i18n_lock_node', $this->variableGet('i18n_lock_node_' . $type, 0));
|
||||
return parent::prepareRow($row);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getIds() {
|
||||
$ids['type']['type'] = 'string';
|
||||
return $ids;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\language\Plugin\migrate\source\d7;
|
||||
|
||||
use Drupal\migrate\Row;
|
||||
use Drupal\migrate_drupal\Plugin\migrate\source\DrupalSqlBase;
|
||||
|
||||
/**
|
||||
* Drupal multilingual node settings from database.
|
||||
*
|
||||
* @MigrateSource(
|
||||
* id = "d7_language_content_settings",
|
||||
* )
|
||||
*/
|
||||
class LanguageContentSettings extends DrupalSqlBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function query() {
|
||||
return $this->select('node_type', 't')
|
||||
->fields('t', array(
|
||||
'type',
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function fields() {
|
||||
$fields = array(
|
||||
'type' => $this->t('Type'),
|
||||
'language_content_type' => $this->t('Multilingual support.'),
|
||||
'i18n_lock_node' => $this->t('Lock language.'),
|
||||
);
|
||||
return $fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function prepareRow(Row $row) {
|
||||
$type = $row->getSourceProperty('type');
|
||||
$row->setSourceProperty('language_content_type', $this->variableGet('language_content_type_' . $type, NULL));
|
||||
$i18n_node_options = $this->variableGet('i18n_node_options_' . $type, NULL);
|
||||
if ($i18n_node_options && in_array('lock', $i18n_node_options)) {
|
||||
$row->setSourceProperty('i18n_lock_node', 1);
|
||||
}
|
||||
else {
|
||||
$row->setSourceProperty('i18n_lock_node', 0);
|
||||
}
|
||||
return parent::prepareRow($row);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getIds() {
|
||||
$ids['type']['type'] = 'string';
|
||||
return $ids;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\language\Kernel\Migrate\d6;
|
||||
|
||||
use Drupal\language\Entity\ContentLanguageSettings;
|
||||
use Drupal\Tests\migrate_drupal\Kernel\d6\MigrateDrupal6TestBase;
|
||||
|
||||
/**
|
||||
* Tests migration of language content setting variables,
|
||||
* language_content_type_$type, i18n_node_options_* and i18n_lock_node_*.
|
||||
*
|
||||
* @group migrate_drupal_6
|
||||
*/
|
||||
class MigrateLanguageContentSettingsTest extends MigrateDrupal6TestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['node', 'text', 'language', 'content_translation'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$this->installConfig(['node']);
|
||||
$this->executeMigrations(['d6_node_type', 'd6_language_content_settings']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests migration of content language settings.
|
||||
*/
|
||||
public function testLanguageContent() {
|
||||
// Assert that a translatable content is still translatable.
|
||||
$config = $this->config('language.content_settings.node.article');
|
||||
$this->assertSame($config->get('target_entity_type_id'), 'node');
|
||||
$this->assertSame($config->get('target_bundle'), 'article');
|
||||
$this->assertSame($config->get('default_langcode'), 'current_interface');
|
||||
$this->assertTrue($config->get('third_party_settings.content_translation.enabled'));
|
||||
|
||||
// Assert that a non-translatable content is not translatable.
|
||||
$config = ContentLanguageSettings::loadByEntityTypeBundle('node', 'company');
|
||||
$this->assertTrue($config->isDefaultConfiguration());
|
||||
$this->assertFalse($config->isLanguageAlterable());
|
||||
$this->assertSame($config->getDefaultLangcode(), 'site_default');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests migration of content language settings when there is no language lock.
|
||||
*/
|
||||
public function testLanguageContentWithNoLanguageLock() {
|
||||
// Assert that a we can assign a language.
|
||||
$config = ContentLanguageSettings::loadByEntityTypeBundle('node', 'employee');
|
||||
$this->assertSame($config->getDefaultLangcode(), 'current_interface');
|
||||
$this->assertTrue($config->isLanguageAlterable());
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\language\Kernel\Migrate\d7;
|
||||
|
||||
use Drupal\language\Entity\ContentLanguageSettings;
|
||||
use Drupal\Tests\migrate_drupal\Kernel\d7\MigrateDrupal7TestBase;
|
||||
|
||||
/**
|
||||
* Tests migration of language content setting variables,
|
||||
* language_content_type_$type, i18n_node_options_* and i18n_lock_node_*.
|
||||
*
|
||||
* @group migrate_drupal_7
|
||||
*/
|
||||
class MigrateLanguageContentSettingsTest extends MigrateDrupal7TestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['node', 'text', 'language', 'content_translation'];
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$this->installConfig(['node']);
|
||||
$this->executeMigrations(['d7_node_type', 'd7_language_content_settings']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests migration of content language settings.
|
||||
*/
|
||||
public function testLanguageContent() {
|
||||
// Assert that a translatable content is still translatable.
|
||||
$config = $this->config('language.content_settings.node.blog');
|
||||
$this->assertIdentical($config->get('target_entity_type_id'), 'node');
|
||||
$this->assertIdentical($config->get('target_bundle'), 'blog');
|
||||
$this->assertIdentical($config->get('default_langcode'), 'current_interface');
|
||||
$this->assertFalse($config->get('language_alterable'));
|
||||
$this->assertTrue($config->get('third_party_settings.content_translation.enabled'));
|
||||
|
||||
// Assert that a non-translatable content is not translatable.
|
||||
$config = ContentLanguageSettings::loadByEntityTypeBundle('node', 'page');
|
||||
$this->assertTrue($config->isDefaultConfiguration());
|
||||
$this->assertFalse($config->isLanguageAlterable());
|
||||
$this->assertSame($config->getDefaultLangcode(), 'site_default');
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -7,7 +7,11 @@ use Drupal\migrate_drupal\Plugin\migrate\cckfield\CckFieldPluginBase;
|
|||
|
||||
/**
|
||||
* @MigrateCckField(
|
||||
* id = "link"
|
||||
* id = "link",
|
||||
* core = {6},
|
||||
* type_map = {
|
||||
* "link_field" = "link"
|
||||
* }
|
||||
* )
|
||||
*/
|
||||
class LinkField extends CckFieldPluginBase {
|
||||
|
|
|
@ -36,6 +36,32 @@ class CckLink extends ProcessPluginBase implements ContainerFactoryPluginInterfa
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Turn a Drupal 6 URI into a Drupal 8-compatible format.
|
||||
*
|
||||
* @param string $uri
|
||||
* The 'url' value from Drupal 6.
|
||||
*
|
||||
* @return string
|
||||
* The Drupal 8-compatible URI.
|
||||
*
|
||||
* @see \Drupal\link\Plugin\Field\FieldWidget\LinkWidget::getUserEnteredStringAsUri()
|
||||
*/
|
||||
protected function canonicalizeUri($uri) {
|
||||
// If we already have a scheme, we're fine.
|
||||
if (empty($uri) || !is_null(parse_url($uri, PHP_URL_SCHEME))) {
|
||||
return $uri;
|
||||
}
|
||||
|
||||
// Remove the <front> component of the URL.
|
||||
if (strpos($uri, '<front>') === 0) {
|
||||
$uri = substr($uri, strlen('<front>'));
|
||||
}
|
||||
|
||||
// Add the internal: scheme and ensure a leading slash.
|
||||
return 'internal:/' . ltrim($uri, '/');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
@ -51,7 +77,7 @@ class CckLink extends ProcessPluginBase implements ContainerFactoryPluginInterfa
|
|||
}
|
||||
|
||||
// Massage the values into the correct form for the link.
|
||||
$route['uri'] = $value['url'];
|
||||
$route['uri'] = $this->canonicalizeUri($value['url']);
|
||||
$route['options']['attributes'] = $attributes;
|
||||
$route['title'] = $value['title'];
|
||||
return $route;
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\link\Unit\Plugin\migrate\process\d6;
|
||||
|
||||
use Drupal\link\Plugin\migrate\process\d6\CckLink;
|
||||
use Drupal\Tests\UnitTestCase;
|
||||
|
||||
/**
|
||||
* @group Link
|
||||
*/
|
||||
class CckLinkTest extends UnitTestCase {
|
||||
|
||||
/**
|
||||
* Test the url transformations in the CckLink process plugin.
|
||||
*
|
||||
* @dataProvider canonicalizeUriDataProvider
|
||||
*/
|
||||
public function testCanonicalizeUri($url, $expected) {
|
||||
$link_plugin = new CckLink([], '', [], $this->getMock('\Drupal\migrate\Plugin\MigrationInterface'));
|
||||
$transformed = $link_plugin->transform([
|
||||
'url' => $url,
|
||||
'title' => '',
|
||||
'attributes' => serialize([]),
|
||||
], $this->getMock('\Drupal\migrate\MigrateExecutableInterface'), $this->getMockBuilder('\Drupal\migrate\Row')->disableOriginalConstructor()->getMock(), NULL);
|
||||
$this->assertEquals($expected, $transformed['uri']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for testCanonicalizeUri.
|
||||
*/
|
||||
public function canonicalizeUriDataProvider() {
|
||||
return [
|
||||
'Simple front-page' => [
|
||||
'<front>',
|
||||
'internal:/',
|
||||
],
|
||||
'Front page with query' => [
|
||||
'<front>?query=1',
|
||||
'internal:/?query=1',
|
||||
],
|
||||
'No leading forward slash' => [
|
||||
'node/10',
|
||||
'internal:/node/10',
|
||||
],
|
||||
'Leading forward slash' => [
|
||||
'/node/10',
|
||||
'internal:/node/10',
|
||||
],
|
||||
'Existing scheme' => [
|
||||
'scheme:test',
|
||||
'scheme:test',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
}
|
|
@ -5,11 +5,8 @@ migration_tags:
|
|||
- Drupal 7
|
||||
source:
|
||||
plugin: menu_link
|
||||
constants:
|
||||
bundle: menu_link_content
|
||||
process:
|
||||
id: mlid
|
||||
bundle: 'constants/bundle'
|
||||
title: link_title
|
||||
description: description
|
||||
menu_name:
|
||||
|
@ -49,6 +46,7 @@ process:
|
|||
changed: updated
|
||||
destination:
|
||||
plugin: entity:menu_link_content
|
||||
default_bundle: menu_link_content
|
||||
no_stub: true
|
||||
migration_dependencies:
|
||||
required:
|
||||
|
|
|
@ -17,33 +17,30 @@ use Drupal\migrate\Row;
|
|||
* @section overview Overview of migration
|
||||
* Migration is an
|
||||
* @link http://wikipedia.org/wiki/Extract,_transform,_load Extract, Transform, Load @endlink
|
||||
* (ETL) process. For historical reasons, in the Drupal migration tool the
|
||||
* extract phase is called "source", the transform phase is called "process",
|
||||
* and the load phase is called "destination".
|
||||
* (ETL) process. In the Drupal migration API the extract phase is called
|
||||
* "source", the transform phase is called "process", and the load phase is
|
||||
* called "destination". It is important to understand that the "load" in ETL
|
||||
* means to load data into storage, while traditionally Drupal uses "load" to
|
||||
* mean load data from storage into memory.
|
||||
*
|
||||
* Source, process, and destination phases are each provided by plugins. Source
|
||||
* plugins extract data from a data source in "rows", containing "properties".
|
||||
* Each row is handed off to one or more series of process plugins, where each
|
||||
* series operates to transform the row data into one result property. After all
|
||||
* the properties are processed, the resulting row is handed off to a
|
||||
* destination plugin, which saves the data.
|
||||
* Source, process, and destination phases are each provided by plugins.
|
||||
* Source plugins extract data from a data source in "rows", containing
|
||||
* "properties". Each row is handed off to one or more process plugins which
|
||||
* transform the row's properties. After all the properties are processed, the
|
||||
* resulting row is handed off to a destination plugin, which saves the data.
|
||||
*
|
||||
* The Migrate module provides process plugins for common operations (setting
|
||||
* default values, mapping values, etc.), and destination plugins for Drupal
|
||||
* core objects (configuration, entity, URL alias, etc.). The Migrate Drupal
|
||||
* module provides source plugins to extract data from various versions of
|
||||
* Drupal. Custom and contributed modules can provide additional plugins; see
|
||||
* the @link plugin_api Plugin API topic @endlink for generic information about
|
||||
* providing plugins, and sections below for details about the plugin types.
|
||||
* A source plugin, one or more process plugins, and a destination plugin are
|
||||
* brought together to extract, transform, and load (in the ETL sense) a specific
|
||||
* type of data by a migration plugin.
|
||||
*
|
||||
* The configuration of migrations is stored in configuration entities, which
|
||||
* list the IDs and configurations of the plugins that are involved. See
|
||||
* @ref sec_entity below for details. To migrate an entire site, you'll need to
|
||||
* create a migration manifest; see @ref sec_manifest for details.
|
||||
*
|
||||
* https://www.drupal.org/node/2127611 has more complete information on the
|
||||
* Migration API, including information on load plugins, which are only used
|
||||
* in Drupal 6 migration.
|
||||
* @section sec_migrations Migration plugins
|
||||
* Migration plugin definitions are stored in a module's 'migrations' directory.
|
||||
* For backwards compatibility we also scan the 'migration_templates' directory.
|
||||
* Examples of migration plugin definitions can be found in
|
||||
* 'core/modules/action/migration_templates'. The plugin class is
|
||||
* \Drupal\migrate\Plugin\Migration, with interface
|
||||
* \Drupal\migrate\Plugin\MigrationInterface. Migration plugins are managed by
|
||||
* the \Drupal\migrate\Plugin\MigrationPluginManager class.
|
||||
*
|
||||
* @section sec_source Source plugins
|
||||
* Migration source plugins implement
|
||||
|
@ -61,7 +58,9 @@ use Drupal\migrate\Row;
|
|||
* with \Drupal\migrate\Annotation\MigrateProcessPlugin annotation, and must be
|
||||
* in namespace subdirectory Plugin\migrate\process under the namespace of the
|
||||
* module that defines them. Migration process plugins are managed by the
|
||||
* \Drupal\migrate\Plugin\MigratePluginManager class.
|
||||
* \Drupal\migrate\Plugin\MigratePluginManager class. The Migrate module
|
||||
* provides process plugins for common operations (setting default values,
|
||||
* mapping values, etc.).
|
||||
*
|
||||
* @section sec_destination Destination plugins
|
||||
* Migration destination plugins implement
|
||||
|
@ -70,34 +69,12 @@ use Drupal\migrate\Row;
|
|||
* annotated with \Drupal\migrate\Annotation\MigrateDestination annotation, and
|
||||
* must be in namespace subdirectory Plugin\migrate\destination under the
|
||||
* namespace of the module that defines them. Migration destination plugins
|
||||
* are managed by the
|
||||
* \Drupal\migrate\Plugin\MigrateDestinationPluginManager class.
|
||||
* are managed by the \Drupal\migrate\Plugin\MigrateDestinationPluginManager
|
||||
* class. The Migrate module provides destination plugins for Drupal core
|
||||
* objects (configuration and entity).
|
||||
*
|
||||
* @section sec_entity Migration configuration entities
|
||||
* The definition of how to migrate each type of data is stored in configuration
|
||||
* entities. The migration configuration entity class is
|
||||
* \Drupal\migrate\Entity\Migration, with interface
|
||||
* \Drupal\migrate\Entity\MigrationInterface; the configuration schema can be
|
||||
* found in the migrate.schema.yml file. Migration configuration consists of IDs
|
||||
* and configuration for the source, process, and destination plugins, as well
|
||||
* as information on dependencies. Process configuration consists of sections,
|
||||
* each of which defines the series of process plugins needed for one
|
||||
* destination property. You can find examples of migration configuration files
|
||||
* in the core/modules/migrate_drupal/config/install directory.
|
||||
*
|
||||
* @section sec_manifest Migration manifests
|
||||
* You can run a migration with the "drush migrate-manifest" command, providing
|
||||
* a migration manifest file. This file lists the configuration names of the
|
||||
* migrations you want to execute, as well as any dependencies they have (you
|
||||
* can find these in the "migration_dependencies" sections of the individual
|
||||
* configuration files). For example, to migrate blocks from a Drupal 6 site,
|
||||
* you would list:
|
||||
* @code
|
||||
* # Migrate blocks from Drupal 6 to 8
|
||||
* - d6_filter_format
|
||||
* - d6_custom_block
|
||||
* - d6_block
|
||||
* @endcode
|
||||
* @section sec_more_info More information
|
||||
* @link https://www.drupal.org/node/2127611 Migration API documentation. @endlink
|
||||
*
|
||||
* @see update_api
|
||||
* @}
|
||||
|
|
|
@ -662,7 +662,7 @@ class Migration extends PluginBase implements MigrationInterface, RequirementsIn
|
|||
* {@inheritdoc}
|
||||
*/
|
||||
public function getMigrationDependencies() {
|
||||
return $this->migration_dependencies + ['required' => [], 'optional' => []];
|
||||
return ($this->migration_dependencies ?: []) + ['required' => [], 'optional' => []];
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -703,14 +703,14 @@ class Migration extends PluginBase implements MigrationInterface, RequirementsIn
|
|||
* {@inheritdoc}
|
||||
*/
|
||||
public function getTrackLastImported() {
|
||||
$this->trackLastImported;
|
||||
return $this->trackLastImported;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getDestinationIds() {
|
||||
$this->destinationIds;
|
||||
return $this->destinationIds;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -88,6 +88,21 @@ abstract class Entity extends DestinationBase implements ContainerFactoryPluginI
|
|||
return substr($plugin_id, 7);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the bundle for the row taking into account the default.
|
||||
*
|
||||
* @param \Drupal\migrate\Row $row
|
||||
* The current row we're importing.
|
||||
*
|
||||
* @return string
|
||||
* The bundle for this row.
|
||||
*/
|
||||
public function getBundle(Row $row) {
|
||||
$default_bundle = isset($this->configuration['default_bundle']) ? $this->configuration['default_bundle'] : '';
|
||||
$bundle_key = $this->getKey('bundle');
|
||||
return $row->getDestinationProperty($bundle_key) ?: $default_bundle;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
@ -112,6 +127,11 @@ abstract class Entity extends DestinationBase implements ContainerFactoryPluginI
|
|||
$this->updateEntity($entity, $row);
|
||||
}
|
||||
else {
|
||||
// Attempt to ensure we always have a bundle.
|
||||
if ($bundle = $this->getBundle($row)) {
|
||||
$row->setDestinationProperty($this->getKey('bundle'), $bundle);
|
||||
}
|
||||
|
||||
// Stubs might need some required fields filled in.
|
||||
if ($row->isStub()) {
|
||||
$this->processStubRow($row);
|
||||
|
|
|
@ -143,7 +143,7 @@ abstract class SourcePluginBase extends PluginBase implements MigrateSourceInter
|
|||
// Set up some defaults based on the source configuration.
|
||||
$this->cacheCounts = !empty($configuration['cache_counts']);
|
||||
$this->skipCount = !empty($configuration['skip_count']);
|
||||
$this->cacheKey = !empty($configuration['cache_key']) ? !empty($configuration['cache_key']) : NULL;
|
||||
$this->cacheKey = !empty($configuration['cache_key']) ? $configuration['cache_key'] : NULL;
|
||||
$this->trackChanges = !empty($configuration['track_changes']) ? $configuration['track_changes'] : FALSE;
|
||||
$this->idMap = $this->migration->getIdMap();
|
||||
|
||||
|
|
|
@ -1,10 +0,0 @@
|
|||
id: node_template
|
||||
label: Template test - node
|
||||
migration_tags:
|
||||
- Template Test
|
||||
source:
|
||||
plugin: empty
|
||||
process:
|
||||
src: barfoo
|
||||
destination:
|
||||
plugin: entity:node
|
|
@ -1,10 +0,0 @@
|
|||
id: other_template
|
||||
label: Template with a different tag
|
||||
migration_tags:
|
||||
- Different Template Test
|
||||
source:
|
||||
plugin: empty
|
||||
process:
|
||||
src: raboof
|
||||
destination:
|
||||
plugin: entity:user
|
|
@ -1,10 +0,0 @@
|
|||
id: url_template
|
||||
label: Template test - URL
|
||||
migration_tags:
|
||||
- Template Test
|
||||
source:
|
||||
plugin: empty
|
||||
process:
|
||||
src: foobar
|
||||
destination:
|
||||
plugin: url_alias
|
|
@ -1,5 +0,0 @@
|
|||
name: 'Migration template test'
|
||||
type: module
|
||||
package: Testing
|
||||
version: VERSION
|
||||
core: 8.x
|
155
core/modules/migrate/tests/src/Kernel/MigrateBundleTest.php
Normal file
155
core/modules/migrate/tests/src/Kernel/MigrateBundleTest.php
Normal file
|
@ -0,0 +1,155 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\migrate\Kernel;
|
||||
|
||||
use Drupal\migrate\MigrateExecutable;
|
||||
use Drupal\taxonomy\Entity\Term;
|
||||
use Drupal\taxonomy\Entity\Vocabulary;
|
||||
|
||||
/**
|
||||
* Tests setting of bundles on content entity migrations.
|
||||
*
|
||||
* @group migrate
|
||||
*/
|
||||
class MigrateBundleTest extends MigrateTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['taxonomy', 'text'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$this->installEntitySchema('taxonomy_vocabulary');
|
||||
$this->installEntitySchema('taxonomy_term');
|
||||
$this->installConfig(['taxonomy']);
|
||||
// Set up two vocabularies (taxonomy bundles).
|
||||
Vocabulary::create(['vid' => 'tags', 'name' => 'Tags']);
|
||||
Vocabulary::create(['vid' => 'categories', 'name' => 'Categories']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests setting the bundle in the destination.
|
||||
*/
|
||||
public function testDestinationBundle() {
|
||||
$term_data_rows = [
|
||||
['id' => 1, 'name' => 'Category 1'],
|
||||
];
|
||||
$ids = ['id' => ['type' => 'integer']];
|
||||
$definition = [
|
||||
'id' => 'terms',
|
||||
'migration_tags' => ['Bundle test'],
|
||||
'source' => [
|
||||
'plugin' => 'embedded_data',
|
||||
'data_rows' => $term_data_rows,
|
||||
'ids' => $ids,
|
||||
],
|
||||
'process' => [
|
||||
'tid' => 'id',
|
||||
'name' => 'name',
|
||||
],
|
||||
'destination' => [
|
||||
'plugin' => 'entity:taxonomy_term',
|
||||
'default_bundle' => 'categories',
|
||||
],
|
||||
'migration_dependencies' => [],
|
||||
];
|
||||
|
||||
$term_migration = \Drupal::service('plugin.manager.migration')->createStubMigration($definition);
|
||||
|
||||
// Import and validate the term entity was created with the correct bundle.
|
||||
$term_executable = new MigrateExecutable($term_migration, $this);
|
||||
$term_executable->import();
|
||||
/** @var Term $term */
|
||||
$term = Term::load(1);
|
||||
$this->assertEquals($term->bundle(), 'categories');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests setting the bundle in the process pipeline.
|
||||
*/
|
||||
public function testProcessBundle() {
|
||||
$term_data_rows = [
|
||||
['id' => 1, 'vocab' => 'categories', 'name' => 'Category 1'],
|
||||
['id' => 2, 'vocab' => 'tags', 'name' => 'Tag 1'],
|
||||
];
|
||||
$ids = ['id' => ['type' => 'integer']];
|
||||
$definition = [
|
||||
'id' => 'terms',
|
||||
'migration_tags' => ['Bundle test'],
|
||||
'source' => [
|
||||
'plugin' => 'embedded_data',
|
||||
'data_rows' => $term_data_rows,
|
||||
'ids' => $ids,
|
||||
],
|
||||
'process' => [
|
||||
'tid' => 'id',
|
||||
'vid' => 'vocab',
|
||||
'name' => 'name',
|
||||
],
|
||||
'destination' => [
|
||||
'plugin' => 'entity:taxonomy_term',
|
||||
],
|
||||
'migration_dependencies' => [],
|
||||
];
|
||||
|
||||
$term_migration = \Drupal::service('plugin.manager.migration')->createStubMigration($definition);
|
||||
|
||||
// Import and validate the term entities were created with the correct bundle.
|
||||
$term_executable = new MigrateExecutable($term_migration, $this);
|
||||
$term_executable->import();
|
||||
/** @var Term $term */
|
||||
$term = Term::load(1);
|
||||
$this->assertEquals($term->bundle(), 'categories');
|
||||
$term = Term::load(2);
|
||||
$this->assertEquals($term->bundle(), 'tags');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests setting bundles both in process and destination.
|
||||
*/
|
||||
public function testMixedBundles() {
|
||||
$term_data_rows = [
|
||||
['id' => 1, 'vocab' => 'categories', 'name' => 'Category 1'],
|
||||
['id' => 2, 'name' => 'Tag 1'],
|
||||
];
|
||||
$ids = ['id' => ['type' => 'integer']];
|
||||
$definition = [
|
||||
'id' => 'terms',
|
||||
'migration_tags' => ['Bundle test'],
|
||||
'source' => [
|
||||
'plugin' => 'embedded_data',
|
||||
'data_rows' => $term_data_rows,
|
||||
'ids' => $ids,
|
||||
],
|
||||
'process' => [
|
||||
'tid' => 'id',
|
||||
'vid' => 'vocab',
|
||||
'name' => 'name',
|
||||
],
|
||||
'destination' => [
|
||||
'plugin' => 'entity:taxonomy_term',
|
||||
// When no vocab is provided, the destination bundle is applied.
|
||||
'default_bundle' => 'tags',
|
||||
],
|
||||
'migration_dependencies' => [],
|
||||
];
|
||||
|
||||
$term_migration = \Drupal::service('plugin.manager.migration')->createStubMigration($definition);
|
||||
|
||||
// Import and validate the term entities were created with the correct bundle.
|
||||
$term_executable = new MigrateExecutable($term_migration, $this);
|
||||
$term_executable->import();
|
||||
/** @var Term $term */
|
||||
$term = Term::load(1);
|
||||
$this->assertEquals($term->bundle(), 'categories');
|
||||
$term = Term::load(2);
|
||||
$this->assertEquals($term->bundle(), 'tags');
|
||||
}
|
||||
|
||||
}
|
|
@ -27,4 +27,41 @@ class MigrationTest extends KernelTestBase {
|
|||
$this->assertEquals([], $migration->getProcessPlugins([]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests Migration::getMigrationDependencies()
|
||||
*
|
||||
* @covers ::getMigrationDependencies
|
||||
*/
|
||||
public function testGetMigrationDependencies() {
|
||||
$migration = \Drupal::service('plugin.manager.migration')->createStubMigration([
|
||||
'migration_dependencies' => NULL
|
||||
]);
|
||||
$this->assertNotEmpty($migration->getMigrationDependencies(), 'Migration dependencies is not empty');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests Migration::getDestinationIds()
|
||||
*
|
||||
* @covers ::getDestinationIds
|
||||
*/
|
||||
public function testGetDestinationIds() {
|
||||
$migration = \Drupal::service('plugin.manager.migration')->createStubMigration(['destinationIds' => ['foo' => 'bar']]);
|
||||
$destination_ids = $migration->getDestinationIds();
|
||||
$this->assertNotEmpty($destination_ids, 'Destination ids are not empty');
|
||||
$this->assertEquals(['foo' => 'bar'], $destination_ids, 'Destination ids match the expected values.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests Migration::getTrackLastImported()
|
||||
*
|
||||
* @covers ::getTrackLastImported
|
||||
* @covers ::isTrackLastImported
|
||||
*/
|
||||
public function testGetTrackLastImported() {
|
||||
$migration = \Drupal::service('plugin.manager.migration')->createStubMigration([]);
|
||||
$migration->setTrackLastImported(TRUE);
|
||||
$this->assertEquals(TRUE, $migration->getTrackLastImported());
|
||||
$this->assertEquals(TRUE, $migration->isTrackLastImported());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -170,6 +170,25 @@ class MigrateSourceTest extends MigrateTestCase {
|
|||
$this->assertEquals(-1, $source->count());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that the key can be set for the count cache.
|
||||
*
|
||||
* @covers ::count
|
||||
*/
|
||||
public function testCountCacheKey() {
|
||||
// Mock the cache to validate set() receives appropriate arguments.
|
||||
$container = new ContainerBuilder();
|
||||
$cache = $this->getMock(CacheBackendInterface::class);
|
||||
$cache->expects($this->any())->method('set')
|
||||
->with('test_key', $this->isType('int'), $this->isType('int'));
|
||||
$container->set('cache.migrate', $cache);
|
||||
\Drupal::setContainer($container);
|
||||
|
||||
// Test caching the count with a configured key works.
|
||||
$source = $this->getSource(['cache_counts' => TRUE, 'cache_key' => 'test_key']);
|
||||
$this->assertEquals(1, $source->count());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that we don't get a row if prepareRow() is false.
|
||||
*/
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Reference in a new issue