diff --git a/core/MAINTAINERS.txt b/core/MAINTAINERS.txt
index c3d5f5622..adc61a74c 100644
--- a/core/MAINTAINERS.txt
+++ b/core/MAINTAINERS.txt
@@ -3,6 +3,9 @@ encouraged to submit issues and changes (patches) to improve Drupal, and to
contribute in other ways -- see https://www.drupal.org/contribute to find out
how.
+This file lists the active maintainers. For a list of past maintainers, see:
+https://www.drupal.org/core/maintainers/past
+
Core committers
---------------
@@ -53,11 +56,10 @@ Actions
- ?
Aggregator
-- Paris Liakos 'ParisLiakos' https://www.drupal.org/u/parisliakos
+- ?
Ajax
- Alex Bronstein 'effulgentsia' https://www.drupal.org/u/effulgentsia
-- Earl Miles 'merlinofchaos' https://www.drupal.org/u/merlinofchaos
- Tim Plunkett 'tim.plunkett' https://www.drupal.org/u/tim.plunkett
Asset Library API
@@ -73,19 +75,17 @@ Ban
- ?
Bartik
-- Jen Simmons 'jensimmons' https://www.drupal.org/u/jensimmons
- Emma Maria Karayiannis 'emma.maria' https://www.drupal.org/u/emma.maria
Base system
-- Damien Tournoud 'damien-tournoud' https://www.drupal.org/u/damien-tournoud
-- Moshe Weitzman 'moshe weitzman' https://www.drupal.org/u/moshe-weitzman
+- ?
Basic Auth
- Klaus Purer 'klausi' https://www.drupal.org/u/klausi
- Juampy Novillo Requena 'juampy' https://www.drupal.org/u/juampy
Batch API
-- Yves Chedemois 'yched' https://www.drupal.org/u/yched
+- ?
BigPipe
- Wim Leers 'Wim Leers' https://www.drupal.org/u/wim-leers
@@ -109,9 +109,7 @@ Breakpoint
- Marc Drummond 'mdrummond' https://www.drupal.org/u/mdrummond
Cache
-- Damien Tournoud 'damien-tournoud' https://www.drupal.org/u/damien-tournoud
- Nathaniel Catchpole 'catch' https://www.drupal.org/u/catch
-- Mark Sonnabaum 'msonnabaum' https://www.drupal.org/u/msonnabaum
CKEditor
- Wim Leers 'Wim Leers' https://www.drupal.org/u/wim-leers
@@ -130,13 +128,11 @@ Comment
- Andrey Postnikov 'andypost' https://www.drupal.org/u/andypost
Configuration API
-- Daniel F. Kudwien 'sun' https://www.drupal.org/u/sun
- Alex Pott 'alexpott' https://www.drupal.org/u/alexpott
- Matthew Tift 'mtift' https://www.drupal.org/u/mtift
Configuration Entity API
- Alex Pott 'alexpott' https://www.drupal.org/u/alexpott
-- Daniel F. Kudwien 'sun' https://www.drupal.org/u/sun
- Tim Plunkett 'tim.plunkett' https://www.drupal.org/u/tim.plunkett
Configuration UI
@@ -159,10 +155,10 @@ Content Translation
- Francesco Placella 'plach' https://www.drupal.org/u/plach
Contextual
-- Daniel F. Kudwien 'sun' https://www.drupal.org/u/sun
+- ?
Cron
-- Derek Wright 'dww' https://www.drupal.org/u/dww
+- ?
CSS
- John Albin Wilkins 'JohnAlbin' https://www.drupal.org/u/johnalbin
@@ -175,14 +171,13 @@ Database API
- David Strauss 'David Strauss' https://www.drupal.org/u/david-strauss
PostgreSQL DB driver
- - Damien Tournoud 'damien-tournoud' https://www.drupal.org/u/damien-tournoud
- - Josh Waihi 'fiasco' https://www.drupal.org/u/fiasco
+ - ?
Sqlite DB driver
- - Damien Tournoud 'damien-tournoud' https://www.drupal.org/u/damien-tournoud
+ - ?
Database Logging
-- Khalid Baheyeldin 'kbahey' https://www.drupal.org/u/kbahey
+- ?
Database Update API
- ?
@@ -203,7 +198,6 @@ Editor
- Wim Leers 'Wim Leers' https://www.drupal.org/u/wim-leers
Entity API
-- Wolfgang Ziegler 'fago' https://www.drupal.org/u/fago
- Nathaniel Catchpole 'catch' https://www.drupal.org/u/catch
- Sascha Grossenbacher 'Berdir' https://www.drupal.org/u/berdir
- Francesco Placella 'plach' https://www.drupal.org/u/plach
@@ -213,7 +207,6 @@ Extension API
- ?
Field API
-- Yves Chedemois 'yched' https://www.drupal.org/u/yched
- Andrei Mateescu 'amateescu' https://www.drupal.org/u/amateescu
Field UI
@@ -221,19 +214,16 @@ Field UI
- Andrei Mateescu 'amateescu' https://www.drupal.org/u/amateescu
File
-- Andrew Morton 'drewish' https://www.drupal.org/u/drewish
-- Aaron Winborn 'aaron' https://www.drupal.org/u/aaron
+- ?
Filter
-- Daniel F. Kudwien 'sun' https://www.drupal.org/u/sun
+- ?
Forum
- Lee Rowlands 'larowlan' https://www.drupal.org/u/larowlan
Form API
- Alex Bronstein 'effulgentsia' https://www.drupal.org/u/effulgentsia
-- Wolfgang Ziegler 'fago' https://www.drupal.org/u/fago
-- Daniel F. Kudwien 'sun' https://www.drupal.org/u/sun
- Tim Plunkett 'tim.plunkett' https://www.drupal.org/u/tim.plunkett
History
@@ -266,23 +256,25 @@ Link Field
- Weber Macedo 'Mac_Weber' https://www.drupal.org/u/mac_weber
Lock
-- Damien Tournoud 'damien-tournoud' https://www.drupal.org/u/damien-tournoud
+- ?
Mail
- ?
Markup
-- Daniel F. Kudwien 'sun' https://www.drupal.org/u/sun
+- ?
Migrate
- Adam Globus-Hoenich 'phenaproxima' https://www.drupal.org/u/phenaproxima
- Ben Dougherty 'benjy' https://www.drupal.org/u/benjy
+- Lucas Hedding 'heddn' https://www.drupal.org/u/heddn
- Michael Anello 'ultimike' https://www.drupal.org/u/ultimike
- Mike Ryan 'mikeryan' https://www.drupal.org/u/mikeryan
- Vicki Spagnolo 'quietone' https://www.drupal.org/u/quietone
Migrate (Drupal)
- Ben Dougherty 'benjy' https://www.drupal.org/u/benjy
+- Lucas Hedding 'heddn' https://www.drupal.org/u/heddn
- Michael Anello 'ultimike' https://www.drupal.org/u/ultimike
- Mike Ryan 'mikeryan' https://www.drupal.org/u/mikeryan
- Vicki Spagnolo 'quietone' https://www.drupal.org/u/quietone
@@ -299,16 +291,15 @@ Menu UI
- ?
Node
-- Moshe Weitzman 'moshe weitzman' https://www.drupal.org/u/moshe-weitzman
-- David Strauss 'David Strauss' https://www.drupal.org/u/david-strauss
+- ?
Node Access
-- Moshe Weitzman 'moshe weitzman' https://www.drupal.org/u/moshe-weitzman
- Ken Rickard 'agentrickard' https://www.drupal.org/u/agentrickard
+- Moshe Weitzman 'moshe weitzman' https://www.drupal.org/u/moshe-weitzman
- Jess Myrbo 'xjm' https://www.drupal.org/u/xjm
Options
-- Yves Chedemois 'yched' https://www.drupal.org/u/yched
+- ?
Outside In
- Ted Bowman 'tedbow' https://www.drupal.org/u/tedbow
@@ -327,7 +318,6 @@ Plugin
Queue
- James Gilliland 'neclimdul' https://www.drupal.org/u/neclimdul
-- Mark Sonnabaum 'msonnabaum' https://www.drupal.org/u/msonnabaum
Quick Edit
- Wim Leers 'Wim Leers' https://www.drupal.org/u/wim-leers
@@ -337,8 +327,8 @@ RDF
- Stéphane Corlosquet 'scor' https://www.drupal.org/u/scor
Render API
-- Moshe Weitzman 'moshe weitzman' https://www.drupal.org/u/moshe-weitzman
- Alex Bronstein 'effulgentsia' https://www.drupal.org/u/effulgentsia
+- Moshe Weitzman 'moshe weitzman' https://www.drupal.org/u/moshe-weitzman
Request Processing
- Larry Garfield 'Crell' https://www.drupal.org/u/crell
@@ -388,10 +378,9 @@ System (module)
Taxonomy
- Jess Myrbo 'xjm' https://www.drupal.org/u/xjm
- Nathaniel Catchpole 'catch' https://www.drupal.org/u/catch
-- Benjamin Doherty 'bangpound' https://www.drupal.org/u/bangpound
Telephone
-- Dave Reid 'dave-reid' https://www.drupal.org/u/dave-reid
+- ?
Testing framework
- Alex Pott 'alexpott' https://www.drupal.org/u/alexpott
@@ -409,7 +398,7 @@ Theme API
- Lauri Eskola 'lauriii' https://www.drupal.org/u/lauriii
Token
-- Dave Reid 'davereid' https://www.drupal.org/u/davereid
+- ?
Toolbar
- Théodore Biadala 'nod_' https://www.drupal.org/u/nod_
@@ -418,22 +407,19 @@ Tour
- Nick Schuch 'nick_schuch' https://www.drupal.org/u/nick_schuch
Tracker
-- David Strauss 'David Strauss' https://www.drupal.org/u/david-strauss
+- ?
Transliteration
- Andrei Mateescu 'amateescu' https://www.drupal.org/u/amateescu
-- Damien Tournoud 'damien-tournoud' https://www.drupal.org/u/damien-tournoud
-- Daniel F. Kudwien 'sun' https://www.drupal.org/u/sun
Typed Data
- Wolfgang Ziegler 'fago' https://www.drupal.org/u/fago
Update UI
-- Derek Wright 'dww' https://www.drupal.org/u/dww
+- ?
User
- Moshe Weitzman 'moshe weitzman' https://www.drupal.org/u/moshe-weitzman
-- David Strauss 'David Strauss' https://www.drupal.org/u/david-strauss
Views
- Daniel Wehner 'dawehner' https://www.drupal.org/u/dawehner
@@ -442,18 +428,11 @@ Views
- Jess Myrbo 'xjm' https://www.drupal.org/u/xjm
- Len Swaneveld 'Lendude' https://www.drupal.org/u/lendude
-Views UI
-- Daniel Wehner 'dawehner' https://www.drupal.org/u/dawehner
-- Tim Plunkett 'tim.plunkett' https://www.drupal.org/u/tim.plunkett
-- Damian Lee 'damiankloip' https://www.drupal.org/u/damiankloip
-- Len Swaneveld 'Lendude' https://www.drupal.org/u/lendude
-
Topic maintainers
-----------------
Accessibility
- Mike Gifford 'mgifford' https://www.drupal.org/u/mgifford
-- Jesse Renée Beach 'jessebeach' https://www.drupal.org/u/jessebeach
- Andrew Macpherson 'andrewmacpherson' https://www.drupal.org/u/andrewmacpherson
Documentation
@@ -492,24 +471,16 @@ re-architect or otherwise improve large areas of Drupal core. See
https://www.drupal.org/community-initiatives/drupal-core for more information on
their responsibilities. The initiative coordinators for Drupal 8 are:
-Configuration management
-- Greg Dunlap 'heyrocker' https://www.drupal.org/u/heyrocker
-
-Design
-- Jeff Burns 'Jeff Burnz' https://www.drupal.org/u/jeff-burnz
-
-Mobile
-- John Albin Wilkins 'JohnAlbin' https://www.drupal.org/u/johnalbin
-
Multi-lingual
- Gábor Hojtsy 'Gábor Hojtsy' https://www.drupal.org/u/gábor-hojtsy
-Web services
-- Larry Garfield 'Crell' https://www.drupal.org/u/crell
-
Workflow Initiative
- Dick Olsson 'dixon_' https://www.drupal.org/u/dixon_
+PHPUnit Initiative
+- Klaus Purer 'klausi' https://www.drupal.org/u/klausi
+- Daniel Wehner 'dawehner' https://www.drupal.org/u/dawehner
+
Provisional membership: None at this time.
diff --git a/core/composer.json b/core/composer.json
index 53ab8fa68..b9a3fad8b 100644
--- a/core/composer.json
+++ b/core/composer.json
@@ -31,7 +31,7 @@
"symfony/psr-http-message-bridge": "v0.2",
"zendframework/zend-diactoros": "~1.1",
"composer/semver": "~1.0",
- "paragonie/random_compat": "~1.0",
+ "paragonie/random_compat": "^1|^2",
"asm89/stack-cors": "~1.0"
},
"require-dev": {
diff --git a/core/core.api.php b/core/core.api.php
index 639e55dd9..eb16ee098 100644
--- a/core/core.api.php
+++ b/core/core.api.php
@@ -1073,8 +1073,9 @@
* yourmodule/tests/src/Unit directory, according to the PSR-4 standard.
* - Your test class needs a phpDoc comment block with a description and
* a @group annotation, which gives information about the test.
- * - Methods in your test class whose names start with 'test' are the actual
- * test cases. Each one should test a logical subset of the functionality.
+ * - Add test cases by adding method names that start with 'test' and have no
+ * arguments, for example testYourTestCase(). Each one should test a logical
+ * subset of the functionality.
* For more details, see:
* - https://www.drupal.org/phpunit for full documentation on how to write
* PHPUnit tests for Drupal.
@@ -1110,9 +1111,9 @@
* set up content types and similar procedures.
* - In some cases, you may need to write a test module to support your test;
* put such modules under the yourmodule/tests/modules directory.
- * - Methods in your test class whose names start with 'test', and which have
- * no arguments, are the actual test cases. Each one should test a logical
- * subset of the functionality, and each one runs in a new, isolated test
+ * - Add test cases by adding method names that start with 'test' and have no
+ * arguments, for example testYourTestCase(). Each one should test a logical
+ * subset of the functionality. Each method runs in a new, isolated test
* environment, so it can only rely on the setUp() method, not what has
* been set up by other test methods.
* For more details, see:
@@ -1121,6 +1122,52 @@
* - @link oo_conventions Object-oriented programming topic @endlink for more
* on PSR-4, namespaces, and where to place classes.
*
+ * @section write_functional_phpunit Write functional PHP tests (phpunit)
+ * Functional tests extend the BrowserTestBase base class, and use PHPUnit as
+ * their underlying framework. They use a simulated browser, in which the test
+ * can click links, visit URLs, post to forms, etc. To write a functional test:
+ * - Extend \Drupal\Tests\BrowserTestBase.
+ * - Place the test in the yourmodule/tests/src/Functional/ directory and use
+ * the \Drupal\Tests\yourmodule\Functional namespace.
+ * - Add a @group annotation. For example, if the test is for a Drupal 6
+ * migration process, the group core uses is migrate_drupal_6. Use yourmodule
+ * as the group name if the test does not belong to another larger group.
+ * - You may also override the default setUp() method, which can be used to set
+ * up content types and similar procedures. Don't forget to call the parent
+ * method.
+ * - In some cases, you may need to write a test module to support your test;
+ * put such modules under the yourmodule/tests/modules directory.
+ * - Add test cases by adding method names that start with 'test' and have no
+ * arguments, for example testYourTestCase(). Each one should test a logical
+ * subset of the functionality. Each method runs in a new, isolated test
+ * environment, so it can only rely on the setUp() method, not what has
+ * been set up by other test methods.
+ * For more details, see:
+ * - https://www.drupal.org/docs/8/phpunit/phpunit-browser-test-tutorial for
+ * a full tutorial on how to write functional PHPUnit tests for Drupal.
+ * - https://www.drupal.org/phpunit for the full documentation on how to write
+ * PHPUnit tests for Drupal.
+ *
+ * @section write_jsfunctional_phpunit Write functional JavaScript tests (phpunit)
+ * To write a functional test that relies on JavaScript:
+ * - Extend \Drupal\FunctionalJavaScriptTests\JavascriptTestBase.
+ * - Place the test into the yourmodule/tests/src/FunctionalJavascript/
+ * directory and use the \Drupal\Tests\yourmodule\FunctionalJavascript
+ * namespace.
+ * - Add a @group annotation. Use yourmodule as the group name if the test does
+ * not belong to another larger group.
+ * - Set up PhantomJS; see http://phantomjs.org/download.html.
+ * - To run tests, see core/tests/README.md.
+ * - When clicking a link/button with Ajax behavior attached, keep in mind that
+ * the underlying browser might take time to deliver changes to the HTML. Use
+ * $this->assertSession()->assertWaitOnAjaxRequest() to wait for the Ajax
+ * request to finish.
+ * For more details, see:
+ * - https://www.drupal.org/docs/8/phpunit/phpunit-javascript-testing-tutorial
+ * for a full tutorial on how to write PHPUnit JavaScript tests for Drupal.
+ * - https://www.drupal.org/phpunit for the full documentation on how to write
+ * PHPUnit tests for Drupal.
+ *
* @section running Running tests
* You can run both Simpletest and PHPUnit tests by enabling the core Testing
* module (core/modules/simpletest). Once that module is enabled, tests can be
@@ -2493,7 +2540,7 @@ function hook_validation_constraint_alter(array &$definitions) {
* this class is subscribed to, and which methods on the class should be
* called for each one. Example:
* @code
- * public function getSubscribedEvents() {
+ * public static function getSubscribedEvents() {
* // Subscribe to kernel terminate with priority 100.
* $events[KernelEvents::TERMINATE][] = array('onTerminate', 100);
* // Subscribe to kernel request with default priority of 0.
diff --git a/core/includes/entity.inc b/core/includes/entity.inc
index b0e5088f9..8b4eb22f0 100644
--- a/core/includes/entity.inc
+++ b/core/includes/entity.inc
@@ -539,12 +539,12 @@ function entity_get_display($entity_type, $bundle, $view_mode) {
* When the entity form display is not available in configuration, you can
* create a new EntityFormDisplay object using:
* @code
- * $values = ('entity_form_display', array(
+ * $values = array(
* 'targetEntityType' => $entity_type,
* 'bundle' => $bundle,
* 'mode' => $form_mode,
* 'status' => TRUE,
- * ));
+ * );
* \Drupal::entityTypeManager()
* ->getStorage('entity_form_display')
* ->create($values);
diff --git a/core/lib/Drupal.php b/core/lib/Drupal.php
index 0d961c12f..1e0da8eb8 100644
--- a/core/lib/Drupal.php
+++ b/core/lib/Drupal.php
@@ -81,7 +81,7 @@ class Drupal {
/**
* The current system version.
*/
- const VERSION = '8.2.3';
+ const VERSION = '8.2.4';
/**
* Core API compatibility.
diff --git a/core/lib/Drupal/Component/Diff/DiffFormatter.php b/core/lib/Drupal/Component/Diff/DiffFormatter.php
index ce08b004d..edcb84df7 100644
--- a/core/lib/Drupal/Component/Diff/DiffFormatter.php
+++ b/core/lib/Drupal/Component/Diff/DiffFormatter.php
@@ -36,6 +36,16 @@ class DiffFormatter {
*/
public $trailing_context_lines = 0;
+ /**
+ * The line stats.
+ *
+ * @var array
+ */
+ protected $line_stats = array(
+ 'counter' => array('x' => 0, 'y' => 0),
+ 'offset' => array('x' => 0, 'y' => 0),
+ );
+
/**
* Format a diff.
*
diff --git a/core/lib/Drupal/Core/Access/CsrfAccessCheck.php b/core/lib/Drupal/Core/Access/CsrfAccessCheck.php
index c72b116fa..753a00899 100644
--- a/core/lib/Drupal/Core/Access/CsrfAccessCheck.php
+++ b/core/lib/Drupal/Core/Access/CsrfAccessCheck.php
@@ -54,7 +54,7 @@ class CsrfAccessCheck implements RoutingAccessInterface {
$path = str_replace("{{$param}}", $value, $path);
}
- if ($this->csrfToken->validate($request->query->get('token'), $path)) {
+ if ($this->csrfToken->validate($request->query->get('token', ''), $path)) {
$result = AccessResult::allowed();
}
else {
diff --git a/core/lib/Drupal/Core/Access/CsrfTokenGenerator.php b/core/lib/Drupal/Core/Access/CsrfTokenGenerator.php
index 23d610ce9..4fd215e38 100644
--- a/core/lib/Drupal/Core/Access/CsrfTokenGenerator.php
+++ b/core/lib/Drupal/Core/Access/CsrfTokenGenerator.php
@@ -87,7 +87,7 @@ class CsrfTokenGenerator {
return FALSE;
}
- return $token === $this->computeToken($seed, $value);
+ return Crypt::hashEquals($this->computeToken($seed, $value), $token);
}
/**
diff --git a/core/lib/Drupal/Core/Config/Entity/DraggableListBuilder.php b/core/lib/Drupal/Core/Config/Entity/DraggableListBuilder.php
index dc0ac923d..3aed1ece8 100644
--- a/core/lib/Drupal/Core/Config/Entity/DraggableListBuilder.php
+++ b/core/lib/Drupal/Core/Config/Entity/DraggableListBuilder.php
@@ -34,6 +34,11 @@ abstract class DraggableListBuilder extends ConfigEntityListBuilder implements F
*/
protected $weightKey = FALSE;
+ /**
+ * {@inheritdoc}
+ */
+ protected $limit = FALSE;
+
/**
* The form builder.
*
diff --git a/core/lib/Drupal/Core/Diff/DiffFormatter.php b/core/lib/Drupal/Core/Diff/DiffFormatter.php
index 52f289491..8ebe2f479 100644
--- a/core/lib/Drupal/Core/Diff/DiffFormatter.php
+++ b/core/lib/Drupal/Core/Diff/DiffFormatter.php
@@ -19,16 +19,6 @@ class DiffFormatter extends DiffFormatterBase {
*/
protected $rows = array();
- /**
- * The line stats.
- *
- * @var array
- */
- protected $line_stats = array(
- 'counter' => array('x' => 0, 'y' => 0),
- 'offset' => array('x' => 0, 'y' => 0),
- );
-
/**
* Creates a DiffFormatter to render diffs in a table.
*
diff --git a/core/lib/Drupal/Core/Entity/Element/EntityAutocomplete.php b/core/lib/Drupal/Core/Entity/Element/EntityAutocomplete.php
index 51adf91b7..9c3e705bd 100644
--- a/core/lib/Drupal/Core/Entity/Element/EntityAutocomplete.php
+++ b/core/lib/Drupal/Core/Entity/Element/EntityAutocomplete.php
@@ -348,13 +348,10 @@ class EntityAutocomplete extends Textfield {
public static function extractEntityIdFromAutocompleteInput($input) {
$match = NULL;
- // Take "label (entity id)', match the ID from parenthesis when it's a
- // number.
- if (preg_match("/.+\s\((\d+)\)/", $input, $matches)) {
- $match = $matches[1];
- }
- // Match the ID when it's a string (e.g. for config entity types).
- elseif (preg_match("/.+\s\(([\w.]+)\)/", $input, $matches)) {
+ // Take "label (entity id)', match the ID from inside the parentheses.
+ // @todo Add support for entities containing parentheses in their ID.
+ // @see https://www.drupal.org/node/2520416
+ if (preg_match("/.+\s\(([^\)]+)\)/", $input, $matches)) {
$match = $matches[1];
}
diff --git a/core/lib/Drupal/Core/Entity/EntityDisplayBase.php b/core/lib/Drupal/Core/Entity/EntityDisplayBase.php
index 4de891a82..f8683e3da 100644
--- a/core/lib/Drupal/Core/Entity/EntityDisplayBase.php
+++ b/core/lib/Drupal/Core/Entity/EntityDisplayBase.php
@@ -94,7 +94,7 @@ abstract class EntityDisplayBase extends ConfigEntityBase implements EntityDispl
protected $plugins = array();
/**
- * Context in which this entity will be used (e.g. 'display', 'form').
+ * Context in which this entity will be used (e.g. 'view', 'form').
*
* @var string
*/
diff --git a/core/lib/Drupal/Core/Entity/EntityViewBuilder.php b/core/lib/Drupal/Core/Entity/EntityViewBuilder.php
index 8bfb3a3e2..7097b85df 100644
--- a/core/lib/Drupal/Core/Entity/EntityViewBuilder.php
+++ b/core/lib/Drupal/Core/Entity/EntityViewBuilder.php
@@ -9,6 +9,7 @@ use Drupal\Core\Field\FieldItemInterface;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Language\LanguageManagerInterface;
use Drupal\Core\Render\Element;
+use Drupal\Core\Theme\Registry;
use Drupal\Core\TypedData\TranslatableInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
@@ -54,6 +55,13 @@ class EntityViewBuilder extends EntityHandlerBase implements EntityHandlerInterf
*/
protected $languageManager;
+ /**
+ * The theme registry.
+ *
+ * @var \Drupal\Core\Theme\Registry
+ */
+ protected $themeRegistry;
+
/**
* The EntityViewDisplay objects created for individual field rendering.
*
@@ -72,12 +80,15 @@ class EntityViewBuilder extends EntityHandlerBase implements EntityHandlerInterf
* The entity manager service.
* @param \Drupal\Core\Language\LanguageManagerInterface $language_manager
* The language manager.
+ * @param \Drupal\Core\Theme\Registry $theme_registry
+ * The theme registry.
*/
- public function __construct(EntityTypeInterface $entity_type, EntityManagerInterface $entity_manager, LanguageManagerInterface $language_manager) {
+ public function __construct(EntityTypeInterface $entity_type, EntityManagerInterface $entity_manager, LanguageManagerInterface $language_manager, Registry $theme_registry = NULL) {
$this->entityTypeId = $entity_type->id();
$this->entityType = $entity_type;
$this->entityManager = $entity_manager;
$this->languageManager = $language_manager;
+ $this->themeRegistry = $theme_registry ?: \Drupal::service('theme.registry');
}
/**
@@ -87,7 +98,8 @@ class EntityViewBuilder extends EntityHandlerBase implements EntityHandlerInterf
return new static(
$entity_type,
$container->get('entity.manager'),
- $container->get('language_manager')
+ $container->get('language_manager'),
+ $container->get('theme.registry')
);
}
@@ -148,7 +160,6 @@ class EntityViewBuilder extends EntityHandlerBase implements EntityHandlerInterf
$this->moduleHandler()->alter('entity_view_mode', $view_mode, $entity, $context);
$build = array(
- '#theme' => $this->entityTypeId,
"#{$this->entityTypeId}" => $entity,
'#view_mode' => $view_mode,
// Collect cache defaults for this entity.
@@ -159,6 +170,11 @@ class EntityViewBuilder extends EntityHandlerBase implements EntityHandlerInterf
),
);
+ // Add the default #theme key if a template exists for it.
+ if ($this->themeRegistry->getRuntime()->has($this->entityTypeId)) {
+ $build['#theme'] = $this->entityTypeId;
+ }
+
// Cache the rendered output if permitted by the view mode and global entity
// type configuration.
if ($this->isViewModeCacheable($view_mode) && !$entity->isNew() && $entity->isDefaultRevision() && $this->entityType->isRenderCacheable()) {
diff --git a/core/lib/Drupal/Core/Entity/Query/QueryInterface.php b/core/lib/Drupal/Core/Entity/Query/QueryInterface.php
index 630d17673..9c05dfa4d 100644
--- a/core/lib/Drupal/Core/Entity/Query/QueryInterface.php
+++ b/core/lib/Drupal/Core/Entity/Query/QueryInterface.php
@@ -35,13 +35,18 @@ interface QueryInterface extends AlterableInterface {
*
* @param $field
* Name of the field being queried. It must contain a field name, optionally
- * followed by a column name. The column can be "entity" for reference
- * fields and that can be followed similarly by a field name and so on. Some
- * examples:
+ * followed by a column name. The column can be the reference property,
+ * usually "entity", for reference fields and that can be followed
+ * similarly by a field name and so on. Additionally, the target entity type
+ * can be specified by appending the ":target_entity_type_id" to "entity".
+ * Some examples:
* - nid
* - tags.value
* - tags
+ * - tags.entity.name
+ * - tags.entity:taxonomy_term.name
* - uid.entity.name
+ * - uid.entity:user.name
* "tags" "is the same as "tags.value" as value is the default column.
* If two or more conditions have the same field names they apply to the
* same delta within that field. In order to limit the condition to a
diff --git a/core/lib/Drupal/Core/Entity/Query/Sql/Tables.php b/core/lib/Drupal/Core/Entity/Query/Sql/Tables.php
index c8bf59d15..1a1509cc4 100644
--- a/core/lib/Drupal/Core/Entity/Query/Sql/Tables.php
+++ b/core/lib/Drupal/Core/Entity/Query/Sql/Tables.php
@@ -6,6 +6,8 @@ use Drupal\Core\Database\Query\SelectInterface;
use Drupal\Core\Entity\Query\QueryException;
use Drupal\Core\Entity\Sql\SqlEntityStorageInterface;
use Drupal\Core\Entity\Sql\TableMappingInterface;
+use Drupal\Core\Entity\TypedData\EntityDataDefinitionInterface;
+use Drupal\Core\TypedData\DataReferenceDefinitionInterface;
/**
* Adds tables and fields to the SQL entity query.
@@ -253,10 +255,20 @@ class Tables implements TablesInterface {
$relationship_specifier = $specifiers[$key + 1];
$next_index_prefix = $relationship_specifier;
}
+ $entity_type_id = NULL;
+ // Relationship specifier can also contain the entity type ID, i.e.
+ // entity:node, entity:user or entity:taxonomy.
+ if (strpos($relationship_specifier, ':') !== FALSE) {
+ list($relationship_specifier, $entity_type_id) = explode(':', $relationship_specifier, 2);
+ }
// Check for a valid relationship.
- if (isset($propertyDefinitions[$relationship_specifier]) && $field_storage->getPropertyDefinition('entity')->getDataType() == 'entity_reference' ) {
- // If it is, use the entity type.
- $entity_type_id = $propertyDefinitions[$relationship_specifier]->getTargetDefinition()->getEntityTypeId();
+ if (isset($propertyDefinitions[$relationship_specifier]) && $propertyDefinitions[$relationship_specifier] instanceof DataReferenceDefinitionInterface) {
+ // If it is, use the entity type if specified already, otherwise use
+ // the definition.
+ $target_definition = $propertyDefinitions[$relationship_specifier]->getTargetDefinition();
+ if (!$entity_type_id && $target_definition instanceof EntityDataDefinitionInterface) {
+ $entity_type_id = $target_definition->getEntityTypeId();
+ }
$entity_type = $this->entityManager->getDefinition($entity_type_id);
$field_storage_definitions = $this->entityManager->getFieldStorageDefinitions($entity_type_id);
// Add the new entity base table using the table and sql column.
diff --git a/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php b/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php
index 2ea450d73..d4945cf3f 100644
--- a/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php
+++ b/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php
@@ -1257,7 +1257,11 @@ class SqlContentEntityStorage extends ContentEntityStorageBase implements SqlEnt
foreach ($storage_definition->getColumns() as $column => $attributes) {
$column_name = $table_mapping->getFieldColumnName($storage_definition, $column);
// Serialize the value if specified in the column schema.
- $record[$column_name] = !empty($attributes['serialize']) ? serialize($item->$column) : $item->$column;
+ $value = $item->$column;
+ if (!empty($attributes['serialize'])) {
+ $value = serialize($value);
+ }
+ $record[$column_name] = drupal_schema_get_field_value($attributes, $value);
}
$query->values($record);
if ($this->entityType->isRevisionable()) {
diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/EntityReferenceEntityFormatter.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/EntityReferenceEntityFormatter.php
index fa83359c0..2692d84e1 100644
--- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/EntityReferenceEntityFormatter.php
+++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/EntityReferenceEntityFormatter.php
@@ -168,6 +168,10 @@ class EntityReferenceEntityFormatter extends EntityReferenceFormatterBase implem
$recursive_render_id = $items->getFieldDefinition()->getTargetEntityTypeId()
. $items->getFieldDefinition()->getTargetBundle()
. $items->getName()
+ // We include the referencing entity, so we can render default images
+ // without hitting recursive protections.
+ . $items->getEntity()->id()
+ . $entity->getEntityTypeId()
. $entity->id();
if (isset(static::$recursiveRenderDepth[$recursive_render_id])) {
diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/UuidItem.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/UuidItem.php
index 94aa8aae7..8bd33ce44 100644
--- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/UuidItem.php
+++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/UuidItem.php
@@ -3,6 +3,7 @@
namespace Drupal\Core\Field\Plugin\Field\FieldType;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
+use Drupal\Core\Field\FieldDefinitionInterface;
/**
* Defines the 'uuid' entity field type.
@@ -48,4 +49,12 @@ class UuidItem extends StringItem {
return $schema;
}
+ /**
+ * {@inheritdoc}
+ */
+ public static function generateSampleValue(FieldDefinitionInterface $field_definition) {
+ $values['value'] = \Drupal::service('uuid')->generate();
+ return $values;
+ }
+
}
diff --git a/core/lib/Drupal/Core/Field/WidgetBase.php b/core/lib/Drupal/Core/Field/WidgetBase.php
index 5f7ce3c14..3d0db4ce4 100644
--- a/core/lib/Drupal/Core/Field/WidgetBase.php
+++ b/core/lib/Drupal/Core/Field/WidgetBase.php
@@ -36,7 +36,7 @@ abstract class WidgetBase extends PluginSettingsBase implements WidgetInterface
/**
* Constructs a WidgetBase object.
*
- * @param array $plugin_id
+ * @param string $plugin_id
* The plugin_id for the widget.
* @param mixed $plugin_definition
* The plugin implementation definition.
diff --git a/core/lib/Drupal/Core/Language/LanguageManager.php b/core/lib/Drupal/Core/Language/LanguageManager.php
index 9016d1e45..ef5421713 100644
--- a/core/lib/Drupal/Core/Language/LanguageManager.php
+++ b/core/lib/Drupal/Core/Language/LanguageManager.php
@@ -318,7 +318,7 @@ class LanguageManager implements LanguageManagerInterface {
'th' => array('Thai', 'ภาษาไทย'),
'tr' => array('Turkish', 'Türkçe'),
'tyv' => array('Tuvan', 'Тыва дыл'),
- 'ug' => array('Uyghur', 'Уйғур'),
+ 'ug' => array('Uyghur', /* Left-to-right marker "" */ 'ئۇيغۇرچە', LanguageInterface::DIRECTION_RTL),
'uk' => array('Ukrainian', 'Українська'),
'ur' => array('Urdu', /* Left-to-right marker "" */ 'اردو', LanguageInterface::DIRECTION_RTL),
'vi' => array('Vietnamese', 'Tiếng Việt'),
diff --git a/core/lib/Drupal/Core/Plugin/Context/ContextDefinition.php b/core/lib/Drupal/Core/Plugin/Context/ContextDefinition.php
index 71cfaa104..1c252e296 100644
--- a/core/lib/Drupal/Core/Plugin/Context/ContextDefinition.php
+++ b/core/lib/Drupal/Core/Plugin/Context/ContextDefinition.php
@@ -2,6 +2,7 @@
namespace Drupal\Core\Plugin\Context;
+use Drupal\Core\DependencyInjection\DependencySerializationTrait;
use Drupal\Core\TypedData\TypedDataTrait;
/**
@@ -9,6 +10,8 @@ use Drupal\Core\TypedData\TypedDataTrait;
*/
class ContextDefinition implements ContextDefinitionInterface {
+ use DependencySerializationTrait;
+
use TypedDataTrait;
/**
diff --git a/core/lib/Drupal/Core/Render/HtmlResponseAttachmentsProcessor.php b/core/lib/Drupal/Core/Render/HtmlResponseAttachmentsProcessor.php
index 2f9aeb366..358b1f1b7 100644
--- a/core/lib/Drupal/Core/Render/HtmlResponseAttachmentsProcessor.php
+++ b/core/lib/Drupal/Core/Render/HtmlResponseAttachmentsProcessor.php
@@ -419,9 +419,13 @@ class HtmlResponseAttachmentsProcessor implements AttachmentsResponseProcessorIn
if ($should_add_header) {
// Also add a HTTP header "Link:".
- $href = '<' . Html::escape($attributes['href'] . '>');
+ $href = '<' . Html::escape($attributes['href']) . '>';
unset($attributes['href']);
- $attached['http_header'][] = ['Link', $href . drupal_http_header_attributes($attributes), TRUE];
+ if ($param = drupal_http_header_attributes($attributes)) {
+ $href .= ';' . $param;
+ }
+
+ $attached['http_header'][] = ['Link', $href, FALSE];
}
}
return $attached;
diff --git a/core/lib/Drupal/Core/StringTranslation/Translator/CustomStrings.php b/core/lib/Drupal/Core/StringTranslation/Translator/CustomStrings.php
index 9d9a3b326..8e733d548 100644
--- a/core/lib/Drupal/Core/StringTranslation/Translator/CustomStrings.php
+++ b/core/lib/Drupal/Core/StringTranslation/Translator/CustomStrings.php
@@ -3,6 +3,7 @@
namespace Drupal\Core\StringTranslation\Translator;
use Drupal\Core\Site\Settings;
+use Drupal\Core\DependencyInjection\DependencySerializationTrait;
/**
* String translator using overrides from variables.
@@ -12,6 +13,8 @@ use Drupal\Core\Site\Settings;
*/
class CustomStrings extends StaticTranslation {
+ use DependencySerializationTrait;
+
/**
* The settings read only object.
*
diff --git a/core/misc/autocomplete.js b/core/misc/autocomplete.js
index 254e7e509..5a1c156d0 100644
--- a/core/misc/autocomplete.js
+++ b/core/misc/autocomplete.js
@@ -77,6 +77,11 @@
*/
function searchHandler(event) {
var options = autocomplete.options;
+
+ if (options.isComposing) {
+ return false;
+ }
+
var term = autocomplete.extractLastTerm(event.target.value);
// Abort search if the first character is in firstCharacterBlacklist.
if (term.length > 0 && options.firstCharacterBlacklist.indexOf(term[0]) !== -1) {
@@ -225,6 +230,14 @@
.each(function () {
$(this).data('ui-autocomplete')._renderItem = autocomplete.options.renderItem;
});
+
+ // Use CompositionEvent to handle IME inputs. It requests remote server on "compositionend" event only.
+ $autocomplete.on('compositionstart.autocomplete', function () {
+ autocomplete.options.isComposing = true;
+ });
+ $autocomplete.on('compositionend.autocomplete', function () {
+ autocomplete.options.isComposing = false;
+ });
}
},
detach: function (context, settings, trigger) {
@@ -261,7 +274,9 @@
renderItem: renderItem,
minLength: 1,
// Custom options, used by Drupal.autocomplete.
- firstCharacterBlacklist: ''
+ firstCharacterBlacklist: '',
+ // Custom options, indicate IME usage status.
+ isComposing: false
},
ajax: {
dataType: 'json'
diff --git a/core/modules/block/block.api.php b/core/modules/block/block.api.php
index 2d61bb004..4c7faf598 100644
--- a/core/modules/block/block.api.php
+++ b/core/modules/block/block.api.php
@@ -151,7 +151,7 @@ function hook_block_view_BASE_BLOCK_ID_alter(array &$build, \Drupal\Core\Block\B
function hook_block_build_alter(array &$build, \Drupal\Core\Block\BlockPluginInterface $block) {
// Add the 'user' cache context to some blocks.
if ($some_condition) {
- $build['#contexts'][] = 'user';
+ $build['#cache']['contexts'][] = 'user';
}
}
diff --git a/core/modules/book/tests/src/FunctionalJavascript/BookJavascriptTest.php b/core/modules/book/tests/src/FunctionalJavascript/BookJavascriptTest.php
index e895b6824..d8d406b44 100644
--- a/core/modules/book/tests/src/FunctionalJavascript/BookJavascriptTest.php
+++ b/core/modules/book/tests/src/FunctionalJavascript/BookJavascriptTest.php
@@ -73,7 +73,7 @@ class BookJavascriptTest extends JavascriptTestBase {
$dragged->dragTo($target);
// Give javascript some time to manipulate the DOM.
- $this->getSession()->wait(1000, 'jQuery(".tabledrag-changed-warning").is(":visible")');
+ $this->assertJsCondition('jQuery(".tabledrag-changed-warning").is(":visible")');
// Check that the 'unsaved changes' text appeared in the message area.
$this->assertSession()->pageTextContains('You have unsaved changes.');
diff --git a/core/modules/ckeditor/src/Plugin/CKEditorPlugin/Language.php b/core/modules/ckeditor/src/Plugin/CKEditorPlugin/Language.php
index 145f74147..980d5e909 100644
--- a/core/modules/ckeditor/src/Plugin/CKEditorPlugin/Language.php
+++ b/core/modules/ckeditor/src/Plugin/CKEditorPlugin/Language.php
@@ -8,7 +8,6 @@ use Drupal\ckeditor\CKEditorPluginCssInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Language\LanguageManager;
use Drupal\Core\Language\LanguageInterface;
-use Drupal\Core\Url;
use Drupal\editor\Entity\Editor;
/**
@@ -115,7 +114,7 @@ class Language extends CKEditorPluginBase implements CKEditorPluginConfigurableI
],
'#default_value' => $config['language_list'],
'#description' => $this->t('The list of languages to show in the language dropdown. The basic list will only show the six official languages of the UN. The extended list will show all @count languages that are available in Drupal.', [
- ':url' => Url::fromUri('http://www.un.org/en/aboutun/languages.shtml/')->toString(),
+ ':url' => 'https://www.un.org/en/sections/about-un/official-languages',
'@count' => count($predefined_languages),
]),
'#attached' => ['library' => ['ckeditor/drupal.ckeditor.language.admin']],
diff --git a/core/modules/comment/migration_templates/d6_comment.yml b/core/modules/comment/migration_templates/d6_comment.yml
index a7ffc9dad..f4dff98e2 100644
--- a/core/modules/comment/migration_templates/d6_comment.yml
+++ b/core/modules/comment/migration_templates/d6_comment.yml
@@ -7,6 +7,8 @@ source:
constants:
entity_type: node
process:
+ # If you are using this file to build a custom migration consider removing
+ # the cid field to allow incremental migrations.
cid: cid
pid:
plugin: migration
diff --git a/core/modules/comment/migration_templates/d6_comment_field.yml b/core/modules/comment/migration_templates/d6_comment_field.yml
index 469d604d0..d14d1aa4f 100644
--- a/core/modules/comment/migration_templates/d6_comment_field.yml
+++ b/core/modules/comment/migration_templates/d6_comment_field.yml
@@ -13,7 +13,10 @@ process:
type: 'constants/type'
'settings/comment_type': comment_type
destination:
- plugin: md_entity:field_storage_config
+ plugin: entity:field_storage_config
+ dependencies:
+ module:
+ - comment
migration_dependencies:
required:
- d6_comment_type
diff --git a/core/modules/comment/migration_templates/d7_comment.yml b/core/modules/comment/migration_templates/d7_comment.yml
index 5845999da..d4e3c57cb 100644
--- a/core/modules/comment/migration_templates/d7_comment.yml
+++ b/core/modules/comment/migration_templates/d7_comment.yml
@@ -7,6 +7,8 @@ source:
constants:
entity_type: node
process:
+ # If you are using this file to build a custom migration consider removing
+ # the cid field to allow incremental migrations.
cid: cid
pid:
plugin: migration
diff --git a/core/modules/comment/src/CommentAccessControlHandler.php b/core/modules/comment/src/CommentAccessControlHandler.php
index ff6b3b96b..fc0d4b2d6 100644
--- a/core/modules/comment/src/CommentAccessControlHandler.php
+++ b/core/modules/comment/src/CommentAccessControlHandler.php
@@ -110,12 +110,13 @@ class CommentAccessControlHandler extends EntityAccessControlHandler {
// access.
return AccessResult::forbidden();
}
+ $is_name = $field_definition->getName() === 'name';
/** @var \Drupal\comment\CommentInterface $entity */
$entity = $items->getEntity();
$commented_entity = $entity->getCommentedEntity();
$anonymous_contact = $commented_entity->get($entity->getFieldName())->getFieldDefinition()->getSetting('anonymous');
$admin_access = AccessResult::allowedIfHasPermission($account, 'administer comments');
- $anonymous_access = AccessResult::allowedIf($entity->isNew() && $account->isAnonymous() && $anonymous_contact != COMMENT_ANONYMOUS_MAYNOT_CONTACT && $account->hasPermission('post comments'))
+ $anonymous_access = AccessResult::allowedIf($entity->isNew() && $account->isAnonymous() && ($anonymous_contact != COMMENT_ANONYMOUS_MAYNOT_CONTACT || $is_name) && $account->hasPermission('post comments'))
->cachePerPermissions()
->addCacheableDependency($entity)
->addCacheableDependency($field_definition->getConfig($commented_entity->bundle()))
diff --git a/core/modules/comment/src/Tests/CommentAnonymousTest.php b/core/modules/comment/src/Tests/CommentAnonymousTest.php
index 660d75406..2a5feb2f1 100644
--- a/core/modules/comment/src/Tests/CommentAnonymousTest.php
+++ b/core/modules/comment/src/Tests/CommentAnonymousTest.php
@@ -65,6 +65,16 @@ class CommentAnonymousTest extends CommentTestBase {
$anonymous_comment1 = $this->postComment($this->node, $this->randomMachineName(), $this->randomMachineName());
$this->assertTrue($this->commentExists($anonymous_comment1), 'Anonymous comment without contact info found.');
+ // Ensure anonymous users cannot post in the name of registered users.
+ $edit = array(
+ 'name' => $this->adminUser->getUsername(),
+ 'comment_body[0][value]' => $this->randomMachineName(),
+ );
+ $this->drupalPostForm('comment/reply/node/' . $this->node->id() . '/comment', $edit, t('Save'));
+ $this->assertRaw(t('The name you used (%name) belongs to a registered user.', [
+ '%name' => $this->adminUser->getUsername(),
+ ]));
+
// Allow contact info.
$this->drupalLogin($this->adminUser);
$this->setCommentAnonymous(COMMENT_ANONYMOUS_MAY_CONTACT);
diff --git a/core/modules/config/tests/src/Functional/ConfigDraggableListBuilderTest.php b/core/modules/config/tests/src/Functional/ConfigDraggableListBuilderTest.php
new file mode 100644
index 000000000..417e9f13c
--- /dev/null
+++ b/core/modules/config/tests/src/Functional/ConfigDraggableListBuilderTest.php
@@ -0,0 +1,49 @@
+drupalLogin($this->drupalCreateUser(array('administer permissions')));
+
+ // Create more than 50 roles.
+ for ($i = 0; $i < 51; $i++) {
+ $role = Role::create([
+ 'id' => 'role_' . $i,
+ 'label' => "Role $i",
+ ]);
+ $role->save();
+ }
+
+ // Navigate to Roles page
+ $this->drupalGet('admin/people/roles');
+
+ // Test for the page title.
+ $this->assertSession()->titleEquals(t('Roles') . ' | Drupal');
+
+ // Count the number of rows in table.
+ $rows = $this->xpath('//form[@class="user-admin-roles-form"]/table/tbody/tr');
+ $this->assertGreaterThan(50, count($rows));
+ for ($i = 0; $i < 51; $i++) {
+ $this->assertSession()->pageTextContains("Role $i");
+ }
+ }
+
+}
diff --git a/core/modules/content_moderation/src/EntityOperations.php b/core/modules/content_moderation/src/EntityOperations.php
index 51ad7d685..d76a35b98 100644
--- a/core/modules/content_moderation/src/EntityOperations.php
+++ b/core/modules/content_moderation/src/EntityOperations.php
@@ -152,7 +152,6 @@ class EntityOperations implements ContainerInjectionInterface {
$entity_type_id = $entity->getEntityTypeId();
$entity_id = $entity->id();
$entity_revision_id = $entity->getRevisionId();
- $entity_langcode = $entity->language()->getId();
$storage = $this->entityTypeManager->getStorage('content_moderation_state');
$entities = $storage->loadByProperties([
@@ -174,11 +173,14 @@ class EntityOperations implements ContainerInjectionInterface {
}
// Sync translations.
- if (!$content_moderation_state->hasTranslation($entity_langcode)) {
- $content_moderation_state->addTranslation($entity_langcode);
- }
- if ($content_moderation_state->language()->getId() !== $entity_langcode) {
- $content_moderation_state = $content_moderation_state->getTranslation($entity_langcode);
+ if ($entity->getEntityType()->hasKey('langcode')) {
+ $entity_langcode = $entity->language()->getId();
+ if (!$content_moderation_state->hasTranslation($entity_langcode)) {
+ $content_moderation_state->addTranslation($entity_langcode);
+ }
+ if ($content_moderation_state->language()->getId() !== $entity_langcode) {
+ $content_moderation_state = $content_moderation_state->getTranslation($entity_langcode);
+ }
}
// Create the ContentModerationState entity for the inserted entity.
diff --git a/core/modules/content_moderation/src/EntityTypeInfo.php b/core/modules/content_moderation/src/EntityTypeInfo.php
index ab7e918e4..047bc23ca 100644
--- a/core/modules/content_moderation/src/EntityTypeInfo.php
+++ b/core/modules/content_moderation/src/EntityTypeInfo.php
@@ -292,8 +292,8 @@ class EntityTypeInfo implements ContainerInjectionInterface {
$fields = [];
$fields['moderation_state'] = BaseFieldDefinition::create('entity_reference')
- ->setLabel(t('Moderation state'))
- ->setDescription(t('The moderation state of this piece of content.'))
+ ->setLabel($this->t('Moderation state'))
+ ->setDescription($this->t('The moderation state of this piece of content.'))
->setComputed(TRUE)
->setClass(ModerationStateFieldItemList::class)
->setSetting('target_type', 'moderation_state')
@@ -310,6 +310,7 @@ class EntityTypeInfo implements ContainerInjectionInterface {
->addConstraint('ModerationState', [])
->setDisplayConfigurable('form', FALSE)
->setDisplayConfigurable('view', FALSE)
+ ->setReadOnly(FALSE)
->setTranslatable(TRUE);
return $fields;
diff --git a/core/modules/content_moderation/src/Plugin/Field/ModerationStateFieldItemList.php b/core/modules/content_moderation/src/Plugin/Field/ModerationStateFieldItemList.php
index 80820b4b4..c32521c44 100644
--- a/core/modules/content_moderation/src/Plugin/Field/ModerationStateFieldItemList.php
+++ b/core/modules/content_moderation/src/Plugin/Field/ModerationStateFieldItemList.php
@@ -43,12 +43,14 @@ class ModerationStateFieldItemList extends EntityReferenceFieldItemList {
->loadRevision($revision_to_load);
// Return the correct translation.
- $langcode = $entity->language()->getId();
- if (!$content_moderation_state->hasTranslation($langcode)) {
- $content_moderation_state->addTranslation($langcode);
- }
- if ($content_moderation_state->language()->getId() !== $langcode) {
- $content_moderation_state = $content_moderation_state->getTranslation($langcode);
+ if ($entity->getEntityType()->hasKey('langcode')) {
+ $langcode = $entity->language()->getId();
+ if (!$content_moderation_state->hasTranslation($langcode)) {
+ $content_moderation_state->addTranslation($langcode);
+ }
+ if ($content_moderation_state->language()->getId() !== $langcode) {
+ $content_moderation_state = $content_moderation_state->getTranslation($langcode);
+ }
}
return $content_moderation_state->get('moderation_state')->entity;
diff --git a/core/modules/content_moderation/tests/src/Kernel/ContentModerationStateTest.php b/core/modules/content_moderation/tests/src/Kernel/ContentModerationStateTest.php
index 3ba37a294..67a7a7498 100644
--- a/core/modules/content_moderation/tests/src/Kernel/ContentModerationStateTest.php
+++ b/core/modules/content_moderation/tests/src/Kernel/ContentModerationStateTest.php
@@ -4,6 +4,8 @@ namespace Drupal\Tests\content_moderation\Kernel;
use Drupal\content_moderation\Entity\ContentModerationState;
use Drupal\content_moderation\Entity\ModerationState;
+use Drupal\entity_test\Entity\EntityTestBundle;
+use Drupal\entity_test\Entity\EntityTestWithBundle;
use Drupal\KernelTests\KernelTestBase;
use Drupal\language\Entity\ConfigurableLanguage;
use Drupal\node\Entity\Node;
@@ -21,12 +23,14 @@ class ContentModerationStateTest extends KernelTestBase {
* {@inheritdoc}
*/
public static $modules = [
+ 'entity_test',
'node',
'content_moderation',
'user',
'system',
'language',
'content_translation',
+ 'text',
];
/**
@@ -38,6 +42,7 @@ class ContentModerationStateTest extends KernelTestBase {
$this->installSchema('node', 'node_access');
$this->installEntitySchema('node');
$this->installEntitySchema('user');
+ $this->installEntitySchema('entity_test_with_bundle');
$this->installEntitySchema('content_moderation_state');
$this->installConfig('content_moderation');
}
@@ -210,6 +215,91 @@ class ContentModerationStateTest extends KernelTestBase {
$this->assertEquals(6, $english_node->getRevisionId());
}
+ /**
+ * Tests that a non-translatable entity type with a langcode can be moderated.
+ */
+ public function testNonTranslatableEntityTypeModeration() {
+ // Make the 'entity_test_with_bundle' entity type revisionable.
+ $entity_type = clone \Drupal::entityTypeManager()->getDefinition('entity_test_with_bundle');
+ $keys = $entity_type->getKeys();
+ $keys['revision'] = 'revision_id';
+ $entity_type->set('entity_keys', $keys);
+ \Drupal::state()->set('entity_test_with_bundle.entity_type', $entity_type);
+ \Drupal::entityDefinitionUpdateManager()->applyUpdates();
+
+ // Create a test bundle.
+ $entity_test_bundle = EntityTestBundle::create([
+ 'id' => 'example',
+ ]);
+ $entity_test_bundle->setThirdPartySetting('content_moderation', 'enabled', TRUE);
+ $entity_test_bundle->setThirdPartySetting('content_moderation', 'allowed_moderation_states', [
+ 'draft',
+ 'published'
+ ]);
+ $entity_test_bundle->setThirdPartySetting('content_moderation', 'default_moderation_state', 'draft');
+ $entity_test_bundle->save();
+
+ // Check that the tested entity type is not translatable.
+ $entity_type = \Drupal::entityTypeManager()->getDefinition('entity_test_with_bundle');
+ $this->assertFalse($entity_type->isTranslatable(), 'The test entity type is not translatable.');
+
+ // Create a test entity.
+ $entity_test_with_bundle = EntityTestWithBundle::create([
+ 'type' => 'example'
+ ]);
+ $entity_test_with_bundle->save();
+ $this->assertEquals('draft', $entity_test_with_bundle->moderation_state->entity->id());
+
+ $entity_test_with_bundle->moderation_state->target_id = 'published';
+ $entity_test_with_bundle->save();
+
+ $this->assertEquals('published', EntityTestWithBundle::load($entity_test_with_bundle->id())->moderation_state->entity->id());
+ }
+
+ /**
+ * Tests that a non-translatable entity type without a langcode can be
+ * moderated.
+ */
+ public function testNonLangcodeEntityTypeModeration() {
+ // Make the 'entity_test_with_bundle' entity type revisionable and unset
+ // the langcode entity key.
+ $entity_type = clone \Drupal::entityTypeManager()->getDefinition('entity_test_with_bundle');
+ $keys = $entity_type->getKeys();
+ $keys['revision'] = 'revision_id';
+ unset($keys['langcode']);
+ $entity_type->set('entity_keys', $keys);
+ \Drupal::state()->set('entity_test_with_bundle.entity_type', $entity_type);
+ \Drupal::entityDefinitionUpdateManager()->applyUpdates();
+
+ // Create a test bundle.
+ $entity_test_bundle = EntityTestBundle::create([
+ 'id' => 'example',
+ ]);
+ $entity_test_bundle->setThirdPartySetting('content_moderation', 'enabled', TRUE);
+ $entity_test_bundle->setThirdPartySetting('content_moderation', 'allowed_moderation_states', [
+ 'draft',
+ 'published'
+ ]);
+ $entity_test_bundle->setThirdPartySetting('content_moderation', 'default_moderation_state', 'draft');
+ $entity_test_bundle->save();
+
+ // Check that the tested entity type is not translatable.
+ $entity_type = \Drupal::entityTypeManager()->getDefinition('entity_test_with_bundle');
+ $this->assertFalse($entity_type->isTranslatable(), 'The test entity type is not translatable.');
+
+ // Create a test entity.
+ $entity_test_with_bundle = EntityTestWithBundle::create([
+ 'type' => 'example'
+ ]);
+ $entity_test_with_bundle->save();
+ $this->assertEquals('draft', $entity_test_with_bundle->moderation_state->entity->id());
+
+ $entity_test_with_bundle->moderation_state->target_id = 'published';
+ $entity_test_with_bundle->save();
+
+ $this->assertEquals('published', EntityTestWithBundle::load($entity_test_with_bundle->id())->moderation_state->entity->id());
+ }
+
/**
* Reloads the node after clearing the static cache.
*
diff --git a/core/modules/content_moderation/tests/src/Kernel/EntityTypeInfoTest.php b/core/modules/content_moderation/tests/src/Kernel/EntityTypeInfoTest.php
new file mode 100644
index 000000000..1c45721d0
--- /dev/null
+++ b/core/modules/content_moderation/tests/src/Kernel/EntityTypeInfoTest.php
@@ -0,0 +1,63 @@
+entityTypeInfo = $this->container->get('class_resolver')->getInstanceFromDefinition(EntityTypeInfo::class);
+ $this->entityTypeManager = $this->container->get('entity_type.manager');
+ }
+
+ /**
+ * @covers ::entityBaseFieldInfo
+ */
+ public function testEntityBaseFieldInfo() {
+ $definition = $this->entityTypeManager->getDefinition('entity_test');
+ $definition->setHandlerClass('moderation', ModerationHandler::class);
+
+ $base_fields = $this->entityTypeInfo->entityBaseFieldInfo($definition);
+
+ $this->assertFalse($base_fields['moderation_state']->isReadOnly());
+ $this->assertTrue($base_fields['moderation_state']->isComputed());
+ $this->assertTrue($base_fields['moderation_state']->isTranslatable());
+ }
+
+}
diff --git a/core/modules/datetime/tests/src/Kernel/DateTimeFormInjectionTest.php b/core/modules/datetime/tests/src/Kernel/DateTimeFormInjectionTest.php
new file mode 100644
index 000000000..a65d43928
--- /dev/null
+++ b/core/modules/datetime/tests/src/Kernel/DateTimeFormInjectionTest.php
@@ -0,0 +1,113 @@
+installSchema('system', ['key_value_expire', 'sequences']);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getFormId() {
+ return 'datetime_test_injection_form';
+ }
+
+ /**
+ * Process callback.
+ *
+ * @param array $element
+ * Form element.
+ *
+ * @return array
+ * Processed element.
+ */
+ public function process($element) {
+ return $element;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function buildForm(array $form, FormStateInterface $form_state) {
+ $form['datelist_element'] = [
+ '#title' => 'datelist test',
+ '#type' => 'datelist',
+ '#default_value' => new DrupalDateTime('2000-01-01 00:00:00'),
+ '#date_part_order' => [
+ 'month',
+ 'day',
+ 'year',
+ 'hour',
+ 'minute', 'ampm',
+ ],
+ '#date_text_parts' => ['year'],
+ '#date_year_range' => '2010:2020',
+ '#date_increment' => 15,
+ ];
+ $form['#process'][] = [$this, 'process'];
+ return $form;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function validateForm(array &$form, FormStateInterface $form_state) {}
+
+ /**
+ * {@inheritdoc}
+ */
+ public function submitForm(array &$form, FormStateInterface $form_state) {
+ $this->assertTrue(TRUE);
+ $form_state->setRebuild();
+ }
+
+ /**
+ * Tests custom string injection serialization.
+ */
+ public function testDatetimeSerialization() {
+ $form_state = new FormState();
+ $form_state->setRequestMethod('POST');
+ $form_state->setCached();
+ $form_builder = $this->container->get('form_builder');
+ $form_id = $form_builder->getFormId($this, $form_state);
+ $form = $form_builder->retrieveForm($form_id, $form_state);
+ $form_builder->prepareForm($form_id, $form, $form_state);
+ $form_builder->processForm($form_id, $form, $form_state);
+ }
+
+}
diff --git a/core/modules/field/migration_templates/d6_field.yml b/core/modules/field/migration_templates/d6_field.yml
index 3157808f5..1205b67ef 100644
--- a/core/modules/field/migration_templates/d6_field.yml
+++ b/core/modules/field/migration_templates/d6_field.yml
@@ -123,4 +123,4 @@ process:
- '@type'
- global_settings
destination:
- plugin: md_entity:field_storage_config
+ plugin: entity:field_storage_config
diff --git a/core/modules/field/migration_templates/d7_field.yml b/core/modules/field/migration_templates/d7_field.yml
index 18135affb..069334322 100644
--- a/core/modules/field/migration_templates/d7_field.yml
+++ b/core/modules/field/migration_templates/d7_field.yml
@@ -22,6 +22,7 @@ process:
datestamp: datetime
datetime: datetime
email: email
+ entityreference: entity_reference
file: file
image: image
link_field: link
diff --git a/core/modules/field/migration_templates/d7_field_formatter_settings.yml b/core/modules/field/migration_templates/d7_field_formatter_settings.yml
index ee07ec4be..14cdd661a 100644
--- a/core/modules/field/migration_templates/d7_field_formatter_settings.yml
+++ b/core/modules/field/migration_templates/d7_field_formatter_settings.yml
@@ -51,7 +51,7 @@ process:
-
plugin: static_map
bypass: true
- source: type
+ source: formatter_type
map:
date_default: datetime_default
email_default: email_mailto
@@ -61,6 +61,9 @@ process:
link_default: link
phone: basic_string
taxonomy_term_reference_link: entity_reference_label
+ entityreference_label: entity_reference_label
+ entityreference_entity_id: entity_reference_entity_id
+ entityreference_entity_view: entity_reference_entity_view
-
plugin: skip_on_empty
method: row
diff --git a/core/modules/field/migration_templates/d7_field_instance.yml b/core/modules/field/migration_templates/d7_field_instance.yml
index b6d2497e5..6f9d07426 100644
--- a/core/modules/field/migration_templates/d7_field_instance.yml
+++ b/core/modules/field/migration_templates/d7_field_instance.yml
@@ -21,6 +21,7 @@ process:
source:
- instance_settings
- widget_settings
+ - field_settings
default_value_function: ''
default_value:
plugin: d7_field_instance_defaults
diff --git a/core/modules/field/migration_templates/d7_field_instance_widget_settings.yml b/core/modules/field/migration_templates/d7_field_instance_widget_settings.yml
index f88f2d205..b5ee41701 100644
--- a/core/modules/field/migration_templates/d7_field_instance_widget_settings.yml
+++ b/core/modules/field/migration_templates/d7_field_instance_widget_settings.yml
@@ -46,6 +46,7 @@ process:
phone_textfield: telephone_default
options_onoff: boolean_checkbox
entityreference_autocomplete: entity_reference_autocomplete
+ entityreference_autocomplete_tags: entity_reference_autocomplete_tags
taxonomy_autocomplete: entity_reference_autocomplete
'options/settings':
plugin: field_instance_widget_settings
diff --git a/core/modules/field/src/Plugin/migrate/process/d7/FieldInstanceSettings.php b/core/modules/field/src/Plugin/migrate/process/d7/FieldInstanceSettings.php
index e8d59ad31..d28007986 100644
--- a/core/modules/field/src/Plugin/migrate/process/d7/FieldInstanceSettings.php
+++ b/core/modules/field/src/Plugin/migrate/process/d7/FieldInstanceSettings.php
@@ -17,9 +17,38 @@ class FieldInstanceSettings extends ProcessPluginBase {
* {@inheritdoc}
*/
public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) {
- list($instance_settings, $widget_settings) = $value;
+ list($instance_settings, $widget_settings, $field_settings) = $value;
$widget_type = $widget_settings['type'];
+ // Get entityreference handler settings from source field configuration.
+ if ($row->getSourceProperty('type') == "entityreference") {
+ $instance_settings['handler'] = 'default:' . $field_settings['target_type'];
+ // Transform the sort settings to D8 structure.
+ $sort = [
+ 'field' => '_none',
+ 'direction' => 'ASC',
+ ];
+ if (!empty(array_filter($field_settings['handler_settings']['sort']))) {
+ if ($field_settings['handler_settings']['sort']['type'] == "property") {
+ $sort = [
+ 'field' => $field_settings['handler_settings']['sort']['property'],
+ 'direction' => $field_settings['handler_settings']['sort']['direction'],
+ ];
+ }
+ elseif ($field_settings['handler_settings']['sort']['type'] == "field") {
+ $sort = [
+ 'field' => $field_settings['handler_settings']['sort']['field'],
+ 'direction' => $field_settings['handler_settings']['sort']['direction'],
+ ];
+ }
+ }
+ if (empty($field_settings['handler_settings']['target_bundles'])) {
+ $field_settings['handler_settings']['target_bundles'] = NULL;
+ }
+ $field_settings['handler_settings']['sort'] = $sort;
+ $instance_settings['handler_settings'] = $field_settings['handler_settings'];
+ }
+
switch ($widget_type) {
case 'image_image':
$settings = $instance_settings;
diff --git a/core/modules/field/src/Plugin/migrate/source/d7/FieldInstance.php b/core/modules/field/src/Plugin/migrate/source/d7/FieldInstance.php
index 7aa281f4e..5d3d6cc06 100644
--- a/core/modules/field/src/Plugin/migrate/source/d7/FieldInstance.php
+++ b/core/modules/field/src/Plugin/migrate/source/d7/FieldInstance.php
@@ -28,6 +28,7 @@ class FieldInstance extends DrupalSqlBase {
->fields('fc', array('type'));
$query->innerJoin('field_config', 'fc', 'fci.field_id = fc.id');
+ $query->addField('fc', 'data', 'field_data');
// Optionally filter by entity type and bundle.
if (isset($this->configuration['entity_type'])) {
@@ -53,6 +54,7 @@ class FieldInstance extends DrupalSqlBase {
'instance_settings' => $this->t('Field instance settings.'),
'widget_settings' => $this->t('Widget settings.'),
'display_settings' => $this->t('Display settings.'),
+ 'field_settings' => $this->t('Field settings.'),
);
}
@@ -81,6 +83,9 @@ class FieldInstance extends DrupalSqlBase {
// This is for parity with the d6_field_instance plugin.
$row->setSourceProperty('widget_type', $data['widget']['type']);
+ $field_data = unserialize($row->getSourceProperty('field_data'));
+ $row->setSourceProperty('field_settings', $field_data['settings']);
+
return parent::prepareRow($row);
}
diff --git a/core/modules/field/src/Plugin/migrate/source/d7/FieldInstancePerViewMode.php b/core/modules/field/src/Plugin/migrate/source/d7/FieldInstancePerViewMode.php
index 17d4e183c..72a845bca 100644
--- a/core/modules/field/src/Plugin/migrate/source/d7/FieldInstancePerViewMode.php
+++ b/core/modules/field/src/Plugin/migrate/source/d7/FieldInstancePerViewMode.php
@@ -24,8 +24,15 @@ class FieldInstancePerViewMode extends DrupalSqlBase {
$data = unserialize($field_instance['data']);
// We don't need to include the serialized data in the returned rows.
unset($field_instance['data']);
+
foreach ($data['display'] as $view_mode => $info) {
- $rows[] = array_merge($field_instance, $info, array('view_mode' => $view_mode));
+ // Rename type to formatter_type in the info array.
+ $info['formatter_type'] = $info['type'];
+ unset($info['type']);
+
+ $rows[] = array_merge($field_instance, $info, [
+ 'view_mode' => $view_mode,
+ ]);
}
}
return new \ArrayIterator($rows);
@@ -35,8 +42,11 @@ class FieldInstancePerViewMode extends DrupalSqlBase {
* {@inheritdoc}
*/
public function query() {
- return $this->select('field_config_instance', 'fci')
- ->fields('fci', array('entity_type', 'bundle', 'field_name', 'data'));
+ $query = $this->select('field_config_instance', 'fci')
+ ->fields('fci', ['entity_type', 'bundle', 'field_name', 'data'])
+ ->fields('fc', ['type']);
+ $query->join('field_config', 'fc', 'fc.field_name = fci.field_name');
+ return $query;
}
/**
@@ -49,7 +59,8 @@ class FieldInstancePerViewMode extends DrupalSqlBase {
'field_name' => $this->t('Machine name of the field.'),
'view_mode' => $this->t('The original machine name of the view mode.'),
'label' => $this->t('The display label of the field.'),
- 'type' => $this->t('The formatter ID.'),
+ 'type' => $this->t('The field ID.'),
+ 'formatter_type' => $this->t('The formatter ID.'),
'settings' => $this->t('Array of formatter-specific settings.'),
'module' => $this->t('The module providing the formatter.'),
'weight' => $this->t('Display weight of the field.'),
diff --git a/core/modules/field/src/Tests/Boolean/BooleanFieldTest.php b/core/modules/field/src/Tests/Boolean/BooleanFieldTest.php
index 30f67d1e6..5fa491b20 100644
--- a/core/modules/field/src/Tests/Boolean/BooleanFieldTest.php
+++ b/core/modules/field/src/Tests/Boolean/BooleanFieldTest.php
@@ -20,7 +20,12 @@ class BooleanFieldTest extends WebTestBase {
*
* @var array
*/
- public static $modules = array('entity_test', 'field_ui', 'options');
+ public static $modules = [
+ 'entity_test',
+ 'field_ui',
+ 'options',
+ 'field_test_boolean_access_denied',
+ ];
/**
* A field to use in this test class.
@@ -179,4 +184,66 @@ class BooleanFieldTest extends WebTestBase {
$this->assertFieldById('edit-settings-off-label', $off);
}
+ /**
+ * Test field access.
+ */
+ public function testFormAccess() {
+ $on = 'boolean_on';
+ $off = 'boolean_off';
+ $label = 'boolean_label';
+ $field_name = 'boolean_name';
+ $this->fieldStorage = FieldStorageConfig::create([
+ 'field_name' => $field_name,
+ 'entity_type' => 'entity_test',
+ 'type' => 'boolean',
+ ]);
+ $this->fieldStorage->save();
+ $this->field = FieldConfig::create([
+ 'field_name' => $field_name,
+ 'entity_type' => 'entity_test',
+ 'bundle' => 'entity_test',
+ 'label' => $label,
+ 'settings' => [
+ 'on_label' => $on,
+ 'off_label' => $off,
+ ],
+ ]);
+ $this->field->save();
+
+ // Create a form display for the default form mode.
+ entity_get_form_display('entity_test', 'entity_test', 'default')
+ ->setComponent($field_name, [
+ 'type' => 'boolean_checkbox',
+ ])
+ ->save();
+
+ // Create a display for the full view mode.
+ entity_get_display('entity_test', 'entity_test', 'full')
+ ->setComponent($field_name, [
+ 'type' => 'boolean',
+ ])
+ ->save();
+
+ // Display creation form.
+ $this->drupalGet('entity_test/add');
+ $this->assertFieldByName("{$field_name}[value]");
+
+ // Should be posted OK.
+ $this->drupalPostForm(NULL, [], t('Save'));
+ preg_match('|entity_test/manage/(\d+)|', $this->url, $match);
+ $id = $match[1];
+ $this->assertText(t('entity_test @id has been created.', ['@id' => $id]));
+
+ // Tell the test module to disable access to the field.
+ \Drupal::state()->set('field.test_boolean_field_access_field', $field_name);
+ $this->drupalGet('entity_test/add');
+ // Field should not be there anymore.
+ $this->assertNoFieldByName("{$field_name}[value]");
+ // Should still be able to post the form.
+ $this->drupalPostForm(NULL, [], t('Save'));
+ preg_match('|entity_test/manage/(\d+)|', $this->url, $match);
+ $id = $match[1];
+ $this->assertText(t('entity_test @id has been created.', ['@id' => $id]));
+ }
+
}
diff --git a/core/modules/field/tests/modules/field_test/src/Plugin/Field/FieldType/TestObjectItem.php b/core/modules/field/tests/modules/field_test/src/Plugin/Field/FieldType/TestObjectItem.php
new file mode 100644
index 000000000..a20265e55
--- /dev/null
+++ b/core/modules/field/tests/modules/field_test/src/Plugin/Field/FieldType/TestObjectItem.php
@@ -0,0 +1,62 @@
+setLabel(t('Value'))
+ ->setRequired(TRUE);
+
+ return $properties;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public static function schema(FieldStorageDefinitionInterface $field_definition) {
+ return [
+ 'columns' => [
+ 'value' => [
+ 'description' => 'The object item value.',
+ 'type' => 'blob',
+ 'not null' => TRUE,
+ 'serialize' => TRUE,
+ ],
+ ],
+ ];
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setValue($values, $notify = TRUE) {
+ if (isset($values['value'])) {
+ // @todo Remove this in https://www.drupal.org/node/2788637.
+ if (is_string($values['value'])) {
+ $values['value'] = unserialize($values['value']);
+ }
+ }
+ parent::setValue($values, $notify);
+ }
+
+}
diff --git a/core/modules/field/tests/modules/field_test_boolean_access_denied/field_test_boolean_access_denied.info.yml b/core/modules/field/tests/modules/field_test_boolean_access_denied/field_test_boolean_access_denied.info.yml
new file mode 100644
index 000000000..d1b578f46
--- /dev/null
+++ b/core/modules/field/tests/modules/field_test_boolean_access_denied/field_test_boolean_access_denied.info.yml
@@ -0,0 +1,8 @@
+name: 'Boolean field Test'
+type: module
+description: 'Support module for the field and entity display tests.'
+core: 8.x
+package: Testing
+version: VERSION
+dependencies:
+ - field
diff --git a/core/modules/field/tests/modules/field_test_boolean_access_denied/field_test_boolean_access_denied.module b/core/modules/field/tests/modules/field_test_boolean_access_denied/field_test_boolean_access_denied.module
new file mode 100644
index 000000000..e1ae2f737
--- /dev/null
+++ b/core/modules/field/tests/modules/field_test_boolean_access_denied/field_test_boolean_access_denied.module
@@ -0,0 +1,18 @@
+getName() === \Drupal::state()->get('field.test_boolean_field_access_field'));
+}
diff --git a/core/modules/field/tests/src/Kernel/EntityReference/EntityReferenceFormatterTest.php b/core/modules/field/tests/src/Kernel/EntityReference/EntityReferenceFormatterTest.php
index d4be1dadc..aaee7d080 100644
--- a/core/modules/field/tests/src/Kernel/EntityReference/EntityReferenceFormatterTest.php
+++ b/core/modules/field/tests/src/Kernel/EntityReference/EntityReferenceFormatterTest.php
@@ -277,6 +277,49 @@ class EntityReferenceFormatterTest extends EntityKernelTestBase {
$this->assertEqual($actual_occurrences, $expected_occurrences);
}
+ /**
+ * Renders the same entity referenced from different places.
+ */
+ public function testEntityReferenceRecursiveProtectionWithManyRenderedEntities() {
+ $formatter = 'entity_reference_entity_view';
+ $view_builder = $this->entityManager->getViewBuilder($this->entityType);
+
+ // Set the default view mode to use the 'entity_reference_entity_view'
+ // formatter.
+ entity_get_display($this->entityType, $this->bundle, 'default')
+ ->setComponent($this->fieldName, [
+ 'type' => $formatter,
+ ])
+ ->save();
+
+ $storage = $this->entityManager->getStorage($this->entityType);
+ /** @var \Drupal\Core\Entity\ContentEntityInterface $referenced_entity */
+ $referenced_entity = $storage->create(['name' => $this->randomMachineName()]);
+
+ $range = range(0, 30);
+ $referencing_entities = array_map(function () use ($storage, $referenced_entity) {
+ $referencing_entity = $storage->create([
+ 'name' => $this->randomMachineName(),
+ $this->fieldName => $referenced_entity,
+ ]);
+ $referencing_entity->save();
+ return $referencing_entity;
+ }, $range);
+
+ $build = $view_builder->viewMultiple($referencing_entities, 'default');
+ $output = $this->render($build);
+
+ // The title of entity_test entities is printed twice by default, so we have
+ // to multiply the formatter's recursive rendering protection limit by 2.
+ // Additionally, we have to take into account 2 additional occurrences of
+ // the entity title because we're rendering the full entity, not just the
+ // reference field.
+ $expected_occurrences = 30 * 2 + 2;
+ $actual_occurrences = substr_count($output, $referenced_entity->get('name')->value);
+ $this->assertEquals($expected_occurrences, $actual_occurrences);
+ }
+
+
/**
* Tests the label formatter.
*/
diff --git a/core/modules/field/tests/src/Kernel/Migrate/d7/MigrateFieldFormatterSettingsTest.php b/core/modules/field/tests/src/Kernel/Migrate/d7/MigrateFieldFormatterSettingsTest.php
index 21cc3aa67..14f37cb41 100644
--- a/core/modules/field/tests/src/Kernel/Migrate/d7/MigrateFieldFormatterSettingsTest.php
+++ b/core/modules/field/tests/src/Kernel/Migrate/d7/MigrateFieldFormatterSettingsTest.php
@@ -276,6 +276,9 @@ class MigrateFieldFormatterSettingsTest extends MigrateDrupal7TestBase {
$this->assertComponent('node.test_content_type.default', 'field_text_list', 'list_default', 'above', 10);
$this->assertComponent('node.test_content_type.default', 'field_integer_list', 'list_default', 'above', 11);
$this->assertComponent('node.test_content_type.default', 'field_long_text', 'text_default', 'above', 12);
+ $this->assertComponent('node.test_content_type.default', 'field_node_entityreference', 'entity_reference_label', 'above', 15);
+ $this->assertComponent('node.test_content_type.default', 'field_user_entityreference', 'entity_reference_label', 'above', 16);
+ $this->assertComponent('node.test_content_type.default', 'field_term_entityreference', 'entity_reference_label', 'above', 17);
$this->assertComponentNotExists('node.test_content_type.default', 'field_term_reference');
$this->assertComponentNotExists('node.test_content_type.default', 'field_text');
diff --git a/core/modules/field/tests/src/Kernel/Migrate/d7/MigrateFieldInstanceTest.php b/core/modules/field/tests/src/Kernel/Migrate/d7/MigrateFieldInstanceTest.php
index 2fa6d5cc0..7c2115fbe 100644
--- a/core/modules/field/tests/src/Kernel/Migrate/d7/MigrateFieldInstanceTest.php
+++ b/core/modules/field/tests/src/Kernel/Migrate/d7/MigrateFieldInstanceTest.php
@@ -141,6 +141,9 @@ class MigrateFieldInstanceTest extends MigrateDrupal7TestBase {
$this->assertEntity('node.test_content_type.field_integer_list', 'Integer List', 'list_integer', FALSE);
$this->assertEntity('node.test_content_type.field_long_text', 'Long text', 'text_with_summary', FALSE);
$this->assertEntity('node.test_content_type.field_term_reference', 'Term Reference', 'entity_reference', FALSE);
+ $this->assertEntity('node.test_content_type.field_node_entityreference', 'Node Entity Reference', 'entity_reference', FALSE);
+ $this->assertEntity('node.test_content_type.field_user_entityreference', 'User Entity Reference', 'entity_reference', FALSE);
+ $this->assertEntity('node.test_content_type.field_term_entityreference', 'Term Entity Reference', 'entity_reference', FALSE);
$this->assertEntity('node.test_content_type.field_text', 'Text', 'text', FALSE);
$this->assertEntity('comment.comment_node_test_content_type.field_integer', 'Integer', 'integer', FALSE);
$this->assertEntity('user.user.field_file', 'File', 'file', FALSE);
diff --git a/core/modules/field/tests/src/Kernel/Migrate/d7/MigrateFieldInstanceWidgetSettingsTest.php b/core/modules/field/tests/src/Kernel/Migrate/d7/MigrateFieldInstanceWidgetSettingsTest.php
index dd4decd00..7f2e0244f 100644
--- a/core/modules/field/tests/src/Kernel/Migrate/d7/MigrateFieldInstanceWidgetSettingsTest.php
+++ b/core/modules/field/tests/src/Kernel/Migrate/d7/MigrateFieldInstanceWidgetSettingsTest.php
@@ -125,6 +125,9 @@ class MigrateFieldInstanceWidgetSettingsTest extends MigrateDrupal7TestBase {
$this->assertComponent('node.test_content_type.default', 'field_long_text', 'text_textarea_with_summary', 13);
$this->assertComponent('node.test_content_type.default', 'field_phone', 'telephone_default', 6);
$this->assertComponent('node.test_content_type.default', 'field_term_reference', 'entity_reference_autocomplete', 14);
+ $this->assertComponent('node.test_content_type.default', 'field_node_entityreference', 'entity_reference_autocomplete', 16);
+ $this->assertComponent('node.test_content_type.default', 'field_user_entityreference', 'options_buttons', 17);
+ $this->assertComponent('node.test_content_type.default', 'field_term_entityreference', 'entity_reference_autocomplete_tags', 18);
$this->assertComponent('node.test_content_type.default', 'field_text', 'text_textfield', 15);
$this->assertComponent('node.test_content_type.default', 'field_text_list', 'options_select', 11);
diff --git a/core/modules/field/tests/src/Kernel/Migrate/d7/MigrateFieldTest.php b/core/modules/field/tests/src/Kernel/Migrate/d7/MigrateFieldTest.php
index b1c2fb8b3..fb275c67c 100644
--- a/core/modules/field/tests/src/Kernel/Migrate/d7/MigrateFieldTest.php
+++ b/core/modules/field/tests/src/Kernel/Migrate/d7/MigrateFieldTest.php
@@ -100,6 +100,9 @@ class MigrateFieldTest extends MigrateDrupal7TestBase {
$this->assertEntity('node.field_phone', 'telephone', FALSE, 1);
$this->assertEntity('node.field_date', 'datetime', FALSE, 1);
$this->assertEntity('node.field_date_with_end_time', 'datetime', FALSE, 1);
+ $this->assertEntity('node.field_node_entityreference', 'entity_reference', FALSE, -1);
+ $this->assertEntity('node.field_user_entityreference', 'entity_reference', FALSE, 1);
+ $this->assertEntity('node.field_term_entityreference', 'entity_reference', FALSE, -1);
// Assert that the taxonomy term reference fields are referencing the
// correct entity type.
@@ -108,6 +111,15 @@ class MigrateFieldTest extends MigrateDrupal7TestBase {
$field = FieldStorageConfig::load('node.taxonomy_forums');
$this->assertIdentical('taxonomy_term', $field->getSetting('target_type'));
+ // Assert that the entityreference fields are referencing the correct
+ // entity type.
+ $field = FieldStorageConfig::load('node.field_node_entityreference');
+ $this->assertIdentical('node', $field->getSetting('target_type'));
+ $field = FieldStorageConfig::load('node.field_user_entityreference');
+ $this->assertIdentical('user', $field->getSetting('target_type'));
+ $field = FieldStorageConfig::load('node.field_term_entityreference');
+ $this->assertIdentical('taxonomy_term', $field->getSetting('target_type'));
+
// Validate that the source count and processed count match up.
/** @var \Drupal\migrate\Plugin\MigrationInterface $migration */
$migration = $this->getMigration('d7_field');
diff --git a/core/modules/field/tests/src/Kernel/Plugin/migrate/source/d7/FieldInstancePerViewModeTest.php b/core/modules/field/tests/src/Kernel/Plugin/migrate/source/d7/FieldInstancePerViewModeTest.php
index 6ed72e43c..ff5993e62 100644
--- a/core/modules/field/tests/src/Kernel/Plugin/migrate/source/d7/FieldInstancePerViewModeTest.php
+++ b/core/modules/field/tests/src/Kernel/Plugin/migrate/source/d7/FieldInstancePerViewModeTest.php
@@ -41,6 +41,24 @@ class FieldInstancePerViewModeTest extends MigrateSqlSourceTestBase {
],
];
+ $tests[0]['source_data']['field_config'] = [
+ [
+ 'id' => '2',
+ 'field_name' => 'body',
+ 'type' => 'text_with_summary',
+ 'module' => 'text',
+ 'active' => '1',
+ 'storage_type' => 'field_sql_storage',
+ 'storage_module' => 'field_sql_storage',
+ 'storage_active' => '1',
+ 'locked' => '0',
+ 'data' => 'a:7:{s:12:"entity_types";a:1:{i:0;s:4:"node";}s:7:"indexes";a:1:{s:6:"format";a:1:{i:0;s:6:"format";}}s:8:"settings";a:0:{}s:12:"translatable";i:0;s:12:"foreign keys";a:1:{s:6:"format";a:2:{s:5:"table";s:13:"filter_format";s:7:"columns";a:1:{s:6:"format";s:6:"format";}}}s:7:"storage";a:4:{s:4:"type";s:17:"field_sql_storage";s:8:"settings";a:0:{}s:6:"module";s:17:"field_sql_storage";s:6:"active";s:1:"1";}s:2:"id";s:2:"25";}',
+ 'cardinality' => '1',
+ 'translatable' => '0',
+ 'deleted' => '0',
+ ],
+ ];
+
// The expected results.
$tests[0]['expected_data'] = [
[
@@ -48,7 +66,8 @@ class FieldInstancePerViewModeTest extends MigrateSqlSourceTestBase {
'bundle' => 'page',
'field_name' => 'body',
'label' => 'hidden',
- 'type' => 'text_default',
+ 'type' => 'text_with_summary',
+ 'formatter_type' => 'text_default',
'settings' => [],
'module' => 'text',
'weight' => 0,
@@ -59,7 +78,8 @@ class FieldInstancePerViewModeTest extends MigrateSqlSourceTestBase {
'bundle' => 'page',
'field_name' => 'body',
'label' => 'hidden',
- 'type' => 'text_summary_or_trimmed',
+ 'type' => 'text_with_summary',
+ 'formatter_type' => 'text_summary_or_trimmed',
'settings' => [
'trim_length' => 600,
],
diff --git a/core/modules/field/tests/src/Kernel/String/UuidItemTest.php b/core/modules/field/tests/src/Kernel/String/UuidItemTest.php
new file mode 100644
index 000000000..480057b90
--- /dev/null
+++ b/core/modules/field/tests/src/Kernel/String/UuidItemTest.php
@@ -0,0 +1,30 @@
+save();
+
+ $uuid_field = $entity->get('uuid');
+
+ // Test the generateSampleValue() method.
+ $uuid_field->generateSampleItems();
+ $this->assertTrue(Uuid::isValid($uuid_field->value));
+ }
+
+}
diff --git a/core/modules/field/tests/src/Kernel/TestObjectItemTest.php b/core/modules/field/tests/src/Kernel/TestObjectItemTest.php
new file mode 100644
index 000000000..8a7875581
--- /dev/null
+++ b/core/modules/field/tests/src/Kernel/TestObjectItemTest.php
@@ -0,0 +1,59 @@
+ 'field_test',
+ 'entity_type' => 'entity_test',
+ 'type' => 'test_object_field',
+ ))->save();
+ FieldConfig::create([
+ 'entity_type' => 'entity_test',
+ 'field_name' => 'field_test',
+ 'bundle' => 'entity_test',
+ ])->save();
+ }
+
+ /**
+ * Tests the serialization of a field type that has an object.
+ */
+ public function testTestObjectItem() {
+ $object = new \stdClass();
+ $object->foo = 'bar';
+ $entity = EntityTest::create();
+ $entity->field_test->value = $object;
+ $entity->save();
+
+ // Verify that the entity has been created properly.
+ $id = $entity->id();
+ $entity = EntityTest::load($id);
+ $this->assertTrue($entity->field_test->value instanceof \stdClass);
+ $this->assertEquals($object, $entity->field_test->value);
+ }
+
+}
diff --git a/core/modules/field/tests/src/Unit/Plugin/migrate/process/d7/FieldInstanceSettingsTest.php b/core/modules/field/tests/src/Unit/Plugin/migrate/process/d7/FieldInstanceSettingsTest.php
index 174271a1b..8c405b04b 100644
--- a/core/modules/field/tests/src/Unit/Plugin/migrate/process/d7/FieldInstanceSettingsTest.php
+++ b/core/modules/field/tests/src/Unit/Plugin/migrate/process/d7/FieldInstanceSettingsTest.php
@@ -28,7 +28,7 @@ class FieldInstanceSettingsTest extends MigrateTestCase {
->disableOriginalConstructor()
->getMock();
- $value = $plugin->transform([[], ['type' => 'image_image']], $executable, $row, 'foo');
+ $value = $plugin->transform([[], ['type' => 'image_image'], []], $executable, $row, 'foo');
$this->assertInternalType('array', $value['default_image']);
$this->assertSame('', $value['default_image']['alt']);
$this->assertSame('', $value['default_image']['title']);
diff --git a/core/modules/file/migration_templates/d6_file.yml b/core/modules/file/migration_templates/d6_file.yml
index 0fdcd8403..6df20b522 100644
--- a/core/modules/file/migration_templates/d6_file.yml
+++ b/core/modules/file/migration_templates/d6_file.yml
@@ -13,6 +13,9 @@ source:
# configuration in this migration's process pipeline as an example.
source_base_path: ''
process:
+ # If you are using both this migration and d6_user_picture_file in a custom
+ # migration and executing migrations incrementally, it is recommended that
+ # you remove the fid mapping here to avoid potential ID conflicts.
fid: fid
filename: filename
source_full_path:
diff --git a/core/modules/file/migration_templates/d6_upload_field.yml b/core/modules/file/migration_templates/d6_upload_field.yml
index c0b4569a6..a919f918f 100644
--- a/core/modules/file/migration_templates/d6_upload_field.yml
+++ b/core/modules/file/migration_templates/d6_upload_field.yml
@@ -20,4 +20,7 @@ process:
cardinality: 'constants/cardinality'
'settings/display_field': 'constants/display_field'
destination:
- plugin: md_entity:field_storage_config
+ plugin: entity:field_storage_config
+ dependencies:
+ module:
+ - file
diff --git a/core/modules/file/migration_templates/d7_file.yml b/core/modules/file/migration_templates/d7_file.yml
index ffd85ab55..7ebf83bf3 100644
--- a/core/modules/file/migration_templates/d7_file.yml
+++ b/core/modules/file/migration_templates/d7_file.yml
@@ -13,6 +13,8 @@ source:
# configuration in this migration's process pipeline as an example.
source_base_path: ''
process:
+ # If you are using this file to build a custom migration consider removing
+ # the fid field to allow incremental migrations.
fid: fid
filename: filename
source_full_path:
diff --git a/core/modules/file/src/Plugin/migrate/process/d6/CckFile.php b/core/modules/file/src/Plugin/migrate/process/d6/CckFile.php
index 0415c7ffb..8cf2d19a4 100644
--- a/core/modules/file/src/Plugin/migrate/process/d6/CckFile.php
+++ b/core/modules/file/src/Plugin/migrate/process/d6/CckFile.php
@@ -5,7 +5,6 @@ namespace Drupal\file\Plugin\migrate\process\d6;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\migrate\Plugin\MigrationInterface;
use Drupal\migrate\MigrateExecutableInterface;
-use Drupal\migrate\MigrateSkipRowException;
use Drupal\migrate\Plugin\MigrateProcessInterface;
use Drupal\migrate\ProcessPluginBase;
use Drupal\migrate\Row;
@@ -76,18 +75,7 @@ class CckFile extends ProcessPluginBase implements ContainerFactoryPluginInterfa
// some reason -- file migration is notoriously brittle -- and we do NOT
// want to send invalid file references into the field system (it causes
// fatals), so return an empty item instead.
- try {
- $fid = $this->migrationPlugin->transform($value['fid'], $migrate_executable, $row, $destination_property);
- }
- // If the migration plugin completely fails its lookup process, it will
- // throw a MigrateSkipRowException. It shouldn't, but that is being dealt
- // with at https://www.drupal.org/node/2487568. Until that lands, return
- // an empty item.
- catch (MigrateSkipRowException $e) {
- return [];
- }
-
- if ($fid) {
+ if ($fid = $this->migrationPlugin->transform($value['fid'], $migrate_executable, $row, $destination_property)) {
return [
'target_id' => $fid,
'display' => $value['list'],
diff --git a/core/modules/hal/tests/src/Functional/EntityResource/Block/BlockHalJsonAnonTest.php b/core/modules/hal/tests/src/Functional/EntityResource/Block/BlockHalJsonAnonTest.php
new file mode 100644
index 000000000..d0758f347
--- /dev/null
+++ b/core/modules/hal/tests/src/Functional/EntityResource/Block/BlockHalJsonAnonTest.php
@@ -0,0 +1,35 @@
+applyHalFieldNormalization($default_normalization);
+
+ // Because \Drupal\comment\Entity\Comment::getOwner() generates an in-memory
+ // User entity without a UUID, we cannot use it.
+ $author = User::load($this->entity->getOwnerId());
+ $commented_entity = EntityTest::load(1);
+ return $normalization + [
+ '_links' => [
+ 'self' => [
+ 'href' => $this->baseUrl . '/comment/1?_format=hal_json',
+ ],
+ 'type' => [
+ 'href' => $this->baseUrl . '/rest/type/comment/comment',
+ ],
+ $this->baseUrl . '/rest/relation/comment/comment/entity_id' => [
+ [
+ 'href' => $this->baseUrl . '/entity_test/1?_format=hal_json',
+ ],
+ ],
+ $this->baseUrl . '/rest/relation/comment/comment/uid' => [
+ [
+ 'href' => $this->baseUrl . '/user/' . $author->id() . '?_format=hal_json',
+ 'lang' => 'en',
+ ],
+ ],
+ ],
+ '_embedded' => [
+ $this->baseUrl . '/rest/relation/comment/comment/entity_id' => [
+ [
+ '_links' => [
+ 'self' => [
+ 'href' => $this->baseUrl . '/entity_test/1?_format=hal_json',
+ ],
+ 'type' => [
+ 'href' => $this->baseUrl . '/rest/type/entity_test/bar',
+ ],
+ ],
+ 'uuid' => [
+ ['value' => $commented_entity->uuid()]
+ ],
+ ],
+ ],
+ $this->baseUrl . '/rest/relation/comment/comment/uid' => [
+ [
+ '_links' => [
+ 'self' => [
+ 'href' => $this->baseUrl . '/user/' . $author->id() . '?_format=hal_json',
+ ],
+ 'type' => [
+ 'href' => $this->baseUrl . '/rest/type/user/user',
+ ],
+ ],
+ 'uuid' => [
+ ['value' => $author->uuid()]
+ ],
+ 'lang' => 'en',
+ ],
+ ],
+ ],
+ ];
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function getNormalizedPostEntity() {
+ return parent::getNormalizedPostEntity() + [
+ '_links' => [
+ 'type' => [
+ 'href' => $this->baseUrl . '/rest/type/comment/comment',
+ ],
+ ],
+ ];
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function getExpectedCacheContexts() {
+ // The 'url.site' cache context is added for '_links' in the response.
+ return Cache::mergeTags(parent::getExpectedCacheContexts(), ['url.site']);
+ }
+
+}
diff --git a/core/modules/hal/tests/src/Functional/EntityResource/ConfigTest/ConfigTestHalJsonAnonTest.php b/core/modules/hal/tests/src/Functional/EntityResource/ConfigTest/ConfigTestHalJsonAnonTest.php
new file mode 100644
index 000000000..45cedb2a9
--- /dev/null
+++ b/core/modules/hal/tests/src/Functional/EntityResource/ConfigTest/ConfigTestHalJsonAnonTest.php
@@ -0,0 +1,35 @@
+applyHalFieldNormalization($default_normalization);
+
+ $author = User::load(0);
+ return $normalization + [
+ '_links' => [
+ 'self' => [
+ 'href' => $this->baseUrl . '/entity_test/1?_format=hal_json',
+ ],
+ 'type' => [
+ 'href' => $this->baseUrl . '/rest/type/entity_test/entity_test',
+ ],
+ $this->baseUrl . '/rest/relation/entity_test/entity_test/user_id' => [
+ [
+ 'href' => $this->baseUrl . '/user/0?_format=hal_json',
+ 'lang' => 'en',
+ ],
+ ],
+ ],
+ '_embedded' => [
+ $this->baseUrl . '/rest/relation/entity_test/entity_test/user_id' => [
+ [
+ '_links' => [
+ 'self' => [
+ 'href' => $this->baseUrl . '/user/0?_format=hal_json',
+ ],
+ 'type' => [
+ 'href' => $this->baseUrl . '/rest/type/user/user',
+ ],
+ ],
+ 'uuid' => [
+ ['value' => $author->uuid()]
+ ],
+ 'lang' => 'en',
+ ],
+ ],
+ ],
+ ];
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function getNormalizedPostEntity() {
+ return parent::getNormalizedPostEntity() + [
+ '_links' => [
+ 'type' => [
+ 'href' => $this->baseUrl . '/rest/type/entity_test/entity_test',
+ ],
+ ],
+ ];
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function getExpectedCacheContexts() {
+ // The 'url.site' cache context is added for '_links' in the response.
+ return Cache::mergeTags(parent::getExpectedCacheContexts(), ['url.site']);
+ }
+
+}
diff --git a/core/modules/hal/tests/src/Functional/EntityResource/EntityTest/EntityTestHalJsonBasicAuthTest.php b/core/modules/hal/tests/src/Functional/EntityResource/EntityTest/EntityTestHalJsonBasicAuthTest.php
new file mode 100644
index 000000000..5604e3b54
--- /dev/null
+++ b/core/modules/hal/tests/src/Functional/EntityResource/EntityTest/EntityTestHalJsonBasicAuthTest.php
@@ -0,0 +1,30 @@
+entity instanceof FieldableEntityInterface) {
+ throw new \LogicException('This trait should only be used for fieldable entity types.');
+ }
+
+ // In the HAL normalization, all translatable fields get a 'lang' attribute.
+ $translatable_non_reference_fields = array_keys(array_filter($this->entity->getTranslatableFields(), function (FieldItemListInterface $field) {
+ return !$field instanceof EntityReferenceFieldItemListInterface;
+ }));
+ foreach ($translatable_non_reference_fields as $field_name) {
+ if (isset($normalization[$field_name])) {
+ $normalization[$field_name][0]['lang'] = 'en';
+ }
+ }
+
+ // In the HAL normalization, reference fields are omitted, except for the
+ // bundle field.
+ $bundle_key = $this->entity->getEntityType()->getKey('bundle');
+ $reference_fields = array_keys(array_filter($this->entity->getFields(), function (FieldItemListInterface $field) use ($bundle_key) {
+ return $field instanceof EntityReferenceFieldItemListInterface && $field->getName() !== $bundle_key;
+ }));
+ foreach ($reference_fields as $field_name) {
+ unset($normalization[$field_name]);
+ }
+
+ // In the HAL normalization, the bundle field omits the 'target_type' and
+ // 'target_uuid' properties, because it's encoded in the '_links' section.
+ if ($bundle_key) {
+ unset($normalization[$bundle_key][0]['target_type']);
+ unset($normalization[$bundle_key][0]['target_uuid']);
+ }
+
+ // In the HAL normalization, empty fields are omitted.
+ $empty_fields = array_keys(array_filter($this->entity->getFields(), function (FieldItemListInterface $field) {
+ return $field->isEmpty();
+ }));
+ foreach ($empty_fields as $field_name) {
+ unset($normalization[$field_name]);
+ }
+
+ return $normalization;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function removeFieldsFromNormalization(array $normalization, $field_names) {
+ $normalization = parent::removeFieldsFromNormalization($normalization, $field_names);
+ foreach ($field_names as $field_name) {
+ $relation_url = Url::fromUri('base:rest/relation/' . static::$entityTypeId . '/' . $this->entity->bundle() . '/' . $field_name)
+ ->setAbsolute(TRUE)
+ ->toString();
+ $normalization['_links'] = array_diff_key($normalization['_links'], [$relation_url => TRUE]);
+ if (isset($normalization['_embedded'])) {
+ $normalization['_embedded'] = array_diff_key($normalization['_embedded'], [$relation_url => TRUE]);
+ }
+ }
+
+ return array_diff_key($normalization, array_flip($field_names));
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function assertNormalizationEdgeCases($method, Url $url, array $request_options) {
+ // \Drupal\serialization\Normalizer\EntityNormalizer::denormalize(): entity
+ // types with bundles MUST send their bundle field to be denormalizable.
+ if ($this->entity->getEntityType()->hasKey('bundle')) {
+ $normalization = $this->getNormalizedPostEntity();
+
+ // @todo Uncomment this in https://www.drupal.org/node/2824827.
+ // @codingStandardsIgnoreStart
+/*
+ $normalization['_links']['type'] = Url::fromUri('base:rest/type/' . static::$entityTypeId . '/bad_bundle_name');
+ $request_options[RequestOptions::BODY] = $this->serializer->encode($normalization, static::$format);
+
+ // DX: 400 when incorrect entity type bundle is specified.
+ $response = $this->request($method, $url, $request_options);
+ // @todo Uncomment, remove next 3 in https://www.drupal.org/node/2813853.
+// $this->assertResourceErrorResponse(400, 'The type link relation must be specified.', $response);
+ $this->assertSame(400, $response->getStatusCode());
+ $this->assertSame([static::$mimeType], $response->getHeader('Content-Type'));
+ $this->assertSame($this->serializer->encode(['error' => 'The type link relation must be specified.'], static::$format), (string) $response->getBody());
+*/
+ // @codingStandardsIgnoreEnd
+
+ unset($normalization['_links']['type']);
+ $request_options[RequestOptions::BODY] = $this->serializer->encode($normalization, static::$format);
+
+
+ // DX: 400 when no entity type bundle is specified.
+ $response = $this->request($method, $url, $request_options);
+ // @todo Uncomment, remove next 3 in https://www.drupal.org/node/2813853.
+ // $this->assertResourceErrorResponse(400, 'The type link relation must be specified.', $response);
+ $this->assertSame(400, $response->getStatusCode());
+ $this->assertSame([static::$mimeType], $response->getHeader('Content-Type'));
+ $this->assertSame($this->serializer->encode(['error' => 'The type link relation must be specified.'], static::$format), (string) $response->getBody());
+ }
+ }
+
+}
diff --git a/core/modules/hal/tests/src/Functional/EntityResource/Node/NodeHalJsonAnonTest.php b/core/modules/hal/tests/src/Functional/EntityResource/Node/NodeHalJsonAnonTest.php
new file mode 100644
index 000000000..c7f242812
--- /dev/null
+++ b/core/modules/hal/tests/src/Functional/EntityResource/Node/NodeHalJsonAnonTest.php
@@ -0,0 +1,137 @@
+applyHalFieldNormalization($default_normalization);
+
+ $author = User::load($this->entity->getOwnerId());
+ return $normalization + [
+ '_links' => [
+ 'self' => [
+ 'href' => $this->baseUrl . '/node/1?_format=hal_json',
+ ],
+ 'type' => [
+ 'href' => $this->baseUrl . '/rest/type/node/camelids',
+ ],
+ $this->baseUrl . '/rest/relation/node/camelids/uid' => [
+ [
+ 'href' => $this->baseUrl . '/user/' . $author->id() . '?_format=hal_json',
+ 'lang' => 'en',
+ ],
+ ],
+ $this->baseUrl . '/rest/relation/node/camelids/revision_uid' => [
+ [
+ 'href' => $this->baseUrl . '/user/' . $author->id() . '?_format=hal_json',
+ ],
+ ],
+ ],
+ '_embedded' => [
+ $this->baseUrl . '/rest/relation/node/camelids/uid' => [
+ [
+ '_links' => [
+ 'self' => [
+ 'href' => $this->baseUrl . '/user/' . $author->id() . '?_format=hal_json',
+ ],
+ 'type' => [
+ 'href' => $this->baseUrl . '/rest/type/user/user',
+ ],
+ ],
+ 'uuid' => [
+ ['value' => $author->uuid()]
+ ],
+ 'lang' => 'en',
+ ],
+ ],
+ $this->baseUrl . '/rest/relation/node/camelids/revision_uid' => [
+ [
+ '_links' => [
+ 'self' => [
+ 'href' => $this->baseUrl . '/user/' . $author->id() . '?_format=hal_json',
+ ],
+ 'type' => [
+ 'href' => $this->baseUrl . '/rest/type/user/user',
+ ],
+ ],
+ 'uuid' => [
+ ['value' => $author->uuid()]
+ ],
+ ],
+ ],
+ ],
+ ];
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function getNormalizedPostEntity() {
+ return parent::getNormalizedPostEntity() + [
+ '_links' => [
+ 'type' => [
+ 'href' => $this->baseUrl . '/rest/type/node/camelids',
+ ],
+ ],
+ ];
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function getExpectedCacheContexts() {
+ // The 'url.site' cache context is added for '_links' in the response.
+ return Cache::mergeContexts(parent::getExpectedCacheContexts(), ['url.site']);
+ }
+
+}
diff --git a/core/modules/hal/tests/src/Functional/EntityResource/Node/NodeHalJsonBasicAuthTest.php b/core/modules/hal/tests/src/Functional/EntityResource/Node/NodeHalJsonBasicAuthTest.php
new file mode 100644
index 000000000..1d7bb6234
--- /dev/null
+++ b/core/modules/hal/tests/src/Functional/EntityResource/Node/NodeHalJsonBasicAuthTest.php
@@ -0,0 +1,30 @@
+applyHalFieldNormalization($default_normalization);
+
+ return $normalization + [
+ '_links' => [
+ 'self' => [
+ 'href' => $this->baseUrl . '/taxonomy/term/1?_format=hal_json',
+ ],
+ 'type' => [
+ 'href' => $this->baseUrl . '/rest/type/taxonomy_term/camelids',
+ ],
+ ],
+ ];
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function getNormalizedPostEntity() {
+ return parent::getNormalizedPostEntity() + [
+ '_links' => [
+ 'type' => [
+ 'href' => $this->baseUrl . '/rest/type/taxonomy_term/camelids',
+ ],
+ ],
+ ];
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function getExpectedCacheContexts() {
+ // The 'url.site' cache context is added for '_links' in the response.
+ return Cache::mergeContexts(parent::getExpectedCacheContexts(), ['url.site']);
+ }
+
+}
diff --git a/core/modules/hal/tests/src/Functional/EntityResource/Term/TermHalJsonBasicAuthTest.php b/core/modules/hal/tests/src/Functional/EntityResource/Term/TermHalJsonBasicAuthTest.php
new file mode 100644
index 000000000..8c7b04b65
--- /dev/null
+++ b/core/modules/hal/tests/src/Functional/EntityResource/Term/TermHalJsonBasicAuthTest.php
@@ -0,0 +1,30 @@
+applyHalFieldNormalization($default_normalization);
+
+ return $normalization + [
+ '_links' => [
+ 'self' => [
+ 'href' => $this->baseUrl . '/user/3?_format=hal_json',
+ ],
+ 'type' => [
+ 'href' => $this->baseUrl . '/rest/type/user/user',
+ ],
+ ],
+ ];
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function getNormalizedPostEntity() {
+ return parent::getNormalizedPostEntity() + [
+ '_links' => [
+ 'type' => [
+ 'href' => $this->baseUrl . '/rest/type/user/user',
+ ],
+ ],
+ ];
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function getExpectedCacheContexts() {
+ // The 'url.site' cache context is added for '_links' in the response.
+ return Cache::mergeContexts(parent::getExpectedCacheContexts(), ['url.site']);
+ }
+
+}
diff --git a/core/modules/hal/tests/src/Functional/EntityResource/User/UserHalJsonBasicAuthTest.php b/core/modules/hal/tests/src/Functional/EntityResource/User/UserHalJsonBasicAuthTest.php
new file mode 100644
index 000000000..dbf17cb54
--- /dev/null
+++ b/core/modules/hal/tests/src/Functional/EntityResource/User/UserHalJsonBasicAuthTest.php
@@ -0,0 +1,30 @@
+markTestSkipped();
+ }
+
+}
diff --git a/core/modules/hal/tests/src/Functional/EntityResource/Vocabulary/VocabularyHalJsonBasicAuthTest.php b/core/modules/hal/tests/src/Functional/EntityResource/Vocabulary/VocabularyHalJsonBasicAuthTest.php
new file mode 100644
index 000000000..4f7896e9b
--- /dev/null
+++ b/core/modules/hal/tests/src/Functional/EntityResource/Vocabulary/VocabularyHalJsonBasicAuthTest.php
@@ -0,0 +1,46 @@
+assertSame(401, $response->getStatusCode());
+ // @todo this works fine locally, but on testbot it comes back with
+ // 'text/plain; charset=UTF-8'. WTF.
+ // $this->assertSame(['application/hal+json'], $response->getHeader('Content-Type'));
+ $this->assertSame('No authentication credentials provided.', (string) $response->getBody());
+ }
+
+}
diff --git a/core/modules/hal/tests/src/Kernel/DenormalizeTest.php b/core/modules/hal/tests/src/Kernel/DenormalizeTest.php
index 64c8311f7..8f6404991 100644
--- a/core/modules/hal/tests/src/Kernel/DenormalizeTest.php
+++ b/core/modules/hal/tests/src/Kernel/DenormalizeTest.php
@@ -7,7 +7,7 @@ use Drupal\field\Entity\FieldConfig;
use Symfony\Component\Serializer\Exception\UnexpectedValueException;
/**
- * Tests that entities can be denormalized from HAL.
+ * Tests HAL denormalization edge cases for EntityResource.
*
* @group hal
*/
@@ -110,98 +110,4 @@ class DenormalizeTest extends NormalizerTestBase {
$this->assertEqual($entity->field_test_text->count(), 0);
}
- /**
- * Test that non-reference fields can be denormalized.
- */
- public function testBasicFieldDenormalization() {
- $data = array(
- '_links' => array(
- 'type' => array(
- 'href' => Url::fromUri('base:rest/type/entity_test/entity_test', array('absolute' => TRUE))->toString(),
- ),
- ),
- 'uuid' => array(
- array(
- 'value' => 'e5c9fb96-3acf-4a8d-9417-23de1b6c3311',
- ),
- ),
- 'field_test_text' => array(
- array(
- 'value' => $this->randomMachineName(),
- 'format' => 'full_html',
- ),
- ),
- 'field_test_translatable_text' => array(
- array(
- 'value' => $this->randomMachineName(),
- 'format' => 'full_html',
- ),
- array(
- 'value' => $this->randomMachineName(),
- 'format' => 'filtered_html',
- ),
- array(
- 'value' => $this->randomMachineName(),
- 'format' => 'filtered_html',
- 'lang' => 'de',
- ),
- array(
- 'value' => $this->randomMachineName(),
- 'format' => 'full_html',
- 'lang' => 'de',
- ),
- ),
- );
-
- $expected_value_default = array(
- array (
- 'value' => $data['field_test_translatable_text'][0]['value'],
- 'format' => 'full_html',
- ),
- array (
- 'value' => $data['field_test_translatable_text'][1]['value'],
- 'format' => 'filtered_html',
- ),
- );
- $expected_value_de = array(
- array (
- 'value' => $data['field_test_translatable_text'][2]['value'],
- 'format' => 'filtered_html',
- ),
- array (
- 'value' => $data['field_test_translatable_text'][3]['value'],
- 'format' => 'full_html',
- ),
- );
- $denormalized = $this->serializer->denormalize($data, $this->entityClass, $this->format);
- $this->assertEqual($data['uuid'], $denormalized->get('uuid')->getValue(), 'A preset value (e.g. UUID) is overridden by incoming data.');
- $this->assertEqual($data['field_test_text'], $denormalized->get('field_test_text')->getValue(), 'A basic text field is denormalized.');
- $this->assertEqual($expected_value_default, $denormalized->get('field_test_translatable_text')->getValue(), 'Values in the default language are properly handled for a translatable field.');
- $this->assertEqual($expected_value_de, $denormalized->getTranslation('de')->get('field_test_translatable_text')->getValue(), 'Values in a translation language are properly handled for a translatable field.');
- }
-
- /**
- * Verifies that the denormalized entity is correct in the PATCH context.
- */
- public function testPatchDenormalization() {
- $data = array(
- '_links' => array(
- 'type' => array(
- 'href' => Url::fromUri('base:rest/type/entity_test/entity_test', array('absolute' => TRUE))->toString(),
- ),
- ),
- 'field_test_text' => array(
- array(
- 'value' => $this->randomMachineName(),
- 'format' => 'full_html',
- ),
- ),
- );
- $denormalized = $this->serializer->denormalize($data, $this->entityClass, $this->format, array('request_method' => 'patch'));
- // Check that the one field got populated as expected.
- $this->assertEqual($data['field_test_text'], $denormalized->get('field_test_text')->getValue());
- // Check the custom property that contains the list of fields to merge.
- $this->assertEqual($denormalized->_restSubmittedFields, ['field_test_text']);
- }
-
}
diff --git a/core/modules/hal/tests/src/Kernel/EntityNormalizeTest.php b/core/modules/hal/tests/src/Kernel/EntityNormalizeTest.php
deleted file mode 100644
index 88db403da..000000000
--- a/core/modules/hal/tests/src/Kernel/EntityNormalizeTest.php
+++ /dev/null
@@ -1,206 +0,0 @@
-rebuild();
- $this->installSchema('system', array('sequences'));
- $this->installSchema('comment', array('comment_entity_statistics'));
- $this->installEntitySchema('taxonomy_term');
- $this->installConfig(['node', 'comment']);
- }
-
- /**
- * Tests the normalization of nodes.
- */
- public function testNode() {
- $node_type = NodeType::create(['type' => 'example_type']);
- $node_type->save();
-
- $user = User::create(['name' => $this->randomMachineName()]);
- $user->save();
-
- // Add comment type.
- $this->container->get('entity.manager')->getStorage('comment_type')->create(array(
- 'id' => 'comment',
- 'label' => 'comment',
- 'target_entity_type_id' => 'node',
- ))->save();
-
- $this->addDefaultCommentField('node', 'example_type');
-
- $node = Node::create([
- 'title' => $this->randomMachineName(),
- 'uid' => $user->id(),
- 'type' => $node_type->id(),
- 'status' => NODE_PUBLISHED,
- 'promote' => 1,
- 'sticky' => 0,
- 'body' => [
- 'value' => $this->randomMachineName(),
- 'format' => $this->randomMachineName()
- ],
- 'revision_log' => $this->randomString(),
- ]);
- $node->save();
-
- $original_values = $node->toArray();
-
- $normalized = $this->serializer->normalize($node, $this->format);
-
- /** @var \Drupal\node\NodeInterface $denormalized_node */
- $denormalized_node = $this->serializer->denormalize($normalized, 'Drupal\node\Entity\Node', $this->format);
-
- $this->assertEqual($original_values, $denormalized_node->toArray(), 'Node values are restored after normalizing and denormalizing.');
- }
-
- /**
- * Tests the normalization of terms.
- */
- public function testTerm() {
- $vocabulary = Vocabulary::create(['vid' => 'example_vocabulary']);
- $vocabulary->save();
-
- $account = User::create(['name' => $this->randomMachineName()]);
- $account->save();
-
- // @todo Until https://www.drupal.org/node/2327935 is fixed, if no parent is
- // set, the test fails because target_id => 0 is reserialized to NULL.
- $term_parent = Term::create([
- 'name' => $this->randomMachineName(),
- 'vid' => $vocabulary->id(),
- ]);
- $term_parent->save();
- $term = Term::create([
- 'name' => $this->randomMachineName(),
- 'vid' => $vocabulary->id(),
- 'description' => array(
- 'value' => $this->randomMachineName(),
- 'format' => $this->randomMachineName(),
- ),
- 'parent' => $term_parent->id(),
- ]);
- $term->save();
-
- $original_values = $term->toArray();
-
- $normalized = $this->serializer->normalize($term, $this->format, ['account' => $account]);
-
- /** @var \Drupal\taxonomy\TermInterface $denormalized_term */
- $denormalized_term = $this->serializer->denormalize($normalized, 'Drupal\taxonomy\Entity\Term', $this->format, ['account' => $account]);
-
- $this->assertEqual($original_values, $denormalized_term->toArray(), 'Term values are restored after normalizing and denormalizing.');
- }
-
- /**
- * Tests the normalization of comments.
- */
- public function testComment() {
- $node_type = NodeType::create(['type' => 'example_type']);
- $node_type->save();
-
- $account = User::create(['name' => $this->randomMachineName()]);
- $account->save();
-
- // Add comment type.
- $this->container->get('entity.manager')->getStorage('comment_type')->create(array(
- 'id' => 'comment',
- 'label' => 'comment',
- 'target_entity_type_id' => 'node',
- ))->save();
-
- $this->addDefaultCommentField('node', 'example_type');
-
- $node = Node::create([
- 'title' => $this->randomMachineName(),
- 'uid' => $account->id(),
- 'type' => $node_type->id(),
- 'status' => NODE_PUBLISHED,
- 'promote' => 1,
- 'sticky' => 0,
- 'body' => [[
- 'value' => $this->randomMachineName(),
- 'format' => $this->randomMachineName()
- ]],
- ]);
- $node->save();
-
- $parent_comment = Comment::create(array(
- 'uid' => $account->id(),
- 'subject' => $this->randomMachineName(),
- 'comment_body' => [
- 'value' => $this->randomMachineName(),
- 'format' => NULL,
- ],
- 'entity_id' => $node->id(),
- 'entity_type' => 'node',
- 'field_name' => 'comment',
- ));
- $parent_comment->save();
-
- $comment = Comment::create(array(
- 'uid' => $account->id(),
- 'subject' => $this->randomMachineName(),
- 'comment_body' => [
- 'value' => $this->randomMachineName(),
- 'format' => NULL,
- ],
- 'entity_id' => $node->id(),
- 'entity_type' => 'node',
- 'field_name' => 'comment',
- 'pid' => $parent_comment->id(),
- 'mail' => 'dries@drupal.org',
- 'homepage' => 'http://buytaert.net',
- ));
- $comment->save();
-
- $original_values = $comment->toArray();
- // Hostname will always be denied view access.
- // No value will exist for name as this is only for anonymous users.
- unset($original_values['hostname'], $original_values['name']);
-
- $normalized = $this->serializer->normalize($comment, $this->format, ['account' => $account]);
-
- // Assert that the hostname field does not appear at all in the normalized
- // data.
- $this->assertFalse(array_key_exists('hostname', $normalized), 'Hostname was not found in normalized comment data.');
-
- /** @var \Drupal\comment\CommentInterface $denormalized_comment */
- $denormalized_comment = $this->serializer->denormalize($normalized, 'Drupal\comment\Entity\Comment', $this->format, ['account' => $account]);
-
- // Before comparing, unset values that are expected to differ.
- $denormalized_comment_values = $denormalized_comment->toArray();
- unset($denormalized_comment_values['hostname'], $denormalized_comment_values['name']);
- $this->assertEqual($original_values, $denormalized_comment_values, 'The expected comment values are restored after normalizing and denormalizing.');
- }
-
-}
diff --git a/core/modules/hal/tests/src/Kernel/NormalizeTest.php b/core/modules/hal/tests/src/Kernel/NormalizeTest.php
index 6ed064c3f..cfffb4a86 100644
--- a/core/modules/hal/tests/src/Kernel/NormalizeTest.php
+++ b/core/modules/hal/tests/src/Kernel/NormalizeTest.php
@@ -7,7 +7,7 @@ use Drupal\Core\Url;
use Drupal\entity_test\Entity\EntityTest;
/**
- * Tests that entities can be normalized in HAL.
+ * Tests HAL normalization edge cases for EntityResource.
*
* @group hal
*/
diff --git a/core/modules/language/migration_templates/d6_language_negotiation_settings.yml b/core/modules/language/migration_templates/d6_language_negotiation_settings.yml
new file mode 100644
index 000000000..abc71f68f
--- /dev/null
+++ b/core/modules/language/migration_templates/d6_language_negotiation_settings.yml
@@ -0,0 +1,34 @@
+id: d6_language_negotiation_settings
+label: Language negotiation settings
+migration_tags:
+ - Drupal 6
+source:
+ plugin: variable
+ variables:
+ - language_negotiation
+process:
+ session/parameter:
+ plugin: default_value
+ default_value: 'language'
+ selected_langcode:
+ plugin: default_value
+ default_value: 'site_default'
+ url/source:
+ plugin: static_map
+ source: language_negotiation
+ default_value: path_prefix
+ map:
+ # LANGUAGE_NEGOTIATION_NONE = 0
+ # LANGUAGE_NEGOTIATION_PATH_DEFAULT = 1
+ # LANGUAGE_NEGOTIATION_PATH = 2
+ # LANGUAGE_NEGOTIATION_DOMAIN = 3
+ 0: path_prefix
+ 1: path_prefix
+ 2: path_prefix
+ 3: domain
+destination:
+ plugin: config
+ config_name: language.negotiation
+migration_dependencies:
+ required:
+ - language
diff --git a/core/modules/language/migration_templates/d6_language_types.yml b/core/modules/language/migration_templates/d6_language_types.yml
new file mode 100644
index 000000000..05ce3001e
--- /dev/null
+++ b/core/modules/language/migration_templates/d6_language_types.yml
@@ -0,0 +1,52 @@
+id: d6_language_types
+label: Language types
+migration_tags:
+ - Drupal 6
+source:
+ plugin: variable
+ variables:
+ - language_negotiation
+process:
+ all:
+ plugin: default_value
+ default_value:
+ - 'language_interface'
+ - 'language_content'
+ - 'language_url'
+ configurable:
+ plugin: default_value
+ default_value:
+ - 'language_interface'
+ negotiation/language_content/enabled:
+ plugin: default_value
+ default_value:
+ 'language-interface': 0
+ negotiation/language_url/enabled:
+ plugin: default_value
+ default_value:
+ 'language-url': 0
+ 'language-url-fallback': 1
+ negotiation/language_interface/enabled:
+ plugin: static_map
+ source: language_negotiation
+ map:
+ # LANGUAGE_NEGOTIATION_NONE = 0
+ # LANGUAGE_NEGOTIATION_PATH_DEFAULT = 1
+ # LANGUAGE_NEGOTIATION_PATH = 2
+ # LANGUAGE_NEGOTIATION_DOMAIN = 3
+ 0:
+ 'language-selected': 0
+ 1:
+ 'language-url': 0
+ 'language-selected': 1
+ 2:
+ 'language-url': 0
+ 'language-user': 1
+ 'language-browser': 2
+ 'language-selected': 3
+ 3:
+ 'language-url': 0
+ 'language-selected': 1
+destination:
+ plugin: config
+ config_name: language.types
diff --git a/core/modules/language/migration_templates/d7_language_negotiation_settings.yml b/core/modules/language/migration_templates/d7_language_negotiation_settings.yml
index f03be789e..775996533 100644
--- a/core/modules/language/migration_templates/d7_language_negotiation_settings.yml
+++ b/core/modules/language/migration_templates/d7_language_negotiation_settings.yml
@@ -8,8 +8,25 @@ source:
- locale_language_negotiation_session_param
- locale_language_negotiation_url_part
process:
- 'session/parameter': locale_language_negotiation_session_param
- 'url/source': locale_language_negotiation_url_part
+ session/parameter:
+ plugin: default_value
+ source: locale_language_negotiation_session_param
+ default_value: 'language'
+ selected_langcode:
+ plugin: default_value
+ default_value: 'site_default'
+ url/source:
+ plugin: static_map
+ source: locale_language_negotiation_url_part
+ default_value: path_prefix
+ map:
+ # LOCALE_LANGUAGE_NEGOTIATION_URL_PREFIX = 0
+ # LOCALE_LANGUAGE_NEGOTIATION_URL_DOMAIN = 1
+ 0: path_prefix
+ 1: domain
destination:
plugin: config
config_name: language.negotiation
+migration_dependencies:
+ required:
+ - language
diff --git a/core/modules/language/migration_templates/d7_language_types.yml b/core/modules/language/migration_templates/d7_language_types.yml
new file mode 100644
index 000000000..3a634a2e6
--- /dev/null
+++ b/core/modules/language/migration_templates/d7_language_types.yml
@@ -0,0 +1,40 @@
+id: d7_language_types
+label: Language types
+migration_tags:
+ - Drupal 7
+source:
+ plugin: variable
+ variables:
+ - language_types
+ - language_negotiation_language
+ - language_negotiation_language_content
+ - language_negotiation_language_url
+ - locale_language_providers_weight_language
+ - locale_language_providers_weight_language_content
+ - locale_language_providers_weight_language_url
+process:
+ all:
+ plugin: language_types
+ source: language_types
+ configurable:
+ plugin: language_types
+ source: language_types
+ filter_configurable: true
+ negotiation/language_content:
+ plugin: language_negotiation
+ source:
+ - language_negotiation_language_content
+ - locale_language_providers_weight_language_content
+ negotiation/language_url:
+ plugin: language_negotiation
+ source:
+ - language_negotiation_language_url
+ - locale_language_providers_weight_language_url
+ negotiation/language_interface:
+ plugin: language_negotiation
+ source:
+ - language_negotiation_language
+ - locale_language_providers_weight_language
+destination:
+ plugin: config
+ config_name: language.types
diff --git a/core/modules/language/migration_templates/language_prefixes_and_domains.yml b/core/modules/language/migration_templates/language_prefixes_and_domains.yml
new file mode 100644
index 000000000..edc5b549d
--- /dev/null
+++ b/core/modules/language/migration_templates/language_prefixes_and_domains.yml
@@ -0,0 +1,26 @@
+id: language_prefixes_and_domains
+label: Language prefixes and domains
+migration_tags:
+ - Drupal 6
+ - Drupal 7
+source:
+ plugin: language
+ fetch_all: true
+ domain_negotiation: true
+process:
+ url/prefixes:
+ plugin: array_build
+ source: languages
+ key: language
+ value: prefix
+ url/domains:
+ plugin: language_domains
+ source: languages
+ key: language
+ value: domain
+destination:
+ plugin: config
+ config_name: language.negotiation
+migration_dependencies:
+ required:
+ - language
diff --git a/core/modules/language/src/Plugin/LanguageNegotiation/LanguageNegotiationUrl.php b/core/modules/language/src/Plugin/LanguageNegotiation/LanguageNegotiationUrl.php
index a1d4da410..25b5484a9 100644
--- a/core/modules/language/src/Plugin/LanguageNegotiation/LanguageNegotiationUrl.php
+++ b/core/modules/language/src/Plugin/LanguageNegotiation/LanguageNegotiationUrl.php
@@ -192,6 +192,7 @@ class LanguageNegotiationUrl extends LanguageNegotiationMethodBase implements In
*/
public function getLanguageSwitchLinks(Request $request, $type, Url $url) {
$links = array();
+ $query = $request->query->all();
foreach ($this->languageManager->getNativeLanguages() as $language) {
$links[$language->getId()] = array(
@@ -202,6 +203,7 @@ class LanguageNegotiationUrl extends LanguageNegotiationMethodBase implements In
'title' => $language->getName(),
'language' => $language,
'attributes' => array('class' => array('language-link')),
+ 'query' => $query,
);
}
diff --git a/core/modules/language/src/Plugin/migrate/process/LanguageDomains.php b/core/modules/language/src/Plugin/migrate/process/LanguageDomains.php
new file mode 100644
index 000000000..2fcf7d759
--- /dev/null
+++ b/core/modules/language/src/Plugin/migrate/process/LanguageDomains.php
@@ -0,0 +1,44 @@
+getSourceProperty('domain_negotiation')) {
+ global $base_url;
+
+ foreach ($value as $old_key => $old_value) {
+ if (empty($old_value['domain'])) {
+ // The default language domain might be empty.
+ // If it is, use the current domain.
+ $value[$old_key]['domain'] = parse_url($base_url, PHP_URL_HOST);
+ }
+ else {
+ // Ensure we have a protocol when checking for the hostname.
+ $domain = 'http://' . str_replace(['http://', 'https://'], '', $old_value['domain']);
+ // Only keep the host part of the domain.
+ $value[$old_key]['domain'] = parse_url($domain, PHP_URL_HOST);
+ }
+ }
+ }
+
+ return parent::transform($value, $migrate_executable, $row, $destination_property);
+ }
+
+}
diff --git a/core/modules/language/src/Plugin/migrate/process/LanguageNegotiation.php b/core/modules/language/src/Plugin/migrate/process/LanguageNegotiation.php
new file mode 100644
index 000000000..837dbbbc6
--- /dev/null
+++ b/core/modules/language/src/Plugin/migrate/process/LanguageNegotiation.php
@@ -0,0 +1,81 @@
+ [],
+ 'method_weights' => [],
+ ];
+
+ if (!is_array($value)) {
+ throw new MigrateException('The input should be an array');
+ }
+
+ // If no weights are provided, use the keys by flipping the array.
+ if (empty($value[1])) {
+ $new_value['enabled'] = array_flip(array_map([$this, 'mapNewMethods'], array_keys($value[0])));
+ unset($new_value['method_weights']);
+ }
+ else {
+ foreach ($value[1] as $method => $weight) {
+ $new_method = $this->mapNewMethods($method);
+ $new_value['method_weights'][$new_method] = $weight;
+ if (in_array($method, array_keys($value[0]))) {
+ $new_value['enabled'][$new_method] = $weight;
+ }
+ }
+ }
+
+ return $new_value;
+ }
+
+ /**
+ * Maps old negotiation method names to the new ones.
+ *
+ * @param string $value
+ * The old negotiation method name.
+ *
+ * @return string
+ * The new negotiation method name.
+ */
+ protected function mapNewMethods($value) {
+ switch ($value) {
+ case 'language-default':
+ return 'language-selected';
+ case 'locale-browser':
+ return 'language-browser';
+ case 'locale-interface':
+ return 'language-interface';
+ case 'locale-session':
+ return 'language-session';
+ case 'locale-url':
+ return 'language-url';
+ case 'locale-url-fallback':
+ return 'language-url-fallback';
+ case 'locale-user':
+ return 'language-user';
+ default:
+ return $value;
+ }
+ }
+
+}
diff --git a/core/modules/language/src/Plugin/migrate/process/LanguageTypes.php b/core/modules/language/src/Plugin/migrate/process/LanguageTypes.php
new file mode 100644
index 000000000..bc09dd77d
--- /dev/null
+++ b/core/modules/language/src/Plugin/migrate/process/LanguageTypes.php
@@ -0,0 +1,40 @@
+configuration['filter_configurable'])) {
+ $value = array_filter($value);
+ }
+
+ return array_keys($value);
+ }
+
+}
diff --git a/core/modules/language/src/Plugin/migrate/source/Language.php b/core/modules/language/src/Plugin/migrate/source/Language.php
index 01a0ccf3c..dc2e0ce38 100644
--- a/core/modules/language/src/Plugin/migrate/source/Language.php
+++ b/core/modules/language/src/Plugin/migrate/source/Language.php
@@ -2,6 +2,7 @@
namespace Drupal\language\Plugin\migrate\source;
+use Drupal\migrate\Row;
use Drupal\migrate_drupal\Plugin\migrate\source\DrupalSqlBase;
/**
@@ -49,4 +50,27 @@ class Language extends DrupalSqlBase {
return $this->select('languages')->fields('languages');
}
+ /**
+ * {@inheritdoc}
+ */
+ public function prepareRow(Row $row) {
+ if (!empty($this->configuration['fetch_all'])) {
+ // Get an array of all languages.
+ $languages = $this->query()->execute()->fetchAll();
+ $row->setSourceProperty('languages', $languages);
+ }
+
+ if (!empty($this->configuration['domain_negotiation'])) {
+ // Check if domain negotiation is used to be able to fill in the default
+ // language domain, which may be empty. In D6, domain negotiation is used
+ // when the 'language_negotiation' variable is set to '3', and in D7, when
+ // the 'locale_language_negotiation_url_part' variable is set to '1'.
+ if ($this->variableGet('language_negotiation', 0) == 3 || $this->variableGet('locale_language_negotiation_url_part', 0) == 1) {
+ $row->setSourceProperty('domain_negotiation', TRUE);
+ }
+ }
+
+ return parent::prepareRow($row);
+ }
+
}
diff --git a/core/modules/language/src/Tests/LanguageSwitchingTest.php b/core/modules/language/src/Tests/LanguageSwitchingTest.php
index c076e6f1e..5d4469d3a 100644
--- a/core/modules/language/src/Tests/LanguageSwitchingTest.php
+++ b/core/modules/language/src/Tests/LanguageSwitchingTest.php
@@ -118,8 +118,9 @@ class LanguageSwitchingTest extends WebTestBase {
protected function doTestLanguageBlockAnonymous($block_label) {
$this->drupalLogout();
- // Assert that the language switching block is displayed on the frontpage.
- $this->drupalGet('');
+ // Assert that the language switching block is displayed on the frontpage
+ // and ensure that the active class is added when query params are present.
+ $this->drupalGet('', ['query' => ['foo' => 'bar']]);
$this->assertText($block_label, 'Language switcher block found.');
// Assert that only the current language is marked as active.
diff --git a/core/modules/language/tests/src/Kernel/Migrate/d6/MigrateLanguageNegotiationSettingsTest.php b/core/modules/language/tests/src/Kernel/Migrate/d6/MigrateLanguageNegotiationSettingsTest.php
new file mode 100644
index 000000000..0e74f494a
--- /dev/null
+++ b/core/modules/language/tests/src/Kernel/Migrate/d6/MigrateLanguageNegotiationSettingsTest.php
@@ -0,0 +1,167 @@
+executeMigrations([
+ 'language',
+ 'd6_language_negotiation_settings',
+ 'language_prefixes_and_domains',
+ 'd6_language_types',
+ ]);
+
+ $config = $this->config('language.negotiation');
+ $this->assertSame($config->get('session.parameter'), 'language');
+ $this->assertSame($config->get('url.source'), LanguageNegotiationUrl::CONFIG_PATH_PREFIX);
+ $this->assertSame($config->get('selected_langcode'), 'site_default');
+ $expected_prefixes = [
+ 'en' => '',
+ 'fr' => 'fr',
+ 'zu' => 'zu',
+ ];
+ $this->assertSame($config->get('url.prefixes'), $expected_prefixes);
+
+ $config = $this->config('language.types');
+ $this->assertSame($config->get('all'), ['language_interface', 'language_content', 'language_url']);
+ $this->assertSame($config->get('configurable'), ['language_interface']);
+ $this->assertSame($config->get('negotiation.language_content.enabled'), ['language-interface' => 0]);
+ $this->assertSame($config->get('negotiation.language_url.enabled'), ['language-url' => 0, 'language-url-fallback' => 1]);
+ $expected_language_interface = [
+ 'language-url' => 0,
+ 'language-selected' => 1,
+ ];
+ $this->assertSame($config->get('negotiation.language_interface.enabled'), $expected_language_interface);
+ }
+
+ /**
+ * Tests the migration with LANGUAGE_NEGOTIATION_NONE.
+ */
+ public function testLanguageNegotiationWithNoNegotiation() {
+ $this->sourceDatabase->update('variable')
+ ->fields(array('value' => serialize(0)))
+ ->condition('name', 'language_negotiation')
+ ->execute();
+
+ $this->executeMigrations([
+ 'language',
+ 'd6_language_negotiation_settings',
+ 'language_prefixes_and_domains',
+ 'd6_language_types',
+ ]);
+
+ $config = $this->config('language.negotiation');
+ $this->assertSame($config->get('session.parameter'), 'language');
+ $this->assertSame($config->get('url.source'), LanguageNegotiationUrl::CONFIG_PATH_PREFIX);
+ $this->assertSame($config->get('selected_langcode'), 'site_default');
+
+ $config = $this->config('language.types');
+ $this->assertSame($config->get('all'), ['language_interface', 'language_content', 'language_url']);
+ $this->assertSame($config->get('configurable'), ['language_interface']);
+ $this->assertSame($config->get('negotiation.language_content.enabled'), ['language-interface' => 0]);
+ $this->assertSame($config->get('negotiation.language_url.enabled'), ['language-url' => 0, 'language-url-fallback' => 1]);
+ $expected_language_interface = [
+ 'language-selected' => 0,
+ ];
+ $this->assertSame($config->get('negotiation.language_interface.enabled'), $expected_language_interface);
+ }
+
+ /**
+ * Tests the migration with LANGUAGE_NEGOTIATION_PATH.
+ */
+ public function testLanguageNegotiationWithPathPrefix() {
+ $this->sourceDatabase->update('variable')
+ ->fields(array('value' => serialize(2)))
+ ->condition('name', 'language_negotiation')
+ ->execute();
+
+ $this->executeMigrations([
+ 'language',
+ 'd6_language_negotiation_settings',
+ 'language_prefixes_and_domains',
+ 'd6_language_types',
+ ]);
+
+ $config = $this->config('language.negotiation');
+ $this->assertSame($config->get('session.parameter'), 'language');
+ $this->assertSame($config->get('url.source'), LanguageNegotiationUrl::CONFIG_PATH_PREFIX);
+ $this->assertSame($config->get('selected_langcode'), 'site_default');
+ $expected_prefixes = [
+ 'en' => '',
+ 'fr' => 'fr',
+ 'zu' => 'zu',
+ ];
+ $this->assertSame($config->get('url.prefixes'), $expected_prefixes);
+
+ $config = $this->config('language.types');
+ $this->assertSame($config->get('all'), ['language_interface', 'language_content', 'language_url']);
+ $this->assertSame($config->get('configurable'), ['language_interface']);
+ $this->assertSame($config->get('negotiation.language_content.enabled'), ['language-interface' => 0]);
+ $this->assertSame($config->get('negotiation.language_url.enabled'), ['language-url' => 0, 'language-url-fallback' => 1]);
+ $expected_language_interface = [
+ 'language-url' => 0,
+ 'language-user' => 1,
+ 'language-browser' => 2,
+ 'language-selected' => 3,
+ ];
+ $this->assertSame($config->get('negotiation.language_interface.enabled'), $expected_language_interface);
+ }
+
+ /**
+ * Tests the migration with LANGUAGE_NEGOTIATION_DOMAIN.
+ */
+ public function testLanguageNegotiationWithDomain() {
+ $this->sourceDatabase->update('variable')
+ ->fields(array('value' => serialize(3)))
+ ->condition('name', 'language_negotiation')
+ ->execute();
+
+ $this->executeMigrations([
+ 'language',
+ 'd6_language_negotiation_settings',
+ 'language_prefixes_and_domains',
+ 'd6_language_types',
+ ]);
+
+ global $base_url;
+ $config = $this->config('language.negotiation');
+ $this->assertSame($config->get('session.parameter'), 'language');
+ $this->assertSame($config->get('url.source'), LanguageNegotiationUrl::CONFIG_DOMAIN);
+ $this->assertSame($config->get('selected_langcode'), 'site_default');
+ $expected_domains = [
+ 'en' => parse_url($base_url, PHP_URL_HOST),
+ 'fr' => 'fr.drupal.org',
+ 'zu' => 'zu.drupal.org',
+ ];
+ $this->assertSame($config->get('url.domains'), $expected_domains);
+
+ $config = $this->config('language.types');
+ $this->assertSame($config->get('all'), ['language_interface', 'language_content', 'language_url']);
+ $this->assertSame($config->get('configurable'), ['language_interface']);
+ $this->assertSame($config->get('negotiation.language_content.enabled'), ['language-interface' => 0]);
+ $this->assertSame($config->get('negotiation.language_url.enabled'), ['language-url' => 0, 'language-url-fallback' => 1]);
+ $expected_language_interface = [
+ 'language-url' => 0,
+ 'language-selected' => 1,
+ ];
+ $this->assertSame($config->get('negotiation.language_interface.enabled'), $expected_language_interface);
+ }
+
+}
diff --git a/core/modules/language/tests/src/Kernel/Migrate/d7/MigrateLanguageNegotiationSettingsTest.php b/core/modules/language/tests/src/Kernel/Migrate/d7/MigrateLanguageNegotiationSettingsTest.php
index f9ac1c85a..269bac697 100644
--- a/core/modules/language/tests/src/Kernel/Migrate/d7/MigrateLanguageNegotiationSettingsTest.php
+++ b/core/modules/language/tests/src/Kernel/Migrate/d7/MigrateLanguageNegotiationSettingsTest.php
@@ -2,37 +2,124 @@
namespace Drupal\Tests\language\Kernel\Migrate\d7;
+use Drupal\language\Plugin\LanguageNegotiation\LanguageNegotiationUrl;
use Drupal\Tests\migrate_drupal\Kernel\d7\MigrateDrupal7TestBase;
/**
- * Tests migration of language negotiation variables.
+ * Tests the migration of language negotiation.
*
- * @group language
+ * @group migrate_drupal_7
*/
class MigrateLanguageNegotiationSettingsTest extends MigrateDrupal7TestBase {
/**
- * Modules to enable.
- *
- * @var array
+ * {@inheritdoc}
*/
public static $modules = ['language'];
/**
- * {@inheritdoc}
+ * Tests migration of language types variables to language.types.yml.
*/
- protected function setUp() {
- parent::setUp();
- $this->executeMigration('d7_language_negotiation_settings');
+ public function testLanguageTypes() {
+ $this->executeMigrations([
+ 'language',
+ 'd7_language_negotiation_settings',
+ 'd7_language_types',
+ ]);
+
+ $config = $this->config('language.types');
+ $this->assertSame($config->get('all'), ['language_content', 'language_url', 'language_interface']);
+ $this->assertSame($config->get('configurable'), ['language_interface']);
+ $this->assertSame($config->get('negotiation.language_content'), ['enabled' => ['language-interface' => 0]]);
+ $this->assertSame($config->get('negotiation.language_url'), ['enabled' => ['language-url' => 0, 'language-url-fallback' => 1]]);
+ $expected_language_interface = [
+ 'enabled' => [
+ 'language-url' => -9,
+ 'language-user' => -10,
+ 'language-selected' => -6,
+ ],
+ 'method_weights' => [
+ 'language-url' => -9,
+ 'language-session' => -8,
+ 'language-user' => -10,
+ 'language-browser' => -7,
+ 'language-selected' => -6,
+ ],
+ ];
+ $this->assertSame($config->get('negotiation.language_interface'), $expected_language_interface);
}
/**
- * Tests migration of language negotiation variables to language.negotiation.yml.
+ * Tests the migration with prefix negotiation.
*/
- public function testLanguageNegotiation() {
+ public function testLanguageNegotiationWithPrefix() {
+ $this->executeMigrations([
+ 'language',
+ 'd7_language_negotiation_settings',
+ 'language_prefixes_and_domains',
+ ]);
+
$config = $this->config('language.negotiation');
- $this->assertIdentical($config->get('session.parameter'), 'language');
- $this->assertIdentical($config->get('url.source'), 'domain');
+ $this->assertSame($config->get('session.parameter'), 'language');
+ $this->assertSame($config->get('url.source'), LanguageNegotiationUrl::CONFIG_PATH_PREFIX);
+ $this->assertSame($config->get('selected_langcode'), 'site_default');
+ $expected_prefixes = [
+ 'en' => '',
+ 'is' => 'is',
+ ];
+ $this->assertSame($config->get('url.prefixes'), $expected_prefixes);
+ }
+
+ /**
+ * Tests the migration with domain negotiation.
+ */
+ public function testLanguageNegotiationWithDomain() {
+ $this->sourceDatabase->update('variable')
+ ->fields(array('value' => serialize(1)))
+ ->condition('name', 'locale_language_negotiation_url_part')
+ ->execute();
+
+ $this->executeMigrations([
+ 'language',
+ 'd7_language_negotiation_settings',
+ 'language_prefixes_and_domains',
+ ]);
+
+ global $base_url;
+ $config = $this->config('language.negotiation');
+ $this->assertSame($config->get('session.parameter'), 'language');
+ $this->assertSame($config->get('url.source'), LanguageNegotiationUrl::CONFIG_DOMAIN);
+ $this->assertSame($config->get('selected_langcode'), 'site_default');
+ $expected_domains = [
+ 'en' => parse_url($base_url, PHP_URL_HOST),
+ 'is' => 'is.drupal.org',
+ ];
+ $this->assertSame($config->get('url.domains'), $expected_domains);
+ }
+
+ /**
+ * Tests the migration with non-existent variables.
+ */
+ public function testLanguageNegotiationWithNonExistentVariables() {
+ $this->sourceDatabase->delete('variable')
+ ->condition('name', ['local_language_negotiation_url_part', 'local_language_negotiation_session_param'], 'IN')
+ ->execute();
+
+ $this->executeMigrations([
+ 'language',
+ 'd6_language_negotiation_settings',
+ 'language_prefixes_and_domains',
+ ]);
+
+ $config = $this->config('language.negotiation');
+ $this->assertSame($config->get('session.parameter'), 'language');
+ $this->assertSame($config->get('url.source'), LanguageNegotiationUrl::CONFIG_PATH_PREFIX);
+ $this->assertSame($config->get('selected_langcode'), 'site_default');
+ $expected_prefixes = [
+ 'en' => '',
+ 'is' => 'is',
+ ];
+ $this->assertSame($config->get('url.prefixes'), $expected_prefixes);
}
}
diff --git a/core/modules/language/tests/src/Unit/process/LanguageDomainsTest.php b/core/modules/language/tests/src/Unit/process/LanguageDomainsTest.php
new file mode 100644
index 000000000..022fc4e6c
--- /dev/null
+++ b/core/modules/language/tests/src/Unit/process/LanguageDomainsTest.php
@@ -0,0 +1,62 @@
+ 'language',
+ 'value' => 'domain',
+ ];
+ $this->plugin = new LanguageDomains($configuration, 'map', []);
+ parent::setUp();
+
+ // The language_domains plugin calls getSourceProperty() to check if domain
+ // negotiation is used. If it is the values will be processed so we need it
+ // to return TRUE to be able to test the process.
+ $this->row->expects($this->once())
+ ->method('getSourceProperty')
+ ->will($this->returnValue(TRUE));
+
+ // The language_domains plugin use $base_url to fill empty domains.
+ global $base_url;
+ $base_url = 'http://example.com';
+ }
+
+ /**
+ * @covers ::transform
+ */
+ public function testTransform() {
+ $source = [
+ ['language' => 'en', 'domain' => ''],
+ ['language' => 'fr', 'domain' => 'fr.example.com'],
+ ['language' => 'es', 'domain' => 'http://es.example.com'],
+ ['language' => 'hu', 'domain' => 'https://hu.example.com'],
+ ];
+ $expected = [
+ 'en' => 'example.com',
+ 'fr' => 'fr.example.com',
+ 'es' => 'es.example.com',
+ 'hu' => 'hu.example.com',
+ ];
+ $value = $this->plugin->transform($source, $this->migrateExecutable, $this->row, 'destinationproperty');
+ $this->assertSame($value, $expected);
+ }
+
+}
diff --git a/core/modules/language/tests/src/Unit/process/LanguageNegotiationTest.php b/core/modules/language/tests/src/Unit/process/LanguageNegotiationTest.php
new file mode 100644
index 000000000..c6e62fbc4
--- /dev/null
+++ b/core/modules/language/tests/src/Unit/process/LanguageNegotiationTest.php
@@ -0,0 +1,87 @@
+plugin = new LanguageNegotiation([], 'map', []);
+ parent::setUp();
+ }
+
+ /**
+ * Tests successful transformation without weights.
+ */
+ public function testTransformWithWeights() {
+ $source = [
+ [
+ 'locale-url' => [],
+ 'language-default' => [],
+ ],
+ [
+ 'locale-url' => -10,
+ 'locale-session' => -9,
+ 'locale-user' => -8,
+ 'locale-browser' => -7,
+ 'language-default' => -6,
+ ],
+ ];
+ $expected = [
+ 'enabled' => [
+ 'language-url' => -10,
+ 'language-selected' => -6,
+ ],
+ 'method_weights' => [
+ 'language-url' => -10,
+ 'language-session' => -9,
+ 'language-user' => -8,
+ 'language-browser' => -7,
+ 'language-selected' => -6,
+ ],
+ ];
+ $value = $this->plugin->transform($source, $this->migrateExecutable, $this->row, 'destinationproperty');
+ $this->assertSame($value, $expected);
+ }
+
+ /**
+ * Tests successful transformation without weights.
+ */
+ public function testTransformWithoutWeights() {
+ $source = [
+ [
+ 'locale-url' => [],
+ 'locale-url-fallback' => [],
+ ],
+ ];
+ $expected = [
+ 'enabled' => [
+ 'language-url' => 0,
+ 'language-url-fallback' => 1,
+ ],
+ ];
+ $value = $this->plugin->transform($source, $this->migrateExecutable, $this->row, 'destinationproperty');
+ $this->assertSame($value, $expected);
+ }
+
+ /**
+ * Tests string input.
+ *
+ * @expectedException \Drupal\migrate\MigrateException
+ * @expectedExceptionMessage The input should be an array
+ */
+ public function testStringInput() {
+ $this->plugin = new LanguageNegotiation([], 'map', []);
+ $this->plugin->transform('foo', $this->migrateExecutable, $this->row, 'destinationproperty');
+ }
+
+}
diff --git a/core/modules/language/tests/src/Unit/process/LanguageTypesTest.php b/core/modules/language/tests/src/Unit/process/LanguageTypesTest.php
new file mode 100644
index 000000000..17cf412a3
--- /dev/null
+++ b/core/modules/language/tests/src/Unit/process/LanguageTypesTest.php
@@ -0,0 +1,61 @@
+plugin = new LanguageTypes([], 'map', []);
+ $source = [
+ 'language' => TRUE,
+ 'language_url' => FALSE,
+ 'language_content' => FALSE,
+ ];
+ $expected = [
+ 0 => 'language_url',
+ 1 => 'language_content',
+ 2 => 'language_interface',
+ ];
+ $value = $this->plugin->transform($source, $this->migrateExecutable, $this->row, 'destinationproperty');
+ $this->assertSame($value, $expected);
+ }
+
+ /**
+ * Tests successful transformation of configurable language types.
+ */
+ public function testTransformConfigurable() {
+ $this->plugin = new LanguageTypes(['filter_configurable' => TRUE], 'map', []);
+ $source = [
+ 'language' => TRUE,
+ 'language_url' => FALSE,
+ 'language_content' => FALSE,
+ ];
+ $expected = [
+ 0 => 'language_interface',
+ ];
+ $value = $this->plugin->transform($source, $this->migrateExecutable, $this->row, 'destinationproperty');
+ $this->assertSame($value, $expected);
+ }
+
+ /**
+ * Tests string input.
+ *
+ * @expectedException \Drupal\migrate\MigrateException
+ * @expectedExceptionMessage The input should be an array
+ */
+ public function testStringInput() {
+ $this->plugin = new LanguageTypes([], 'map', []);
+ $this->plugin->transform('foo', $this->migrateExecutable, $this->row, 'destinationproperty');
+ }
+
+}
diff --git a/core/modules/menu_link_content/src/Plugin/migrate/process/LinkUri.php b/core/modules/menu_link_content/src/Plugin/migrate/process/LinkUri.php
new file mode 100644
index 000000000..93656c847
--- /dev/null
+++ b/core/modules/menu_link_content/src/Plugin/migrate/process/LinkUri.php
@@ -0,0 +1,84 @@
+entityTypeManager = $entity_type_manager;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
+ return new static(
+ $configuration,
+ $plugin_id,
+ $plugin_definition,
+ $container->get('entity_type.manager')
+ );
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) {
+ list($path) = $value;
+ $path = ltrim($path, '/');
+
+ if (parse_url($path, PHP_URL_SCHEME) === NULL) {
+ $path = 'internal:/' . $path;
+
+ // Convert entity URIs to the entity scheme, if the path matches a route
+ // of the form "entity.$entity_type_id.canonical".
+ // @see \Drupal\Core\Url::fromEntityUri()
+ $url = Url::fromUri($path);
+ if ($url->isRouted()) {
+ $route_name = $url->getRouteName();
+ foreach (array_keys($this->entityTypeManager->getDefinitions()) as $entity_type_id) {
+ if ($route_name == "entity.$entity_type_id.canonical" && isset($url->getRouteParameters()[$entity_type_id])) {
+ return "entity:$entity_type_id/" . $url->getRouteParameters()[$entity_type_id];
+ }
+ }
+ }
+ }
+ return $path;
+ }
+
+}
diff --git a/core/modules/menu_link_content/src/Plugin/migrate/process/d6/LinkUri.php b/core/modules/menu_link_content/src/Plugin/migrate/process/d6/LinkUri.php
index 08c45d812..46b53a04e 100644
--- a/core/modules/menu_link_content/src/Plugin/migrate/process/d6/LinkUri.php
+++ b/core/modules/menu_link_content/src/Plugin/migrate/process/d6/LinkUri.php
@@ -2,83 +2,12 @@
namespace Drupal\menu_link_content\Plugin\migrate\process\d6;
-use Drupal\Core\Entity\EntityTypeManagerInterface;
-use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
-use Drupal\Core\Url;
-use Drupal\migrate\MigrateExecutableInterface;
-use Drupal\migrate\ProcessPluginBase;
-use Drupal\migrate\Row;
-use Symfony\Component\DependencyInjection\ContainerInterface;
+use \Drupal\menu_link_content\Plugin\migrate\process\LinkUri as RealLinkUri;
/**
* Processes a link path into an 'internal:' or 'entity:' URI.
*
- * @MigrateProcessPlugin(
- * id = "link_uri"
- * )
+ * @deprecated in Drupal 8.2.0, will be removed before Drupal 9.0.0. Use
+ * \Drupal\menu_link_content\Plugin\migrate\process\LinkUri instead.
*/
-class LinkUri extends ProcessPluginBase implements ContainerFactoryPluginInterface {
-
- /**
- * The entity type manager, used to fetch entity link templates.
- *
- * @var \Drupal\Core\Entity\EntityTypeManagerInterface
- */
- protected $entityTypeManager;
-
- /**
- * Constructs a LinkUri object.
- *
- * @param array $configuration
- * A configuration array containing information about the plugin instance.
- * @param string $plugin_id
- * The plugin_id for the plugin instance.
- * @param mixed $plugin_definition
- * The plugin implementation definition.
- * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
- * The entity type manager, used to fetch entity link templates.
- */
- public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityTypeManagerInterface $entity_type_manager) {
- parent::__construct($configuration, $plugin_id, $plugin_definition);
- $this->entityTypeManager = $entity_type_manager;
- }
-
- /**
- * {@inheritdoc}
- */
- public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
- return new static(
- $configuration,
- $plugin_id,
- $plugin_definition,
- $container->get('entity_type.manager')
- );
- }
-
- /**
- * {@inheritdoc}
- */
- public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) {
- list($path) = $value;
- $path = ltrim($path, '/');
-
- if (parse_url($path, PHP_URL_SCHEME) === NULL) {
- $path = 'internal:/' . $path;
-
- // Convert entity URIs to the entity scheme, if the path matches a route
- // of the form "entity.$entity_type_id.canonical".
- // @see \Drupal\Core\Url::fromEntityUri()
- $url = Url::fromUri($path);
- if ($url->isRouted()) {
- $route_name = $url->getRouteName();
- foreach (array_keys($this->entityTypeManager->getDefinitions()) as $entity_type_id) {
- if ($route_name == "entity.$entity_type_id.canonical" && isset($url->getRouteParameters()[$entity_type_id])) {
- return "entity:$entity_type_id/" . $url->getRouteParameters()[$entity_type_id];
- }
- }
- }
- }
- return $path;
- }
-
-}
+class LinkUri extends RealLinkUri {}
diff --git a/core/modules/menu_link_content/tests/src/Unit/Plugin/migrate/process/d6/LinkUriTest.php b/core/modules/menu_link_content/tests/src/Unit/Plugin/migrate/process/LinkUriTest.php
similarity index 94%
rename from core/modules/menu_link_content/tests/src/Unit/Plugin/migrate/process/d6/LinkUriTest.php
rename to core/modules/menu_link_content/tests/src/Unit/Plugin/migrate/process/LinkUriTest.php
index 93a72802a..073180f6b 100644
--- a/core/modules/menu_link_content/tests/src/Unit/Plugin/migrate/process/d6/LinkUriTest.php
+++ b/core/modules/menu_link_content/tests/src/Unit/Plugin/migrate/process/LinkUriTest.php
@@ -1,10 +1,10 @@
multiple();
+ $multiple = $plugin->multiple();
}
}
// No plugins or no value means do not set.
diff --git a/core/modules/migrate/src/Plugin/MigrateDestinationInterface.php b/core/modules/migrate/src/Plugin/MigrateDestinationInterface.php
index b6e86a09f..9c83baf29 100644
--- a/core/modules/migrate/src/Plugin/MigrateDestinationInterface.php
+++ b/core/modules/migrate/src/Plugin/MigrateDestinationInterface.php
@@ -83,11 +83,8 @@ interface MigrateDestinationInterface extends PluginInspectionInterface {
* Derived classes must implement fields(), returning a list of available
* destination fields.
*
- * @todo Review the cases where we need the Migration parameter, can we avoid
- * that? To be resolved with https://www.drupal.org/node/2543568.
- *
* @param \Drupal\migrate\Plugin\MigrationInterface $migration
- * (optional) The migration containing this destination. Defaults to NULL.
+ * Unused, will be removed before Drupal 9.0.x. Defaults to NULL.
*
* @return array
* - Keys: machine names of the fields
diff --git a/core/modules/migrate/src/Plugin/MigrateSourcePluginManager.php b/core/modules/migrate/src/Plugin/MigrateSourcePluginManager.php
index 1aaf4f180..2d1275023 100644
--- a/core/modules/migrate/src/Plugin/MigrateSourcePluginManager.php
+++ b/core/modules/migrate/src/Plugin/MigrateSourcePluginManager.php
@@ -20,13 +20,6 @@ use Drupal\migrate\Plugin\Discovery\ProviderFilterDecorator;
*/
class MigrateSourcePluginManager extends MigratePluginManager {
- /**
- * The class loader.
- *
- * @var object
- */
- protected $classLoader;
-
/**
* MigrateSourcePluginManager constructor.
*
diff --git a/core/modules/migrate/src/Plugin/migrate/process/ArrayBuild.php b/core/modules/migrate/src/Plugin/migrate/process/ArrayBuild.php
new file mode 100644
index 000000000..d5f9d2feb
--- /dev/null
+++ b/core/modules/migrate/src/Plugin/migrate/process/ArrayBuild.php
@@ -0,0 +1,107 @@
+ Array
+ * (
+ * [language] => en
+ * ...
+ * [domain] => http://example.com
+ * )
+ * [1] => Array
+ * (
+ * [language] => fr
+ * ...
+ * [domain] => http://fr.example.com
+ * )
+ * ...
+ * @endcode
+ *
+ * The destination should be an array of all the domains keyed by their
+ * language code:
+ *
+ * @code
+ * domains: Array
+ * (
+ * [en] => http://example.com
+ * [fr] => http://fr.example.com
+ * ...
+ * @endcode
+ *
+ * The array_build process plugin would be used like this:
+ *
+ * @code
+ * process:
+ * domains:
+ * plugin: array_build
+ * key: language
+ * value: domain
+ * source: languages
+ * @endcode
+ *
+ * @see \Drupal\migrate\Plugin\MigrateProcessInterface
+ *
+ * @MigrateProcessPlugin(
+ * id = "array_build",
+ * handle_multiples = TRUE
+ * )
+ */
+class ArrayBuild extends ProcessPluginBase {
+
+ /**
+ * {@inheritdoc}
+ */
+ public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) {
+ $new_value = [];
+
+ foreach ((array) $value as $old_key => $old_value) {
+ // Checks that $old_value is an array.
+ if (!is_array($old_value)) {
+ throw new MigrateException("The input should be an array of arrays");
+ }
+
+ // Checks that the key exists.
+ if (!array_key_exists($this->configuration['key'], $old_value)) {
+ throw new MigrateException("The key '" . $this->configuration['key'] . "' does not exist");
+ }
+
+ // Checks that the value exists.
+ if (!array_key_exists($this->configuration['value'], $old_value)) {
+ throw new MigrateException("The key '" . $this->configuration['value'] . "' does not exist");
+ }
+
+ $new_value[$old_value[$this->configuration['key']]] = $old_value[$this->configuration['value']];
+ }
+
+ return $new_value;
+ }
+
+}
diff --git a/core/modules/migrate/src/Plugin/migrate/process/DedupeEntity.php b/core/modules/migrate/src/Plugin/migrate/process/DedupeEntity.php
index d2afe8f58..a616c86c3 100644
--- a/core/modules/migrate/src/Plugin/migrate/process/DedupeEntity.php
+++ b/core/modules/migrate/src/Plugin/migrate/process/DedupeEntity.php
@@ -10,6 +10,9 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Ensures value is not duplicated against an entity field.
*
+ * If the 'migrated' configuration value is true, an entity will only be
+ * considered a duplicate if it was migrated by the current migration.
+ *
* @link https://www.drupal.org/node/2135325 Online handbook documentation for dedupe_entity process plugin @endlink
*
* @MigrateProcessPlugin(
@@ -25,11 +28,19 @@ class DedupeEntity extends DedupeBase implements ContainerFactoryPluginInterface
*/
protected $entityQueryFactory;
+ /**
+ * The current migration.
+ *
+ * @var \Drupal\migrate\Plugin\MigrationInterface
+ */
+ protected $migration;
+
/**
* {@inheritdoc}
*/
public function __construct(array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration, QueryFactory $entity_query_factory) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
+ $this->migration = $migration;
$this->entityQueryFactory = $entity_query_factory;
}
@@ -51,12 +62,25 @@ class DedupeEntity extends DedupeBase implements ContainerFactoryPluginInterface
*/
protected function exists($value) {
// Plugins are cached so for every run we need a new query object.
- return $this
+ $query = $this
->entityQueryFactory
->get($this->configuration['entity_type'], 'AND')
- ->condition($this->configuration['field'], $value)
- ->count()
- ->execute();
+ ->condition($this->configuration['field'], $value);
+ if (!empty($this->configuration['migrated'])) {
+ // Check if each entity is in the ID map.
+ $idMap = $this->migration->getIdMap();
+ foreach ($query->execute() as $id) {
+ $dest_id_values[$this->configuration['field']] = $id;
+ if ($idMap->lookupSourceID($dest_id_values)) {
+ return TRUE;
+ }
+ }
+ return FALSE;
+ }
+ else {
+ // Just check if any such entity exists.
+ return $query->count()->execute();
+ }
}
}
diff --git a/core/modules/migrate/src/Plugin/migrate/process/Migration.php b/core/modules/migrate/src/Plugin/migrate/process/Migration.php
index a8d5b601b..8520a5ec3 100644
--- a/core/modules/migrate/src/Plugin/migrate/process/Migration.php
+++ b/core/modules/migrate/src/Plugin/migrate/process/Migration.php
@@ -38,6 +38,13 @@ class Migration extends ProcessPluginBase implements ContainerFactoryPluginInter
*/
protected $migrationPluginManager;
+ /**
+ * The migration to be executed.
+ *
+ * @var \Drupal\migrate\Plugin\MigrationInterface
+ */
+ protected $migration;
+
/**
* {@inheritdoc}
*/
@@ -70,9 +77,7 @@ class Migration extends ProcessPluginBase implements ContainerFactoryPluginInter
if (!is_array($migration_ids)) {
$migration_ids = array($migration_ids);
}
- $scalar = FALSE;
if (!is_array($value)) {
- $scalar = TRUE;
$value = array($value);
}
$this->skipOnEmpty($value);
@@ -145,10 +150,8 @@ class Migration extends ProcessPluginBase implements ContainerFactoryPluginInter
}
}
if ($destination_ids) {
- if ($scalar) {
- if (count($destination_ids) == 1) {
- return reset($destination_ids);
- }
+ if (count($destination_ids) == 1) {
+ return reset($destination_ids);
}
else {
return $destination_ids;
diff --git a/core/modules/migrate/src/Plugin/migrate/process/Route.php b/core/modules/migrate/src/Plugin/migrate/process/Route.php
index 2c0144bcb..7ff472048 100644
--- a/core/modules/migrate/src/Plugin/migrate/process/Route.php
+++ b/core/modules/migrate/src/Plugin/migrate/process/Route.php
@@ -3,10 +3,10 @@
namespace Drupal\migrate\Plugin\migrate\process;
use Symfony\Component\DependencyInjection\ContainerInterface;
-use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
-use Drupal\migrate\Plugin\MigrationInterface;
use Drupal\Core\Path\PathValidatorInterface;
+use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\migrate\MigrateExecutableInterface;
+use Drupal\migrate\Plugin\MigrationInterface;
use Drupal\migrate\ProcessPluginBase;
use Drupal\migrate\Row;
@@ -55,7 +55,14 @@ class Route extends ProcessPluginBase implements ContainerFactoryPluginInterface
* Set the destination route information based on the source link_path.
*/
public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) {
- list($link_path, $options) = $value;
+ if (is_string($value)) {
+ $link_path = $value;
+ $options = [];
+ }
+ else {
+ list($link_path, $options) = $value;
+ }
+
$extracted = $this->pathValidator->getUrlIfValidWithoutAccessCheck($link_path);
$route = array();
diff --git a/core/modules/migrate/tests/src/Kernel/process/DownloadTest.php b/core/modules/migrate/tests/src/Kernel/process/DownloadTest.php
index 69e3aa002..576539eb3 100644
--- a/core/modules/migrate/tests/src/Kernel/process/DownloadTest.php
+++ b/core/modules/migrate/tests/src/Kernel/process/DownloadTest.php
@@ -60,7 +60,7 @@ class DownloadTest extends FileTestBase {
/**
* Tests that an exception is thrown if the destination URI is not writable.
*/
- public function testWriteProectedDestination() {
+ public function testWriteProtectedDestination() {
// Create a pre-existing file at the destination, to test overwrite behavior.
$destination_uri = $this->createUri('not-writable.txt');
diff --git a/core/modules/migrate/tests/src/Kernel/process/HandleMultiplesTest.php b/core/modules/migrate/tests/src/Kernel/process/HandleMultiplesTest.php
new file mode 100644
index 000000000..b4cc0e82b
--- /dev/null
+++ b/core/modules/migrate/tests/src/Kernel/process/HandleMultiplesTest.php
@@ -0,0 +1,138 @@
+ [
+ 'plugin' => 'embedded_data',
+ 'data_rows' => [],
+ 'ids' => [
+ 'id' => ['type' => 'string'],
+ ],
+ ],
+ 'process' => [
+ // Process pipeline for testing values from string to array to string.
+ 'first' => [
+ // Expects a string and returns an array.
+ [
+ 'plugin' => 'explode',
+ 'source' => 'scalar',
+ 'delimiter' => '/',
+ ],
+ // Expects an array and returns a string.
+ [
+ 'plugin' => 'extract',
+ 'index' => [1],
+ ],
+ // Expects a string and returns a string.
+ [
+ 'plugin' => 'callback',
+ 'callable' => 'strtoupper',
+ ],
+ ],
+ // Process pipeline for testing values from array to string to array.
+ 'second' => [
+ // Expects an array and returns a string.
+ [
+ 'plugin' => 'extract',
+ 'source' => 'multiple',
+ 'index' => [1],
+ ],
+ // Expects a string and returns a string.
+ [
+ 'plugin' => 'callback',
+ 'callable' => 'strtoupper',
+ ],
+ // Expects a string and returns an array.
+ [
+ 'plugin' => 'explode',
+ 'delimiter' => '/',
+ ],
+ ],
+ ],
+ 'destination' => [
+ 'plugin' => 'config',
+ 'config_name' => 'migrate_test.settings',
+ ],
+ ];
+ }
+
+ /**
+ * Tests process pipelines with scalar and multiple values handling.
+ *
+ * @dataProvider scalarAndMultipleValuesProviderSource
+ *
+ * @param array $source_data
+ * @param array $expected_data
+ */
+ public function testScalarAndMultipleValues(array $source_data, array $expected_data) {
+ $definition = $this->getDefinition();
+ $definition['source']['data_rows'] = [$source_data];
+
+ $migration = \Drupal::service('plugin.manager.migration')->createStubMigration($definition);
+
+ $executable = new MigrateExecutable($migration, new MigrateMessage());
+ $result = $executable->import();
+
+ // Migration needs to succeed before further assertions are made.
+ $this->assertSame(MigrationInterface::RESULT_COMPLETED, $result);
+
+ // Compare with expected data.
+ $this->assertEquals($expected_data, \Drupal::config('migrate_test.settings')->get());
+ }
+
+ /**
+ * Provides the source data with scalar and multiple values.
+ *
+ * @return array
+ */
+ public function scalarAndMultipleValuesProviderSource() {
+ return [
+ [
+ 'source_data' => [
+ 'id' => '1',
+ // Source value for the first pipeline.
+ 'scalar' => 'foo/bar',
+ // Source value for the second pipeline.
+ 'multiple' => [
+ 'foo',
+ 'bar/baz',
+ ],
+ ],
+ 'expected_data' => [
+ // Expected value from the first pipeline.
+ 'first' => 'BAR',
+ // Expected value from the second pipeline.
+ 'second' => [
+ 'BAR',
+ 'BAZ',
+ ],
+ ],
+ ],
+ ];
+ }
+
+}
diff --git a/core/modules/migrate/tests/src/Kernel/process/RouteTest.php b/core/modules/migrate/tests/src/Kernel/process/RouteTest.php
new file mode 100644
index 000000000..3de8d2d6a
--- /dev/null
+++ b/core/modules/migrate/tests/src/Kernel/process/RouteTest.php
@@ -0,0 +1,278 @@
+doTransform($value);
+ $this->assertSame($expected, $actual);
+ }
+
+ /**
+ * Data provider for testRoute().
+ *
+ * @return array
+ * An array of arrays, where the first element is the input to the Route
+ * process plugin, and the second is the expected results.
+ */
+ public function providerTestRoute() {
+ // Internal link tests.
+ // Valid link path and options.
+ $values[0] = [
+ 'user/login',
+ [
+ 'attributes' => [
+ 'title' => 'Test menu link 1',
+ ],
+ ],
+ ];
+ $expected[0] = [
+ 'route_name' => 'user.login',
+ 'route_parameters' => [],
+ 'options' => [
+ 'query' => [],
+ 'attributes' => [
+ 'title' => 'Test menu link 1',
+ ],
+ ],
+ 'url' => NULL,
+ ];
+
+ // Valid link path and empty options.
+ $values[1] = [
+ 'user/login',
+ [],
+ ];
+ $expected[1] = [
+ 'route_name' => 'user.login',
+ 'route_parameters' => [],
+ 'options' => [
+ 'query' => [],
+ ],
+ 'url' => NULL,
+ ];
+
+ // Valid link path and no options.
+ $values[2] = 'user/login';
+ $expected[2] = [
+ 'route_name' => 'user.login',
+ 'route_parameters' => [],
+ 'options' => [
+ 'query' => [],
+ ],
+ 'url' => NULL,
+ ];
+
+ // Invalid link path.
+ $values[3] = 'users';
+ $expected[3] = [];
+
+ // Valid link path with parameter.
+ $values[4] = [
+ 'system/timezone/nzdt',
+ [
+ 'attributes' => [
+ 'title' => 'Show NZDT',
+ ],
+ ],
+ ];
+ $expected[4] = [
+ 'route_name' => 'system.timezone',
+ 'route_parameters' => [
+ 'abbreviation' => 'nzdt',
+ 'offset' => -1,
+ 'is_daylight_saving_time' => NULL,
+ ],
+ 'options' => [
+ 'query' => [],
+ 'attributes' => [
+ 'title' => 'Show NZDT',
+ ],
+ ],
+ 'url' => NULL,
+ ];
+
+ // External link tests.
+ // Valid external link path and options.
+ $values[5] = [
+ 'https://www.drupal.org',
+ [
+ 'attributes' => [
+ 'title' => 'Drupal',
+ ],
+ ],
+ ];
+ $expected[5] = [
+ 'route_name' => NULL,
+ 'route_parameters' => [],
+ 'options' => [
+ 'attributes' => [
+ 'title' => 'Drupal',
+ ],
+ ],
+ 'url' => 'https://www.drupal.org',
+ ];
+
+ // Valid external link path and options.
+ $values[6] = [
+ 'https://www.drupal.org/user/1/edit?pass-reset-token=QgtDKcRV4e4fjg6v2HTa6CbWx-XzMZ5XBZTufinqsM73qIhscIuU_BjZ6J2tv4dQI6N50ZJOag',
+ [
+ 'attributes' => [
+ 'title' => 'Drupal password reset',
+ ],
+ ],
+ ];
+ $expected[6] = [
+ 'route_name' => NULL,
+ 'route_parameters' => [],
+ 'options' => [
+ 'attributes' => [
+ 'title' => 'Drupal password reset',
+ ],
+ ],
+ 'url' => 'https://www.drupal.org/user/1/edit?pass-reset-token=QgtDKcRV4e4fjg6v2HTa6CbWx-XzMZ5XBZTufinqsM73qIhscIuU_BjZ6J2tv4dQI6N50ZJOag',
+ ];
+
+ return [
+ // Test data for internal paths.
+ // Test with valid link path and options.
+ [$values[0], $expected[0]],
+ // Test with valid link path and empty options.
+ [$values[1], $expected[1]],
+ // Test with valid link path and no options.
+ [$values[2], $expected[2]],
+ // Test with Invalid link path.
+ [$values[3], $expected[3]],
+ // Test with Valid link path with query options and parameters.
+ [$values[4], $expected[4]],
+
+ // Test data for external paths.
+ // Test with external link path and options.
+ [$values[5], $expected[5]],
+ // Test with valid link path and query options.
+ [$values[6], $expected[6]],
+ ];
+ }
+
+ /**
+ * Tests Route plugin based on providerTestRoute() values.
+ *
+ * @param mixed $value
+ * Input value for the Route process plugin.
+ * @param array $expected
+ * The expected results from the Route transform process.
+ *
+ * @dataProvider providerTestRouteWithParamQuery
+ */
+ public function testRouteWithParamQuery($value, $expected) {
+ $this->installSchema('system', ['sequences']);
+ $this->installEntitySchema('user');
+ $this->installConfig(['user']);
+
+ // Create a user so that user/1/edit is a valid path.
+ $adminUser = User::create([
+ 'name' => $this->randomMachineName(),
+ ]);
+ $adminUser->save();
+
+ $actual = $this->doTransform($value);
+ $this->assertSame($expected, $actual);
+ }
+
+ /**
+ * Data provider for testRouteWithParamQuery().
+ *
+ * @return array
+ * An array of arrays, where the first element is the input to the Route
+ * process plugin, and the second is the expected results.
+ */
+ public function providerTestRouteWithParamQuery() {
+ $values = [];
+ $expected = [];
+ // Valid link path with query options and parameters.
+ $values[0] = [
+ 'user/1/edit',
+ [
+ 'attributes' => [
+ 'title' => 'Edit admin',
+ ],
+ 'query' => [
+ 'destination' => '/admin/people',
+ ],
+ ],
+ ];
+ $expected[0] = [
+ 'route_name' => 'entity.user.edit_form',
+ 'route_parameters' => [
+ 'user' => '1',
+ ],
+ 'options' => [
+ 'attributes' => [
+ 'title' => 'Edit admin',
+ ],
+ 'query' => [
+ 'destination' => '/admin/people',
+ ],
+ ],
+ 'url' => NULL,
+ ];
+
+ return [
+ // Test with valid link path with parameters and options.
+ [$values[0], $expected[0]],
+ ];
+ }
+
+ /**
+ * Transforms link path data to a route.
+ *
+ * @param array|string $value
+ * Source link path information.
+ *
+ * @return array $actual
+ * The route information based on the source link_path.
+ */
+ protected function doTransform($value) {
+ // Rebuild the routes.
+ $this->container->get('router.builder')->rebuild();
+ $pathValidator = $this->container->get('path.validator');
+ $row = new Row();
+ $migration = $this->prophesize(MigrationInterface::class)->reveal();
+ $executable = $this->prophesize(MigrateExecutableInterface::class)->reveal();
+
+ $plugin = new Route([], 'route', [], $migration, $pathValidator);
+ $actual = $plugin->transform($value, $executable, $row, 'destinationproperty');
+ return $actual;
+ }
+
+}
diff --git a/core/modules/migrate/tests/src/Unit/process/ArrayBuildTest.php b/core/modules/migrate/tests/src/Unit/process/ArrayBuildTest.php
new file mode 100644
index 000000000..bbfef8b19
--- /dev/null
+++ b/core/modules/migrate/tests/src/Unit/process/ArrayBuildTest.php
@@ -0,0 +1,82 @@
+ 'foo',
+ 'value' => 'bar',
+ ];
+ $this->plugin = new ArrayBuild($configuration, 'map', []);
+ parent::setUp();
+ }
+
+ /**
+ * Tests successful transformation.
+ */
+ public function testTransform() {
+ $source = [
+ ['foo' => 'Foo', 'bar' => 'Bar'],
+ ['foo' => 'foo bar', 'bar' => 'bar foo'],
+ ];
+ $expected = [
+ 'Foo' => 'Bar',
+ 'foo bar' => 'bar foo',
+ ];
+ $value = $this->plugin->transform($source, $this->migrateExecutable, $this->row, 'destinationproperty');
+ $this->assertSame($value, $expected);
+ }
+
+ /**
+ * Tests non-existent key for the key configuration.
+ */
+ public function testNonExistentKey() {
+ $source = [
+ ['bar' => 'foo'],
+ ];
+ $this->setExpectedException(MigrateException::class, "The key 'foo' does not exist");
+ $this->plugin->transform($source, $this->migrateExecutable, $this->row, 'destinationproperty');
+ }
+
+ /**
+ * Tests non-existent key for the value configuration.
+ */
+ public function testNonExistentValue() {
+ $source = [
+ ['foo' => 'bar'],
+ ];
+ $this->setExpectedException(MigrateException::class, "The key 'bar' does not exist");
+ $this->plugin->transform($source, $this->migrateExecutable, $this->row, 'destinationproperty');
+ }
+
+ /**
+ * Tests one-dimensional array input.
+ */
+ public function testOneDimensionalArrayInput() {
+ $source = ['foo' => 'bar'];
+ $this->setExpectedException(MigrateException::class, 'The input should be an array of arrays');
+ $this->plugin->transform($source, $this->migrateExecutable, $this->row, 'destinationproperty');
+ }
+
+ /**
+ * Tests string input.
+ */
+ public function testStringInput() {
+ $source = 'foo';
+ $this->setExpectedException(MigrateException::class, 'The input should be an array of arrays');
+ $this->plugin->transform($source, $this->migrateExecutable, $this->row, 'destinationproperty');
+ }
+
+}
diff --git a/core/modules/migrate/tests/src/Unit/process/DedupeEntityTest.php b/core/modules/migrate/tests/src/Unit/process/DedupeEntityTest.php
index a1960deab..4fe8db3bc 100644
--- a/core/modules/migrate/tests/src/Unit/process/DedupeEntityTest.php
+++ b/core/modules/migrate/tests/src/Unit/process/DedupeEntityTest.php
@@ -2,6 +2,7 @@
namespace Drupal\Tests\migrate\Unit\process;
+use Drupal\Core\Entity\Query\QueryInterface;
use Drupal\migrate\Plugin\migrate\process\DedupeEntity;
use Drupal\Component\Utility\Unicode;
@@ -161,4 +162,47 @@ class DedupeEntityTest extends MigrateProcessTestCase {
->will($this->returnCallback(function () use (&$count) { return $count--;}));
}
+ /**
+ * Test deduplicating only migrated entities.
+ */
+ public function testDedupeMigrated() {
+ $configuration = array(
+ 'entity_type' => 'test_entity_type',
+ 'field' => 'test_field',
+ 'migrated' => TRUE,
+ );
+ $plugin = new DedupeEntity($configuration, 'dedupe_entity', array(), $this->getMigration(), $this->entityQueryFactory);
+
+ // Setup the entityQuery used in DedupeEntity::exists. The map, $map, is
+ // an array consisting of the four input parameters to the query condition
+ // method and then the query to return. Both 'forum' and
+ // 'test_vocab' are existing entities. There is no 'test_vocab1'.
+ $map = [];
+ foreach (['forums', 'test_vocab', 'test_vocab1'] as $id) {
+ $query = $this->prophesize(QueryInterface::class);
+ $query->willBeConstructedWith([]);
+ $query->execute()->willReturn($id === 'test_vocab1' ? [] : [$id]);
+ $map[] = ['test_field', $id, NULL, NULL, $query->reveal()];
+ }
+ $this->entityQuery
+ ->method('condition')
+ ->will($this->returnValueMap($map));
+
+ // Entity 'forums' is pre-existing, entity 'test_vocab' was migrated.
+ $this->idMap
+ ->method('lookupSourceID')
+ ->will($this->returnValueMap([
+ [['test_field' => 'forums'], FALSE],
+ [['test_field' => 'test_vocab'], ['source_id' => 42]],
+ ]));
+
+ // Existing entity 'forums' was not migrated, it should not be deduplicated.
+ $actual = $plugin->transform('forums', $this->migrateExecutable, $this->row, 'testproperty');
+ $this->assertEquals('forums', $actual, 'Pre-existing name is re-used');
+
+ // Entity 'test_vocab' was migrated, should be deduplicated.
+ $actual = $plugin->transform('test_vocab', $this->migrateExecutable, $this->row, 'testproperty');
+ $this->assertEquals('test_vocab1', $actual, 'Migrated name is deduplicated');
+ }
+
}
diff --git a/core/modules/migrate/tests/src/Unit/process/MigrationTest.php b/core/modules/migrate/tests/src/Unit/process/MigrationTest.php
index 4eb52da98..b62c1f934 100644
--- a/core/modules/migrate/tests/src/Unit/process/MigrationTest.php
+++ b/core/modules/migrate/tests/src/Unit/process/MigrationTest.php
@@ -89,7 +89,7 @@ class MigrationTest extends MigrateProcessTestCase {
/**
* Tests that processing is skipped when the input value is empty.
- *
+ *
* @expectedException \Drupal\migrate\MigrateSkipProcessException
*/
public function testSkipOnEmpty() {
@@ -107,8 +107,19 @@ class MigrationTest extends MigrateProcessTestCase {
/**
* Tests a successful lookup.
+ *
+ * @dataProvider successfulLookupDataProvider
+ *
+ * @param array $source_id_values
+ * The source id(s) of the migration map.
+ * @param array $destination_id_values
+ * The destination id(s) of the migration map.
+ * @param string|array $source_value
+ * The source value(s) for the migration process plugin.
+ * @param string|array $expected_value
+ * The expected value(s) of the migration process plugin.
*/
- public function testSuccessfulLookup() {
+ public function testSuccessfulLookup($source_id_values, $destination_id_values, $source_value, $expected_value) {
$migration_plugin = $this->prophesize(MigrationInterface::class);
$migration_plugin_manager = $this->prophesize(MigrationPluginManagerInterface::class);
$process_plugin_manager = $this->prophesize(MigratePluginManager::class);
@@ -119,7 +130,7 @@ class MigrationTest extends MigrateProcessTestCase {
$migration_plugin->id()->willReturn(uniqid());
$id_map = $this->prophesize(MigrateIdMapInterface::class);
- $id_map->lookupDestinationId([1])->willReturn([3]);
+ $id_map->lookupDestinationId($source_id_values)->willReturn($destination_id_values);
$migration_plugin->getIdMap()->willReturn($id_map->reveal());
$migration_plugin_manager->createInstances(['foobaz'])
@@ -131,7 +142,61 @@ class MigrationTest extends MigrateProcessTestCase {
->willReturn([$migration_plugin->reveal()]);
$migration = new Migration($configuration, 'migration', [], $migration_plugin->reveal(), $migration_plugin_manager->reveal(), $process_plugin_manager->reveal());
- $this->assertSame(3, $migration->transform(1, $this->migrateExecutable, $this->row, 'foo'));
+ $this->assertSame($expected_value, $migration->transform($source_value, $this->migrateExecutable, $this->row, 'foo'));
+ }
+
+ /**
+ * Provides data for the successful lookup test.
+ *
+ * @return array
+ */
+ public function successfulLookupDataProvider() {
+ return [
+ // Test data for scalar to scalar.
+ [
+ // Source ID of the migration map.
+ [1],
+ // Destination ID of the migration map.
+ [3],
+ // Input value for the migration plugin.
+ 1,
+ // Expected output value of the migration plugin.
+ 3,
+ ],
+ // Test data for scalar to array.
+ [
+ // Source ID of the migration map.
+ [1],
+ // Destination IDs of the migration map.
+ [3, 'foo'],
+ // Input value for the migration plugin.
+ 1,
+ // Expected output values of the migration plugin.
+ [3, 'foo'],
+ ],
+ // Test data for array to scalar.
+ [
+ // Source IDs of the migration map.
+ [1, 3],
+ // Destination ID of the migration map.
+ ['foo'],
+ // Input values for the migration plugin.
+ [1, 3],
+ // Expected output value of the migration plugin.
+ 'foo',
+ ],
+ // Test data for array to array.
+ [
+ // Source IDs of the migration map.
+ [1, 3],
+ // Destination IDs of the migration map.
+ [3, 'foo'],
+ // Input values for the migration plugin.
+ [1, 3],
+ // Expected output values of the migration plugin.
+ [3, 'foo'],
+ ],
+ ];
}
}
diff --git a/core/modules/migrate_drupal/src/Plugin/migrate/destination/EntityFieldStorageConfig.php b/core/modules/migrate_drupal/src/Plugin/migrate/destination/EntityFieldStorageConfig.php
index cc8431de3..169390a6a 100644
--- a/core/modules/migrate_drupal/src/Plugin/migrate/destination/EntityFieldStorageConfig.php
+++ b/core/modules/migrate_drupal/src/Plugin/migrate/destination/EntityFieldStorageConfig.php
@@ -9,11 +9,17 @@ use Drupal\migrate\Plugin\MigrationInterface;
use Drupal\migrate\Plugin\migrate\destination\EntityFieldStorageConfig as BaseEntityFieldStorageConfig;
/**
- * Destination with Drupal specific config dependencies.
+ * Deprecated. Destination with Drupal specific config dependencies.
*
* @MigrateDestination(
* id = "md_entity:field_storage_config"
* )
+ *
+ * @deprecated in Drupal 8.2.x and will be removed in Drupal 9.0.x. Use
+ * \Drupal\migrate\Plugin\migrate\destination\EntityFieldStorageConfig
+ * instead.
+ *
+ * @see \Drupal\migrate\Plugin\migrate\destination\EntityFieldStorageConfig
*/
class EntityFieldStorageConfig extends BaseEntityFieldStorageConfig {
diff --git a/core/modules/migrate_drupal/tests/fixtures/drupal6.php b/core/modules/migrate_drupal/tests/fixtures/drupal6.php
index 9debae008..91251aab7 100644
--- a/core/modules/migrate_drupal/tests/fixtures/drupal6.php
+++ b/core/modules/migrate_drupal/tests/fixtures/drupal6.php
@@ -9812,7 +9812,7 @@ $connection->insert('languages')
'enabled' => '1',
'plurals' => '2',
'formula' => '($n>1)',
- 'domain' => '',
+ 'domain' => 'http://fr.drupal.org',
'prefix' => 'fr',
'weight' => '0',
'javascript' => '047746d30d76aa44a54db9923c7c5fb0',
@@ -9825,7 +9825,7 @@ $connection->insert('languages')
'enabled' => '1',
'plurals' => '0',
'formula' => '',
- 'domain' => '',
+ 'domain' => 'http://zu.drupal.org',
'prefix' => 'zu',
'weight' => '0',
'javascript' => '',
@@ -41378,6 +41378,40 @@ $connection->insert('node')
'tnid' => '10',
'translate' => '0',
))
+->values(array(
+ 'nid' => '12',
+ 'vid' => '15',
+ 'type' => 'page',
+ 'language' => 'zu',
+ 'title' => 'Abantu zulu',
+ 'uid' => '1',
+ 'status' => '1',
+ 'created' => '1444238800',
+ 'changed' => '1444238808',
+ 'comment' => '0',
+ 'promote' => '0',
+ 'moderate' => '0',
+ 'sticky' => '0',
+ 'tnid' => '12',
+ 'translate' => '0',
+))
+->values(array(
+ 'nid' => '13',
+ 'vid' => '16',
+ 'type' => 'page',
+ 'language' => 'en',
+ 'title' => 'The Zulu People',
+ 'uid' => '1',
+ 'status' => '1',
+ 'created' => '1444239050',
+ 'changed' => '1444239050',
+ 'comment' => '0',
+ 'promote' => '0',
+ 'moderate' => '0',
+ 'sticky' => '0',
+ 'tnid' => '12',
+ 'translate' => '0',
+))
->execute();
$connection->schema()->createTable('node_access', array(
@@ -41807,6 +41841,28 @@ $connection->insert('node_revisions')
'timestamp' => '1444239050',
'format' => '1',
))
+->values(array(
+ 'nid' => '12',
+ 'vid' => '15',
+ 'uid' => '1',
+ 'title' => 'Abantu zulu',
+ 'body' => "Mr. Crusher, ready a collision course with the Borg ship.",
+ 'teaser' => "Mr. Crusher, ready a collision course with the Borg ship.",
+ 'log' => '',
+ 'timestamp' => '1444238808',
+ 'format' => '1',
+))
+->values(array(
+ 'nid' => '13',
+ 'vid' => '16',
+ 'uid' => '1',
+ 'title' => 'The Zulu People',
+ 'body' => 'Mr. Crusher, ready a collision course with the Borg ship.',
+ 'teaser' => 'Mr. Crusher, ready a collision course with the Borg ship.',
+ 'log' => '',
+ 'timestamp' => '1444239050',
+ 'format' => '1',
+))
->execute();
$connection->schema()->createTable('node_type', array(
diff --git a/core/modules/migrate_drupal/tests/fixtures/drupal7.php b/core/modules/migrate_drupal/tests/fixtures/drupal7.php
index 98e56382f..6853e1e87 100644
--- a/core/modules/migrate_drupal/tests/fixtures/drupal7.php
+++ b/core/modules/migrate_drupal/tests/fixtures/drupal7.php
@@ -3381,6 +3381,51 @@ $connection->insert('field_config')
'translatable' => '0',
'deleted' => '0',
))
+->values(array(
+ 'id' => '22',
+ 'field_name' => 'field_node_entityreference',
+ 'type' => 'entityreference',
+ 'module' => 'entityreference',
+ 'active' => '1',
+ 'storage_type' => 'field_sql_storage',
+ 'storage_module' => 'field_sql_storage',
+ 'storage_active' => '1',
+ 'locked' => '0',
+ 'data' => 'a:7:{s:12:"translatable";s:1:"0";s:12:"entity_types";a:0:{}s:8:"settings";a:3:{s:11:"target_type";s:4:"node";s:7:"handler";s:4:"base";s:16:"handler_settings";a:2:{s:14:"target_bundles";a:1:{s:7:"article";s:7:"article";}s:4:"sort";a:1:{s:4:"type";s:4:"none";}}}s:7:"storage";a:5:{s:4:"type";s:17:"field_sql_storage";s:8:"settings";a:0:{}s:6:"module";s:17:"field_sql_storage";s:6:"active";s:1:"1";s:7:"details";a:1:{s:3:"sql";a:2:{s:18:"FIELD_LOAD_CURRENT";a:1:{s:37:"field_data_field_node_entityreference";a:1:{s:9:"target_id";s:36:"field_node_entityreference_target_id";}}s:19:"FIELD_LOAD_REVISION";a:1:{s:41:"field_revision_field_node_entityreference";a:1:{s:9:"target_id";s:36:"field_node_entityreference_target_id";}}}}}s:12:"foreign keys";a:1:{s:4:"node";a:2:{s:5:"table";s:4:"node";s:7:"columns";a:1:{s:9:"target_id";s:3:"nid";}}}s:7:"indexes";a:1:{s:9:"target_id";a:1:{i:0;s:9:"target_id";}}s:2:"id";s:2:"22";}',
+ 'cardinality' => '-1',
+ 'translatable' => '0',
+ 'deleted' => '0',
+))
+->values(array(
+ 'id' => '23',
+ 'field_name' => 'field_user_entityreference',
+ 'type' => 'entityreference',
+ 'module' => 'entityreference',
+ 'active' => '1',
+ 'storage_type' => 'field_sql_storage',
+ 'storage_module' => 'field_sql_storage',
+ 'storage_active' => '1',
+ 'locked' => '0',
+ 'data' => 'a:7:{s:12:"translatable";s:1:"0";s:12:"entity_types";a:0:{}s:8:"settings";a:3:{s:11:"target_type";s:4:"user";s:7:"handler";s:4:"base";s:16:"handler_settings";a:2:{s:14:"target_bundles";a:0:{}s:4:"sort";a:3:{s:4:"type";s:8:"property";s:8:"property";s:7:"created";s:9:"direction";s:4:"DESC";}}}s:7:"storage";a:5:{s:4:"type";s:17:"field_sql_storage";s:8:"settings";a:0:{}s:6:"module";s:17:"field_sql_storage";s:6:"active";s:1:"1";s:7:"details";a:1:{s:3:"sql";a:2:{s:18:"FIELD_LOAD_CURRENT";a:1:{s:37:"field_data_field_user_entityreference";a:1:{s:9:"target_id";s:36:"field_user_entityreference_target_id";}}s:19:"FIELD_LOAD_REVISION";a:1:{s:41:"field_revision_field_user_entityreference";a:1:{s:9:"target_id";s:36:"field_user_entityreference_target_id";}}}}}s:12:"foreign keys";a:1:{s:5:"users";a:2:{s:5:"table";s:5:"users";s:7:"columns";a:1:{s:9:"target_id";s:3:"uid";}}}s:7:"indexes";a:1:{s:9:"target_id";a:1:{i:0;s:9:"target_id";}}s:2:"id";s:2:"23";}',
+ 'cardinality' => '1',
+ 'translatable' => '0',
+ 'deleted' => '0',
+))
+->values(array(
+ 'id' => '24',
+ 'field_name' => 'field_term_entityreference',
+ 'type' => 'entityreference',
+ 'module' => 'entityreference',
+ 'active' => '1',
+ 'storage_type' => 'field_sql_storage',
+ 'storage_module' => 'field_sql_storage',
+ 'storage_active' => '1',
+ 'locked' => '0',
+ 'data' => 'a:7:{s:12:"translatable";s:1:"0";s:12:"entity_types";a:0:{}s:8:"settings";a:3:{s:11:"target_type";s:13:"taxonomy_term";s:7:"handler";s:4:"base";s:16:"handler_settings";a:2:{s:14:"target_bundles";a:1:{s:4:"tags";s:4:"tags";}s:4:"sort";a:1:{s:4:"type";s:4:"none";}}}s:7:"storage";a:5:{s:4:"type";s:17:"field_sql_storage";s:8:"settings";a:0:{}s:6:"module";s:17:"field_sql_storage";s:6:"active";s:1:"1";s:7:"details";a:1:{s:3:"sql";a:2:{s:18:"FIELD_LOAD_CURRENT";a:1:{s:37:"field_data_field_term_entityreference";a:1:{s:9:"target_id";s:36:"field_term_entityreference_target_id";}}s:19:"FIELD_LOAD_REVISION";a:1:{s:41:"field_revision_field_term_entityreference";a:1:{s:9:"target_id";s:36:"field_term_entityreference_target_id";}}}}}s:12:"foreign keys";a:1:{s:18:"taxonomy_term_data";a:2:{s:5:"table";s:18:"taxonomy_term_data";s:7:"columns";a:1:{s:9:"target_id";s:3:"tid";}}}s:7:"indexes";a:1:{s:9:"target_id";a:1:{i:0;s:9:"target_id";}}s:2:"id";s:2:"24";}',
+ 'cardinality' => '-1',
+ 'translatable' => '0',
+ 'deleted' => '0',
+))
->execute();
$connection->schema()->createTable('field_config_instance', array(
@@ -3756,6 +3801,33 @@ $connection->insert('field_config_instance')
'data' => 'a:7:{s:5:"label";s:4:"Link";s:6:"widget";a:5:{s:6:"weight";s:2:"10";s:4:"type";s:10:"link_field";s:6:"module";s:4:"link";s:6:"active";i:0;s:8:"settings";a:0:{}}s:8:"settings";a:12:{s:12:"absolute_url";i:1;s:12:"validate_url";i:1;s:3:"url";i:0;s:5:"title";s:8:"required";s:11:"title_value";s:19:"Unused Static Title";s:27:"title_label_use_field_label";i:0;s:15:"title_maxlength";s:3:"128";s:7:"display";a:1:{s:10:"url_cutoff";s:2:"81";}s:10:"attributes";a:6:{s:6:"target";s:6:"_blank";s:3:"rel";s:8:"nofollow";s:18:"configurable_class";i:0;s:5:"class";s:7:"classes";s:18:"configurable_title";i:1;s:5:"title";s:0:"";}s:10:"rel_remove";s:19:"rel_remove_external";s:13:"enable_tokens";i:1;s:18:"user_register_form";b:0;}s:7:"display";a:1:{s:7:"default";a:5:{s:5:"label";s:5:"above";s:4:"type";s:12:"link_default";s:6:"weight";s:1:"9";s:8:"settings";a:0:{}s:6:"module";s:4:"link";}}s:8:"required";i:0;s:11:"description";s:0:"";s:13:"default_value";N;}',
'deleted' => '0',
))
+->values(array(
+ 'id' => '38',
+ 'field_id' => '22',
+ 'field_name' => 'field_node_entityreference',
+ 'entity_type' => 'node',
+ 'bundle' => 'test_content_type',
+ 'data' => 'a:7:{s:5:"label";s:21:"Node Entity Reference";s:6:"widget";a:5:{s:6:"weight";s:2:"16";s:4:"type";s:28:"entityreference_autocomplete";s:6:"module";s:15:"entityreference";s:6:"active";i:1;s:8:"settings";a:3:{s:14:"match_operator";s:8:"CONTAINS";s:4:"size";s:2:"60";s:4:"path";s:0:"";}}s:8:"settings";a:1:{s:18:"user_register_form";b:0;}s:7:"display";a:1:{s:7:"default";a:5:{s:5:"label";s:5:"above";s:4:"type";s:21:"entityreference_label";s:8:"settings";a:1:{s:4:"link";b:0;}s:6:"module";s:15:"entityreference";s:6:"weight";i:15;}}s:8:"required";i:0;s:11:"description";s:0:"";s:13:"default_value";N;}',
+ 'deleted' => '0',
+))
+->values(array(
+ 'id' => '39',
+ 'field_id' => '23',
+ 'field_name' => 'field_user_entityreference',
+ 'entity_type' => 'node',
+ 'bundle' => 'test_content_type',
+ 'data' => 'a:7:{s:5:"label";s:21:"User Entity Reference";s:6:"widget";a:5:{s:6:"weight";s:2:"17";s:4:"type";s:15:"options_buttons";s:6:"module";s:7:"options";s:6:"active";i:1;s:8:"settings";a:0:{}}s:8:"settings";a:1:{s:18:"user_register_form";b:0;}s:7:"display";a:1:{s:7:"default";a:5:{s:5:"label";s:5:"above";s:4:"type";s:21:"entityreference_label";s:8:"settings";a:1:{s:4:"link";b:0;}s:6:"module";s:15:"entityreference";s:6:"weight";i:16;}}s:8:"required";i:0;s:11:"description";s:0:"";s:13:"default_value";N;}',
+ 'deleted' => '0',
+))
+->values(array(
+ 'id' => '40',
+ 'field_id' => '24',
+ 'field_name' => 'field_term_entityreference',
+ 'entity_type' => 'node',
+ 'bundle' => 'test_content_type',
+ 'data' => 'a:7:{s:5:"label";s:21:"Term Entity Reference";s:6:"widget";a:5:{s:6:"weight";s:2:"18";s:4:"type";s:33:"entityreference_autocomplete_tags";s:6:"module";s:15:"entityreference";s:6:"active";i:1;s:8:"settings";a:3:{s:14:"match_operator";s:8:"CONTAINS";s:4:"size";s:2:"60";s:4:"path";s:0:"";}}s:8:"settings";a:2:{s:9:"behaviors";a:1:{s:14:"taxonomy-index";a:1:{s:6:"status";b:1;}}s:18:"user_register_form";b:0;}s:7:"display";a:1:{s:7:"default";a:5:{s:5:"label";s:5:"above";s:4:"type";s:21:"entityreference_label";s:8:"settings";a:1:{s:4:"link";b:0;}s:6:"module";s:15:"entityreference";s:6:"weight";i:17;}}s:8:"required";i:0;s:11:"description";s:0:"";s:13:"default_value";N;}',
+ 'deleted' => '0',
+))
->execute();
$connection->schema()->createTable('field_data_body', array(
@@ -5054,6 +5126,113 @@ $connection->schema()->createTable('field_data_field_long_text', array(
'mysql_character_set' => 'utf8',
));
+$connection->schema()->createTable('field_data_field_node_entityreference', array(
+ 'fields' => array(
+ 'entity_type' => array(
+ 'type' => 'varchar',
+ 'not null' => TRUE,
+ 'length' => '128',
+ 'default' => '',
+ ),
+ 'bundle' => array(
+ 'type' => 'varchar',
+ 'not null' => TRUE,
+ 'length' => '128',
+ 'default' => '',
+ ),
+ 'deleted' => array(
+ 'type' => 'int',
+ 'not null' => TRUE,
+ 'size' => 'tiny',
+ 'default' => '0',
+ ),
+ 'entity_id' => array(
+ 'type' => 'int',
+ 'not null' => TRUE,
+ 'size' => 'normal',
+ 'unsigned' => TRUE,
+ ),
+ 'revision_id' => array(
+ 'type' => 'int',
+ 'not null' => FALSE,
+ 'size' => 'normal',
+ 'unsigned' => TRUE,
+ ),
+ 'language' => array(
+ 'type' => 'varchar',
+ 'not null' => TRUE,
+ 'length' => '32',
+ 'default' => '',
+ ),
+ 'delta' => array(
+ 'type' => 'int',
+ 'not null' => TRUE,
+ 'size' => 'normal',
+ 'unsigned' => TRUE,
+ ),
+ 'field_node_entityreference_target_id' => array(
+ 'type' => 'int',
+ 'not null' => TRUE,
+ 'size' => 'normal',
+ 'unsigned' => TRUE,
+ ),
+ ),
+ 'primary key' => array(
+ 'entity_type',
+ 'entity_id',
+ 'deleted',
+ 'delta',
+ 'language',
+ ),
+ 'indexes' => array(
+ 'entity_type' => array(
+ 'entity_type',
+ ),
+ 'bundle' => array(
+ 'bundle',
+ ),
+ 'deleted' => array(
+ 'deleted',
+ ),
+ 'entity_id' => array(
+ 'entity_id',
+ ),
+ 'revision_id' => array(
+ 'revision_id',
+ ),
+ 'language' => array(
+ 'language',
+ ),
+ 'field_node_entityreference_target_id' => array(
+ 'field_node_entityreference_target_id',
+ ),
+ ),
+ 'mysql_character_set' => 'utf8',
+));
+
+$connection->insert('field_data_field_node_entityreference')
+->fields(array(
+ 'entity_type',
+ 'bundle',
+ 'deleted',
+ 'entity_id',
+ 'revision_id',
+ 'language',
+ 'delta',
+ 'field_node_entityreference_target_id',
+))
+->values(array(
+ 'entity_type' => 'node',
+ 'bundle' => 'test_content_type',
+ 'deleted' => '0',
+ 'entity_id' => '1',
+ 'revision_id' => '1',
+ 'language' => 'und',
+ 'delta' => '0',
+ 'field_node_entityreference_target_id' => '2',
+))
+->execute();
+
$connection->schema()->createTable('field_data_field_phone', array(
'fields' => array(
'entity_type' => array(
@@ -5219,6 +5398,26 @@ $connection->insert('field_data_field_tags')
'delta' => '0',
'field_tags_tid' => '9',
))
+->values(array(
+ 'entity_type' => 'node',
+ 'bundle' => 'article',
+ 'deleted' => '0',
+ 'entity_id' => '2',
+ 'revision_id' => '2',
+ 'language' => 'und',
+ 'delta' => '1',
+ 'field_tags_tid' => '14',
+))
+->values(array(
+ 'entity_type' => 'node',
+ 'bundle' => 'article',
+ 'deleted' => '0',
+ 'entity_id' => '2',
+ 'revision_id' => '2',
+ 'language' => 'und',
+ 'delta' => '2',
+ 'field_tags_tid' => '17',
+))
->values(array(
'entity_type' => 'node',
'bundle' => 'article',
@@ -5233,8 +5432,8 @@ $connection->insert('field_data_field_tags')
'entity_type' => 'node',
'bundle' => 'article',
'deleted' => '0',
- 'entity_id' => '2',
- 'revision_id' => '2',
+ 'entity_id' => '3',
+ 'revision_id' => '3',
'language' => 'und',
'delta' => '1',
'field_tags_tid' => '14',
@@ -5246,28 +5445,125 @@ $connection->insert('field_data_field_tags')
'entity_id' => '3',
'revision_id' => '3',
'language' => 'und',
+ 'delta' => '2',
+ 'field_tags_tid' => '17',
+))
+->execute();
+
+$connection->schema()->createTable('field_data_field_term_entityreference', array(
+ 'fields' => array(
+ 'entity_type' => array(
+ 'type' => 'varchar',
+ 'not null' => TRUE,
+ 'length' => '128',
+ 'default' => '',
+ ),
+ 'bundle' => array(
+ 'type' => 'varchar',
+ 'not null' => TRUE,
+ 'length' => '128',
+ 'default' => '',
+ ),
+ 'deleted' => array(
+ 'type' => 'int',
+ 'not null' => TRUE,
+ 'size' => 'tiny',
+ 'default' => '0',
+ ),
+ 'entity_id' => array(
+ 'type' => 'int',
+ 'not null' => TRUE,
+ 'size' => 'normal',
+ 'unsigned' => TRUE,
+ ),
+ 'revision_id' => array(
+ 'type' => 'int',
+ 'not null' => FALSE,
+ 'size' => 'normal',
+ 'unsigned' => TRUE,
+ ),
+ 'language' => array(
+ 'type' => 'varchar',
+ 'not null' => TRUE,
+ 'length' => '32',
+ 'default' => '',
+ ),
+ 'delta' => array(
+ 'type' => 'int',
+ 'not null' => TRUE,
+ 'size' => 'normal',
+ 'unsigned' => TRUE,
+ ),
+ 'field_term_entityreference_target_id' => array(
+ 'type' => 'int',
+ 'not null' => TRUE,
+ 'size' => 'normal',
+ 'unsigned' => TRUE,
+ ),
+ ),
+ 'primary key' => array(
+ 'entity_type',
+ 'entity_id',
+ 'deleted',
+ 'delta',
+ 'language',
+ ),
+ 'indexes' => array(
+ 'entity_type' => array(
+ 'entity_type',
+ ),
+ 'bundle' => array(
+ 'bundle',
+ ),
+ 'deleted' => array(
+ 'deleted',
+ ),
+ 'entity_id' => array(
+ 'entity_id',
+ ),
+ 'revision_id' => array(
+ 'revision_id',
+ ),
+ 'language' => array(
+ 'language',
+ ),
+ 'field_term_entityreference_target_id' => array(
+ 'field_term_entityreference_target_id',
+ ),
+ ),
+ 'mysql_character_set' => 'utf8',
+));
+
+$connection->insert('field_data_field_term_entityreference')
+->fields(array(
+ 'entity_type',
+ 'bundle',
+ 'deleted',
+ 'entity_id',
+ 'revision_id',
+ 'language',
+ 'delta',
+ 'field_term_entityreference_target_id',
+))
+->values(array(
+ 'entity_type' => 'node',
+ 'bundle' => 'test_content_type',
+ 'deleted' => '0',
+ 'entity_id' => '1',
+ 'revision_id' => '1',
+ 'language' => 'und',
+ 'delta' => '0',
+ 'field_term_entityreference_target_id' => '17',
+))
+->values(array(
+ 'entity_type' => 'node',
+ 'bundle' => 'test_content_type',
+ 'deleted' => '0',
+ 'entity_id' => '1',
+ 'revision_id' => '1',
+ 'language' => 'und',
'delta' => '1',
- 'field_tags_tid' => '14',
-))
-->values(array(
- 'entity_type' => 'node',
- 'bundle' => 'article',
- 'deleted' => '0',
- 'entity_id' => '2',
- 'revision_id' => '2',
- 'language' => 'und',
- 'delta' => '2',
- 'field_tags_tid' => '17',
-))
-->values(array(
- 'entity_type' => 'node',
- 'bundle' => 'article',
- 'deleted' => '0',
- 'entity_id' => '3',
- 'revision_id' => '3',
- 'language' => 'und',
- 'delta' => '2',
- 'field_tags_tid' => '17',
+ 'field_term_entityreference_target_id' => '15',
))
->execute();
@@ -5528,6 +5824,113 @@ $connection->insert('field_data_field_text_list')
))
->execute();
+$connection->schema()->createTable('field_data_field_user_entityreference', array(
+ 'fields' => array(
+ 'entity_type' => array(
+ 'type' => 'varchar',
+ 'not null' => TRUE,
+ 'length' => '128',
+ 'default' => '',
+ ),
+ 'bundle' => array(
+ 'type' => 'varchar',
+ 'not null' => TRUE,
+ 'length' => '128',
+ 'default' => '',
+ ),
+ 'deleted' => array(
+ 'type' => 'int',
+ 'not null' => TRUE,
+ 'size' => 'tiny',
+ 'default' => '0',
+ ),
+ 'entity_id' => array(
+ 'type' => 'int',
+ 'not null' => TRUE,
+ 'size' => 'normal',
+ 'unsigned' => TRUE,
+ ),
+ 'revision_id' => array(
+ 'type' => 'int',
+ 'not null' => FALSE,
+ 'size' => 'normal',
+ 'unsigned' => TRUE,
+ ),
+ 'language' => array(
+ 'type' => 'varchar',
+ 'not null' => TRUE,
+ 'length' => '32',
+ 'default' => '',
+ ),
+ 'delta' => array(
+ 'type' => 'int',
+ 'not null' => TRUE,
+ 'size' => 'normal',
+ 'unsigned' => TRUE,
+ ),
+ 'field_user_entityreference_target_id' => array(
+ 'type' => 'int',
+ 'not null' => TRUE,
+ 'size' => 'normal',
+ 'unsigned' => TRUE,
+ ),
+ ),
+ 'primary key' => array(
+ 'entity_type',
+ 'entity_id',
+ 'deleted',
+ 'delta',
+ 'language',
+ ),
+ 'indexes' => array(
+ 'entity_type' => array(
+ 'entity_type',
+ ),
+ 'bundle' => array(
+ 'bundle',
+ ),
+ 'deleted' => array(
+ 'deleted',
+ ),
+ 'entity_id' => array(
+ 'entity_id',
+ ),
+ 'revision_id' => array(
+ 'revision_id',
+ ),
+ 'language' => array(
+ 'language',
+ ),
+ 'field_user_entityreference_target_id' => array(
+ 'field_user_entityreference_target_id',
+ ),
+ ),
+ 'mysql_character_set' => 'utf8',
+));
+
+$connection->insert('field_data_field_user_entityreference')
+->fields(array(
+ 'entity_type',
+ 'bundle',
+ 'deleted',
+ 'entity_id',
+ 'revision_id',
+ 'language',
+ 'delta',
+ 'field_user_entityreference_target_id',
+))
+->values(array(
+ 'entity_type' => 'node',
+ 'bundle' => 'test_content_type',
+ 'deleted' => '0',
+ 'entity_id' => '1',
+ 'revision_id' => '1',
+ 'language' => 'und',
+ 'delta' => '0',
+ 'field_user_entityreference_target_id' => '2',
+))
+->execute();
+
$connection->schema()->createTable('field_data_taxonomy_forums', array(
'fields' => array(
'entity_type' => array(
@@ -6899,6 +7302,114 @@ $connection->schema()->createTable('field_revision_field_long_text', array(
'mysql_character_set' => 'utf8',
));
+$connection->schema()->createTable('field_revision_field_node_entityreference', array(
+ 'fields' => array(
+ 'entity_type' => array(
+ 'type' => 'varchar',
+ 'not null' => TRUE,
+ 'length' => '128',
+ 'default' => '',
+ ),
+ 'bundle' => array(
+ 'type' => 'varchar',
+ 'not null' => TRUE,
+ 'length' => '128',
+ 'default' => '',
+ ),
+ 'deleted' => array(
+ 'type' => 'int',
+ 'not null' => TRUE,
+ 'size' => 'tiny',
+ 'default' => '0',
+ ),
+ 'entity_id' => array(
+ 'type' => 'int',
+ 'not null' => TRUE,
+ 'size' => 'normal',
+ 'unsigned' => TRUE,
+ ),
+ 'revision_id' => array(
+ 'type' => 'int',
+ 'not null' => TRUE,
+ 'size' => 'normal',
+ 'unsigned' => TRUE,
+ ),
+ 'language' => array(
+ 'type' => 'varchar',
+ 'not null' => TRUE,
+ 'length' => '32',
+ 'default' => '',
+ ),
+ 'delta' => array(
+ 'type' => 'int',
+ 'not null' => TRUE,
+ 'size' => 'normal',
+ 'unsigned' => TRUE,
+ ),
+ 'field_node_entityreference_target_id' => array(
+ 'type' => 'int',
+ 'not null' => TRUE,
+ 'size' => 'normal',
+ 'unsigned' => TRUE,
+ ),
+ ),
+ 'primary key' => array(
+ 'entity_type',
+ 'entity_id',
+ 'revision_id',
+ 'deleted',
+ 'delta',
+ 'language',
+ ),
+ 'indexes' => array(
+ 'entity_type' => array(
+ 'entity_type',
+ ),
+ 'bundle' => array(
+ 'bundle',
+ ),
+ 'deleted' => array(
+ 'deleted',
+ ),
+ 'entity_id' => array(
+ 'entity_id',
+ ),
+ 'revision_id' => array(
+ 'revision_id',
+ ),
+ 'language' => array(
+ 'language',
+ ),
+ 'field_node_entityreference_target_id' => array(
+ 'field_node_entityreference_target_id',
+ ),
+ ),
+ 'mysql_character_set' => 'utf8',
+));
+
+$connection->insert('field_revision_field_node_entityreference')
+->fields(array(
+ 'entity_type',
+ 'bundle',
+ 'deleted',
+ 'entity_id',
+ 'revision_id',
+ 'language',
+ 'delta',
+ 'field_node_entityreference_target_id',
+))
+->values(array(
+ 'entity_type' => 'node',
+ 'bundle' => 'test_content_type',
+ 'deleted' => '0',
+ 'entity_id' => '1',
+ 'revision_id' => '1',
+ 'language' => 'und',
+ 'delta' => '0',
+ 'field_node_entityreference_target_id' => '2',
+))
+->execute();
+
$connection->schema()->createTable('field_revision_field_phone', array(
'fields' => array(
'entity_type' => array(
@@ -7066,6 +7577,26 @@ $connection->insert('field_revision_field_tags')
'delta' => '0',
'field_tags_tid' => '9',
))
+->values(array(
+ 'entity_type' => 'node',
+ 'bundle' => 'article',
+ 'deleted' => '0',
+ 'entity_id' => '2',
+ 'revision_id' => '2',
+ 'language' => 'und',
+ 'delta' => '1',
+ 'field_tags_tid' => '14',
+))
+->values(array(
+ 'entity_type' => 'node',
+ 'bundle' => 'article',
+ 'deleted' => '0',
+ 'entity_id' => '2',
+ 'revision_id' => '2',
+ 'language' => 'und',
+ 'delta' => '2',
+ 'field_tags_tid' => '17',
+))
->values(array(
'entity_type' => 'node',
'bundle' => 'article',
@@ -7080,8 +7611,8 @@ $connection->insert('field_revision_field_tags')
'entity_type' => 'node',
'bundle' => 'article',
'deleted' => '0',
- 'entity_id' => '2',
- 'revision_id' => '2',
+ 'entity_id' => '3',
+ 'revision_id' => '3',
'language' => 'und',
'delta' => '1',
'field_tags_tid' => '14',
@@ -7093,28 +7624,126 @@ $connection->insert('field_revision_field_tags')
'entity_id' => '3',
'revision_id' => '3',
'language' => 'und',
+ 'delta' => '2',
+ 'field_tags_tid' => '17',
+))
+->execute();
+
+$connection->schema()->createTable('field_revision_field_term_entityreference', array(
+ 'fields' => array(
+ 'entity_type' => array(
+ 'type' => 'varchar',
+ 'not null' => TRUE,
+ 'length' => '128',
+ 'default' => '',
+ ),
+ 'bundle' => array(
+ 'type' => 'varchar',
+ 'not null' => TRUE,
+ 'length' => '128',
+ 'default' => '',
+ ),
+ 'deleted' => array(
+ 'type' => 'int',
+ 'not null' => TRUE,
+ 'size' => 'tiny',
+ 'default' => '0',
+ ),
+ 'entity_id' => array(
+ 'type' => 'int',
+ 'not null' => TRUE,
+ 'size' => 'normal',
+ 'unsigned' => TRUE,
+ ),
+ 'revision_id' => array(
+ 'type' => 'int',
+ 'not null' => TRUE,
+ 'size' => 'normal',
+ 'unsigned' => TRUE,
+ ),
+ 'language' => array(
+ 'type' => 'varchar',
+ 'not null' => TRUE,
+ 'length' => '32',
+ 'default' => '',
+ ),
+ 'delta' => array(
+ 'type' => 'int',
+ 'not null' => TRUE,
+ 'size' => 'normal',
+ 'unsigned' => TRUE,
+ ),
+ 'field_term_entityreference_target_id' => array(
+ 'type' => 'int',
+ 'not null' => TRUE,
+ 'size' => 'normal',
+ 'unsigned' => TRUE,
+ ),
+ ),
+ 'primary key' => array(
+ 'entity_type',
+ 'entity_id',
+ 'revision_id',
+ 'deleted',
+ 'delta',
+ 'language',
+ ),
+ 'indexes' => array(
+ 'entity_type' => array(
+ 'entity_type',
+ ),
+ 'bundle' => array(
+ 'bundle',
+ ),
+ 'deleted' => array(
+ 'deleted',
+ ),
+ 'entity_id' => array(
+ 'entity_id',
+ ),
+ 'revision_id' => array(
+ 'revision_id',
+ ),
+ 'language' => array(
+ 'language',
+ ),
+ 'field_term_entityreference_target_id' => array(
+ 'field_term_entityreference_target_id',
+ ),
+ ),
+ 'mysql_character_set' => 'utf8',
+));
+
+$connection->insert('field_revision_field_term_entityreference')
+->fields(array(
+ 'entity_type',
+ 'bundle',
+ 'deleted',
+ 'entity_id',
+ 'revision_id',
+ 'language',
+ 'delta',
+ 'field_term_entityreference_target_id',
+))
+->values(array(
+ 'entity_type' => 'node',
+ 'bundle' => 'test_content_type',
+ 'deleted' => '0',
+ 'entity_id' => '1',
+ 'revision_id' => '1',
+ 'language' => 'und',
+ 'delta' => '0',
+ 'field_term_entityreference_target_id' => '17',
+))
+->values(array(
+ 'entity_type' => 'node',
+ 'bundle' => 'test_content_type',
+ 'deleted' => '0',
+ 'entity_id' => '1',
+ 'revision_id' => '1',
+ 'language' => 'und',
'delta' => '1',
- 'field_tags_tid' => '14',
-))
-->values(array(
- 'entity_type' => 'node',
- 'bundle' => 'article',
- 'deleted' => '0',
- 'entity_id' => '2',
- 'revision_id' => '2',
- 'language' => 'und',
- 'delta' => '2',
- 'field_tags_tid' => '17',
-))
-->values(array(
- 'entity_type' => 'node',
- 'bundle' => 'article',
- 'deleted' => '0',
- 'entity_id' => '3',
- 'revision_id' => '3',
- 'language' => 'und',
- 'delta' => '2',
- 'field_tags_tid' => '17',
+ 'field_term_entityreference_target_id' => '15',
))
->execute();
@@ -7378,6 +8007,114 @@ $connection->insert('field_revision_field_text_list')
))
->execute();
+$connection->schema()->createTable('field_revision_field_user_entityreference', array(
+ 'fields' => array(
+ 'entity_type' => array(
+ 'type' => 'varchar',
+ 'not null' => TRUE,
+ 'length' => '128',
+ 'default' => '',
+ ),
+ 'bundle' => array(
+ 'type' => 'varchar',
+ 'not null' => TRUE,
+ 'length' => '128',
+ 'default' => '',
+ ),
+ 'deleted' => array(
+ 'type' => 'int',
+ 'not null' => TRUE,
+ 'size' => 'tiny',
+ 'default' => '0',
+ ),
+ 'entity_id' => array(
+ 'type' => 'int',
+ 'not null' => TRUE,
+ 'size' => 'normal',
+ 'unsigned' => TRUE,
+ ),
+ 'revision_id' => array(
+ 'type' => 'int',
+ 'not null' => TRUE,
+ 'size' => 'normal',
+ 'unsigned' => TRUE,
+ ),
+ 'language' => array(
+ 'type' => 'varchar',
+ 'not null' => TRUE,
+ 'length' => '32',
+ 'default' => '',
+ ),
+ 'delta' => array(
+ 'type' => 'int',
+ 'not null' => TRUE,
+ 'size' => 'normal',
+ 'unsigned' => TRUE,
+ ),
+ 'field_user_entityreference_target_id' => array(
+ 'type' => 'int',
+ 'not null' => TRUE,
+ 'size' => 'normal',
+ 'unsigned' => TRUE,
+ ),
+ ),
+ 'primary key' => array(
+ 'entity_type',
+ 'entity_id',
+ 'revision_id',
+ 'deleted',
+ 'delta',
+ 'language',
+ ),
+ 'indexes' => array(
+ 'entity_type' => array(
+ 'entity_type',
+ ),
+ 'bundle' => array(
+ 'bundle',
+ ),
+ 'deleted' => array(
+ 'deleted',
+ ),
+ 'entity_id' => array(
+ 'entity_id',
+ ),
+ 'revision_id' => array(
+ 'revision_id',
+ ),
+ 'language' => array(
+ 'language',
+ ),
+ 'field_user_entityreference_target_id' => array(
+ 'field_user_entityreference_target_id',
+ ),
+ ),
+ 'mysql_character_set' => 'utf8',
+));
+
+$connection->insert('field_revision_field_user_entityreference')
+->fields(array(
+ 'entity_type',
+ 'bundle',
+ 'deleted',
+ 'entity_id',
+ 'revision_id',
+ 'language',
+ 'delta',
+ 'field_user_entityreference_target_id',
+))
+->values(array(
+ 'entity_type' => 'node',
+ 'bundle' => 'test_content_type',
+ 'deleted' => '0',
+ 'entity_id' => '1',
+ 'revision_id' => '1',
+ 'language' => 'und',
+ 'delta' => '0',
+ 'field_user_entityreference_target_id' => '2',
+))
+->execute();
+
$connection->schema()->createTable('field_revision_taxonomy_forums', array(
'fields' => array(
'entity_type' => array(
@@ -8335,7 +9072,7 @@ $connection->insert('languages')
'enabled' => '1',
'plurals' => '0',
'formula' => '',
- 'domain' => '',
+ 'domain' => 'is.drupal.org',
'prefix' => 'is',
'weight' => '0',
'javascript' => '',
@@ -28082,6 +28819,181 @@ $connection->insert('menu_router')
'weight' => '0',
'include_file' => 'modules/contact/contact.pages.inc',
))
+->values(array(
+ 'path' => 'ctools/autocomplete/%',
+ 'load_functions' => 'a:1:{i:2;N;}',
+ 'to_arg_functions' => '',
+ 'access_callback' => 'user_access',
+ 'access_arguments' => 'a:1:{i:0;s:14:"access content";}',
+ 'page_callback' => 'ctools_content_autocomplete_entity',
+ 'page_arguments' => 'a:1:{i:0;i:2;}',
+ 'delivery_callback' => '',
+ 'fit' => '6',
+ 'number_parts' => '3',
+ 'context' => '0',
+ 'tab_parent' => '',
+ 'tab_root' => 'ctools/autocomplete/%',
+ 'title' => '',
+ 'title_callback' => 't',
+ 'title_arguments' => '',
+ 'theme_callback' => '',
+ 'theme_arguments' => 'a:0:{}',
+ 'type' => '0',
+ 'description' => '',
+ 'position' => '',
+ 'weight' => '0',
+ 'include_file' => 'sites/all/modules/ctools/includes/content.menu.inc',
+))
+->values(array(
+ 'path' => 'ctools/context/ajax/access/add',
+ 'load_functions' => '',
+ 'to_arg_functions' => '',
+ 'access_callback' => 'user_access',
+ 'access_arguments' => 'a:1:{i:0;s:14:"access content";}',
+ 'page_callback' => 'ctools_access_ajax_add',
+ 'page_arguments' => 'a:0:{}',
+ 'delivery_callback' => '',
+ 'fit' => '31',
+ 'number_parts' => '5',
+ 'context' => '0',
+ 'tab_parent' => '',
+ 'tab_root' => 'ctools/context/ajax/access/add',
+ 'title' => '',
+ 'title_callback' => 't',
+ 'title_arguments' => '',
+ 'theme_callback' => 'ajax_base_page_theme',
+ 'theme_arguments' => 'a:0:{}',
+ 'type' => '0',
+ 'description' => '',
+ 'position' => '',
+ 'weight' => '0',
+ 'include_file' => 'sites/all/modules/ctools/includes/context-access-admin.inc',
+))
+->values(array(
+ 'path' => 'ctools/context/ajax/access/configure',
+ 'load_functions' => '',
+ 'to_arg_functions' => '',
+ 'access_callback' => 'user_access',
+ 'access_arguments' => 'a:1:{i:0;s:14:"access content";}',
+ 'page_callback' => 'ctools_access_ajax_edit',
+ 'page_arguments' => 'a:0:{}',
+ 'delivery_callback' => '',
+ 'fit' => '31',
+ 'number_parts' => '5',
+ 'context' => '0',
+ 'tab_parent' => '',
+ 'tab_root' => 'ctools/context/ajax/access/configure',
+ 'title' => '',
+ 'title_callback' => 't',
+ 'title_arguments' => '',
+ 'theme_callback' => 'ajax_base_page_theme',
+ 'theme_arguments' => 'a:0:{}',
+ 'type' => '0',
+ 'description' => '',
+ 'position' => '',
+ 'weight' => '0',
+ 'include_file' => 'sites/all/modules/ctools/includes/context-access-admin.inc',
+))
+->values(array(
+ 'path' => 'ctools/context/ajax/access/delete',
+ 'load_functions' => '',
+ 'to_arg_functions' => '',
+ 'access_callback' => 'user_access',
+ 'access_arguments' => 'a:1:{i:0;s:14:"access content";}',
+ 'page_callback' => 'ctools_access_ajax_delete',
+ 'page_arguments' => 'a:0:{}',
+ 'delivery_callback' => '',
+ 'fit' => '31',
+ 'number_parts' => '5',
+ 'context' => '0',
+ 'tab_parent' => '',
+ 'tab_root' => 'ctools/context/ajax/access/delete',
+ 'title' => '',
+ 'title_callback' => 't',
+ 'title_arguments' => '',
+ 'theme_callback' => 'ajax_base_page_theme',
+ 'theme_arguments' => 'a:0:{}',
+ 'type' => '0',
+ 'description' => '',
+ 'position' => '',
+ 'weight' => '0',
+ 'include_file' => 'sites/all/modules/ctools/includes/context-access-admin.inc',
+))
+->values(array(
+ 'path' => 'ctools/context/ajax/add',
+ 'load_functions' => '',
+ 'to_arg_functions' => '',
+ 'access_callback' => 'user_access',
+ 'access_arguments' => 'a:1:{i:0;s:14:"access content";}',
+ 'page_callback' => 'ctools_context_ajax_item_add',
+ 'page_arguments' => 'a:0:{}',
+ 'delivery_callback' => '',
+ 'fit' => '15',
+ 'number_parts' => '4',
+ 'context' => '0',
+ 'tab_parent' => '',
+ 'tab_root' => 'ctools/context/ajax/add',
+ 'title' => '',
+ 'title_callback' => 't',
+ 'title_arguments' => '',
+ 'theme_callback' => 'ajax_base_page_theme',
+ 'theme_arguments' => 'a:0:{}',
+ 'type' => '0',
+ 'description' => '',
+ 'position' => '',
+ 'weight' => '0',
+ 'include_file' => 'sites/all/modules/ctools/includes/context-admin.inc',
+))
+->values(array(
+ 'path' => 'ctools/context/ajax/configure',
+ 'load_functions' => '',
+ 'to_arg_functions' => '',
+ 'access_callback' => 'user_access',
+ 'access_arguments' => 'a:1:{i:0;s:14:"access content";}',
+ 'page_callback' => 'ctools_context_ajax_item_edit',
+ 'page_arguments' => 'a:0:{}',
+ 'delivery_callback' => '',
+ 'fit' => '15',
+ 'number_parts' => '4',
+ 'context' => '0',
+ 'tab_parent' => '',
+ 'tab_root' => 'ctools/context/ajax/configure',
+ 'title' => '',
+ 'title_callback' => 't',
+ 'title_arguments' => '',
+ 'theme_callback' => 'ajax_base_page_theme',
+ 'theme_arguments' => 'a:0:{}',
+ 'type' => '0',
+ 'description' => '',
+ 'position' => '',
+ 'weight' => '0',
+ 'include_file' => 'sites/all/modules/ctools/includes/context-admin.inc',
+))
+->values(array(
+ 'path' => 'ctools/context/ajax/delete',
+ 'load_functions' => '',
+ 'to_arg_functions' => '',
+ 'access_callback' => 'user_access',
+ 'access_arguments' => 'a:1:{i:0;s:14:"access content";}',
+ 'page_callback' => 'ctools_context_ajax_item_delete',
+ 'page_arguments' => 'a:0:{}',
+ 'delivery_callback' => '',
+ 'fit' => '15',
+ 'number_parts' => '4',
+ 'context' => '0',
+ 'tab_parent' => '',
+ 'tab_root' => 'ctools/context/ajax/delete',
+ 'title' => '',
+ 'title_callback' => 't',
+ 'title_arguments' => '',
+ 'theme_callback' => 'ajax_base_page_theme',
+ 'theme_arguments' => 'a:0:{}',
+ 'type' => '0',
+ 'description' => '',
+ 'position' => '',
+ 'weight' => '0',
+ 'include_file' => 'sites/all/modules/ctools/includes/context-admin.inc',
+))
->values(array(
'path' => 'email/%/%/%',
'load_functions' => 'a:3:{i:1;N;i:2;N;i:3;N;}',
@@ -28107,6 +29019,56 @@ $connection->insert('menu_router')
'weight' => '0',
'include_file' => '',
))
+->values(array(
+ 'path' => 'entityreference/autocomplete/single/%/%/%',
+ 'load_functions' => 'a:3:{i:3;N;i:4;N;i:5;N;}',
+ 'to_arg_functions' => '',
+ 'access_callback' => 'entityreference_autocomplete_access_callback',
+ 'access_arguments' => 'a:4:{i:0;i:2;i:1;i:3;i:2;i:4;i:3;i:5;}',
+ 'page_callback' => 'entityreference_autocomplete_callback',
+ 'page_arguments' => 'a:4:{i:0;i:2;i:1;i:3;i:2;i:4;i:3;i:5;}',
+ 'delivery_callback' => '',
+ 'fit' => '56',
+ 'number_parts' => '6',
+ 'context' => '0',
+ 'tab_parent' => '',
+ 'tab_root' => 'entityreference/autocomplete/single/%/%/%',
+ 'title' => 'Entity Reference Autocomplete',
+ 'title_callback' => 't',
+ 'title_arguments' => '',
+ 'theme_callback' => '',
+ 'theme_arguments' => 'a:0:{}',
+ 'type' => '0',
+ 'description' => '',
+ 'position' => '',
+ 'weight' => '0',
+ 'include_file' => '',
+))
+->values(array(
+ 'path' => 'entityreference/autocomplete/tags/%/%/%',
+ 'load_functions' => 'a:3:{i:3;N;i:4;N;i:5;N;}',
+ 'to_arg_functions' => '',
+ 'access_callback' => 'entityreference_autocomplete_access_callback',
+ 'access_arguments' => 'a:4:{i:0;i:2;i:1;i:3;i:2;i:4;i:3;i:5;}',
+ 'page_callback' => 'entityreference_autocomplete_callback',
+ 'page_arguments' => 'a:4:{i:0;i:2;i:1;i:3;i:2;i:4;i:3;i:5;}',
+ 'delivery_callback' => '',
+ 'fit' => '56',
+ 'number_parts' => '6',
+ 'context' => '0',
+ 'tab_parent' => '',
+ 'tab_root' => 'entityreference/autocomplete/tags/%/%/%',
+ 'title' => 'Entity Reference Autocomplete',
+ 'title_callback' => 't',
+ 'title_arguments' => '',
+ 'theme_callback' => '',
+ 'theme_arguments' => 'a:0:{}',
+ 'type' => '0',
+ 'description' => '',
+ 'position' => '',
+ 'weight' => '0',
+ 'include_file' => '',
+))
->values(array(
'path' => 'file/ajax',
'load_functions' => '',
@@ -31227,6 +32189,111 @@ $connection->insert('registry')
'module' => 'phone',
'weight' => '0',
))
+->values(array(
+ 'name' => 'CtoolsContextKeywordsSubstitutionTestCase',
+ 'type' => 'class',
+ 'filename' => 'sites/all/modules/ctools/tests/context.test',
+ 'module' => 'ctools_plugin_test',
+ 'weight' => '0',
+))
+->values(array(
+ 'name' => 'CToolsCssCache',
+ 'type' => 'class',
+ 'filename' => 'sites/all/modules/ctools/includes/css-cache.inc',
+ 'module' => 'ctools',
+ 'weight' => '0',
+))
+->values(array(
+ 'name' => 'CtoolsCssTestCase',
+ 'type' => 'class',
+ 'filename' => 'sites/all/modules/ctools/tests/css.test',
+ 'module' => 'ctools_plugin_test',
+ 'weight' => '0',
+))
+->values(array(
+ 'name' => 'CtoolsExportCrudTestCase',
+ 'type' => 'class',
+ 'filename' => 'sites/all/modules/ctools/tests/ctools_export_test/ctools_export.test',
+ 'module' => 'ctools_export_test',
+ 'weight' => '0',
+))
+->values(array(
+ 'name' => 'CtoolsMathExpressionStackTestCase',
+ 'type' => 'class',
+ 'filename' => 'sites/all/modules/ctools/tests/math_expression_stack.test',
+ 'module' => 'ctools_plugin_test',
+ 'weight' => '0',
+))
+->values(array(
+ 'name' => 'CtoolsMathExpressionTestCase',
+ 'type' => 'class',
+ 'filename' => 'sites/all/modules/ctools/tests/math_expression.test',
+ 'module' => 'ctools_plugin_test',
+ 'weight' => '0',
+))
+->values(array(
+ 'name' => 'CtoolsObjectCache',
+ 'type' => 'class',
+ 'filename' => 'sites/all/modules/ctools/tests/object_cache.test',
+ 'module' => 'ctools_plugin_test',
+ 'weight' => '0',
+))
+->values(array(
+ 'name' => 'CtoolsPluginsGetInfoTestCase',
+ 'type' => 'class',
+ 'filename' => 'sites/all/modules/ctools/tests/ctools.plugins.test',
+ 'module' => 'ctools_plugin_test',
+ 'weight' => '0',
+))
+->values(array(
+ 'name' => 'ctools_context',
+ 'type' => 'class',
+ 'filename' => 'sites/all/modules/ctools/includes/context.inc',
+ 'module' => 'ctools',
+ 'weight' => '0',
+))
+->values(array(
+ 'name' => 'ctools_context_optional',
+ 'type' => 'class',
+ 'filename' => 'sites/all/modules/ctools/includes/context.inc',
+ 'module' => 'ctools',
+ 'weight' => '0',
+))
+->values(array(
+ 'name' => 'ctools_context_required',
+ 'type' => 'class',
+ 'filename' => 'sites/all/modules/ctools/includes/context.inc',
+ 'module' => 'ctools',
+ 'weight' => '0',
+))
+->values(array(
+ 'name' => 'ctools_export_ui',
+ 'type' => 'class',
+ 'filename' => 'sites/all/modules/ctools/plugins/export_ui/ctools_export_ui.class.php',
+ 'module' => 'ctools',
+ 'weight' => '0',
+))
+->values(array(
+ 'name' => 'ctools_math_expr',
+ 'type' => 'class',
+ 'filename' => 'sites/all/modules/ctools/includes/math-expr.inc',
+ 'module' => 'ctools',
+ 'weight' => '0',
+))
+->values(array(
+ 'name' => 'ctools_math_expr_stack',
+ 'type' => 'class',
+ 'filename' => 'sites/all/modules/ctools/includes/math-expr.inc',
+ 'module' => 'ctools',
+ 'weight' => '0',
+))
+->values(array(
+ 'name' => 'ctools_stylizer_image_processor',
+ 'type' => 'class',
+ 'filename' => 'sites/all/modules/ctools/includes/stylizer.inc',
+ 'module' => 'ctools',
+ 'weight' => '0',
+))
->values(array(
'name' => 'CSPhoneNumberTestCase',
'type' => 'class',
@@ -31234,6 +32301,7 @@ $connection->insert('registry')
'module' => 'phone',
'weight' => '0',
))
+
->values(array(
'name' => 'DashboardBlocksTestCase',
'type' => 'class',
@@ -32130,6 +33198,83 @@ $connection->insert('registry')
'module' => 'system',
'weight' => '0',
))
+->values(array(
+ 'name' => 'Entity',
+ 'type' => 'class',
+ 'filename' => 'sites/all/modules/entity/includes/entity.inc',
+ 'module' => 'entity',
+ 'weight' => '0',
+))
+->values(array(
+ 'name' => 'EntityAPICommentNodeAccessTestCase',
+ 'type' => 'class',
+ 'filename' => 'sites/all/modules/entity/entity.test',
+ 'module' => 'entity',
+ 'weight' => '0',
+))
+->values(array(
+ 'name' => 'EntityAPIController',
+ 'type' => 'class',
+ 'filename' => 'sites/all/modules/entity/includes/entity.controller.inc',
+ 'module' => 'entity',
+ 'weight' => '0',
+))
+->values(array(
+ 'name' => 'EntityAPIControllerExportable',
+ 'type' => 'class',
+ 'filename' => 'sites/all/modules/entity/includes/entity.controller.inc',
+ 'module' => 'entity',
+ 'weight' => '0',
+))
+->values(array(
+ 'name' => 'EntityAPIControllerInterface',
+ 'type' => 'interface',
+ 'filename' => 'sites/all/modules/entity/includes/entity.controller.inc',
+ 'module' => 'entity',
+ 'weight' => '0',
+))
+->values(array(
+ 'name' => 'EntityAPIControllerRevisionableInterface',
+ 'type' => 'interface',
+ 'filename' => 'sites/all/modules/entity/includes/entity.controller.inc',
+ 'module' => 'entity',
+ 'weight' => '0',
+))
+->values(array(
+ 'name' => 'EntityAPIi18nItegrationTestCase',
+ 'type' => 'class',
+ 'filename' => 'sites/all/modules/entity/entity.test',
+ 'module' => 'entity',
+ 'weight' => '0',
+))
+->values(array(
+ 'name' => 'EntityAPIRulesIntegrationTestCase',
+ 'type' => 'class',
+ 'filename' => 'sites/all/modules/entity/entity.test',
+ 'module' => 'entity',
+ 'weight' => '0',
+))
+->values(array(
+ 'name' => 'EntityAPITestCase',
+ 'type' => 'class',
+ 'filename' => 'sites/all/modules/entity/entity.test',
+ 'module' => 'entity',
+ 'weight' => '0',
+))
+->values(array(
+ 'name' => 'EntityBundleableUIController',
+ 'type' => 'class',
+ 'filename' => 'sites/all/modules/entity/includes/entity.ui.inc',
+ 'module' => 'entity',
+ 'weight' => '0',
+))
+->values(array(
+ 'name' => 'EntityContentUIController',
+ 'type' => 'class',
+ 'filename' => 'sites/all/modules/entity/includes/entity.ui.inc',
+ 'module' => 'entity',
+ 'weight' => '0',
+))
->values(array(
'name' => 'EntityCrudHookTestCase',
'type' => 'class',
@@ -32137,6 +33282,97 @@ $connection->insert('registry')
'module' => 'simpletest',
'weight' => '0',
))
+->values(array(
+ 'name' => 'EntityDB',
+ 'type' => 'class',
+ 'filename' => 'sites/all/modules/entity/includes/entity.inc',
+ 'module' => 'entity',
+ 'weight' => '0',
+))
+->values(array(
+ 'name' => 'EntityDBExtendable',
+ 'type' => 'class',
+ 'filename' => 'sites/all/modules/entity/includes/entity.inc',
+ 'module' => 'entity',
+ 'weight' => '0',
+))
+->values(array(
+ 'name' => 'EntityDefaultExtraFieldsController',
+ 'type' => 'class',
+ 'filename' => 'sites/all/modules/entity/entity.info.inc',
+ 'module' => 'entity',
+ 'weight' => '0',
+))
+->values(array(
+ 'name' => 'EntityDefaultFeaturesController',
+ 'type' => 'class',
+ 'filename' => 'sites/all/modules/entity/entity.features.inc',
+ 'module' => 'entity',
+ 'weight' => '0',
+))
+->values(array(
+ 'name' => 'EntityDefaultI18nStringController',
+ 'type' => 'class',
+ 'filename' => 'sites/all/modules/entity/entity.i18n.inc',
+ 'module' => 'entity',
+ 'weight' => '0',
+))
+->values(array(
+ 'name' => 'EntityDefaultMetadataController',
+ 'type' => 'class',
+ 'filename' => 'sites/all/modules/entity/entity.info.inc',
+ 'module' => 'entity',
+ 'weight' => '0',
+))
+->values(array(
+ 'name' => 'EntityDefaultRulesController',
+ 'type' => 'class',
+ 'filename' => 'sites/all/modules/entity/entity.rules.inc',
+ 'module' => 'entity',
+ 'weight' => '0',
+))
+->values(array(
+ 'name' => 'EntityDefaultUIController',
+ 'type' => 'class',
+ 'filename' => 'sites/all/modules/entity/includes/entity.ui.inc',
+ 'module' => 'entity',
+ 'weight' => '0',
+))
+->values(array(
+ 'name' => 'EntityDefaultViewsController',
+ 'type' => 'class',
+ 'filename' => 'sites/all/modules/entity/views/entity.views.inc',
+ 'module' => 'entity',
+ 'weight' => '0',
+))
+->values(array(
+ 'name' => 'EntityDrupalWrapper',
+ 'type' => 'class',
+ 'filename' => 'sites/all/modules/entity/includes/entity.wrapper.inc',
+ 'module' => 'entity',
+ 'weight' => '0',
+))
+->values(array(
+ 'name' => 'EntityExtendable',
+ 'type' => 'class',
+ 'filename' => 'sites/all/modules/entity/includes/entity.inc',
+ 'module' => 'entity',
+ 'weight' => '0',
+))
+->values(array(
+ 'name' => 'EntityExtraFieldsControllerInterface',
+ 'type' => 'interface',
+ 'filename' => 'sites/all/modules/entity/entity.info.inc',
+ 'module' => 'entity',
+ 'weight' => '0',
+))
+->values(array(
+ 'name' => 'EntityFieldHandlerHelper',
+ 'type' => 'class',
+ 'filename' => 'sites/all/modules/entity/views/handlers/entity_views_field_handler_helper.inc',
+ 'module' => 'entity',
+ 'weight' => '0',
+))
->values(array(
'name' => 'EntityFieldQuery',
'type' => 'class',
@@ -32172,6 +33408,69 @@ $connection->insert('registry')
'module' => '',
'weight' => '0',
))
+->values(array(
+ 'name' => 'EntityMetadataArrayObject',
+ 'type' => 'class',
+ 'filename' => 'sites/all/modules/entity/includes/entity.wrapper.inc',
+ 'module' => 'entity',
+ 'weight' => '0',
+))
+->values(array(
+ 'name' => 'EntityMetadataIntegrationTestCase',
+ 'type' => 'class',
+ 'filename' => 'sites/all/modules/entity/entity.test',
+ 'module' => 'entity',
+ 'weight' => '0',
+))
+->values(array(
+ 'name' => 'EntityMetadataNodeAccessTestCase',
+ 'type' => 'class',
+ 'filename' => 'sites/all/modules/entity/entity.test',
+ 'module' => 'entity',
+ 'weight' => '0',
+))
+->values(array(
+ 'name' => 'EntityMetadataNodeCreateAccessTestCase',
+ 'type' => 'class',
+ 'filename' => 'sites/all/modules/entity/entity.test',
+ 'module' => 'entity',
+ 'weight' => '0',
+))
+->values(array(
+ 'name' => 'EntityMetadataNodeRevisionAccessTestCase',
+ 'type' => 'class',
+ 'filename' => 'sites/all/modules/entity/entity.test',
+ 'module' => 'entity',
+ 'weight' => '0',
+))
+->values(array(
+ 'name' => 'EntityMetadataTestCase',
+ 'type' => 'class',
+ 'filename' => 'sites/all/modules/entity/entity.test',
+ 'module' => 'entity',
+ 'weight' => '0',
+))
+->values(array(
+ 'name' => 'EntityMetadataWrapper',
+ 'type' => 'class',
+ 'filename' => 'sites/all/modules/entity/includes/entity.wrapper.inc',
+ 'module' => 'entity',
+ 'weight' => '0',
+))
+->values(array(
+ 'name' => 'EntityMetadataWrapperException',
+ 'type' => 'class',
+ 'filename' => 'sites/all/modules/entity/includes/entity.wrapper.inc',
+ 'module' => 'entity',
+ 'weight' => '0',
+))
+->values(array(
+ 'name' => 'EntityMetadataWrapperIterator',
+ 'type' => 'class',
+ 'filename' => 'sites/all/modules/entity/includes/entity.wrapper.inc',
+ 'module' => 'entity',
+ 'weight' => '0',
+))
->values(array(
'name' => 'EntityPropertiesTestCase',
'type' => 'class',
@@ -32179,6 +33478,251 @@ $connection->insert('registry')
'module' => 'field',
'weight' => '0',
))
+->values(array(
+ 'name' => 'EntityReferenceAdminTestCase',
+ 'type' => 'class',
+ 'filename' => 'sites/all/modules/entityreference/tests/entityreference.admin.test',
+ 'module' => 'entityreference',
+ 'weight' => '0',
+))
+->values(array(
+ 'name' => 'EntityReferenceBehavior_TaxonomyIndex',
+ 'type' => 'class',
+ 'filename' => 'sites/all/modules/entityreference/plugins/behavior/EntityReferenceBehavior_TaxonomyIndex.class.php',
+ 'module' => 'entityreference',
+ 'weight' => '0',
+))
+->values(array(
+ 'name' => 'EntityReferenceHandlersTestCase',
+ 'type' => 'class',
+ 'filename' => 'sites/all/modules/entityreference/tests/entityreference.handlers.test',
+ 'module' => 'entityreference',
+ 'weight' => '0',
+))
+->values(array(
+ 'name' => 'EntityReferenceTaxonomyTestCase',
+ 'type' => 'class',
+ 'filename' => 'sites/all/modules/entityreference/tests/entityreference.taxonomy.test',
+ 'module' => 'entityreference',
+ 'weight' => '0',
+))
+->values(array(
+ 'name' => 'EntityReference_BehaviorHandler',
+ 'type' => 'interface',
+ 'filename' => 'sites/all/modules/entityreference/plugins/behavior/abstract.inc',
+ 'module' => 'entityreference',
+ 'weight' => '0',
+))
+->values(array(
+ 'name' => 'EntityReference_BehaviorHandler_Abstract',
+ 'type' => 'class',
+ 'filename' => 'sites/all/modules/entityreference/plugins/behavior/abstract.inc',
+ 'module' => 'entityreference',
+ 'weight' => '0',
+))
+->values(array(
+ 'name' => 'EntityReference_BehaviorHandler_Broken',
+ 'type' => 'class',
+ 'filename' => 'sites/all/modules/entityreference/plugins/behavior/abstract.inc',
+ 'module' => 'entityreference',
+ 'weight' => '0',
+))
+->values(array(
+ 'name' => 'entityreference_plugin_display',
+ 'type' => 'class',
+ 'filename' => 'sites/all/modules/entityreference/views/entityreference_plugin_display.inc',
+ 'module' => 'entityreference',
+ 'weight' => '0',
+))
+->values(array(
+ 'name' => 'entityreference_plugin_row_fields',
+ 'type' => 'class',
+ 'filename' => 'sites/all/modules/entityreference/views/entityreference_plugin_row_fields.inc',
+ 'module' => 'entityreference',
+ 'weight' => '0',
+))
+->values(array(
+ 'name' => 'entityreference_plugin_style',
+ 'type' => 'class',
+ 'filename' => 'sites/all/modules/entityreference/views/entityreference_plugin_style.inc',
+ 'module' => 'entityreference',
+ 'weight' => '0',
+))
+->values(array(
+ 'name' => 'EntityReference_SelectionHandler',
+ 'type' => 'interface',
+ 'filename' => 'sites/all/modules/entityreference/plugins/selection/abstract.inc',
+ 'module' => 'entityreference',
+ 'weight' => '0',
+))
+->values(array(
+ 'name' => 'EntityReference_SelectionHandler_Broken',
+ 'type' => 'class',
+ 'filename' => 'sites/all/modules/entityreference/plugins/selection/abstract.inc',
+ 'module' => 'entityreference',
+ 'weight' => '0',
+))
+->values(array(
+ 'name' => 'EntityReference_SelectionHandler_Generic',
+ 'type' => 'class',
+ 'filename' => 'sites/all/modules/entityreference/plugins/selection/EntityReference_SelectionHandler_Generic.class.php',
+ 'module' => 'entityreference',
+ 'weight' => '0',
+))
+->values(array(
+ 'name' => 'EntityReference_SelectionHandler_Generic_comment',
+ 'type' => 'class',
+ 'filename' => 'sites/all/modules/entityreference/plugins/selection/EntityReference_SelectionHandler_Generic.class.php',
+ 'module' => 'entityreference',
+ 'weight' => '0',
+))
+->values(array(
+ 'name' => 'EntityReference_SelectionHandler_Generic_file',
+ 'type' => 'class',
+ 'filename' => 'sites/all/modules/entityreference/plugins/selection/EntityReference_SelectionHandler_Generic.class.php',
+ 'module' => 'entityreference',
+ 'weight' => '0',
+))
+->values(array(
+ 'name' => 'EntityReference_SelectionHandler_Generic_node',
+ 'type' => 'class',
+ 'filename' => 'sites/all/modules/entityreference/plugins/selection/EntityReference_SelectionHandler_Generic.class.php',
+ 'module' => 'entityreference',
+ 'weight' => '0',
+))
+->values(array(
+ 'name' => 'EntityReference_SelectionHandler_Generic_taxonomy_term',
+ 'type' => 'class',
+ 'filename' => 'sites/all/modules/entityreference/plugins/selection/EntityReference_SelectionHandler_Generic.class.php',
+ 'module' => 'entityreference',
+ 'weight' => '0',
+))
+->values(array(
+ 'name' => 'EntityReference_SelectionHandler_Generic_user',
+ 'type' => 'class',
+ 'filename' => 'sites/all/modules/entityreference/plugins/selection/EntityReference_SelectionHandler_Generic.class.php',
+ 'module' => 'entityreference',
+ 'weight' => '0',
+))
+->values(array(
+ 'name' => 'EntityStructureWrapper',
+ 'type' => 'class',
+ 'filename' => 'sites/all/modules/entity/includes/entity.wrapper.inc',
+ 'module' => 'entity',
+ 'weight' => '0',
+))
+->values(array(
+ 'name' => 'EntityTokenTestCase',
+ 'type' => 'class',
+ 'filename' => 'sites/all/modules/entity/entity.test',
+ 'module' => 'entity',
+ 'weight' => '0',
+))
+->values(array(
+ 'name' => 'EntityValueWrapper',
+ 'type' => 'class',
+ 'filename' => 'sites/all/modules/entity/includes/entity.wrapper.inc',
+ 'module' => 'entity',
+ 'weight' => '0',
+))
+->values(array(
+ 'name' => 'EntityWebTestCase',
+ 'type' => 'class',
+ 'filename' => 'sites/all/modules/entity/entity.test',
+ 'module' => 'entity',
+ 'weight' => '0',
+))
+->values(array(
+ 'name' => 'entity_views_handler_area_entity',
+ 'type' => 'class',
+ 'filename' => 'sites/all/modules/entity/views/handlers/entity_views_handler_area_entity.inc',
+ 'module' => 'entity',
+ 'weight' => '0',
+))
+->values(array(
+ 'name' => 'entity_views_handler_field_boolean',
+ 'type' => 'class',
+ 'filename' => 'sites/all/modules/entity/views/handlers/entity_views_handler_field_boolean.inc',
+ 'module' => 'entity',
+ 'weight' => '0',
+))
+->values(array(
+ 'name' => 'entity_views_handler_field_date',
+ 'type' => 'class',
+ 'filename' => 'sites/all/modules/entity/views/handlers/entity_views_handler_field_date.inc',
+ 'module' => 'entity',
+ 'weight' => '0',
+))
+->values(array(
+ 'name' => 'entity_views_handler_field_duration',
+ 'type' => 'class',
+ 'filename' => 'sites/all/modules/entity/views/handlers/entity_views_handler_field_duration.inc',
+ 'module' => 'entity',
+ 'weight' => '0',
+))
+->values(array(
+ 'name' => 'entity_views_handler_field_entity',
+ 'type' => 'class',
+ 'filename' => 'sites/all/modules/entity/views/handlers/entity_views_handler_field_entity.inc',
+ 'module' => 'entity',
+ 'weight' => '0',
+))
+->values(array(
+ 'name' => 'entity_views_handler_field_field',
+ 'type' => 'class',
+ 'filename' => 'sites/all/modules/entity/views/handlers/entity_views_handler_field_field.inc',
+ 'module' => 'entity',
+ 'weight' => '0',
+))
+->values(array(
+ 'name' => 'entity_views_handler_field_numeric',
+ 'type' => 'class',
+ 'filename' => 'sites/all/modules/entity/views/handlers/entity_views_handler_field_numeric.inc',
+ 'module' => 'entity',
+ 'weight' => '0',
+))
+->values(array(
+ 'name' => 'entity_views_handler_field_options',
+ 'type' => 'class',
+ 'filename' => 'sites/all/modules/entity/views/handlers/entity_views_handler_field_options.inc',
+ 'module' => 'entity',
+ 'weight' => '0',
+))
+->values(array(
+ 'name' => 'entity_views_handler_field_text',
+ 'type' => 'class',
+ 'filename' => 'sites/all/modules/entity/views/handlers/entity_views_handler_field_text.inc',
+ 'module' => 'entity',
+ 'weight' => '0',
+))
+->values(array(
+ 'name' => 'entity_views_handler_field_uri',
+ 'type' => 'class',
+ 'filename' => 'sites/all/modules/entity/views/handlers/entity_views_handler_field_uri.inc',
+ 'module' => 'entity',
+ 'weight' => '0',
+))
+->values(array(
+ 'name' => 'entity_views_handler_relationship',
+ 'type' => 'class',
+ 'filename' => 'sites/all/modules/entity/views/handlers/entity_views_handler_relationship.inc',
+ 'module' => 'entity',
+ 'weight' => '0',
+))
+->values(array(
+ 'name' => 'entity_views_handler_relationship_by_bundle',
+ 'type' => 'class',
+ 'filename' => 'sites/all/modules/entity/views/handlers/entity_views_handler_relationship_by_bundle.inc',
+ 'module' => 'entity',
+ 'weight' => '0',
+))
+->values(array(
+ 'name' => 'entity_views_plugin_row_entity_view',
+ 'type' => 'class',
+ 'filename' => 'sites/all/modules/entity/views/plugins/entity_views_plugin_row_entity_view.inc',
+ 'module' => 'entity',
+ 'weight' => '0',
+))
->values(array(
'name' => 'ESPhoneNumberTestCase',
'type' => 'class',
@@ -32207,6 +33751,13 @@ $connection->insert('registry')
'module' => 'aggregator',
'weight' => '0',
))
+->values(array(
+ 'name' => 'FeedsMapperFieldTestCase',
+ 'type' => 'class',
+ 'filename' => 'sites/all/modules/entityreference/tests/entityreference.feeds.test',
+ 'module' => 'entityreference',
+ 'weight' => '0',
+))
->values(array(
'name' => 'FieldAttachOtherTestCase',
'type' => 'class',
@@ -33558,6 +35109,13 @@ $connection->insert('registry')
'module' => 'email',
'weight' => '0',
))
+->values(array(
+ 'name' => 'MigrateEntityReferenceFieldHandler',
+ 'type' => 'class',
+ 'filename' => 'sites/all/modules/entityreference/entityreference.migrate.inc',
+ 'module' => 'entityreference',
+ 'weight' => '0',
+))
->values(array(
'name' => 'MigrateLinkFieldHandler',
'type' => 'class',
@@ -36912,6 +38470,58 @@ $connection->insert('registry_file')
'filename' => 'modules/user/user.test',
'hash' => '178320fdb9a0c8754f1fa7272f68f536dcb94ae82ce7d0fc6a0f8a476c1f6922',
))
+->values(array(
+ 'filename' => 'sites/all/modules/ctools/includes/context.inc',
+ 'hash' => '4cec11a71872eb916c4315c9f727a184d46758aa64bb950d86877a60b9007157',
+))
+->values(array(
+ 'filename' => 'sites/all/modules/ctools/includes/css-cache.inc',
+ 'hash' => 'db90ff67669d9fa445e91074ac67fb97cdb191a19e68d42744f0fd4158649cfa',
+))
+->values(array(
+ 'filename' => 'sites/all/modules/ctools/includes/math-expr.inc',
+ 'hash' => '601db581743dd22d67f7aaf228bd8d26298d72033fc675d02385a1fd6d31888f',
+))
+->values(array(
+ 'filename' => 'sites/all/modules/ctools/includes/stylizer.inc',
+ 'hash' => '3f91f5ed42fb6ee1b65ddef7ac22577b07a5d75ca1eb2df60041243ced5c7079',
+))
+->values(array(
+ 'filename' => 'sites/all/modules/ctools/plugins/export_ui/ctools_export_ui.class.php',
+ 'hash' => '2fd87a7d80689e4d44673b31c07b762144eb8ac57324fd0b9cd9ede5f4ea34b5',
+))
+->values(array(
+ 'filename' => 'sites/all/modules/ctools/tests/context.test',
+ 'hash' => '3a8dd81dd1b99da05a28425f9a017cb611e0470ba88cf000c8b74339c8c91d91',
+))
+->values(array(
+ 'filename' => 'sites/all/modules/ctools/tests/css.test',
+ 'hash' => '20ba7d780a8bdd8f512472a8becef11240da74b96599f6968fecea0ad7ae49c6',
+))
+->values(array(
+ 'filename' => 'sites/all/modules/ctools/tests/css_cache.test',
+ 'hash' => '0dbc038efedb1fa06d2617b7c72b3a45d6ee5b5b791dcb1134876f174a2a7733',
+))
+->values(array(
+ 'filename' => 'sites/all/modules/ctools/tests/ctools.plugins.test',
+ 'hash' => '6af9d9caa3afe93faf5051d3d42c0ce33a1ff6e3a18a09f281df1260d43337d6',
+))
+->values(array(
+ 'filename' => 'sites/all/modules/ctools/tests/ctools_export_test/ctools_export.test',
+ 'hash' => '65e96eabc5c62d7ad29f63309671e2761f221a1c15bb6836d7eadfd263653abc',
+))
+->values(array(
+ 'filename' => 'sites/all/modules/ctools/tests/math_expression.test',
+ 'hash' => 'b99d5c3096857de944dba0e88e21628c7268d8056f42903786172b7a95563dbf',
+))
+->values(array(
+ 'filename' => 'sites/all/modules/ctools/tests/math_expression_stack.test',
+ 'hash' => '797d9e0844f9e214799d96b33d55dd041720d27b11ceb96c3790634d93a62be6',
+))
+->values(array(
+ 'filename' => 'sites/all/modules/ctools/tests/object_cache.test',
+ 'hash' => '18e03c7760a2fc8858d801479ec5471b8c93bd4044c80db557c5e77e7ab20d79',
+))
->values(array(
'filename' => 'sites/all/modules/date/date.migrate.inc',
'hash' => '47ffb48daf97c13ef154cf2ffff577018f02a7091b85dfb39e9c2c89e1da6a5d',
@@ -36972,6 +38582,154 @@ $connection->insert('registry_file')
'filename' => 'sites/all/modules/email/email.migrate.inc',
'hash' => 'bf3859ca39a3e5570e4ac862858f066668caab33841d65bdfa229c8445e12d5a',
))
+->values(array(
+ 'filename' => 'sites/all/modules/entity/entity.features.inc',
+ 'hash' => '47261e1f4f39ac3707a16fdea8a8147c09df1281bcb4b9e46b0c8120603137e8',
+))
+->values(array(
+ 'filename' => 'sites/all/modules/entity/entity.i18n.inc',
+ 'hash' => '41e0e62af7e2774f62b162d597bb3244551c280296b692b29d039a2c243d7059',
+))
+->values(array(
+ 'filename' => 'sites/all/modules/entity/entity.info.inc',
+ 'hash' => '8799080b9393c9560e64feae1276fb7d26fef4d92bb0edacc863ee3e7b67bf04',
+))
+->values(array(
+ 'filename' => 'sites/all/modules/entity/entity.rules.inc',
+ 'hash' => '774199059d1b3ebe6d3fe7a49dbb1550df489055a3d066b5de54edda8dd7ba84',
+))
+->values(array(
+ 'filename' => 'sites/all/modules/entity/entity.test',
+ 'hash' => 'df253128e41f152b45ef30b5674009c51cf4112450e5dad8e815f39ced280db5',
+))
+->values(array(
+ 'filename' => 'sites/all/modules/entity/includes/entity.controller.inc',
+ 'hash' => '342db185e6170b63c59a9b360a196eb322edb9a5b8c7819f66b0eae48ed13ebd',
+))
+->values(array(
+ 'filename' => 'sites/all/modules/entity/includes/entity.inc',
+ 'hash' => '57411fa3d7b5cd2afe8b84f20c1741f48c32673a9da07bd2c35d4a11c50c640e',
+))
+->values(array(
+ 'filename' => 'sites/all/modules/entity/includes/entity.ui.inc',
+ 'hash' => '65739b31af0e6b422919c17805799dc99143fd89cacfb56b9186e26ece2d0df2',
+))
+->values(array(
+ 'filename' => 'sites/all/modules/entity/includes/entity.wrapper.inc',
+ 'hash' => '0db08cbb6b730035e3e9a483e6e5c06a744a73f19e4ca83936446b44f0c3d158',
+))
+->values(array(
+ 'filename' => 'sites/all/modules/entity/views/entity.views.inc',
+ 'hash' => 'de657f42389ed6832df787e4b618d8d7117b60d145d34ce5dcf3a5b65db29df9',
+))
+->values(array(
+ 'filename' => 'sites/all/modules/entity/views/handlers/entity_views_field_handler_helper.inc',
+ 'hash' => '4ec395881109a71327ab8d7c5b5702bef30288ca66557e44e8539cc15a2135bb',
+))
+->values(array(
+ 'filename' => 'sites/all/modules/entity/views/handlers/entity_views_handler_area_entity.inc',
+ 'hash' => '7b7bb88e53861739b7279f705f0492fc83ce95f5b20d89339480f546422ebf25',
+))
+->values(array(
+ 'filename' => 'sites/all/modules/entity/views/handlers/entity_views_handler_field_boolean.inc',
+ 'hash' => 'b28b8eee8761ba7a6af35d97ab7aaee28406e6c227271f9769818560626c5791',
+))
+->values(array(
+ 'filename' => 'sites/all/modules/entity/views/handlers/entity_views_handler_field_date.inc',
+ 'hash' => 'b0f5be5b399de94934b24e84c8cf6053a043f6b00c60dcffa752daeafdd38778',
+))
+->values(array(
+ 'filename' => 'sites/all/modules/entity/views/handlers/entity_views_handler_field_duration.inc',
+ 'hash' => 'ed7bb64cb63b94a20c8cde98cfb053b5ea252804396cf61ac562faf1d850266b',
+))
+->values(array(
+ 'filename' => 'sites/all/modules/entity/views/handlers/entity_views_handler_field_entity.inc',
+ 'hash' => '4f255918a22fefebe9c7734f200751457a7ca4d3648e32a98511bb51968d7521',
+))
+->values(array(
+ 'filename' => 'sites/all/modules/entity/views/handlers/entity_views_handler_field_field.inc',
+ 'hash' => '893121efbce2a7181e31147bade260c9cc657cbd33b0d254cb28b2650e57566d',
+))
+->values(array(
+ 'filename' => 'sites/all/modules/entity/views/handlers/entity_views_handler_field_numeric.inc',
+ 'hash' => 'f14e2b063930e8820af381b4f5e83c7278440e7804ab88cfde865b6c94e7c0f6',
+))
+->values(array(
+ 'filename' => 'sites/all/modules/entity/views/handlers/entity_views_handler_field_options.inc',
+ 'hash' => '27ef31b8ee7b9999930380d6a5fdb477772329c4ddbd5c70cc34bcdc7543ce56',
+))
+->values(array(
+ 'filename' => 'sites/all/modules/entity/views/handlers/entity_views_handler_field_text.inc',
+ 'hash' => '5fb0a85d35d29944c699ceaf6efed5eda2df757009e44caba8ff2be397568b60',
+))
+->values(array(
+ 'filename' => 'sites/all/modules/entity/views/handlers/entity_views_handler_field_uri.inc',
+ 'hash' => '79ecaa3eb17dfdd0ca077351b75a2c0adf411ebc04720e7cc0e2397674225f24',
+))
+->values(array(
+ 'filename' => 'sites/all/modules/entity/views/handlers/entity_views_handler_relationship.inc',
+ 'hash' => 'b69bc538d1e1e0f91f8485ca54c3b6e2be025caa47619734c467377cf89041b9',
+))
+->values(array(
+ 'filename' => 'sites/all/modules/entity/views/handlers/entity_views_handler_relationship_by_bundle.inc',
+ 'hash' => '65300c793c4591d60ad908dc02cf3148fe4e899fa6ad218e875fd92d411374dc',
+))
+->values(array(
+ 'filename' => 'sites/all/modules/entity/views/plugins/entity_views_plugin_row_entity_view.inc',
+ 'hash' => 'ba557790215f2658146424d933e0d17787a0b15180c5815f23428448ccf056a0',
+))
+->values(array(
+ 'filename' => 'sites/all/modules/entityreference/entityreference.migrate.inc',
+ 'hash' => '617c6c49e6e0fa4d106cfb49b61a6994b5520934ac3b64a8400a9d969eab7c59',
+))
+->values(array(
+ 'filename' => 'sites/all/modules/entityreference/plugins/behavior/abstract.inc',
+ 'hash' => 'a7959ddece2ce3490f92d916162e07aed313e28ca299ca0375bad633b42d93e3',
+))
+->values(array(
+ 'filename' => 'sites/all/modules/entityreference/plugins/behavior/EntityReferenceBehavior_TaxonomyIndex.class.php',
+ 'hash' => '92fa0cf46ecdf6200659646e6666c562ea506c40efa41a8edd4758dc0c551b92',
+))
+->values(array(
+ 'filename' => 'sites/all/modules/entityreference/plugins/selection/abstract.inc',
+ 'hash' => '7ecf94f5dc3456e4a5c87117d19deb98c368617fb07d610505b1dfa351f14a0b',
+))
+->values(array(
+ 'filename' => 'sites/all/modules/entityreference/plugins/selection/EntityReference_SelectionHandler_Generic.class.php',
+ 'hash' => 'e9a8a3c693ed24218d00c10c445cdb21daed10a26e6b55e5c9d6a8c616cfd871',
+))
+->values(array(
+ 'filename' => 'sites/all/modules/entityreference/plugins/selection/views.inc',
+ 'hash' => '7bbe8900b6b71c2d41e370deaccca869884d0fe9ca81772d7d5bca5f58ec1cd8',
+))
+->values(array(
+ 'filename' => 'sites/all/modules/entityreference/tests/entityreference.admin.test',
+ 'hash' => 'bcd6516be3099ae87a4c3d41add08edd17eafb4244db8442c5dc15f19ebde7ae',
+))
+->values(array(
+ 'filename' => 'sites/all/modules/entityreference/tests/entityreference.feeds.test',
+ 'hash' => '320c7480b1758e4d80e91c0a6ea3d43b6b35d1adfe00b6155b61ef786510bb7c',
+))
+->values(array(
+ 'filename' => 'sites/all/modules/entityreference/tests/entityreference.handlers.test',
+ 'hash' => '2fa170925ac5303c519378f1763e918cc2f111205220d90998b547a08db90d8c',
+))
+->values(array(
+ 'filename' => 'sites/all/modules/entityreference/tests/entityreference.taxonomy.test',
+ 'hash' => '8e4f7d9ae621df0f587b6fcbf139adea2a35c69305ef018ced88447a41164c5f',
+))
+->values(array(
+ 'filename' => 'sites/all/modules/entityreference/views/entityreference_plugin_display.inc',
+ 'hash' => '9216a065ea4fdb2daacb1280e5c9549e3400b8553b5293534cf65a0d703ab189',
+))
+->values(array(
+ 'filename' => 'sites/all/modules/entityreference/views/entityreference_plugin_row_fields.inc',
+ 'hash' => '7f5a58c099c2df6fd1c3ae285197a4648841d44fa107bcb2064bc1edf435ea8b',
+))
+->values(array(
+ 'filename' => 'sites/all/modules/entityreference/views/entityreference_plugin_style.inc',
+ 'hash' => 'ad9a7ea5a37c2d9658c2b1d19ade3011c27ed5d9959423ebf7a390372507e6b0',
+))
->values(array(
'filename' => 'sites/all/modules/link/link.migrate.inc',
'hash' => '0a17ff0daa79813174fff92e9db787e75e710fe757b6924eec193c66fe13f3df',
@@ -40064,6 +41822,17 @@ $connection->insert('system')
'weight' => '1000',
'info' => 'a:15:{s:4:"name";s:8:"Standard";s:11:"description";s:51:"Install with commonly used features pre-configured.";s:7:"version";s:4:"7.40";s:4:"core";s:3:"7.x";s:12:"dependencies";a:21:{i:0;s:5:"block";i:1;s:5:"color";i:2;s:7:"comment";i:3;s:10:"contextual";i:4;s:9:"dashboard";i:5;s:4:"help";i:6;s:5:"image";i:7;s:4:"list";i:8;s:4:"menu";i:9;s:6:"number";i:10;s:7:"options";i:11;s:4:"path";i:12;s:8:"taxonomy";i:13;s:5:"dblog";i:14;s:6:"search";i:15;s:8:"shortcut";i:16;s:7:"toolbar";i:17;s:7:"overlay";i:18;s:8:"field_ui";i:19;s:4:"file";i:20;s:3:"rdf";}s:7:"project";s:6:"drupal";s:9:"datestamp";s:10:"1444866674";s:5:"mtime";i:1444866674;s:7:"package";s:5:"Other";s:3:"php";s:5:"5.2.4";s:5:"files";a:0:{}s:9:"bootstrap";i:0;s:6:"hidden";b:1;s:8:"required";b:1;s:17:"distribution_name";s:6:"Drupal";}',
))
+->values(array(
+ 'filename' => 'sites/all/modules/ctools/bulk_export/bulk_export.module',
+ 'name' => 'bulk_export',
+ 'type' => 'module',
+ 'owner' => '',
+ 'status' => '0',
+ 'bootstrap' => '0',
+ 'schema_version' => '-1',
+ 'weight' => '0',
+ 'info' => 'a:12:{s:4:"name";s:11:"Bulk Export";s:11:"description";s:67:"Performs bulk exporting of data objects known about by Chaos tools.";s:4:"core";s:3:"7.x";s:12:"dependencies";a:1:{i:0;s:6:"ctools";}s:7:"package";s:16:"Chaos tool suite";s:7:"version";s:7:"7.x-1.9";s:7:"project";s:6:"ctools";s:9:"datestamp";s:10:"1440020680";s:5:"mtime";i:1440020680;s:3:"php";s:5:"5.2.4";s:5:"files";a:0:{}s:9:"bootstrap";i:0;}',
+))
->values(array(
'filename' => 'sites/all/modules/ctools/ctools.module',
'name' => 'ctools',
@@ -40075,6 +41844,116 @@ $connection->insert('system')
'weight' => '0',
'info' => 'a:12:{s:4:"name";s:11:"Chaos tools";s:11:"description";s:46:"A library of helpful tools by Merlin of Chaos.";s:4:"core";s:3:"7.x";s:7:"package";s:16:"Chaos tool suite";s:5:"files";a:3:{i:0;s:20:"includes/context.inc";i:1;s:22:"includes/math-expr.inc";i:2;s:21:"includes/stylizer.inc";}s:7:"version";s:7:"7.x-1.4";s:7:"project";s:6:"ctools";s:9:"datestamp";s:10:"1392220730";s:5:"mtime";i:1392220730;s:12:"dependencies";a:0:{}s:3:"php";s:5:"5.2.4";s:9:"bootstrap";i:0;}',
))
+->values(array(
+ 'filename' => 'sites/all/modules/ctools/ctools_access_ruleset/ctools_access_ruleset.module',
+ 'name' => 'ctools_access_ruleset',
+ 'type' => 'module',
+ 'owner' => '',
+ 'status' => '0',
+ 'bootstrap' => '0',
+ 'schema_version' => '-1',
+ 'weight' => '0',
+ 'info' => 'a:12:{s:4:"name";s:15:"Custom rulesets";s:11:"description";s:81:"Create custom, exportable, reusable access rulesets for applications like Panels.";s:4:"core";s:3:"7.x";s:7:"package";s:16:"Chaos tool suite";s:7:"version";s:7:"7.x-1.9";s:12:"dependencies";a:1:{i:0;s:6:"ctools";}s:7:"project";s:6:"ctools";s:9:"datestamp";s:10:"1440020680";s:5:"mtime";i:1440020680;s:3:"php";s:5:"5.2.4";s:5:"files";a:0:{}s:9:"bootstrap";i:0;}',
+))
+->values(array(
+ 'filename' => 'sites/all/modules/ctools/ctools_ajax_sample/ctools_ajax_sample.module',
+ 'name' => 'ctools_ajax_sample',
+ 'type' => 'module',
+ 'owner' => '',
+ 'status' => '0',
+ 'bootstrap' => '0',
+ 'schema_version' => '-1',
+ 'weight' => '0',
+ 'info' => 'a:12:{s:4:"name";s:33:"Chaos Tools (CTools) AJAX Example";s:11:"description";s:41:"Shows how to use the power of Chaos AJAX.";s:7:"package";s:16:"Chaos tool suite";s:7:"version";s:7:"7.x-1.9";s:12:"dependencies";a:1:{i:0;s:6:"ctools";}s:4:"core";s:3:"7.x";s:7:"project";s:6:"ctools";s:9:"datestamp";s:10:"1440020680";s:5:"mtime";i:1440020680;s:3:"php";s:5:"5.2.4";s:5:"files";a:0:{}s:9:"bootstrap";i:0;}',
+))
+->values(array(
+ 'filename' => 'sites/all/modules/ctools/ctools_custom_content/ctools_custom_content.module',
+ 'name' => 'ctools_custom_content',
+ 'type' => 'module',
+ 'owner' => '',
+ 'status' => '0',
+ 'bootstrap' => '0',
+ 'schema_version' => '-1',
+ 'weight' => '0',
+ 'info' => 'a:12:{s:4:"name";s:20:"Custom content panes";s:11:"description";s:79:"Create custom, exportable, reusable content panes for applications like Panels.";s:4:"core";s:3:"7.x";s:7:"package";s:16:"Chaos tool suite";s:7:"version";s:7:"7.x-1.9";s:12:"dependencies";a:1:{i:0;s:6:"ctools";}s:7:"project";s:6:"ctools";s:9:"datestamp";s:10:"1440020680";s:5:"mtime";i:1440020680;s:3:"php";s:5:"5.2.4";s:5:"files";a:0:{}s:9:"bootstrap";i:0;}',
+))
+->values(array(
+ 'filename' => 'sites/all/modules/ctools/ctools_plugin_example/ctools_plugin_example.module',
+ 'name' => 'ctools_plugin_example',
+ 'type' => 'module',
+ 'owner' => '',
+ 'status' => '0',
+ 'bootstrap' => '0',
+ 'schema_version' => '-1',
+ 'weight' => '0',
+ 'info' => 'a:12:{s:4:"name";s:35:"Chaos Tools (CTools) Plugin Example";s:11:"description";s:75:"Shows how an external module can provide ctools plugins (for Panels, etc.).";s:7:"package";s:16:"Chaos tool suite";s:7:"version";s:7:"7.x-1.9";s:12:"dependencies";a:4:{i:0;s:6:"ctools";i:1;s:6:"panels";i:2;s:12:"page_manager";i:3;s:13:"advanced_help";}s:4:"core";s:3:"7.x";s:7:"project";s:6:"ctools";s:9:"datestamp";s:10:"1440020680";s:5:"mtime";i:1440020680;s:3:"php";s:5:"5.2.4";s:5:"files";a:0:{}s:9:"bootstrap";i:0;}',
+))
+->values(array(
+ 'filename' => 'sites/all/modules/ctools/page_manager/page_manager.module',
+ 'name' => 'page_manager',
+ 'type' => 'module',
+ 'owner' => '',
+ 'status' => '0',
+ 'bootstrap' => '0',
+ 'schema_version' => '-1',
+ 'weight' => '0',
+ 'info' => 'a:12:{s:4:"name";s:12:"Page manager";s:11:"description";s:54:"Provides a UI and API to manage pages within the site.";s:4:"core";s:3:"7.x";s:12:"dependencies";a:1:{i:0;s:6:"ctools";}s:7:"package";s:16:"Chaos tool suite";s:7:"version";s:7:"7.x-1.9";s:7:"project";s:6:"ctools";s:9:"datestamp";s:10:"1440020680";s:5:"mtime";i:1440020680;s:3:"php";s:5:"5.2.4";s:5:"files";a:0:{}s:9:"bootstrap";i:0;}',
+))
+->values(array(
+ 'filename' => 'sites/all/modules/ctools/stylizer/stylizer.module',
+ 'name' => 'stylizer',
+ 'type' => 'module',
+ 'owner' => '',
+ 'status' => '0',
+ 'bootstrap' => '0',
+ 'schema_version' => '-1',
+ 'weight' => '0',
+ 'info' => 'a:12:{s:4:"name";s:8:"Stylizer";s:11:"description";s:53:"Create custom styles for applications such as Panels.";s:4:"core";s:3:"7.x";s:7:"package";s:16:"Chaos tool suite";s:7:"version";s:7:"7.x-1.9";s:12:"dependencies";a:2:{i:0;s:6:"ctools";i:1;s:5:"color";}s:7:"project";s:6:"ctools";s:9:"datestamp";s:10:"1440020680";s:5:"mtime";i:1440020680;s:3:"php";s:5:"5.2.4";s:5:"files";a:0:{}s:9:"bootstrap";i:0;}',
+))
+->values(array(
+ 'filename' => 'sites/all/modules/ctools/term_depth/term_depth.module',
+ 'name' => 'term_depth',
+ 'type' => 'module',
+ 'owner' => '',
+ 'status' => '0',
+ 'bootstrap' => '0',
+ 'schema_version' => '-1',
+ 'weight' => '0',
+ 'info' => 'a:12:{s:4:"name";s:17:"Term Depth access";s:11:"description";s:48:"Controls access to context based upon term depth";s:4:"core";s:3:"7.x";s:12:"dependencies";a:1:{i:0;s:6:"ctools";}s:7:"package";s:16:"Chaos tool suite";s:7:"version";s:7:"7.x-1.9";s:7:"project";s:6:"ctools";s:9:"datestamp";s:10:"1440020680";s:5:"mtime";i:1440020680;s:3:"php";s:5:"5.2.4";s:5:"files";a:0:{}s:9:"bootstrap";i:0;}',
+))
+->values(array(
+ 'filename' => 'sites/all/modules/ctools/tests/ctools_export_test/ctools_export_test.module',
+ 'name' => 'ctools_export_test',
+ 'type' => 'module',
+ 'owner' => '',
+ 'status' => '0',
+ 'bootstrap' => '0',
+ 'schema_version' => '-1',
+ 'weight' => '0',
+ 'info' => 'a:13:{s:4:"name";s:18:"CTools export test";s:11:"description";s:25:"CTools export test module";s:4:"core";s:3:"7.x";s:7:"package";s:16:"Chaos tool suite";s:7:"version";s:7:"7.x-1.9";s:12:"dependencies";a:1:{i:0;s:6:"ctools";}s:6:"hidden";b:1;s:5:"files";a:1:{i:0;s:18:"ctools_export.test";}s:7:"project";s:6:"ctools";s:9:"datestamp";s:10:"1440020680";s:5:"mtime";i:1440020680;s:3:"php";s:5:"5.2.4";s:9:"bootstrap";i:0;}',
+))
+->values(array(
+ 'filename' => 'sites/all/modules/ctools/tests/ctools_plugin_test.module',
+ 'name' => 'ctools_plugin_test',
+ 'type' => 'module',
+ 'owner' => '',
+ 'status' => '0',
+ 'bootstrap' => '0',
+ 'schema_version' => '-1',
+ 'weight' => '0',
+ 'info' => 'a:13:{s:4:"name";s:24:"Chaos tools plugins test";s:11:"description";s:42:"Provides hooks for testing ctools plugins.";s:7:"package";s:16:"Chaos tool suite";s:7:"version";s:7:"7.x-1.9";s:4:"core";s:3:"7.x";s:12:"dependencies";a:1:{i:0;s:6:"ctools";}s:5:"files";a:6:{i:0;s:19:"ctools.plugins.test";i:1;s:17:"object_cache.test";i:2;s:8:"css.test";i:3;s:12:"context.test";i:4;s:20:"math_expression.test";i:5;s:26:"math_expression_stack.test";}s:6:"hidden";b:1;s:7:"project";s:6:"ctools";s:9:"datestamp";s:10:"1440020680";s:5:"mtime";i:1440020680;s:3:"php";s:5:"5.2.4";s:9:"bootstrap";i:0;}',
+))
+->values(array(
+ 'filename' => 'sites/all/modules/ctools/views_content/views_content.module',
+ 'name' => 'views_content',
+ 'type' => 'module',
+ 'owner' => '',
+ 'status' => '0',
+ 'bootstrap' => '0',
+ 'schema_version' => '-1',
+ 'weight' => '0',
+ 'info' => 'a:12:{s:4:"name";s:19:"Views content panes";s:11:"description";s:104:"Allows Views content to be used in Panels, Dashboard and other modules which use the CTools Content API.";s:7:"package";s:16:"Chaos tool suite";s:12:"dependencies";a:2:{i:0;s:6:"ctools";i:1;s:5:"views";}s:4:"core";s:3:"7.x";s:7:"version";s:7:"7.x-1.9";s:5:"files";a:3:{i:0;s:61:"plugins/views/views_content_plugin_display_ctools_context.inc";i:1;s:57:"plugins/views/views_content_plugin_display_panel_pane.inc";i:2;s:59:"plugins/views/views_content_plugin_style_ctools_context.inc";}s:7:"project";s:6:"ctools";s:9:"datestamp";s:10:"1440020680";s:5:"mtime";i:1440020680;s:3:"php";s:5:"5.2.4";s:9:"bootstrap";i:0;}',
+))
->values(array(
'filename' => 'sites/all/modules/date/date.module',
'name' => 'date',
@@ -40207,6 +42086,94 @@ $connection->insert('system')
'weight' => '0',
'info' => 'a:14:{s:4:"name";s:5:"Email";s:11:"description";s:28:"Defines an email field type.";s:4:"core";s:3:"7.x";s:7:"package";s:6:"Fields";s:5:"files";a:1:{i:0;s:17:"email.migrate.inc";}s:7:"version";s:7:"7.x-1.3";s:7:"project";s:5:"email";s:9:"datestamp";s:10:"1397134155";s:5:"mtime";i:1397134155;s:12:"dependencies";a:0:{}s:3:"php";s:5:"5.2.4";s:9:"bootstrap";i:0;s:8:"required";b:1;s:11:"explanation";s:73:"Field type(s) in use - see Field list";}',
))
+->values(array(
+ 'filename' => 'sites/all/modules/entity/entity.module',
+ 'name' => 'entity',
+ 'type' => 'module',
+ 'owner' => '',
+ 'status' => '1',
+ 'bootstrap' => '0',
+ 'schema_version' => '7003',
+ 'weight' => '0',
+ 'info' => 'a:12:{s:4:"name";s:10:"Entity API";s:11:"description";s:69:"Enables modules to work with any entity type and to provide entities.";s:4:"core";s:3:"7.x";s:5:"files";a:24:{i:0;s:19:"entity.features.inc";i:1;s:15:"entity.i18n.inc";i:2;s:15:"entity.info.inc";i:3;s:16:"entity.rules.inc";i:4;s:11:"entity.test";i:5;s:19:"includes/entity.inc";i:6;s:30:"includes/entity.controller.inc";i:7;s:22:"includes/entity.ui.inc";i:8;s:27:"includes/entity.wrapper.inc";i:9;s:22:"views/entity.views.inc";i:10;s:52:"views/handlers/entity_views_field_handler_helper.inc";i:11;s:51:"views/handlers/entity_views_handler_area_entity.inc";i:12;s:53:"views/handlers/entity_views_handler_field_boolean.inc";i:13;s:50:"views/handlers/entity_views_handler_field_date.inc";i:14;s:54:"views/handlers/entity_views_handler_field_duration.inc";i:15;s:52:"views/handlers/entity_views_handler_field_entity.inc";i:16;s:51:"views/handlers/entity_views_handler_field_field.inc";i:17;s:53:"views/handlers/entity_views_handler_field_numeric.inc";i:18;s:53:"views/handlers/entity_views_handler_field_options.inc";i:19;s:50:"views/handlers/entity_views_handler_field_text.inc";i:20;s:49:"views/handlers/entity_views_handler_field_uri.inc";i:21;s:62:"views/handlers/entity_views_handler_relationship_by_bundle.inc";i:22;s:52:"views/handlers/entity_views_handler_relationship.inc";i:23;s:53:"views/plugins/entity_views_plugin_row_entity_view.inc";}s:7:"version";s:7:"7.x-1.6";s:7:"project";s:6:"entity";s:9:"datestamp";s:10:"1424876582";s:5:"mtime";i:1424876582;s:12:"dependencies";a:0:{}s:7:"package";s:5:"Other";s:3:"php";s:5:"5.2.4";s:9:"bootstrap";i:0;}',
+))
+->values(array(
+ 'filename' => 'sites/all/modules/entity/entity_token.module',
+ 'name' => 'entity_token',
+ 'type' => 'module',
+ 'owner' => '',
+ 'status' => '0',
+ 'bootstrap' => '0',
+ 'schema_version' => '-1',
+ 'weight' => '0',
+ 'info' => 'a:12:{s:4:"name";s:13:"Entity tokens";s:11:"description";s:99:"Provides token replacements for all properties that have no tokens and are known to the entity API.";s:4:"core";s:3:"7.x";s:5:"files";a:2:{i:0;s:23:"entity_token.tokens.inc";i:1;s:19:"entity_token.module";}s:12:"dependencies";a:1:{i:0;s:6:"entity";}s:7:"version";s:7:"7.x-1.6";s:7:"project";s:6:"entity";s:9:"datestamp";s:10:"1424876582";s:5:"mtime";i:1424876582;s:7:"package";s:5:"Other";s:3:"php";s:5:"5.2.4";s:9:"bootstrap";i:0;}',
+))
+->values(array(
+ 'filename' => 'sites/all/modules/entity/tests/entity_feature.module',
+ 'name' => 'entity_feature',
+ 'type' => 'module',
+ 'owner' => '',
+ 'status' => '0',
+ 'bootstrap' => '0',
+ 'schema_version' => '-1',
+ 'weight' => '0',
+ 'info' => 'a:13:{s:4:"name";s:21:"Entity feature module";s:11:"description";s:31:"Provides some entities in code.";s:7:"version";s:7:"7.x-1.6";s:4:"core";s:3:"7.x";s:5:"files";a:1:{i:0;s:21:"entity_feature.module";}s:12:"dependencies";a:1:{i:0;s:11:"entity_test";}s:6:"hidden";b:1;s:7:"project";s:6:"entity";s:9:"datestamp";s:10:"1424876582";s:5:"mtime";i:1424876582;s:7:"package";s:5:"Other";s:3:"php";s:5:"5.2.4";s:9:"bootstrap";i:0;}',
+))
+->values(array(
+ 'filename' => 'sites/all/modules/entity/tests/entity_test.module',
+ 'name' => 'entity_test',
+ 'type' => 'module',
+ 'owner' => '',
+ 'status' => '0',
+ 'bootstrap' => '0',
+ 'schema_version' => '-1',
+ 'weight' => '0',
+ 'info' => 'a:13:{s:4:"name";s:23:"Entity CRUD test module";s:11:"description";s:46:"Provides entity types based upon the CRUD API.";s:7:"version";s:7:"7.x-1.6";s:4:"core";s:3:"7.x";s:5:"files";a:2:{i:0;s:18:"entity_test.module";i:1;s:19:"entity_test.install";}s:12:"dependencies";a:1:{i:0;s:6:"entity";}s:6:"hidden";b:1;s:7:"project";s:6:"entity";s:9:"datestamp";s:10:"1424876582";s:5:"mtime";i:1424876582;s:7:"package";s:5:"Other";s:3:"php";s:5:"5.2.4";s:9:"bootstrap";i:0;}',
+))
+->values(array(
+ 'filename' => 'sites/all/modules/entity/tests/entity_test_i18n.module',
+ 'name' => 'entity_test_i18n',
+ 'type' => 'module',
+ 'owner' => '',
+ 'status' => '0',
+ 'bootstrap' => '0',
+ 'schema_version' => '-1',
+ 'weight' => '0',
+ 'info' => 'a:13:{s:4:"name";s:28:"Entity-test type translation";s:11:"description";s:37:"Allows translating entity-test types.";s:12:"dependencies";a:2:{i:0;s:11:"entity_test";i:1;s:11:"i18n_string";}s:7:"package";s:35:"Multilingual - Internationalization";s:4:"core";s:3:"7.x";s:6:"hidden";b:1;s:7:"version";s:7:"7.x-1.6";s:7:"project";s:6:"entity";s:9:"datestamp";s:10:"1424876582";s:5:"mtime";i:1424876582;s:3:"php";s:5:"5.2.4";s:5:"files";a:0:{}s:9:"bootstrap";i:0;}',
+))
+->values(array(
+ 'filename' => 'sites/all/modules/entityreference/entityreference.module',
+ 'name' => 'entityreference',
+ 'type' => 'module',
+ 'owner' => '',
+ 'status' => '1',
+ 'bootstrap' => '0',
+ 'schema_version' => '7002',
+ 'weight' => '0',
+ 'info' => 'a:14:{s:4:"name";s:16:"Entity Reference";s:11:"description";s:51:"Provides a field that can reference other entities.";s:4:"core";s:3:"7.x";s:7:"package";s:6:"Fields";s:12:"dependencies";a:2:{i:0;s:6:"entity";i:1;s:6:"ctools";}s:5:"files";a:11:{i:0;s:27:"entityreference.migrate.inc";i:1;s:30:"plugins/selection/abstract.inc";i:2;s:27:"plugins/selection/views.inc";i:3;s:29:"plugins/behavior/abstract.inc";i:4;s:40:"views/entityreference_plugin_display.inc";i:5;s:38:"views/entityreference_plugin_style.inc";i:6;s:43:"views/entityreference_plugin_row_fields.inc";i:7;s:35:"tests/entityreference.handlers.test";i:8;s:35:"tests/entityreference.taxonomy.test";i:9;s:32:"tests/entityreference.admin.test";i:10;s:32:"tests/entityreference.feeds.test";}s:7:"version";s:7:"7.x-1.1";s:7:"project";s:15:"entityreference";s:9:"datestamp";s:10:"1384973110";s:5:"mtime";i:1384973110;s:3:"php";s:5:"5.2.4";s:9:"bootstrap";i:0;s:8:"required";b:1;s:11:"explanation";s:73:"Field type(s) in use - see Field list";}',
+))
+->values(array(
+ 'filename' => 'sites/all/modules/entityreference/examples/entityreference_behavior_example/entityreference_behavior_example.module',
+ 'name' => 'entityreference_behavior_example',
+ 'type' => 'module',
+ 'owner' => '',
+ 'status' => '0',
+ 'bootstrap' => '0',
+ 'schema_version' => '-1',
+ 'weight' => '0',
+ 'info' => 'a:12:{s:4:"name";s:33:"Entity Reference Behavior Example";s:11:"description";s:71:"Provides some example code for implementing Entity Reference behaviors.";s:4:"core";s:3:"7.x";s:7:"package";s:6:"Fields";s:12:"dependencies";a:1:{i:0;s:15:"entityreference";}s:7:"version";s:7:"7.x-1.1";s:7:"project";s:15:"entityreference";s:9:"datestamp";s:10:"1384973110";s:5:"mtime";i:1384973110;s:3:"php";s:5:"5.2.4";s:5:"files";a:0:{}s:9:"bootstrap";i:0;}',
+))
+->values(array(
+ 'filename' => 'sites/all/modules/entityreference/tests/modules/entityreference_feeds_test/entityreference_feeds_test.module',
+ 'name' => 'entityreference_feeds_test',
+ 'type' => 'module',
+ 'owner' => '',
+ 'status' => '0',
+ 'bootstrap' => '0',
+ 'schema_version' => '-1',
+ 'weight' => '0',
+ 'info' => 'a:13:{s:4:"name";s:41:"Entityreference - Feeds integration tests";s:11:"description";s:65:"Support module for the Entityreference - Feeds integration tests.";s:7:"package";s:7:"Testing";s:4:"core";s:3:"7.x";s:6:"hidden";b:1;s:12:"dependencies";a:3:{i:0;s:5:"feeds";i:1;s:8:"feeds_ui";i:2;s:15:"entityreference";}s:7:"version";s:7:"7.x-1.1";s:7:"project";s:15:"entityreference";s:9:"datestamp";s:10:"1384973110";s:5:"mtime";i:1384973110;s:3:"php";s:5:"5.2.4";s:5:"files";a:0:{}s:9:"bootstrap";i:0;}',
+))
->values(array(
'filename' => 'sites/all/modules/link/link.module',
'name' => 'link',
@@ -40378,6 +42345,24 @@ $connection->insert('taxonomy_index')
'sticky' => '0',
'created' => '1471428152',
))
+->values(array(
+ 'nid' => '1',
+ 'tid' => '4',
+ 'sticky' => '0',
+ 'created' => '1421727515',
+))
+->values(array(
+ 'nid' => '1',
+ 'tid' => '17',
+ 'sticky' => '0',
+ 'created' => '1421727515',
+))
+->values(array(
+ 'nid' => '1',
+ 'tid' => '15',
+ 'sticky' => '0',
+ 'created' => '1421727515',
+))
->execute();
$connection->schema()->createTable('taxonomy_term_data', array(
@@ -41608,6 +43593,10 @@ $connection->insert('variable')
'name' => 'feed_item_length',
'value' => 's:8:"fulltext";',
))
+->values(array(
+ 'name' => 'entityreference:base-tables',
+ 'value' => 'a:6:{s:7:"comment";a:2:{i:0;s:7:"comment";i:1;s:3:"cid";}s:4:"node";a:2:{i:0;s:4:"node";i:1;s:3:"nid";}s:4:"file";a:2:{i:0;s:12:"file_managed";i:1;s:3:"fid";}s:13:"taxonomy_term";a:2:{i:0;s:18:"taxonomy_term_data";i:1;s:3:"tid";}s:19:"taxonomy_vocabulary";a:2:{i:0;s:19:"taxonomy_vocabulary";i:1;s:3:"vid";}s:4:"user";a:2:{i:0;s:5:"users";i:1;s:3:"uid";}}',
+))
->values(array(
'name' => 'field_bundle_settings_comment__comment_node_test_content_type',
'value' => 'a:2:{s:10:"view_modes";a:0:{}s:12:"extra_fields";a:2:{s:4:"form";a:2:{s:6:"author";a:1:{s:6:"weight";s:2:"-2";}s:7:"subject";a:1:{s:6:"weight";s:2:"-1";}}s:7:"display";a:0:{}}}',
@@ -41750,7 +43739,7 @@ $connection->insert('variable')
))
->values(array(
'name' => 'language_negotiation_language',
- 'value' => 'a:0:{}',
+ 'value' => 'a:3:{s:11:"locale-user";a:2:{s:9:"callbacks";a:1:{s:8:"language";s:25:"locale_language_from_user";}s:4:"file";s:19:"includes/locale.inc";}s:10:"locale-url";a:2:{s:9:"callbacks";a:3:{s:8:"language";s:24:"locale_language_from_url";s:8:"switcher";s:28:"locale_language_switcher_url";s:11:"url_rewrite";s:31:"locale_language_url_rewrite_url";}s:4:"file";s:19:"includes/locale.inc";}s:16:"language-default";a:1:{s:9:"callbacks";a:1:{s:8:"language";s:21:"language_from_default";}}}',
))
->values(array(
'name' => 'language_negotiation_language_content',
@@ -41770,7 +43759,11 @@ $connection->insert('variable')
))
->values(array(
'name' => 'locale_language_negotiation_url_part',
- 'value' => 's:6:"domain";',
+ 'value' => 'i:0;',
+))
+->values(array(
+ 'name' => 'locale_language_providers_weight_language',
+ 'value' => 'a:5:{s:10:"locale-url";s:2:"-9";s:14:"locale-session";s:2:"-8";s:11:"locale-user";s:3:"-10";s:14:"locale-browser";s:2:"-7";s:16:"language-default";s:2:"-6";}',
))
->values(array(
'name' => 'mail_system',
@@ -42100,6 +44093,10 @@ $connection->insert('variable')
'name' => 'theme_default',
'value' => 's:6:"bartik";',
))
+->values(array(
+ 'name' => 'theme_settings',
+ 'value' => 'a:16:{s:11:"toggle_logo";i:0;s:11:"toggle_name";i:1;s:13:"toggle_slogan";i:0;s:24:"toggle_node_user_picture";i:0;s:27:"toggle_comment_user_picture";i:0;s:32:"toggle_comment_user_verification";i:0;s:14:"toggle_favicon";i:0;s:16:"toggle_main_menu";i:0;s:21:"toggle_secondary_menu";i:0;s:12:"default_logo";i:1;s:9:"logo_path";s:23:"public://customlogo.png";s:11:"logo_upload";s:0:"";s:15:"default_favicon";i:0;s:12:"favicon_path";s:24:"public://somefavicon.png";s:14:"favicon_upload";s:0:"";s:16:"favicon_mimetype";s:9:"image/png";}',
+))
->values(array(
'name' => 'tracker_batch_size',
'value' => 'i:999;',
diff --git a/core/modules/migrate_drupal_ui/src/MigrateMessageCapture.php b/core/modules/migrate_drupal_ui/src/Batch/MigrateMessageCapture.php
similarity index 94%
rename from core/modules/migrate_drupal_ui/src/MigrateMessageCapture.php
rename to core/modules/migrate_drupal_ui/src/Batch/MigrateMessageCapture.php
index 72e1ace15..efa0a57a4 100644
--- a/core/modules/migrate_drupal_ui/src/MigrateMessageCapture.php
+++ b/core/modules/migrate_drupal_ui/src/Batch/MigrateMessageCapture.php
@@ -1,6 +1,6 @@
addListener(MigrateEvents::POST_ROW_SAVE, [static::class, 'onPostRowSave']);
- $event_dispatcher->addListener(MigrateEvents::MAP_SAVE, [static::class, 'onMapSave']);
- $event_dispatcher->addListener(MigrateEvents::IDMAP_MESSAGE, [static::class, 'onIdMapMessage']);
- }
+ $event_dispatcher->addListener(MigrateEvents::POST_ROW_SAVE, [static::class, 'onPostRowSave']);
+ $event_dispatcher->addListener(MigrateEvents::MAP_SAVE, [static::class, 'onMapSave']);
+ $event_dispatcher->addListener(MigrateEvents::IDMAP_MESSAGE, [static::class, 'onIdMapMessage']);
+
static::$maxExecTime = ini_get('max_execution_time');
if (static::$maxExecTime <= 0) {
static::$maxExecTime = 60;
@@ -98,7 +92,6 @@ class MigrateUpgradeRunBatch {
$context['sandbox']['messages'] = [];
$context['results']['failures'] = 0;
$context['results']['successes'] = 0;
- $context['results']['operation'] = $operation;
}
// Number processed in this batch.
@@ -124,12 +117,10 @@ class MigrateUpgradeRunBatch {
$migration_name = $migration->label() ? $migration->label() : $migration_id;
try {
- if ($operation == 'import') {
- $migration_status = $executable->import();
- }
+ $migration_status = $executable->import();
}
catch (\Exception $e) {
- static::logger()->error($e->getMessage());
+ \Drupal::logger('migrate_drupal_ui')->error($e->getMessage());
$migration_status = MigrationInterface::RESULT_FAILED;
}
@@ -137,13 +128,11 @@ class MigrateUpgradeRunBatch {
case MigrationInterface::RESULT_COMPLETED:
// Store the number processed in the sandbox.
$context['sandbox']['num_processed'] += static::$numProcessed;
- if ($operation == 'import') {
- $message = new PluralTranslatableMarkup(
- $context['sandbox']['num_processed'], 'Upgraded @migration (processed 1 item total)', 'Upgraded @migration (processed @count items total)',
- ['@migration' => $migration_name]);
- }
+ $message = new PluralTranslatableMarkup(
+ $context['sandbox']['num_processed'], 'Upgraded @migration (processed 1 item total)', 'Upgraded @migration (processed @count items total)',
+ ['@migration' => $migration_name]);
$context['sandbox']['messages'][] = (string) $message;
- static::logger()->notice($message);
+ \Drupal::logger('migrate_drupal_ui')->notice($message);
$context['sandbox']['num_processed'] = 0;
$context['results']['successes']++;
break;
@@ -162,12 +151,12 @@ class MigrateUpgradeRunBatch {
case MigrationInterface::RESULT_FAILED:
$context['sandbox']['messages'][] = (string) new TranslatableMarkup('Operation on @migration failed', ['@migration' => $migration_name]);
$context['results']['failures']++;
- static::logger()->error('Operation on @migration failed', ['@migration' => $migration_name]);
+ \Drupal::logger('migrate_drupal_ui')->error('Operation on @migration failed', ['@migration' => $migration_name]);
break;
case MigrationInterface::RESULT_SKIPPED:
$context['sandbox']['messages'][] = (string) new TranslatableMarkup('Operation on @migration skipped due to unfulfilled dependencies', ['@migration' => $migration_name]);
- static::logger()->error('Operation on @migration skipped due to unfulfilled dependencies', ['@migration' => $migration_name]);
+ \Drupal::logger('migrate_drupal_ui')->error('Operation on @migration skipped due to unfulfilled dependencies', ['@migration' => $migration_name]);
break;
case MigrationInterface::RESULT_DISABLED:
@@ -184,7 +173,7 @@ class MigrateUpgradeRunBatch {
// Add and log any captured messages.
foreach (static::$messages->getMessages() as $message) {
$context['sandbox']['messages'][] = (string) $message;
- static::logger()->error($message);
+ \Drupal::logger('migrate_drupal_ui')->error($message);
}
// Only display the last MESSAGE_LENGTH messages, in reverse order.
@@ -203,13 +192,11 @@ class MigrateUpgradeRunBatch {
$migration_id = reset($context['sandbox']['migration_ids']);
$migration = \Drupal::service('plugin.manager.migration')->createInstance($migration_id);
$migration_name = $migration->label() ? $migration->label() : $migration_id;
- if ($operation == 'import') {
- $context['message'] = (string) new TranslatableMarkup('Currently upgrading @migration (@current of @max total tasks)', [
+ $context['message'] = (string) new TranslatableMarkup('Currently upgrading @migration (@current of @max total tasks)', [
'@migration' => $migration_name,
'@current' => $context['sandbox']['current'],
'@max' => $context['sandbox']['max'],
]) . "
\n" . $context['message'];
- }
}
}
else {
@@ -221,52 +208,36 @@ class MigrateUpgradeRunBatch {
}
/**
- * Returns the logger using the migrate_drupal_ui channel.
+ * Callback executed when the Migrate Upgrade Import batch process completes.
*
- * @return \Psr\Log\LoggerInterface
- * The logger instance.
- */
- protected static function logger() {
- return \Drupal::logger('migrate_drupal_ui');
- }
-
- /**
- * Implements the Batch API finished method.
+ * @param bool $success
+ * TRUE if batch successfully completed.
+ * @param array $results
+ * Batch results.
+ * @param array $operations
+ * An array of methods run in the batch.
+ * @param string $elapsed
+ * The time to run the batch.
*/
public static function finished($success, $results, $operations, $elapsed) {
- static::displayResults($results);
- }
-
- /**
- * Displays counts of success/failures on the migration upgrade complete page.
- *
- * @param array $results
- * An array of result data built during the batch.
- */
- protected static function displayResults($results) {
$successes = $results['successes'];
$failures = $results['failures'];
// If we had any successes log that for the user.
if ($successes > 0) {
- if ($results['operation'] == 'import') {
- drupal_set_message(new PluralTranslatableMarkup($successes, 'Completed 1 upgrade task successfully', 'Completed @count upgrade tasks successfully'));
- }
+ drupal_set_message(\Drupal::translation()
+ ->formatPlural($successes, 'Completed 1 upgrade task successfully', 'Completed @count upgrade tasks successfully'));
}
-
// If we had failures, log them and show the migration failed.
if ($failures > 0) {
- if ($results['operation'] == 'import') {
- drupal_set_message(new PluralTranslatableMarkup($failures, '1 upgrade failed', '@count upgrades failed'));
- drupal_set_message(new TranslatableMarkup('Upgrade process not completed'), 'error');
- }
+ drupal_set_message(\Drupal::translation()
+ ->formatPlural($failures, '1 upgrade failed', '@count upgrades failed'));
+ drupal_set_message(t('Upgrade process not completed'), 'error');
}
else {
- if ($results['operation'] == 'import') {
- // Everything went off without a hitch. We may not have had successes
- // but we didn't have failures so this is fine.
- drupal_set_message(new TranslatableMarkup('Congratulations, you upgraded Drupal!'));
- }
+ // Everything went off without a hitch. We may not have had successes
+ // but we didn't have failures so this is fine.
+ drupal_set_message(t('Congratulations, you upgraded Drupal!'));
}
if (\Drupal::moduleHandler()->moduleExists('dblog')) {
@@ -335,7 +306,7 @@ class MigrateUpgradeRunBatch {
$type = 'error';
}
$source_id_string = implode(',', $event->getSourceIdValues());
- $message = new TranslatableMarkup('Source ID @source_id: @message', ['@source_id' => $source_id_string, '@message' => $event->getMessage()]);
+ $message = t('Source ID @source_id: @message', ['@source_id' => $source_id_string, '@message' => $event->getMessage()]);
static::$messages->display($message, $type);
}
diff --git a/core/modules/migrate_drupal_ui/src/Form/MigrateUpgradeForm.php b/core/modules/migrate_drupal_ui/src/Form/MigrateUpgradeForm.php
index 2d60c4694..0b98237b7 100644
--- a/core/modules/migrate_drupal_ui/src/Form/MigrateUpgradeForm.php
+++ b/core/modules/migrate_drupal_ui/src/Form/MigrateUpgradeForm.php
@@ -9,7 +9,7 @@ use Drupal\Core\Render\RendererInterface;
use Drupal\Core\State\StateInterface;
use Drupal\Core\Url;
use Drupal\migrate\Plugin\MigrationPluginManagerInterface;
-use Drupal\migrate_drupal_ui\MigrateUpgradeRunBatch;
+use Drupal\migrate_drupal_ui\Batch\MigrateUpgradeImportBatch;
use Drupal\migrate_drupal\MigrationConfigurationTrait;
use Symfony\Component\DependencyInjection\ContainerInterface;
@@ -258,6 +258,10 @@ class MigrateUpgradeForm extends ConfirmFormBase {
'source_module' => 'forum',
'destination_module' => 'forum',
],
+ 'd7_global_theme_settings' => [
+ 'source_module' => 'system',
+ 'destination_module' => 'system',
+ ],
'd6_imagecache_presets' => [
'source_module' => 'imagecache',
'destination_module' => 'image',
@@ -278,14 +282,30 @@ class MigrateUpgradeForm extends ConfirmFormBase {
'source_module' => 'locale',
'destination_module' => 'language',
],
+ 'd6_language_negotiation_settings' => [
+ 'source_module' => 'locale',
+ 'destination_module' => 'language',
+ ],
'd7_language_negotiation_settings' => [
'source_module' => 'locale',
'destination_module' => 'language',
],
+ 'language_prefixes_and_domains' => [
+ 'source_module' => 'locale',
+ 'destination_module' => 'language',
+ ],
+ 'd6_language_types' => [
+ 'source_module' => 'locale',
+ 'destination_module' => 'language',
+ ],
'language' => [
'source_module' => 'locale',
'destination_module' => 'language',
],
+ 'd7_language_types' => [
+ 'source_module' => 'locale',
+ 'destination_module' => 'language',
+ ],
'locale_settings' => [
'source_module' => 'locale',
'destination_module' => 'locale',
@@ -744,7 +764,7 @@ class MigrateUpgradeForm extends ConfirmFormBase {
$form['upgrade_option_item'] = [
'#type' => 'item',
'#prefix' => $this->t('An upgrade has already been performed on this site. To perform a new migration, create a clean and empty new install of Drupal 8. Rollbacks and incremental migrations are not yet supported through the user interface. For more information, see the upgrading handbook.', [':url' => 'https://www.drupal.org/upgrade/migrate']),
- '#description' => $this->t('
Last upgrade: @date
', ['@date' => $this->dateFormatter->format($date_performed)]), + '#description' => $this->t('Last upgrade: @date', ['@date' => $this->dateFormatter->format($date_performed)]), ]; return $form; } @@ -961,16 +981,10 @@ class MigrateUpgradeForm extends ConfirmFormBase { } catch (\Exception $e) { $error_message = [ - '#type' => 'inline_template', - '#template' => '{% trans %}Resolve the issue below to continue the upgrade.{% endtrans%}{{ errors }}', - '#context' => [ - 'errors' => [ - '#theme' => 'item_list', - '#items' => [$e->getMessage()], - ], - ], + '#title' => $this->t('Resolve the issue below to continue the upgrade.'), + '#theme' => 'item_list', + '#items' => [$e->getMessage()], ]; - $form_state->setErrorByName($database['driver'] . '][0', $this->renderer->renderPlain($error_message)); } } @@ -1083,8 +1097,12 @@ class MigrateUpgradeForm extends ConfirmFormBase { ]; } $form['counts'] = [ - '#type' => 'item', - '#title' => 'Upgrade analysis report
'); + // The description is added by the buildConfirmForm() method. + // @see \Drupal\migrate_drupal_ui\Form\MigrateUpgradeForm::buildConfirmForm() + return; } /** diff --git a/core/modules/migrate_drupal_ui/src/Tests/d6/MigrateUpgrade6Test.php b/core/modules/migrate_drupal_ui/src/Tests/d6/MigrateUpgrade6Test.php index 2a806dedf..50829f026 100644 --- a/core/modules/migrate_drupal_ui/src/Tests/d6/MigrateUpgrade6Test.php +++ b/core/modules/migrate_drupal_ui/src/Tests/d6/MigrateUpgrade6Test.php @@ -49,7 +49,7 @@ class MigrateUpgrade6Test extends MigrateUpgradeTestBase { 'image_style' => 5, 'language_content_settings' => 2, 'migration' => 105, - 'node' => 10, + 'node' => 11, 'node_type' => 11, 'rdf_mapping' => 5, 'search_page' => 2, @@ -58,7 +58,7 @@ class MigrateUpgrade6Test extends MigrateUpgradeTestBase { 'action' => 22, 'menu' => 8, 'taxonomy_term' => 6, - 'taxonomy_vocabulary' => 6, + 'taxonomy_vocabulary' => 5, 'tour' => 4, 'user' => 7, 'user_role' => 6, diff --git a/core/modules/migrate_drupal_ui/src/Tests/d7/MigrateUpgrade7Test.php b/core/modules/migrate_drupal_ui/src/Tests/d7/MigrateUpgrade7Test.php index 74d4237ca..d69308580 100644 --- a/core/modules/migrate_drupal_ui/src/Tests/d7/MigrateUpgrade7Test.php +++ b/core/modules/migrate_drupal_ui/src/Tests/d7/MigrateUpgrade7Test.php @@ -43,8 +43,8 @@ class MigrateUpgrade7Test extends MigrateUpgradeTestBase { 'configurable_language' => 4, 'contact_form' => 3, 'editor' => 2, - 'field_config' => 45, - 'field_storage_config' => 33, + 'field_config' => 48, + 'field_storage_config' => 36, 'file' => 1, 'filter_format' => 7, 'image_style' => 6, diff --git a/core/modules/node/migration_templates/d6_node.yml b/core/modules/node/migration_templates/d6_node.yml index 58aea356d..4e19bb407 100644 --- a/core/modules/node/migration_templates/d6_node.yml +++ b/core/modules/node/migration_templates/d6_node.yml @@ -9,6 +9,8 @@ process: # In D6, nodes always have a tnid, but it's zero for untranslated nodes. # We normalize it to equal the nid in that case. # @see \Drupal\node\Plugin\migrate\source\d6\Node::prepareRow(). + # If you are using this file to build a custom migration consider removing + # the nid and vid fields to allow incremental migrations. nid: tnid vid: vid langcode: diff --git a/core/modules/node/migration_templates/d6_node_revision.yml b/core/modules/node/migration_templates/d6_node_revision.yml index b7826a18b..046e9bbe4 100644 --- a/core/modules/node/migration_templates/d6_node_revision.yml +++ b/core/modules/node/migration_templates/d6_node_revision.yml @@ -6,6 +6,8 @@ deriver: Drupal\node\Plugin\migrate\D6NodeDeriver source: plugin: d6_node_revision process: + # If you are using this file to build a custom migration consider removing + # the nid and vid fields to allow incremental migrations. nid: nid vid: vid langcode: diff --git a/core/modules/node/migration_templates/d6_node_translation.yml b/core/modules/node/migration_templates/d6_node_translation.yml index b4a240217..3b923d181 100644 --- a/core/modules/node/migration_templates/d6_node_translation.yml +++ b/core/modules/node/migration_templates/d6_node_translation.yml @@ -7,6 +7,8 @@ source: plugin: d6_node translations: true process: + # If you are using this file to build a custom migration consider removing + # the nid field to allow incremental migrations. nid: tnid type: type langcode: @@ -29,6 +31,7 @@ process: revision_uid: revision_uid revision_log: log revision_timestamp: timestamp + content_translation_source: source_langcode # unmapped d6 fields. # translate diff --git a/core/modules/node/migration_templates/d7_node.yml b/core/modules/node/migration_templates/d7_node.yml index b763534dd..381f7ce70 100644 --- a/core/modules/node/migration_templates/d7_node.yml +++ b/core/modules/node/migration_templates/d7_node.yml @@ -6,6 +6,8 @@ deriver: Drupal\node\Plugin\migrate\D7NodeDeriver source: plugin: d7_node process: + # If you are using this file to build a custom migration consider removing + # the nid and vid fields to allow incremental migrations. nid: nid vid: vid langcode: diff --git a/core/modules/node/migration_templates/d7_node_revision.yml b/core/modules/node/migration_templates/d7_node_revision.yml index 0ee8bca6e..c6081ef11 100644 --- a/core/modules/node/migration_templates/d7_node_revision.yml +++ b/core/modules/node/migration_templates/d7_node_revision.yml @@ -6,6 +6,8 @@ deriver: Drupal\node\Plugin\migrate\D7NodeDeriver source: plugin: d7_node_revision process: + # If you are using this file to build a custom migration consider removing + # the nid and vid fields to allow incremental migrations. nid: nid vid: vid langcode: diff --git a/core/modules/node/src/Plugin/migrate/source/d6/Node.php b/core/modules/node/src/Plugin/migrate/source/d6/Node.php index 86864156c..2e4d1a605 100644 --- a/core/modules/node/src/Plugin/migrate/source/d6/Node.php +++ b/core/modules/node/src/Plugin/migrate/source/d6/Node.php @@ -3,8 +3,13 @@ namespace Drupal\node\Plugin\migrate\source\d6; use Drupal\Core\Database\Query\SelectInterface; +use Drupal\Core\Entity\EntityManagerInterface; +use Drupal\Core\Extension\ModuleHandler; +use Drupal\Core\State\StateInterface; +use Drupal\migrate\Plugin\MigrationInterface; use Drupal\migrate\Row; use Drupal\migrate_drupal\Plugin\migrate\source\DrupalSqlBase; +use Symfony\Component\DependencyInjection\ContainerInterface; /** * Drupal 6 node source from database. @@ -34,6 +39,36 @@ class Node extends DrupalSqlBase { */ protected $fieldInfo; + /** + * The module handler. + * + * @var \Drupal\Core\Extension\ModuleHandler + */ + protected $moduleHandler; + + /** + * {@inheritdoc} + */ + public function __construct(array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration, StateInterface $state, EntityManagerInterface $entity_manager, ModuleHandler $module_handler) { + parent::__construct($configuration, $plugin_id, $plugin_definition, $migration, $state, $entity_manager); + $this->moduleHandler = $module_handler; + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration = NULL) { + return new static( + $configuration, + $plugin_id, + $plugin_definition, + $migration, + $container->get('state'), + $container->get('entity.manager'), + $container->get('module_handler') + ); + } + /** * {@inheritdoc} */ @@ -68,6 +103,13 @@ class Node extends DrupalSqlBase { $query->addField('n', 'uid', 'node_uid'); $query->addField('nr', 'uid', 'revision_uid'); + // If the content_translation module is enabled, get the source langcode + // to fill the content_translation_source field. + if ($this->moduleHandler->moduleExists('content_translation')) { + $query->leftJoin('node', 'nt', 'n.tnid = nt.nid'); + $query->addField('nt', 'language', 'source_langcode'); + } + if (isset($this->configuration['node_type'])) { $query->condition('n.type', $this->configuration['node_type']); } diff --git a/core/modules/node/src/Plugin/views/filter/Access.php b/core/modules/node/src/Plugin/views/filter/Access.php index 4b34afeff..73844e11d 100644 --- a/core/modules/node/src/Plugin/views/filter/Access.php +++ b/core/modules/node/src/Plugin/views/filter/Access.php @@ -25,7 +25,7 @@ class Access extends FilterPluginBase { */ public function query() { $account = $this->view->getUser(); - if (!$account->hasPermission('administer nodes')) { + if (!$account->hasPermission('bypass node access')) { $table = $this->ensureMyTable(); $grants = db_or(); foreach (node_access_grants('view', $account) as $realm => $gids) { diff --git a/core/modules/node/src/Tests/NodeViewTest.php b/core/modules/node/src/Tests/NodeViewTest.php index fae056c6f..3a27ade0d 100644 --- a/core/modules/node/src/Tests/NodeViewTest.php +++ b/core/modules/node/src/Tests/NodeViewTest.php @@ -2,6 +2,8 @@ namespace Drupal\node\Tests; +use Drupal\Component\Utility\Html; + /** * Tests the node/{node} page. * @@ -63,6 +65,24 @@ class NodeViewTest extends NodeTestBase { $this->assertEqual($result[0]['href'], $node->url('edit-form')); } + /** + * Tests the Link header. + */ + public function testLinkHeader() { + $node = $this->drupalCreateNode(); + + $expected = [ + '<' . Html::escape($node->url('canonical')) . '>; rel="canonical"', + '<' . Html::escape($node->url('canonical'), ['alias' => TRUE]) . '>; rel="shortlink"', + '<' . Html::escape($node->url('revision')) . '>; rel="revision"', + ]; + + $this->drupalGet($node->urlInfo()); + + $links = explode(',', $this->drupalGetHeader('Link')); + $this->assertEqual($links, $expected); + } + /** * Tests that we store and retrieve multi-byte UTF-8 characters correctly. */ diff --git a/core/modules/node/src/Tests/Views/FilterNodeAccessTest.php b/core/modules/node/src/Tests/Views/FilterNodeAccessTest.php new file mode 100644 index 000000000..dba441957 --- /dev/null +++ b/core/modules/node/src/Tests/Views/FilterNodeAccessTest.php @@ -0,0 +1,111 @@ +drupalCreateContentType(['type' => 'article', 'name' => 'Article']); + + node_access_test_add_field(NodeType::load('article')); + + node_access_rebuild(); + \Drupal::state()->set('node_access_test.private', TRUE); + + $num_simple_users = 2; + $this->users = []; + + for ($i = 0; $i < $num_simple_users; $i++) { + $this->users[$i] = $this->drupalCreateUser(['access content', 'create article content']); + } + foreach ($this->users as $web_user) { + $this->drupalLogin($web_user); + foreach ([0 => 'Public', 1 => 'Private'] as $is_private => $type) { + $settings = [ + 'body' => [[ + 'value' => $type . ' node', + 'format' => filter_default_format(), + ]], + 'title' => t('@private_public Article created by @user', ['@private_public' => $type, '@user' => $web_user->getUsername()]), + 'type' => 'article', + 'uid' => $web_user->id(), + 'private' => (bool) $is_private, + ]; + + $node = $this->drupalCreateNode($settings); + $this->assertEqual($is_private, (int) $node->private->value, 'The private status of the node was properly set in the node_access_test table.'); + } + } + } + + /** + * Tests the node access filter. + */ + public function testFilterNodeAccess() { + $this->drupalLogin($this->users[0]); + $this->drupalGet('test_filter_node_access'); + // Test that the private node of the current user is shown. + $this->assertText('Private Article created by ' . $this->users[0]->getUsername()); + // Test that the private node of the other use isn't shown. + $this->assertNoText('Private Article created by ' . $this->users[1]->getUsername()); + // Test that both public nodes are shown. + $this->assertText('Public Article created by ' . $this->users[0]->getUsername()); + $this->assertText('Public Article created by ' . $this->users[1]->getUsername()); + + // Switch users and test the other private node is shown. + $this->drupalLogin($this->users[1]); + $this->drupalGet('test_filter_node_access'); + // Test that the private node of the current user is shown. + $this->assertText('Private Article created by ' . $this->users[1]->getUsername()); + // Test that the private node of the other use isn't shown. + $this->assertNoText('Private Article created by ' . $this->users[0]->getUsername()); + + // Test that a user with administer nodes permission can't see all nodes. + $administer_nodes_user = $this->drupalCreateUser(['access content', 'administer nodes']); + $this->drupalLogin($administer_nodes_user); + $this->drupalGet('test_filter_node_access'); + $this->assertNoText('Private Article created by ' . $this->users[0]->getUsername()); + $this->assertNoText('Private Article created by ' . $this->users[1]->getUsername()); + $this->assertText('Public Article created by ' . $this->users[0]->getUsername()); + $this->assertText('Public Article created by ' . $this->users[1]->getUsername()); + + // Test that a user with bypass node access can see all nodes. + $bypass_access_user = $this->drupalCreateUser(['access content', 'bypass node access']); + $this->drupalLogin($bypass_access_user); + $this->drupalGet('test_filter_node_access'); + $this->assertText('Private Article created by ' . $this->users[0]->getUsername()); + $this->assertText('Private Article created by ' . $this->users[1]->getUsername()); + $this->assertText('Public Article created by ' . $this->users[0]->getUsername()); + $this->assertText('Public Article created by ' . $this->users[1]->getUsername()); + } + +} diff --git a/core/modules/node/tests/modules/node_test_views/test_views/views.view.test_filter_node_access.yml b/core/modules/node/tests/modules/node_test_views/test_views/views.view.test_filter_node_access.yml new file mode 100644 index 000000000..6663fa826 --- /dev/null +++ b/core/modules/node/tests/modules/node_test_views/test_views/views.view.test_filter_node_access.yml @@ -0,0 +1,203 @@ +langcode: en +status: true +dependencies: + module: + - node + - user +id: test_filter_node_access +label: test_filter_node_access +module: views +description: '' +tag: '' +base_table: node_field_data +base_field: nid +core: 8.x +display: + default: + display_plugin: default + id: default + display_title: Master + position: 0 + display_options: + access: + type: perm + options: + perm: 'access content' + cache: + type: tag + options: { } + query: + type: views_query + options: + disable_sql_rewrite: true + distinct: false + replica: false + query_comment: '' + query_tags: { } + exposed_form: + type: basic + options: + submit_button: Apply + reset_button: false + reset_button_label: Reset + exposed_sorts_label: 'Sort by' + expose_sort_order: true + sort_asc_label: Asc + sort_desc_label: Desc + pager: + type: some + options: + items_per_page: 10 + offset: 0 + style: + type: default + row: + type: fields + options: + default_field_elements: true + inline: { } + separator: '' + hide_empty: false + fields: + title: + id: title + table: node_field_data + field: title + entity_type: node + entity_field: title + label: '' + alter: + alter_text: false + make_link: false + absolute: false + trim: false + word_boundary: false + ellipsis: false + strip_tags: false + html: false + hide_empty: false + empty_zero: false + settings: + link_to_entity: true + plugin_id: field + relationship: none + group_type: group + admin_label: '' + exclude: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_alter_empty: true + click_sort_column: value + type: string + group_column: value + group_columns: { } + group_rows: true + delta_limit: 0 + delta_offset: 0 + delta_reversed: false + delta_first_last: false + multi_type: separator + separator: ', ' + field_api_classes: false + filters: + status: + value: '1' + table: node_field_data + field: status + plugin_id: boolean + entity_type: node + entity_field: status + id: status + expose: + operator: '' + group: 1 + nid: + id: nid + table: node_access + field: nid + relationship: none + group_type: group + admin_label: '' + operator: '=' + value: '' + group: 1 + exposed: false + expose: + operator_id: '' + label: '' + description: '' + use_operator: false + operator: '' + identifier: '' + required: false + remember: false + multiple: false + remember_roles: + authenticated: authenticated + is_grouped: false + group_info: + label: '' + description: '' + identifier: '' + optional: true + widget: select + multiple: false + remember: false + default_group: All + default_group_multiple: { } + group_items: { } + plugin_id: node_access + sorts: + created: + id: created + table: node_field_data + field: created + order: DESC + entity_type: node + entity_field: created + plugin_id: date + relationship: none + group_type: group + admin_label: '' + exposed: false + expose: + label: '' + granularity: second + title: test_filter_node_access + header: { } + footer: { } + empty: { } + relationships: { } + arguments: { } + display_extenders: { } + cache_metadata: + max-age: -1 + contexts: + - 'languages:language_content' + - 'languages:language_interface' + - 'user.node_grants:view' + - user.permissions + tags: { } + page_1: + display_plugin: page + id: page_1 + display_title: Page + position: 1 + display_options: + display_extenders: { } + path: test_filter_node_access + cache_metadata: + max-age: -1 + contexts: + - 'languages:language_content' + - 'languages:language_interface' + - 'user.node_grants:view' + - user.permissions + tags: { } diff --git a/core/modules/node/tests/src/Kernel/Migrate/d6/MigrateNodeTest.php b/core/modules/node/tests/src/Kernel/Migrate/d6/MigrateNodeTest.php index 122199fe5..7a0a272a1 100644 --- a/core/modules/node/tests/src/Kernel/Migrate/d6/MigrateNodeTest.php +++ b/core/modules/node/tests/src/Kernel/Migrate/d6/MigrateNodeTest.php @@ -28,7 +28,12 @@ class MigrateNodeTest extends MigrateNodeTestBase { parent::setUp(); $this->setUpMigratedFiles(); $this->installSchema('file', ['file_usage']); - $this->executeMigrations(['language', 'd6_node', 'd6_node_translation']); + $this->executeMigrations([ + 'language', + 'd6_language_content_settings', + 'd6_node', + 'd6_node_translation', + ]); } /** @@ -96,6 +101,14 @@ class MigrateNodeTest extends MigrateNodeTestBase { $this->assertIdentical('The Real McCoy', $node->title->value); $this->assertTrue($node->hasTranslation('fr'), "Node 10 has french translation"); + // Test that content_translation_source is set. + $manager = $this->container->get('content_translation.manager'); + $this->assertIdentical('en', $manager->getTranslationMetadata($node->getTranslation('fr'))->getSource()); + + // Test that content_translation_source for a source other than English. + $node = Node::load(12); + $this->assertIdentical('zu', $manager->getTranslationMetadata($node->getTranslation('en'))->getSource()); + // Node 11 is a translation of node 10, and should not be imported separately. $this->assertNull(Node::load(11), "Node 11 doesn't exist in D8, it was a translation"); diff --git a/core/modules/outside_in/css/outside_in.module.css b/core/modules/outside_in/css/outside_in.module.css index 9e360372d..a534dd159 100644 --- a/core/modules/outside_in/css/outside_in.module.css +++ b/core/modules/outside_in/css/outside_in.module.css @@ -38,12 +38,3 @@ [dir="rtl"] .toolbar .toolbar-bar .contextual-toolbar-tab.toolbar-tab { float: right; } - -.offcanvas-lining { - background: #333; - position: absolute; - top: 0; - height: 100%; - width: 100%; - z-index: -1; -} diff --git a/core/modules/outside_in/css/outside_in.motion.css b/core/modules/outside_in/css/outside_in.motion.css index 8fbf5cb34..8e1981150 100644 --- a/core/modules/outside_in/css/outside_in.motion.css +++ b/core/modules/outside_in/css/outside_in.motion.css @@ -32,8 +32,8 @@ /* Transition the editables on the page, their contextual links and their hover states. */ #main-canvas-wrapper .contextual, -#main-canvas-wrapper .outside-in-editable, -#main-canvas-wrapper.js-tray-open .outside-in-editable { +#main-canvas-wrapper .js-outside-in-edit-mode .outside-in-editable, +#main-canvas-wrapper.js-tray-open .js-outside-in-edit-mode .outside-in-editable { -webkit-transition: all .7s ease; -moz-transition: all .7s ease; transition: all .7s ease; diff --git a/core/modules/outside_in/js/offcanvas.js b/core/modules/outside_in/js/offcanvas.js index b3c4237e4..ffcb5e896 100644 --- a/core/modules/outside_in/js/offcanvas.js +++ b/core/modules/outside_in/js/offcanvas.js @@ -120,6 +120,9 @@ of: window }; settings.dialogClass = 'ui-dialog-offcanvas'; + // Applies initial height to dialog based on window height. + // See http://api.jqueryui.com/dialog for all dialog options. + settings.height = $(window).height(); } }, 'dialog:beforeclose': function (event, dialog, $element) { diff --git a/core/modules/outside_in/js/outside_in.js b/core/modules/outside_in/js/outside_in.js index d079664cd..e802a6cc9 100644 --- a/core/modules/outside_in/js/outside_in.js +++ b/core/modules/outside_in/js/outside_in.js @@ -84,6 +84,17 @@ event.preventDefault(); } + /** + * Close any active toolbar tray before entering edit mode. + */ + function closeToolbarTrays() { + $('#toolbar-bar') + .find('.toolbar-tab') + .not('.contextual-toolbar-tab') + .has('.toolbar-tray.is-active') + .find('.toolbar-item').click(); + } + /** * Helper to switch edit mode state. * @@ -97,10 +108,7 @@ // Turn on edit mode. if (editMode) { $editButton.text(Drupal.t('Editing')); - // Close the Manage tray if open when entering edit mode. - if ($('#toolbar-item-administration-tray').hasClass('is-active')) { - $('#toolbar-item-administration').trigger('click'); - } + closeToolbarTrays(); $editables = $('[data-drupal-outsidein="editable"]').once('outsidein'); if ($editables.length) { diff --git a/core/modules/outside_in/templates/outside-in-page-wrapper.html.twig b/core/modules/outside_in/templates/outside-in-page-wrapper.html.twig index 588918334..d28cb4fae 100644 --- a/core/modules/outside_in/templates/outside-in-page-wrapper.html.twig +++ b/core/modules/outside_in/templates/outside-in-page-wrapper.html.twig @@ -17,5 +17,4 @@ {{ children }} - {% endif %} diff --git a/core/modules/outside_in/tests/src/FunctionalJavascript/OutsideInBlockFormTest.php b/core/modules/outside_in/tests/src/FunctionalJavascript/OutsideInBlockFormTest.php index dd79fc2c4..9388ec8d7 100644 --- a/core/modules/outside_in/tests/src/FunctionalJavascript/OutsideInBlockFormTest.php +++ b/core/modules/outside_in/tests/src/FunctionalJavascript/OutsideInBlockFormTest.php @@ -51,18 +51,24 @@ class OutsideInBlockFormTest extends OutsideInJavascriptTestBase { * Tests opening Offcanvas tray by click blocks and elements in the blocks. */ public function testBlocks() { + // @todo: re-enable once https://www.drupal.org/node/2830485 is resolved. + $this->markTestSkipped('Test skipped due to random failures in DrupalCI, see https://www.drupal.org/node/2830485'); + + $web_assert = $this->assertSession(); $blocks = [ [ 'id' => 'block-powered', 'new_page_text' => 'Can you imagine anyone showing the label on this block?', 'element_selector' => '.content a', 'button_text' => 'Save Powered by Drupal', + 'toolbar_item' => '#toolbar-item-user', ], [ 'id' => 'block-branding', 'new_page_text' => 'The site that will live a very short life.', 'element_selector' => 'a[rel="home"]:nth-child(2)', 'button_text' => 'Save Site branding', + 'toolbar_item' => '#toolbar-item-administration', ], [ 'id' => 'block-search', @@ -74,7 +80,22 @@ class OutsideInBlockFormTest extends OutsideInJavascriptTestBase { foreach ($blocks as $block) { $block_selector = '#' . $block['id']; $this->drupalGet('user'); + if (isset($block['toolbar_item'])) { + // Check that you can open a toolbar tray and it will be closed after + // entering edit mode. + if ($element = $page->find('css', "#toolbar-administration a.is-active")) { + // If a tray was open from page load close it. + $element->click(); + $this->waitForNoElement("#toolbar-administration a.is-active"); + } + $page->find('css', $block['toolbar_item'])->click(); + $this->waitForElement("{$block['toolbar_item']}.is-active"); + } $this->toggleEditingMode(); + if (isset($block['toolbar_item'])) { + $this->waitForNoElement("{$block['toolbar_item']}.is-active"); + } + $this->openBlockForm($block_selector); switch ($block['id']) { @@ -93,8 +114,7 @@ class OutsideInBlockFormTest extends OutsideInJavascriptTestBase { if (isset($block['new_page_text'])) { $page->pressButton($block['button_text']); // Make sure the changes are present. - $this->getSession()->wait(500); - $web_assert = $this->assertSession(); + $this->assertSession()->assertWaitOnAjaxRequest(); $web_assert->pageTextContains($block['new_page_text']); } @@ -124,7 +144,7 @@ class OutsideInBlockFormTest extends OutsideInJavascriptTestBase { protected function toggleEditingMode() { $this->waitForElement('div[data-contextual-id="block:block=powered:langcode=en|outside_in::langcode=en"] .contextual-links a'); - $this->waitForElement('#toolbar-bar', 3000); + $this->waitForElement('#toolbar-bar'); $edit_button = $this->getSession()->getPage()->find('css', '#toolbar-bar div.contextual-toolbar-tab button'); @@ -155,4 +175,5 @@ class OutsideInBlockFormTest extends OutsideInJavascriptTestBase { $this->waitForOffCanvasToOpen(); $this->assertOffCanvasBlockFormIsValid(); } + } diff --git a/core/modules/outside_in/tests/src/FunctionalJavascript/OutsideInJavascriptTestBase.php b/core/modules/outside_in/tests/src/FunctionalJavascript/OutsideInJavascriptTestBase.php index da0be1b2b..fe8fcf405 100644 --- a/core/modules/outside_in/tests/src/FunctionalJavascript/OutsideInJavascriptTestBase.php +++ b/core/modules/outside_in/tests/src/FunctionalJavascript/OutsideInJavascriptTestBase.php @@ -36,8 +36,7 @@ abstract class OutsideInJavascriptTestBase extends JavascriptTestBase { * Waits for Off-canvas tray to close. */ protected function waitForOffCanvasToClose() { - $condition = "(jQuery('#drupal-offcanvas').length == 0)"; - $this->assertJsCondition($condition); + $this->waitForNoElement('#drupal-offcanvas'); } /** @@ -46,9 +45,9 @@ abstract class OutsideInJavascriptTestBase extends JavascriptTestBase { * @param string $selector * CSS selector. * @param int $timeout - * (optional) Timeout in milliseconds, defaults to 1000. + * (optional) Timeout in milliseconds, defaults to 10000. */ - protected function waitForElement($selector, $timeout = 1000) { + protected function waitForElement($selector, $timeout = 10000) { $condition = "(jQuery('$selector').length > 0)"; $this->assertJsCondition($condition, $timeout); } @@ -64,4 +63,17 @@ abstract class OutsideInJavascriptTestBase extends JavascriptTestBase { return $tray; } + /** + * Waits for an element to be removed from the page. + * + * @param string $selector + * CSS selector. + * @param int $timeout + * (optional) Timeout in milliseconds, defaults to 10000. + */ + protected function waitForNoElement($selector, $timeout = 10000) { + $condition = "(jQuery('$selector').length == 0)"; + $this->assertJsCondition($condition, $timeout); + } + } diff --git a/core/modules/responsive_image/responsive_image.module b/core/modules/responsive_image/responsive_image.module index 15ec5375a..8c7bf8ddd 100644 --- a/core/modules/responsive_image/responsive_image.module +++ b/core/modules/responsive_image/responsive_image.module @@ -158,7 +158,6 @@ function template_preprocess_responsive_image(&$variables) { unset($variables['height']); } - $image = \Drupal::service('image.factory')->get($variables['uri']); $responsive_image_style = ResponsiveImageStyle::load($variables['responsive_image_style_id']); // If a responsive image style is not selected, log the error and stop // execution. @@ -176,7 +175,7 @@ function template_preprocess_responsive_image(&$variables) { $breakpoints = array_reverse(\Drupal::service('breakpoint.manager')->getBreakpointsByGroup($responsive_image_style->getBreakpointGroup())); foreach ($responsive_image_style->getKeyedImageStyleMappings() as $breakpoint_id => $multipliers) { if (isset($breakpoints[$breakpoint_id])) { - $variables['sources'][] = responsive_image_build_source_attributes($image, $variables, $breakpoints[$breakpoint_id], $multipliers); + $variables['sources'][] = _responsive_image_build_source_attributes($variables, $breakpoints[$breakpoint_id], $multipliers); } } @@ -192,7 +191,7 @@ function template_preprocess_responsive_image(&$variables) { } $variables['img_element'] = array( '#theme' => 'image', - '#uri' => _responsive_image_image_style_url($responsive_image_style->getFallbackImageStyle(), $image->getSource()), + '#uri' => _responsive_image_image_style_url($responsive_image_style->getFallbackImageStyle(), $variables['uri']), ); } else { @@ -205,7 +204,7 @@ function template_preprocess_responsive_image(&$variables) { '#theme' => 'image', '#srcset' => array( array( - 'uri' => _responsive_image_image_style_url($responsive_image_style->getFallbackImageStyle(), $image->getSource()), + 'uri' => _responsive_image_image_style_url($responsive_image_style->getFallbackImageStyle(), $variables['uri']), ), ), ); @@ -224,6 +223,32 @@ function template_preprocess_responsive_image(&$variables) { } } +/** + * Helper function for template_preprocess_responsive_image(). + * + * @param \Drupal\Core\Image\ImageInterface $image + * The image to build the