composer update

This commit is contained in:
Oliver Davies 2019-01-24 08:00:03 +00:00
parent f6abc3dce2
commit 71dfaca858
1753 changed files with 45274 additions and 14619 deletions

View file

@ -3,6 +3,7 @@
namespace Drupal\Component\Plugin;
use Drupal\Component\Plugin\Context\ContextInterface;
use Drupal\Component\Plugin\Definition\ContextAwarePluginDefinitionInterface;
use Drupal\Component\Plugin\Exception\ContextException;
use Drupal\Component\Plugin\Context\Context;
use Symfony\Component\Validator\ConstraintViolationList;
@ -67,7 +68,12 @@ abstract class ContextAwarePluginBase extends PluginBase implements ContextAware
*/
public function getContextDefinitions() {
$definition = $this->getPluginDefinition();
return !empty($definition['context']) ? $definition['context'] : [];
if ($definition instanceof ContextAwarePluginDefinitionInterface) {
return $definition->getContextDefinitions();
}
else {
return !empty($definition['context']) ? $definition['context'] : [];
}
}
/**
@ -75,10 +81,15 @@ abstract class ContextAwarePluginBase extends PluginBase implements ContextAware
*/
public function getContextDefinition($name) {
$definition = $this->getPluginDefinition();
if (empty($definition['context'][$name])) {
throw new ContextException(sprintf("The %s context is not a valid context.", $name));
if ($definition instanceof ContextAwarePluginDefinitionInterface) {
if ($definition->hasContextDefinition($name)) {
return $definition->getContextDefinition($name);
}
}
return $definition['context'][$name];
elseif (!empty($definition['context'][$name])) {
return $definition['context'][$name];
}
throw new ContextException(sprintf("The %s context is not a valid context.", $name));
}
/**

View file

@ -107,6 +107,29 @@ class PhpTransliteration implements TransliterationInterface {
public function transliterate($string, $langcode = 'en', $unknown_character = '?', $max_length = NULL) {
$result = '';
$length = 0;
$hash = FALSE;
// Replace question marks with a unique hash if necessary. This because
// mb_convert_encoding() replaces all invalid characters with a question
// mark.
if ($unknown_character != '?' && strpos($string, '?') !== FALSE) {
$hash = hash('sha256', $string);
$string = str_replace('?', $hash, $string);
}
// Ensure the string is valid UTF8 for preg_split(). Unknown characters will
// be replaced by a question mark.
$string = mb_convert_encoding($string, 'UTF-8', 'UTF-8');
// Use the provided unknown character instead of a question mark.
if ($unknown_character != '?') {
$string = str_replace('?', $unknown_character, $string);
// Restore original question marks if necessary.
if ($hash !== FALSE) {
$string = str_replace($hash, '?', $string);
}
}
// Split into Unicode characters and transliterate each one.
foreach (preg_split('//u', $string, 0, PREG_SPLIT_NO_EMPTY) as $character) {
$code = self::ordUTF8($character);

View file

@ -0,0 +1,67 @@
<?php
namespace Drupal\Component\Utility;
/**
* Provides helpers to ensure emails are compliant with RFCs.
*
* @ingroup utility
*/
class Mail {
/**
* RFC-2822 "specials" characters.
*/
const RFC_2822_SPECIALS = '()<>[]:;@\,."';
/**
* Return a RFC-2822 compliant "display-name" component.
*
* The "display-name" component is used in mail header "Originator" fields
* (From, Sender, Reply-to) to give a human-friendly description of the
* address, i.e. From: My Display Name <xyz@example.org>. RFC-822 and
* RFC-2822 define its syntax and rules. This method gets as input a string
* to be used as "display-name" and formats it to be RFC compliant.
*
* @param string $string
* A string to be used as "display-name".
*
* @return string
* A RFC compliant version of the string, ready to be used as
* "display-name" in mail originator header fields.
*/
public static function formatDisplayName($string) {
// Make sure we don't process html-encoded characters. They may create
// unneeded trouble if left encoded, besides they will be correctly
// processed if decoded.
$string = Html::decodeEntities($string);
// If string contains non-ASCII characters it must be (short) encoded
// according to RFC-2047. The output of a "B" (Base64) encoded-word is
// always safe to be used as display-name.
$safe_display_name = Unicode::mimeHeaderEncode($string, TRUE);
// Encoded-words are always safe to be used as display-name because don't
// contain any RFC 2822 "specials" characters. However
// Unicode::mimeHeaderEncode() encodes a string only if it contains any
// non-ASCII characters, and leaves its value untouched (un-encoded) if
// ASCII only. For this reason in order to produce a valid display-name we
// still need to make sure there are no "specials" characters left.
if (preg_match('/[' . preg_quote(Mail::RFC_2822_SPECIALS) . ']/', $safe_display_name)) {
// If string is already quoted, it may or may not be escaped properly, so
// don't trust it and reset.
if (preg_match('/^"(.+)"$/', $safe_display_name, $matches)) {
$safe_display_name = str_replace(['\\\\', '\\"'], ['\\', '"'], $matches[1]);
}
// Transform the string in a RFC-2822 "quoted-string" by wrapping it in
// double-quotes. Also make sure '"' and '\' occurrences are escaped.
$safe_display_name = '"' . str_replace(['\\', '"'], ['\\\\', '\\"'], $safe_display_name) . '"';
}
return $safe_display_name;
}
}

View file

@ -42,7 +42,7 @@
/**
* Note on Drupal 8 porting.
* This file origin is Tar.php, release 1.4.0 (stable) with some code
* This file origin is Tar.php, release 1.4.5 (stable) with some code
* from PEAR.php, release 1.9.5 (stable) both at http://pear.php.net.
* To simplify future porting from pear of this file, you should not
* do cosmetic or other non significant changes to this file.
@ -151,6 +151,13 @@ class ArchiveTar
*/
public $error_object = null;
/**
* Format for data extraction
*
* @var string
*/
public $_fmt ='';
/**
* Archive_Tar Class constructor. This flavour of the constructor only
* declare a new Archive_Tar object, identifying it by the name of the
@ -257,6 +264,18 @@ class ArchiveTar
return false;
}
}
if (version_compare(PHP_VERSION, "5.5.0-dev") < 0) {
$this->_fmt = "a100filename/a8mode/a8uid/a8gid/a12size/a12mtime/" .
"a8checksum/a1typeflag/a100link/a6magic/a2version/" .
"a32uname/a32gname/a8devmajor/a8devminor/a131prefix";
} else {
$this->_fmt = "Z100filename/Z8mode/Z8uid/Z8gid/Z12size/Z12mtime/" .
"Z8checksum/Z1typeflag/Z100link/Z6magic/Z2version/" .
"Z32uname/Z32gname/Z8devmajor/Z8devminor/Z131prefix";
}
}
public function __destruct()
@ -712,7 +731,7 @@ class ArchiveTar
}
// ----- Get the arguments
$v_att_list = & func_get_args();
$v_att_list = func_get_args();
// ----- Read the attributes
$i = 0;
@ -1392,10 +1411,20 @@ class ArchiveTar
if ($p_stored_filename == '') {
$p_stored_filename = $p_filename;
}
$v_reduce_filename = $this->_pathReduction($p_stored_filename);
$v_reduced_filename = $this->_pathReduction($p_stored_filename);
if (strlen($v_reduce_filename) > 99) {
if (!$this->_writeLongHeader($v_reduce_filename)) {
if (strlen($v_reduced_filename) > 99) {
if (!$this->_writeLongHeader($v_reduced_filename, false)) {
return false;
}
}
$v_linkname = '';
if (@is_link($p_filename)) {
$v_linkname = readlink($p_filename);
}
if (strlen($v_linkname) > 99) {
if (!$this->_writeLongHeader($v_linkname, true)) {
return false;
}
}
@ -1404,14 +1433,10 @@ class ArchiveTar
$v_uid = sprintf("%07s", DecOct($v_info[4]));
$v_gid = sprintf("%07s", DecOct($v_info[5]));
$v_perms = sprintf("%07s", DecOct($v_info['mode'] & 000777));
$v_mtime = sprintf("%011s", DecOct($v_info['mtime']));
$v_linkname = '';
if (@is_link($p_filename)) {
$v_typeflag = '2';
$v_linkname = readlink($p_filename);
$v_size = sprintf("%011s", DecOct(0));
} elseif (@is_dir($p_filename)) {
$v_typeflag = "5";
@ -1423,7 +1448,6 @@ class ArchiveTar
}
$v_magic = 'ustar ';
$v_version = ' ';
if (function_exists('posix_getpwuid')) {
@ -1438,14 +1462,12 @@ class ArchiveTar
}
$v_devmajor = '';
$v_devminor = '';
$v_prefix = '';
$v_binary_data_first = pack(
"a100a8a8a8a12a12",
$v_reduce_filename,
$v_perms,
$v_uid,
$v_gid,
@ -1485,7 +1507,7 @@ class ArchiveTar
$this->_writeBlock($v_binary_data_first, 148);
// ----- Write the calculated checksum
$v_checksum = sprintf("%06s ", DecOct($v_checksum));
$v_checksum = sprintf("%06s\0 ", DecOct($v_checksum));
$v_binary_data = pack("a8", $v_checksum);
$this->_writeBlock($v_binary_data, 8);
@ -1517,7 +1539,7 @@ class ArchiveTar
$p_filename = $this->_pathReduction($p_filename);
if (strlen($p_filename) > 99) {
if (!$this->_writeLongHeader($p_filename)) {
if (!$this->_writeLongHeader($p_filename, false)) {
return false;
}
}
@ -1613,36 +1635,31 @@ class ArchiveTar
* @param string $p_filename
* @return bool
*/
public function _writeLongHeader($p_filename)
public function _writeLongHeader($p_filename, $is_link = false)
{
$v_size = sprintf("%11s ", DecOct(strlen($p_filename)));
$v_typeflag = 'L';
$v_uid = sprintf("%07s", 0);
$v_gid = sprintf("%07s", 0);
$v_perms = sprintf("%07s", 0);
$v_size = sprintf("%'011s", DecOct(strlen($p_filename)));
$v_mtime = sprintf("%011s", 0);
$v_typeflag = ($is_link ? 'K' : 'L');
$v_linkname = '';
$v_magic = '';
$v_version = '';
$v_magic = 'ustar ';
$v_version = ' ';
$v_uname = '';
$v_gname = '';
$v_devmajor = '';
$v_devminor = '';
$v_prefix = '';
$v_binary_data_first = pack(
"a100a8a8a8a12a12",
'././@LongLink',
0,
0,
0,
$v_perms,
$v_uid,
$v_gid,
$v_size,
0
$v_mtime
);
$v_binary_data_last = pack(
"a1a100a6a2a32a32a8a8a155a12",
@ -1677,7 +1694,7 @@ class ArchiveTar
$this->_writeBlock($v_binary_data_first, 148);
// ----- Write the calculated checksum
$v_checksum = sprintf("%06s ", DecOct($v_checksum));
$v_checksum = sprintf("%06s\0 ", DecOct($v_checksum));
$v_binary_data = pack("a8", $v_checksum);
$this->_writeBlock($v_binary_data, 8);
@ -1718,28 +1735,12 @@ class ArchiveTar
// ----- Calculate the checksum
$v_checksum = 0;
// ..... First part of the header
for ($i = 0; $i < 148; $i++) {
$v_checksum += ord(substr($v_binary_data, $i, 1));
}
// ..... Ignore the checksum value and replace it by ' ' (space)
for ($i = 148; $i < 156; $i++) {
$v_checksum += ord(' ');
}
// ..... Last part of the header
for ($i = 156; $i < 512; $i++) {
$v_checksum += ord(substr($v_binary_data, $i, 1));
}
$v_binary_split = str_split($v_binary_data);
$v_checksum += array_sum(array_map('ord', array_slice($v_binary_split, 0, 148)));
$v_checksum += array_sum(array_map('ord', array(' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',)));
$v_checksum += array_sum(array_map('ord', array_slice($v_binary_split, 156, 512)));
if (version_compare(PHP_VERSION, "5.5.0-dev") < 0) {
$fmt = "a100filename/a8mode/a8uid/a8gid/a12size/a12mtime/" .
"a8checksum/a1typeflag/a100link/a6magic/a2version/" .
"a32uname/a32gname/a8devmajor/a8devminor/a131prefix";
} else {
$fmt = "Z100filename/Z8mode/Z8uid/Z8gid/Z12size/Z12mtime/" .
"Z8checksum/Z1typeflag/Z100link/Z6magic/Z2version/" .
"Z32uname/Z32gname/Z8devmajor/Z8devminor/Z131prefix";
}
$v_data = unpack($fmt, $v_binary_data);
$v_data = unpack($this->_fmt, $v_binary_data);
if (strlen($v_data["prefix"]) > 0) {
$v_data["filename"] = "$v_data[prefix]/$v_data[filename]";
@ -1775,7 +1776,7 @@ class ArchiveTar
$v_header['mode'] = OctDec(trim($v_data['mode']));
$v_header['uid'] = OctDec(trim($v_data['uid']));
$v_header['gid'] = OctDec(trim($v_data['gid']));
$v_header['size'] = OctDec(trim($v_data['size']));
$v_header['size'] = $this->_tarRecToSize($v_data['size']);
$v_header['mtime'] = OctDec(trim($v_data['mtime']));
if (($v_header['typeflag'] = $v_data['typeflag']) == "5") {
$v_header['size'] = 0;
@ -1794,6 +1795,41 @@ class ArchiveTar
return true;
}
/**
* Convert Tar record size to actual size
*
* @param string $tar_size
* @return size of tar record in bytes
*/
private function _tarRecToSize($tar_size)
{
/*
* First byte of size has a special meaning if bit 7 is set.
*
* Bit 7 indicates base-256 encoding if set.
* Bit 6 is the sign bit.
* Bits 5:0 are most significant value bits.
*/
$ch = ord($tar_size[0]);
if ($ch & 0x80) {
// Full 12-bytes record is required.
$rec_str = $tar_size . "\x00";
$size = ($ch & 0x40) ? -1 : 0;
$size = ($size << 6) | ($ch & 0x3f);
for ($num_ch = 1; $num_ch < 12; ++$num_ch) {
$size = ($size * 256) + ord($rec_str[$num_ch]);
}
return $size;
} else {
return OctDec(trim($tar_size));
}
}
/**
* Detect and report a malicious file name
*
@ -1803,10 +1839,13 @@ class ArchiveTar
*/
private function _maliciousFilename($file)
{
if (strpos($file, '/../') !== false) {
if (strpos($file, 'phar://') === 0) {
return true;
}
if (strpos($file, '../') === 0) {
if (strpos($file, DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR) !== false) {
return true;
}
if (strpos($file, '..' . DIRECTORY_SEPARATOR) === 0) {
return true;
}
return false;
@ -1871,11 +1910,20 @@ class ArchiveTar
continue;
}
// ----- Look for long filename
if ($v_header['typeflag'] == 'L') {
if (!$this->_readLongHeader($v_header)) {
return null;
}
switch ($v_header['typeflag']) {
case 'L': {
if (!$this->_readLongHeader($v_header)) {
return null;
}
} break;
case 'K': {
$v_link_header = $v_header;
if (!$this->_readLongHeader($v_link_header)) {
return null;
}
$v_header['link'] = $v_link_header['filename'];
} break;
}
if ($v_header['filename'] == $p_filename) {
@ -1976,11 +2024,20 @@ class ArchiveTar
continue;
}
// ----- Look for long filename
if ($v_header['typeflag'] == 'L') {
if (!$this->_readLongHeader($v_header)) {
return false;
}
switch ($v_header['typeflag']) {
case 'L': {
if (!$this->_readLongHeader($v_header)) {
return null;
}
} break;
case 'K': {
$v_link_header = $v_header;
if (!$this->_readLongHeader($v_link_header)) {
return null;
}
$v_header['link'] = $v_link_header['filename'];
} break;
}
// ignore extended / pax headers

View file

@ -11,6 +11,7 @@ use Drupal\Component\Utility\NestedArray;
use Drupal\Core\Language\LanguageInterface;
use Drupal\Core\Plugin\PluginWithFormsInterface;
use Drupal\Core\Plugin\PluginWithFormsTrait;
use Drupal\Core\Render\PreviewFallbackInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\Component\Transliteration\TransliterationInterface;
@ -23,7 +24,7 @@ use Drupal\Component\Transliteration\TransliterationInterface;
*
* @ingroup block_api
*/
abstract class BlockBase extends ContextAwarePluginBase implements BlockPluginInterface, PluginWithFormsInterface {
abstract class BlockBase extends ContextAwarePluginBase implements BlockPluginInterface, PluginWithFormsInterface, PreviewFallbackInterface {
use ContextAwarePluginAssignmentTrait;
use MessengerTrait;
@ -252,6 +253,13 @@ abstract class BlockBase extends ContextAwarePluginBase implements BlockPluginIn
return $transliterated;
}
/**
* {@inheritdoc}
*/
public function getPreviewFallbackString() {
return $this->t('Placeholder for the "@block" block', ['@block' => $this->label()]);
}
/**
* Wraps the transliteration service.
*

View file

@ -156,7 +156,8 @@ class MemoryBackend implements CacheBackendInterface, CacheTagsInvalidatorInterf
* {@inheritdoc}
*/
public function invalidateMultiple(array $cids) {
foreach ($cids as $cid) {
$items = array_intersect_key($this->cache, array_flip($cids));
foreach ($items as $cid => $item) {
$this->cache[$cid]->expire = $this->getRequestTime() - 1;
}
}

View file

@ -162,12 +162,19 @@ class DbDumpCommand extends DbCommandBase {
$definition['fields'][$name]['precision'] = $matches[2];
$definition['fields'][$name]['scale'] = $matches[3];
}
elseif ($type === 'time' || $type === 'datetime') {
elseif ($type === 'time') {
// @todo Core doesn't support these, but copied from `migrate-db.sh` for now.
// Convert to varchar.
$definition['fields'][$name]['type'] = 'varchar';
$definition['fields'][$name]['length'] = '100';
}
elseif ($type === 'datetime') {
// Adjust for other database types.
$definition['fields'][$name]['mysql_type'] = 'datetime';
$definition['fields'][$name]['pgsql_type'] = 'timestamp without time zone';
$definition['fields'][$name]['sqlite_type'] = 'varchar';
$definition['fields'][$name]['sqlsrv_type'] = 'smalldatetime';
}
elseif (!isset($definition['fields'][$name]['size'])) {
// Try use the provided length, if it doesn't exist default to 100. It's
// not great but good enough for our dumps at this point.

View file

@ -33,7 +33,7 @@ abstract class Tasks {
],
[
'arguments' => [
'CREATE TABLE {drupal_install_test} (id int NULL)',
'CREATE TABLE {drupal_install_test} (id int NOT NULL PRIMARY KEY)',
'Drupal can use CREATE TABLE database commands.',
'Failed to <strong>CREATE</strong> a test table on your database server with the command %query. The server reports the following message: %error.<p>Are you sure the configured username has the necessary permissions to create tables in the database?</p>',
TRUE,

View file

@ -248,18 +248,15 @@ use Drupal\Core\Database\Query\Condition;
*
* The following keys are defined:
* - 'description': A string in non-markup plain text describing this table
* and its purpose. References to other tables should be enclosed in
* curly-brackets. For example, the node_field_revision table
* description field might contain "Stores per-revision title and
* body data for each {node}."
* and its purpose. References to other tables should be enclosed in curly
* brackets.
* - 'fields': An associative array ('fieldname' => specification)
* that describes the table's database columns. The specification
* is also an array. The following specification parameters are defined:
* - 'description': A string in non-markup plain text describing this field
* and its purpose. References to other tables should be enclosed in
* curly-brackets. For example, the node table vid field
* description might contain "Always holds the largest (most
* recent) {node_field_revision}.vid value for this nid."
* and its purpose. References to other tables should be enclosed in curly
* brackets. For example, the users_data table 'uid' field description
* might contain "The {users}.uid this record affects."
* - 'type': The generic datatype: 'char', 'varchar', 'text', 'blob', 'int',
* 'float', 'numeric', or 'serial'. Most types just map to the according
* database engine specific data types. Use 'serial' for auto incrementing
@ -322,64 +319,70 @@ use Drupal\Core\Database\Query\Condition;
* key column specifiers (see below) that form an index on the
* table.
*
* A key column specifier is either a string naming a column or an
* array of two elements, column name and length, specifying a prefix
* of the named column.
* A key column specifier is either a string naming a column or an array of two
* elements, column name and length, specifying a prefix of the named column.
*
* As an example, here is a SUBSET of the schema definition for
* Drupal's 'node' table. It show four fields (nid, vid, type, and
* title), the primary key on field 'nid', a unique key named 'vid' on
* field 'vid', and two indexes, one named 'nid' on field 'nid' and
* one named 'node_title_type' on the field 'title' and the first four
* bytes of the field 'type':
* As an example, this is the schema definition for the 'users_data' table. It
* shows five fields ('uid', 'module', 'name', 'value', and 'serialized'), the
* primary key (on the 'uid', 'module', and 'name' fields), and two indexes (the
* 'module' index on the 'module' field and the 'name' index on the 'name'
* field).
*
* @code
* $schema['node'] = array(
* 'description' => 'The base table for nodes.',
* 'fields' => array(
* 'nid' => array('type' => 'serial', 'unsigned' => TRUE, 'not null' => TRUE),
* 'vid' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE,'default' => 0),
* 'type' => array('type' => 'varchar','length' => 32,'not null' => TRUE, 'default' => ''),
* 'language' => array('type' => 'varchar','length' => 12,'not null' => TRUE,'default' => ''),
* 'title' => array('type' => 'varchar','length' => 255,'not null' => TRUE, 'default' => ''),
* 'uid' => array('type' => 'int', 'not null' => TRUE, 'default' => 0),
* 'status' => array('type' => 'int', 'not null' => TRUE, 'default' => 1),
* 'created' => array('type' => 'int', 'not null' => TRUE, 'default' => 0),
* 'changed' => array('type' => 'int', 'not null' => TRUE, 'default' => 0),
* 'comment' => array('type' => 'int', 'not null' => TRUE, 'default' => 0),
* 'promote' => array('type' => 'int', 'not null' => TRUE, 'default' => 0),
* 'moderate' => array('type' => 'int', 'not null' => TRUE,'default' => 0),
* 'sticky' => array('type' => 'int', 'not null' => TRUE, 'default' => 0),
* 'translate' => array('type' => 'int', 'not null' => TRUE, 'default' => 0),
* ),
* 'indexes' => array(
* 'node_changed' => array('changed'),
* 'node_created' => array('created'),
* 'node_moderate' => array('moderate'),
* 'node_frontpage' => array('promote', 'status', 'sticky', 'created'),
* 'node_status_type' => array('status', 'type', 'nid'),
* 'node_title_type' => array('title', array('type', 4)),
* 'node_type' => array(array('type', 4)),
* 'uid' => array('uid'),
* 'translate' => array('translate'),
* ),
* 'unique keys' => array(
* 'vid' => array('vid'),
* ),
* $schema['users_data'] = [
* 'description' => 'Stores module data as key/value pairs per user.',
* 'fields' => [
* 'uid' => [
* 'description' => 'The {users}.uid this record affects.',
* 'type' => 'int',
* 'unsigned' => TRUE,
* 'not null' => TRUE,
* 'default' => 0,
* ],
* 'module' => [
* 'description' => 'The name of the module declaring the variable.',
* 'type' => 'varchar_ascii',
* 'length' => DRUPAL_EXTENSION_NAME_MAX_LENGTH,
* 'not null' => TRUE,
* 'default' => '',
* ],
* 'name' => [
* 'description' => 'The identifier of the data.',
* 'type' => 'varchar_ascii',
* 'length' => 128,
* 'not null' => TRUE,
* 'default' => '',
* ],
* 'value' => [
* 'description' => 'The value.',
* 'type' => 'blob',
* 'not null' => FALSE,
* 'size' => 'big',
* ],
* 'serialized' => [
* 'description' => 'Whether value is serialized.',
* 'type' => 'int',
* 'size' => 'tiny',
* 'unsigned' => TRUE,
* 'default' => 0,
* ],
* ],
* 'primary key' => ['uid', 'module', 'name'],
* 'indexes' => [
* 'module' => ['module'],
* 'name' => ['name'],
* ],
* // For documentation purposes only; foreign keys are not created in the
* // database.
* 'foreign keys' => array(
* 'node_revision' => array(
* 'table' => 'node_field_revision',
* 'columns' => array('vid' => 'vid'),
* ),
* 'node_author' => array(
* 'foreign keys' => [
* 'data_user' => [
* 'table' => 'users',
* 'columns' => array('uid' => 'uid'),
* ),
* ),
* 'primary key' => array('nid'),
* );
* 'columns' => [
* 'uid' => 'uid',
* ],
* ],
* ],
* ];
* @endcode
*
* @see drupal_install_schema()
@ -490,60 +493,61 @@ function hook_query_TAG_alter(Drupal\Core\Database\Query\AlterableInterface $que
* @ingroup schemaapi
*/
function hook_schema() {
$schema['node'] = [
// Example (partial) specification for table "node".
'description' => 'The base table for nodes.',
$schema['users_data'] = [
'description' => 'Stores module data as key/value pairs per user.',
'fields' => [
'nid' => [
'description' => 'The primary identifier for a node.',
'type' => 'serial',
'unsigned' => TRUE,
'not null' => TRUE,
],
'vid' => [
'description' => 'The current {node_field_revision}.vid version identifier.',
'uid' => [
'description' => 'The {users}.uid this record affects.',
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
'default' => 0,
],
'type' => [
'description' => 'The type of this node.',
'type' => 'varchar',
'length' => 32,
'module' => [
'description' => 'The name of the module declaring the variable.',
'type' => 'varchar_ascii',
'length' => DRUPAL_EXTENSION_NAME_MAX_LENGTH,
'not null' => TRUE,
'default' => '',
],
'title' => [
'description' => 'The node title.',
'type' => 'varchar',
'length' => 255,
'name' => [
'description' => 'The identifier of the data.',
'type' => 'varchar_ascii',
'length' => 128,
'not null' => TRUE,
'default' => '',
],
'value' => [
'description' => 'The value.',
'type' => 'blob',
'not null' => FALSE,
'size' => 'big',
],
'serialized' => [
'description' => 'Whether value is serialized.',
'type' => 'int',
'size' => 'tiny',
'unsigned' => TRUE,
'default' => 0,
],
],
'primary key' => ['uid', 'module', 'name'],
'indexes' => [
'node_changed' => ['changed'],
'node_created' => ['created'],
],
'unique keys' => [
'nid_vid' => ['nid', 'vid'],
'vid' => ['vid'],
'module' => ['module'],
'name' => ['name'],
],
// For documentation purposes only; foreign keys are not created in the
// database.
'foreign keys' => [
'node_revision' => [
'table' => 'node_field_revision',
'columns' => ['vid' => 'vid'],
],
'node_author' => [
'data_user' => [
'table' => 'users',
'columns' => ['uid' => 'uid'],
'columns' => [
'uid' => 'uid',
],
],
],
'primary key' => ['nid'],
];
return $schema;
}

View file

@ -19,6 +19,7 @@ use Drupal\Core\File\MimeType\MimeTypeGuesser;
use Drupal\Core\Http\TrustedHostsRequestFactory;
use Drupal\Core\Installer\InstallerRedirectTrait;
use Drupal\Core\Language\Language;
use Drupal\Core\Security\PharExtensionInterceptor;
use Drupal\Core\Security\RequestSanitizer;
use Drupal\Core\Site\Settings;
use Drupal\Core\Test\TestDatabase;
@ -35,6 +36,9 @@ use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
use Symfony\Component\HttpKernel\TerminableInterface;
use Symfony\Component\Routing\Route;
use TYPO3\PharStreamWrapper\Manager as PharStreamWrapperManager;
use TYPO3\PharStreamWrapper\Behavior as PharStreamWrapperBehavior;
use TYPO3\PharStreamWrapper\PharStreamWrapper;
/**
* The DrupalKernel class is the core of Drupal itself.
@ -471,6 +475,26 @@ class DrupalKernel implements DrupalKernelInterface, TerminableInterface {
// Initialize the container.
$this->initializeContainer();
if (in_array('phar', stream_get_wrappers(), TRUE)) {
// Set up a stream wrapper to handle insecurities due to PHP's builtin
// phar stream wrapper. This is not registered as a regular stream wrapper
// to prevent \Drupal\Core\File\FileSystem::validScheme() treating "phar"
// as a valid scheme.
try {
$behavior = new PharStreamWrapperBehavior();
PharStreamWrapperManager::initialize(
$behavior->withAssertion(new PharExtensionInterceptor())
);
}
catch (\LogicException $e) {
// Continue if the PharStreamWrapperManager is already initialized. For
// example, this occurs during a module install.
// @see \Drupal\Core\Extension\ModuleInstaller::install()
};
stream_wrapper_unregister('phar');
stream_wrapper_register('phar', PharStreamWrapper::class);
}
$this->booted = TRUE;
return $this;

View file

@ -8,6 +8,7 @@ use Drupal\Core\Entity\EntityDisplayPluginCollection;
use Drupal\Core\Entity\EntityStorageInterface;
use Drupal\Core\Entity\FieldableEntityInterface;
use Drupal\Core\Entity\EntityDisplayBase;
use Drupal\Core\Render\Element;
use Drupal\Core\TypedData\TranslatableInterface as TranslatableDataInterface;
/**
@ -269,7 +270,7 @@ class EntityViewDisplay extends EntityDisplayBase implements EntityViewDisplayIn
foreach ($entities as $id => $entity) {
// Assign the configured weights.
foreach ($this->getComponents() as $name => $options) {
if (isset($build_list[$id][$name])) {
if (isset($build_list[$id][$name]) && !Element::isEmpty($build_list[$id][$name])) {
$build_list[$id][$name]['#weight'] = $options['weight'];
}
}

View file

@ -2,7 +2,9 @@
namespace Drupal\Core\Entity\Plugin\DataType;
use Drupal\Core\Config\TypedConfigManagerInterface;
use Drupal\Core\TypedData\Exception\MissingDataException;
use Drupal\Core\TypedData\TypedDataManagerInterface;
/**
* Enhances EntityAdapter for config entities.
@ -16,6 +18,13 @@ class ConfigEntityAdapter extends EntityAdapter {
*/
protected $entity;
/**
* The typed config manager.
*
* @var \Drupal\Core\Config\TypedConfigManagerInterface
*/
protected $typedConfigManager;
/**
* {@inheritdoc}
*/
@ -68,10 +77,31 @@ class ConfigEntityAdapter extends EntityAdapter {
}
/**
* Gets the typed data manager.
* Gets the typed config manager.
*
* @return \Drupal\Core\Config\TypedConfigManagerInterface
* The typed data manager.
* The typed config manager.
*/
protected function getTypedConfigManager() {
if (empty($this->typedConfigManager)) {
// Use the typed data manager if it is also the typed config manager.
// @todo Remove this in https://www.drupal.org/node/3011137.
$typed_data_manager = $this->getTypedDataManager();
if ($typed_data_manager instanceof TypedConfigManagerInterface) {
$this->typedConfigManager = $typed_data_manager;
}
else {
$this->typedConfigManager = \Drupal::service('config.typed');
}
}
return $this->typedConfigManager;
}
/**
* {@inheritdoc}
*
* @todo Remove this in https://www.drupal.org/node/3011137.
*/
public function getTypedDataManager() {
if (empty($this->typedDataManager)) {
@ -81,6 +111,19 @@ class ConfigEntityAdapter extends EntityAdapter {
return $this->typedDataManager;
}
/**
* {@inheritdoc}
*
* @todo Remove this in https://www.drupal.org/node/3011137.
*/
public function setTypedDataManager(TypedDataManagerInterface $typed_data_manager) {
$this->typedDataManager = $typed_data_manager;
if ($typed_data_manager instanceof TypedConfigManagerInterface) {
$this->typedConfigManager = $typed_data_manager;
}
return $this;
}
/**
* {@inheritdoc}
*/
@ -97,7 +140,7 @@ class ConfigEntityAdapter extends EntityAdapter {
* The typed data.
*/
protected function getConfigTypedData() {
return $this->getTypedDataManager()->createFromNameAndData($this->entity->getConfigDependencyName(), $this->entity->toArray());
return $this->getTypedConfigManager()->createFromNameAndData($this->entity->getConfigDependencyName(), $this->entity->toArray());
}
}

View file

@ -184,6 +184,7 @@ class Tables implements TablesInterface {
// finds the property first. The data table is preferred, which is why
// it gets added before the base table.
$entity_tables = [];
$revision_table = NULL;
if ($all_revisions && $field_storage && $field_storage->isRevisionable()) {
$data_table = $entity_type->getRevisionDataTable();
$entity_base_table = $entity_type->getRevisionTable();
@ -191,11 +192,18 @@ class Tables implements TablesInterface {
else {
$data_table = $entity_type->getDataTable();
$entity_base_table = $entity_type->getBaseTable();
if ($field_storage && $field_storage->isRevisionable() && in_array($field_storage->getName(), $entity_type->getRevisionMetadataKeys())) {
$revision_table = $entity_type->getRevisionTable();
}
}
if ($data_table) {
$this->sqlQuery->addMetaData('simple_query', FALSE);
$entity_tables[$data_table] = $this->getTableMapping($data_table, $entity_type_id);
}
if ($revision_table) {
$entity_tables[$revision_table] = $this->getTableMapping($revision_table, $entity_type_id);
}
$entity_tables[$entity_base_table] = $this->getTableMapping($entity_base_table, $entity_type_id);
$sql_column = $specifier;

View file

@ -821,10 +821,13 @@ class SqlContentEntityStorage extends ContentEntityStorageBase implements SqlEnt
if ($update) {
$default_revision = $entity->isDefaultRevision();
if ($default_revision) {
// Remove the ID from the record to enable updates on SQL variants
// that prevent updating serial columns, for example, mssql.
unset($record->{$this->idKey});
$this->database
->update($this->baseTable)
->fields((array) $record)
->condition($this->idKey, $record->{$this->idKey})
->condition($this->idKey, $entity->get($this->idKey)->value)
->execute();
}
if ($this->revisionTable) {
@ -833,11 +836,15 @@ class SqlContentEntityStorage extends ContentEntityStorageBase implements SqlEnt
}
else {
$record = $this->mapToStorageRecord($entity->getUntranslated(), $this->revisionTable);
// Remove the revision ID from the record to enable updates on SQL
// variants that prevent updating serial columns, for example,
// mssql.
unset($record->{$this->revisionKey});
$entity->preSaveRevision($this, $record);
$this->database
->update($this->revisionTable)
->fields((array) $record)
->condition($this->revisionKey, $record->{$this->revisionKey})
->condition($this->revisionKey, $entity->getRevisionId())
->execute();
}
}
@ -1064,19 +1071,21 @@ class SqlContentEntityStorage extends ContentEntityStorageBase implements SqlEnt
->condition($this->idKey, $record->{$this->idKey})
->execute();
}
// Make sure to update the new revision key for the entity.
$entity->{$this->revisionKey}->value = $record->{$this->revisionKey};
}
else {
// Remove the revision ID from the record to enable updates on SQL
// variants that prevent updating serial columns, for example,
// mssql.
unset($record->{$this->revisionKey});
$this->database
->update($this->revisionTable)
->fields((array) $record)
->condition($this->revisionKey, $record->{$this->revisionKey})
->condition($this->revisionKey, $entity->getRevisionId())
->execute();
}
// Make sure to update the new revision key for the entity.
$entity->{$this->revisionKey}->value = $record->{$this->revisionKey};
return $record->{$this->revisionKey};
return $entity->getRevisionId();
}
/**

View file

@ -811,10 +811,10 @@ function hook_entity_view_mode_info_alter(&$view_modes) {
* An associative array of all entity bundles, keyed by the entity
* type name, and then the bundle name, with the following keys:
* - label: The human-readable name of the bundle.
* - uri_callback: The same as the 'uri_callback' key defined for the entity
* type in the EntityManager, but for the bundle only. When determining
* the URI of an entity, if a 'uri_callback' is defined for both the
* entity type and the bundle, the one for the bundle is used.
* - uri_callback: (optional) The same as the 'uri_callback' key defined for
* the entity type in the EntityManager, but for the bundle only. When
* determining the URI of an entity, if a 'uri_callback' is defined for both
* the entity type and the bundle, the one for the bundle is used.
* - translatable: (optional) A boolean value specifying whether this bundle
* has translation support enabled. Defaults to FALSE.
*

View file

@ -684,6 +684,20 @@ function hook_update_N(&$sandbox) {
* Drupal also ensures to not execute the same hook_post_update_NAME() function
* twice.
*
* @section sec_bulk Batch updates
* If running your update all at once could possibly cause PHP to time out, use
* the $sandbox parameter to indicate that the Batch API should be used for your
* update. In this case, your update function acts as an implementation of
* callback_batch_operation(), and $sandbox acts as the batch context
* parameter. In your function, read the state information from the previous
* run from $sandbox (or initialize), run a chunk of updates, save the state in
* $sandbox, and set $sandbox['#finished'] to a value between 0 and 1 to
* indicate the percent completed, or 1 if it is finished (you need to do this
* explicitly in each pass).
*
* See the @link batch Batch operations topic @endlink for more information on
* how to use the Batch API.
*
* @param array $sandbox
* Stores information for batch updates. See above for more information.
*

View file

@ -124,7 +124,6 @@ class StringFormatter extends FormatterBase implements ContainerFactoryPluginInt
$elements = [];
$url = NULL;
if ($this->getSetting('link_to_entity')) {
// For the default revision this falls back to 'canonical'.
$url = $this->getEntityUrl($items->getEntity());
}
@ -173,8 +172,11 @@ class StringFormatter extends FormatterBase implements ContainerFactoryPluginInt
* The URI elements of the entity.
*/
protected function getEntityUrl(EntityInterface $entity) {
// For the default revision this falls back to 'canonical'.
return $entity->toUrl('revision');
// For the default revision, the 'revision' link template falls back to
// 'canonical'.
// @see \Drupal\Core\Entity\Entity::toUrl()
$rel = $entity->getEntityType()->hasLinkTemplate('revision') ? 'revision' : 'canonical';
return $entity->toUrl($rel);
}
}

View file

@ -13,6 +13,7 @@ use Drupal\Core\Plugin\Discovery\ContainerDerivativeDiscoveryDecorator;
use Drupal\Core\Plugin\Discovery\YamlDiscoveryDecorator;
use Drupal\Core\Layout\Annotation\Layout;
use Drupal\Core\Plugin\FilteredPluginManagerTrait;
use Drupal\Core\StringTranslation\TranslatableMarkup;
/**
* Provides a plugin manager for layouts.
@ -71,6 +72,10 @@ class LayoutPluginManager extends DefaultPluginManager implements LayoutPluginMa
if (!$this->discovery) {
$discovery = new AnnotatedClassDiscovery($this->subdir, $this->namespaces, $this->pluginDefinitionAnnotationName, $this->additionalAnnotationNamespaces);
$discovery = new YamlDiscoveryDecorator($discovery, 'layouts', $this->moduleHandler->getModuleDirectories() + $this->themeHandler->getThemeDirectories());
$discovery
->addTranslatableProperty('label')
->addTranslatableProperty('description')
->addTranslatableProperty('category');
$discovery = new AnnotationBridgeDecorator($discovery, $this->pluginDefinitionAnnotationName);
$discovery = new ContainerDerivativeDiscoveryDecorator($discovery);
$this->discovery = $discovery;
@ -140,6 +145,15 @@ class LayoutPluginManager extends DefaultPluginManager implements LayoutPluginMa
if (!$definition->getDefaultRegion()) {
$definition->setDefaultRegion(key($definition->getRegions()));
}
// Makes sure region names are translatable.
$regions = array_map(function ($region) {
if (!$region['label'] instanceof TranslatableMarkup) {
// Region labels from YAML discovery needs translation.
$region['label'] = new TranslatableMarkup($region['label'], [], ['context' => 'layout_region']);
}
return $region;
}, $definition->getRegions());
$definition->setRegions($regions);
}
/**

View file

@ -5,7 +5,7 @@ namespace Drupal\Core\Mail;
use Drupal\Component\Render\MarkupInterface;
use Drupal\Component\Render\PlainTextOutput;
use Drupal\Component\Utility\Html;
use Drupal\Component\Utility\Unicode;
use Drupal\Component\Utility\Mail as MailHelper;
use Drupal\Core\Logger\LoggerChannelFactoryInterface;
use Drupal\Core\Messenger\MessengerTrait;
use Drupal\Core\Plugin\DefaultPluginManager;
@ -254,12 +254,8 @@ class MailManager extends DefaultPluginManager implements MailManagerInterface {
// Return-Path headers should have a domain authorized to use the
// originating SMTP server.
$headers['Sender'] = $headers['Return-Path'] = $site_mail;
// Headers are usually encoded in the mail plugin that implements
// \Drupal\Core\Mail\MailInterface::mail(), for example,
// \Drupal\Core\Mail\Plugin\Mail\PhpMail::mail(). The site name must be
// encoded here to prevent mail plugins from encoding the email address,
// which would break the header.
$headers['From'] = Unicode::mimeHeaderEncode($site_config->get('name'), TRUE) . ' <' . $site_mail . '>';
// Make sure the site-name is a RFC-2822 compliant 'display-name'.
$headers['From'] = MailHelper::formatDisplayName($site_config->get('name')) . ' <' . $site_mail . '>';
if ($reply) {
$headers['Reply-to'] = $reply;
}

View file

@ -106,11 +106,11 @@ class AliasStorage implements AliasStorageInterface {
$this->catchException($e);
$original = FALSE;
}
$fields['pid'] = $pid;
$query = $this->connection->update(static::TABLE)
->fields($fields)
->condition('pid', $pid);
$pid = $query->execute();
$fields['pid'] = $pid;
$fields['original'] = $original;
$operation = 'update';
}

View file

@ -270,7 +270,7 @@ class ContextDefinition implements ContextDefinitionInterface {
public function setConstraints(array $constraints) {
// If the backwards compatibility layer is present, delegate to that.
if ($this->entityContextDefinition) {
$this->entityContextDefinition->setConstraint();
$this->entityContextDefinition->setConstraints($constraints);
}
$this->constraints = $constraints;

View file

@ -48,7 +48,10 @@ trait ContextAwarePluginAssignmentTrait {
];
}
if (count($options) > 1 || !$definition->isRequired()) {
// Show the context selector only if there is more than 1 option to choose
// from. Also, show if there is a single option but the plugin does not
// require a context.
if (count($options) > 1 || (count($options) == 1 && !$definition->isRequired())) {
$assignments = $plugin->getContextMapping();
$element[$context_slot] = [
'#title' => $definition->getLabel() ?: $this->t('Select a @context value:', ['@context' => $context_slot]),

View file

@ -70,7 +70,7 @@ abstract class ContextAwarePluginBase extends ComponentContextAwarePluginBase im
* {@inheritdoc}
*/
public function setContextValue($name, $value) {
$this->context[$name] = Context::createFromContext($this->getContext($name), $value);
$this->setContext($name, Context::createFromContext($this->getContext($name), $value));
return $this;
}

View file

@ -44,7 +44,7 @@ class File extends FormElement {
*/
public static function processFile(&$element, FormStateInterface $form_state, &$complete_form) {
if ($element['#multiple']) {
$element['#attributes'] = ['multiple' => 'multiple'];
$element['#attributes']['multiple'] = 'multiple';
$element['#name'] .= '[]';
}
return $element;

View file

@ -76,7 +76,9 @@ class StatusMessages extends RenderElement {
public static function renderMessages($type = NULL) {
$render = [];
if (isset($type)) {
$messages = \Drupal::messenger()->deleteByType($type);
$messages = [
$type => \Drupal::messenger()->deleteByType($type),
];
}
else {
$messages = \Drupal::messenger()->deleteAll();

View file

@ -0,0 +1,21 @@
<?php
namespace Drupal\Core\Render;
/**
* Allows an element to provide a fallback representation of itself for preview.
*/
interface PreviewFallbackInterface {
/**
* Returns a string to be used as a fallback during preview.
*
* This is typically used when an element has no output and must be displayed,
* for example during configuration.
*
* @return string|\Drupal\Core\StringTranslation\TranslatableMarkup
* A string representing for this.
*/
public function getPreviewFallbackString();
}

View file

@ -125,6 +125,7 @@ class Router extends UrlMatcher implements RequestMatcherInterface, RouterInterf
throw new ResourceNotFoundException(sprintf('No routes found for "%s".', $this->currentPath->getPath()));
}
$collection = $this->applyRouteFilters($collection, $request);
$collection = $this->applyFitOrder($collection);
if ($ret = $this->matchCollection(rawurldecode($this->currentPath->getPath($request)), $collection)) {
return $this->applyRouteEnhancers($ret, $request);
@ -286,6 +287,44 @@ class Router extends UrlMatcher implements RequestMatcherInterface, RouterInterf
return $collection;
}
/**
* Reapplies the fit order to a RouteCollection object.
*
* Route filters can reorder route collections. For example, routes with an
* explicit _format requirement will be preferred. This can result in a less
* fit route being used. For example, as a result of filtering /user/% comes
* before /user/login. In order to not break this fundamental property of
* routes, we need to reapply the fit order. We also need to ensure that order
* within each group of the same fit is preserved.
*
* @param \Symfony\Component\Routing\RouteCollection $collection
* The route collection.
*
* @return \Symfony\Component\Routing\RouteCollection
* The reordered route collection.
*/
protected function applyFitOrder(RouteCollection $collection) {
$buckets = [];
// Sort all the routes by fit descending.
foreach ($collection->all() as $name => $route) {
$fit = $route->compile()->getFit();
$buckets += [$fit => []];
$buckets[$fit][] = [$name, $route];
}
krsort($buckets);
$flattened = array_reduce($buckets, 'array_merge', []);
// Add them back onto a new route collection.
$collection = new RouteCollection();
foreach ($flattened as $pair) {
$name = $pair[0];
$route = $pair[1];
$collection->add($name, $route);
}
return $collection;
}
/**
* {@inheritdoc}
*/

View file

@ -0,0 +1,79 @@
<?php
namespace Drupal\Core\Security;
use TYPO3\PharStreamWrapper\Assertable;
use TYPO3\PharStreamWrapper\Helper;
use TYPO3\PharStreamWrapper\Exception;
/**
* An alternate PharExtensionInterceptor to support phar-based CLI tools.
*
* @see \TYPO3\PharStreamWrapper\Interceptor\PharExtensionInterceptor
*/
class PharExtensionInterceptor implements Assertable {
/**
* Determines whether phar file is allowed to execute.
*
* The phar file is allowed to execute if:
* - the base file name has a ".phar" suffix.
* - it is the CLI tool that has invoked the interceptor.
*
* @param string $path
* The path of the phar file to check.
* @param string $command
* The command being carried out.
*
* @return bool
* TRUE if the phar file is allowed to execute.
*
* @throws Exception
* Thrown when the file is not allowed to execute.
*/
public function assert($path, $command) {
if ($this->baseFileContainsPharExtension($path)) {
return TRUE;
}
throw new Exception(
sprintf(
'Unexpected file extension in "%s"',
$path
),
1535198703
);
}
/**
* Determines if a path has a .phar extension or invoked execution.
*
* @param string $path
* The path of the phar file to check.
*
* @return bool
* TRUE if the file has a .phar extension or if the execution has been
* invoked by the phar file.
*/
private function baseFileContainsPharExtension($path) {
$baseFile = Helper::determineBaseFile($path);
if ($baseFile === NULL) {
return FALSE;
}
// If the stream wrapper is registered by invoking a phar file that does
// not not have .phar extension then this should be allowed. For
// example, some CLI tools recommend removing the extension.
$backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
// Find the last entry in the backtrace containing a 'file' key as
// sometimes the last caller is executed outside the scope of a file. For
// example, this occurs with shutdown functions.
do {
$caller = array_pop($backtrace);
} while (empty($caller['file']) && !empty($backtrace));
if (isset($caller['file']) && $baseFile === Helper::determineBaseFile($caller['file'])) {
return TRUE;
}
$fileExtension = pathinfo($baseFile, PATHINFO_EXTENSION);
return strtolower($fileExtension) === 'phar';
}
}

View file

@ -218,6 +218,11 @@ class SessionManager extends NativeSessionStorage implements SessionManagerInter
if ($this->isStarted()) {
$old_session_id = $this->getId();
// Save and close the old session. Call the parent method to avoid issue
// with session destruction due to the session being considered obsolete.
parent::save();
// Ensure the session is reloaded correctly.
$this->startedLazy = TRUE;
}
session_id(Crypt::randomBytesBase64());
@ -230,10 +235,7 @@ class SessionManager extends NativeSessionStorage implements SessionManagerInter
$this->migrateStoredSession($old_session_id);
}
if (!$this->isStarted()) {
// Start the session when it doesn't exist yet.
$this->startNow();
}
$this->startNow();
}
/**

View file

@ -2,6 +2,7 @@
namespace Drupal\Core\TempStore;
use Drupal\Core\DependencyInjection\DependencySerializationTrait;
use Drupal\Core\KeyValueStore\KeyValueStoreExpirableInterface;
use Drupal\Core\Lock\LockBackendInterface;
use Drupal\Core\Session\AccountProxyInterface;
@ -27,6 +28,7 @@ use Symfony\Component\HttpFoundation\RequestStack;
* \Drupal\Core\TempStore\SharedTempStore.
*/
class PrivateTempStore {
use DependencySerializationTrait;
/**
* The key/value storage object used for this data.

View file

@ -126,10 +126,16 @@ class RecursiveContextualValidator implements ContextualValidatorInterface {
$metadata = $this->metadataFactory->getMetadataFor($data);
$cache_key = spl_object_hash($data);
$property_path = $is_root_call ? '' : PropertyPath::append($previous_path, $data->getName());
// Prefer a specific instance of the typed data manager stored by the data
// if it is available. This is necessary for specialized typed data objects,
// for example those using the typed config subclass of the manager.
$typed_data_manager = method_exists($data, 'getTypedDataManager') ? $data->getTypedDataManager() : $this->typedDataManager;
// Pass the canonical representation of the data as validated value to
// constraint validators, such that they do not have to care about Typed
// Data.
$value = $this->typedDataManager->getCanonicalRepresentation($data);
$value = $typed_data_manager->getCanonicalRepresentation($data);
$this->context->setNode($value, $data, $metadata, $property_path);
if (isset($constraints) || !$this->context->isGroupValidated($cache_key, Constraint::DEFAULT_GROUP)) {

View file

@ -5,6 +5,7 @@ namespace Drupal\Core\Update;
use Drupal\Core\DrupalKernel;
use Drupal\Core\Session\AnonymousUserSession;
use Drupal\Core\Site\Settings;
use Drupal\Core\StackMiddleware\ReverseProxyMiddleware;
use Symfony\Cmf\Component\Routing\RouteObjectInterface;
use Symfony\Component\HttpFoundation\ParameterBag;
use Symfony\Component\HttpFoundation\Request;
@ -59,6 +60,7 @@ class UpdateKernel extends DrupalKernel {
// First boot up basic things, like loading the include files.
$this->initializeSettings($request);
ReverseProxyMiddleware::setSettingsOnRequest($request, Settings::getInstance());
$this->boot();
$container = $this->getContainer();
/** @var \Symfony\Component\HttpFoundation\RequestStack $request_stack */