Update to Drupal 8.1.1. For more information, see https://www.drupal.org/node/2718713

This commit is contained in:
Pantheon Automation 2016-05-04 14:35:41 -07:00 committed by Greg Anderson
parent c0a0d5a94c
commit 9eae24d844
669 changed files with 3873 additions and 1553 deletions

View file

@ -11,7 +11,7 @@ Drupal 8.1.0, 2016-04-20
* Added Symfony Polyfill Iconv 1.1.0. * Added Symfony Polyfill Iconv 1.1.0.
* Added paragonie/random_compat 1.4.1. * Added paragonie/random_compat 1.4.1.
- Updated vendor libraries: - Updated vendor libraries:
* Updated to Symfony 2.8.4. * Updated to the last 2.x minor version of Symfony: 2.8 (2.8.4).
* Updated to CKEditor 4.5.8. * Updated to CKEditor 4.5.8.
* Updated to Modernizr 3.3.1. * Updated to Modernizr 3.3.1.
- Added modules: - Added modules:
@ -34,6 +34,7 @@ Drupal 8.1.0, 2016-04-20
reducing the code needed to extend them. reducing the code needed to extend them.
* Simplified Migrate API by replacing migration configuration entities with * Simplified Migrate API by replacing migration configuration entities with
migration plugins. migration plugins.
* Various improvements for defining entity types:
* Added support for entity types to specify translatable plural labels. * Added support for entity types to specify translatable plural labels.
* Added a revision log interface and trait for revisionable entity types. * Added a revision log interface and trait for revisionable entity types.
* Added key field definitions to ContentEntityBase, reducing code from * Added key field definitions to ContentEntityBase, reducing code from
@ -414,8 +415,8 @@ Drupal 7.0, 2011-01-05
are available. are available.
- OpenID: - OpenID:
* Added support for Gmail and Google Apps for Domain identifiers. Users can * Added support for Gmail and Google Apps for Domain identifiers. Users can
now login with their user@example.com identifier when example.com is powered now log in with their user@example.com identifier when example.com is
by Google. powered by Google.
* Made the OpenID module more pluggable. * Made the OpenID module more pluggable.
- Added code registry: - Added code registry:
* Using the registry, modules declare their includable files via their .info file, * Using the registry, modules declare their includable files via their .info file,

View file

@ -314,6 +314,7 @@ Database Logging module
- Khalid Baheyeldin 'kbahey' https://www.drupal.org/u/kbahey - Khalid Baheyeldin 'kbahey' https://www.drupal.org/u/kbahey
DateTime module DateTime module
- Jonathan Hedstrom 'jhedstrom' https://www.drupal.org/u/jhedstrom
- Matthew Donadio 'mpdonadio' https://www.drupal.org/u/mpdonadio - Matthew Donadio 'mpdonadio' https://www.drupal.org/u/mpdonadio
Dynamic Page Cache module Dynamic Page Cache module

View file

@ -140,10 +140,8 @@
"Drupal\\Component\\": "lib/Drupal/Component", "Drupal\\Component\\": "lib/Drupal/Component",
"Drupal\\Driver\\": "../drivers/lib/Drupal/Driver" "Drupal\\Driver\\": "../drivers/lib/Drupal/Driver"
}, },
"files": [
"lib/Drupal.php"
],
"classmap": [ "classmap": [
"lib/Drupal.php",
"lib/Drupal/Component/Utility/Timer.php", "lib/Drupal/Component/Utility/Timer.php",
"lib/Drupal/Component/Utility/Unicode.php", "lib/Drupal/Component/Utility/Unicode.php",
"lib/Drupal/Core/Database/Database.php", "lib/Drupal/Core/Database/Database.php",

View file

@ -80,6 +80,11 @@ services:
arguments: ['@request_stack'] arguments: ['@request_stack']
tags: tags:
- { name: cache.context } - { name: cache.context }
cache_context.url.path.parent:
class: Drupal\Core\Cache\Context\PathParentCacheContext
arguments: ['@request_stack']
tags:
- { name: cache.context }
cache_context.url.query_args: cache_context.url.query_args:
class: Drupal\Core\Cache\Context\QueryArgsCacheContext class: Drupal\Core\Cache\Context\QueryArgsCacheContext
arguments: ['@request_stack'] arguments: ['@request_stack']

View file

@ -14,6 +14,7 @@ use Drupal\Component\Utility\Html;
use Drupal\Component\Utility\SortArray; use Drupal\Component\Utility\SortArray;
use Drupal\Component\Utility\UrlHelper; use Drupal\Component\Utility\UrlHelper;
use Drupal\Core\Cache\Cache; use Drupal\Core\Cache\Cache;
use Drupal\Core\Render\Element\Link;
use Drupal\Core\Render\Markup; use Drupal\Core\Render\Markup;
use Drupal\Core\StringTranslation\TranslatableMarkup; use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\Core\PhpStorage\PhpStorageFactory; use Drupal\Core\PhpStorage\PhpStorageFactory;
@ -748,7 +749,7 @@ function drupal_clear_js_cache() {
* Use \Drupal\Core\Render\Element\Link::preRenderLink(). * Use \Drupal\Core\Render\Element\Link::preRenderLink().
*/ */
function drupal_pre_render_link($element) { function drupal_pre_render_link($element) {
return Element\Link::preRenderLink($element); return Link::preRenderLink($element);
} }
/** /**

View file

@ -7,6 +7,7 @@
use Drupal\Component\Utility\UrlHelper; use Drupal\Component\Utility\UrlHelper;
use Drupal\Core\Render\Element; use Drupal\Core\Render\Element;
use Drupal\Core\Render\Element\RenderElement;
use Drupal\Core\Template\Attribute; use Drupal\Core\Template\Attribute;
use Drupal\Core\Url; use Drupal\Core\Url;
use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpFoundation\RedirectResponse;
@ -29,7 +30,7 @@ use Symfony\Component\HttpFoundation\RedirectResponse;
function template_preprocess_select(&$variables) { function template_preprocess_select(&$variables) {
$element = $variables['element']; $element = $variables['element'];
Element::setAttributes($element, array('id', 'name', 'size')); Element::setAttributes($element, array('id', 'name', 'size'));
Element\RenderElement::setAttributes($element, array('form-select')); RenderElement::setAttributes($element, array('form-select'));
$variables['attributes'] = $element['#attributes']; $variables['attributes'] = $element['#attributes'];
$variables['options'] = form_select_options($element); $variables['options'] = form_select_options($element);
@ -191,7 +192,7 @@ function form_get_options($element, $key) {
function template_preprocess_fieldset(&$variables) { function template_preprocess_fieldset(&$variables) {
$element = $variables['element']; $element = $variables['element'];
Element::setAttributes($element, array('id')); Element::setAttributes($element, array('id'));
Element\RenderElement::setAttributes($element); RenderElement::setAttributes($element);
$variables['attributes'] = isset($element['#attributes']) ? $element['#attributes'] : array(); $variables['attributes'] = isset($element['#attributes']) ? $element['#attributes'] : array();
$variables['prefix'] = isset($element['#field_prefix']) ? $element['#field_prefix'] : NULL; $variables['prefix'] = isset($element['#field_prefix']) ? $element['#field_prefix'] : NULL;
$variables['suffix'] = isset($element['#field_suffix']) ? $element['#field_suffix'] : NULL; $variables['suffix'] = isset($element['#field_suffix']) ? $element['#field_suffix'] : NULL;
@ -376,7 +377,7 @@ function template_preprocess_form(&$variables) {
function template_preprocess_textarea(&$variables) { function template_preprocess_textarea(&$variables) {
$element = $variables['element']; $element = $variables['element'];
Element::setAttributes($element, array('id', 'name', 'rows', 'cols', 'placeholder')); Element::setAttributes($element, array('id', 'name', 'rows', 'cols', 'placeholder'));
Element\RenderElement::setAttributes($element, array('form-textarea')); RenderElement::setAttributes($element, array('form-textarea'));
$variables['wrapper_attributes'] = new Attribute(); $variables['wrapper_attributes'] = new Attribute();
$variables['attributes'] = new Attribute($element['#attributes']); $variables['attributes'] = new Attribute($element['#attributes']);
$variables['value'] = $element['#value']; $variables['value'] = $element['#value'];

View file

@ -7,7 +7,6 @@
use Drupal\Component\Utility\UrlHelper; use Drupal\Component\Utility\UrlHelper;
use Drupal\Core\DrupalKernel; use Drupal\Core\DrupalKernel;
use Drupal\Core\Config\BootstrapConfigStorageFactory;
use Drupal\Core\Database\Database; use Drupal\Core\Database\Database;
use Drupal\Core\Database\DatabaseExceptionWrapper; use Drupal\Core\Database\DatabaseExceptionWrapper;
use Drupal\Core\Form\FormState; use Drupal\Core\Form\FormState;
@ -489,8 +488,7 @@ function install_begin_request($class_loader, &$install_state) {
// Ensure that the active configuration is empty before installation starts. // Ensure that the active configuration is empty before installation starts.
if ($install_state['config_verified'] && empty($task)) { if ($install_state['config_verified'] && empty($task)) {
$config = BootstrapConfigStorageFactory::get()->listAll(); if (count($kernel->getConfigStorage()->listAll())) {
if (!empty($config)) {
$task = NULL; $task = NULL;
throw new AlreadyInstalledException($container->get('string_translation')); throw new AlreadyInstalledException($container->get('string_translation'));
} }

View file

@ -580,20 +580,29 @@ function template_preprocess_datetime_wrapper(&$variables) {
* *
* Default template: links.html.twig. * Default template: links.html.twig.
* *
* Unfortunately links templates duplicate the "active" class handling of l()
* and LinkGenerator::generate() because it needs to be able to set the "active"
* class not on the links themselves ("a" tags), but on the list items ("li"
* tags) that contain the links. This is necessary for CSS to be able to style
* list items differently when the link is active, since CSS does not yet allow
* one to style list items only if it contains a certain element with a certain
* class. I.e. we cannot yet convert this jQuery selector to a CSS selector:
* jQuery('li:has("a.is-active")')
*
* @param array $variables * @param array $variables
* An associative array containing: * An associative array containing:
* - links: An array of links to be themed. Each link should be itself an * - links: An array of links to be themed. Each link should be itself an
* array, with the following elements: * array, with the following elements:
* - title: The link text. * - title: The link text.
* - url: (optional) The url object to link to. If omitted, no a tag is * - url: (optional) The \Drupal\Core\Url object to link to. If omitted, no
* printed out. * anchor tag is printed out.
* - attributes: (optional) Attributes for the anchor, or for the <span> * - attributes: (optional) Attributes for the anchor, or for the <span>
* tag used in its place if no 'href' is supplied. If element 'class' is * tag used in its place if no 'href' is supplied. If element 'class' is
* included, it must be an array of one or more class names. * included, it must be an array of one or more class names.
* If the 'href' element is supplied, the entire link array is passed to * If the 'href' element is supplied, the entire link array is passed to
* l() as its $options parameter. * l() as its $options parameter.
* - attributes: A keyed array of attributes for the UL containing the * - attributes: A keyed array of attributes for the <ul> containing the list
* list of links. * of links.
* - set_active_class: (optional) Whether each link should compare the * - set_active_class: (optional) Whether each link should compare the
* route_name + route_parameters or href (path), language and query options * route_name + route_parameters or href (path), language and query options
* to the current URL, to determine whether the link is "active". If so, an * to the current URL, to determine whether the link is "active". If so, an
@ -622,15 +631,6 @@ function template_preprocess_datetime_wrapper(&$variables) {
* http://juicystudio.com/article/screen-readers-display-none.php and * http://juicystudio.com/article/screen-readers-display-none.php and
* http://www.w3.org/TR/WCAG-TECHS/H42.html for more information. * http://www.w3.org/TR/WCAG-TECHS/H42.html for more information.
* *
* Unfortunately links templates duplicate the "active" class handling of l()
* and LinkGenerator::generate() because it needs to be able to set the "active"
* class not on the links themselves ("a" tags), but on the list items ("li"
* tags) that contain the links. This is necessary for CSS to be able to style
* list items differently when the link is active, since CSS does not yet allow
* one to style list items only if it contains a certain element with a certain
* class. I.e. we cannot yet convert this jQuery selector to a CSS selector:
* jQuery('li:has("a.is-active")')
*
* @see \Drupal\Core\Utility\LinkGenerator * @see \Drupal\Core\Utility\LinkGenerator
* @see \Drupal\Core\Utility\LinkGenerator::generate() * @see \Drupal\Core\Utility\LinkGenerator::generate()
* @see system_page_attachments() * @see system_page_attachments()
@ -1052,6 +1052,7 @@ function template_preprocess_table(&$variables) {
* render properties for all nested child lists. * render properties for all nested child lists.
* - title: A title to be prepended to the list. * - title: A title to be prepended to the list.
* - list_type: The type of list to return (e.g. "ul", "ol"). * - list_type: The type of list to return (e.g. "ul", "ol").
* - wrapper_attributes: HTML attributes to be applied to the list wrapper.
* *
* @see https://www.drupal.org/node/1842756 * @see https://www.drupal.org/node/1842756
*/ */
@ -1527,7 +1528,7 @@ function template_preprocess_field(&$variables, $hook) {
static $default_attributes; static $default_attributes;
if (!isset($default_attributes)) { if (!isset($default_attributes)) {
$default_attributes = new Attribute; $default_attributes = new Attribute();
} }
// Merge attributes when a single-value field has a hidden label. // Merge attributes when a single-value field has a hidden label.

View file

@ -81,7 +81,7 @@ class Drupal {
/** /**
* The current system version. * The current system version.
*/ */
const VERSION = '8.1.0'; const VERSION = '8.1.1';
/** /**
* Core API compatibility. * Core API compatibility.

View file

@ -116,7 +116,7 @@ class DateTimePlus {
* date even if some values are missing. * date even if some values are missing.
* *
* @param array $date_parts * @param array $date_parts
* An array of date parts, like ('year' => 2014, 'month => 4). * An array of date parts, like ('year' => 2014, 'month' => 4).
* @param mixed $timezone * @param mixed $timezone
* (optional) \DateTimeZone object, time zone string or NULL. NULL uses the * (optional) \DateTimeZone object, time zone string or NULL. NULL uses the
* default system time zone. Defaults to NULL. * default system time zone. Defaults to NULL.

View file

@ -169,4 +169,3 @@ class Diff {
return $this->edits; return $this->edits;
} }
} }

View file

@ -56,4 +56,3 @@ class MappedDiff extends Diff {
} }
} }
} }

View file

@ -86,4 +86,3 @@ class YamlDiscovery implements DiscoverableInterface {
} }
} }

View file

@ -219,7 +219,7 @@ class PoStreamReader implements PoStreamInterface, PoReaderInterface {
if (!$item) { if (!$item) {
return; return;
} }
$header = new PoHeader; $header = new PoHeader();
$header->setFromString(trim($item->getTranslation())); $header->setFromString(trim($item->getTranslation()));
$this->_header = $header; $this->_header = $header;
} }

View file

@ -163,9 +163,9 @@ class FormattableMarkup implements MarkupInterface, \Countable {
* wrapped in quotes: * wrapped in quotes:
* @code * @code
* // Secure (with quotes): * // Secure (with quotes):
* $this->placeholderFormat('<a href=":url">@variable</a>', [':url' => $url, @variable => $variable]); * $this->placeholderFormat('<a href=":url">@variable</a>', [':url' => $url, '@variable' => $variable]);
* // Insecure (without quotes): * // Insecure (without quotes):
* $this->placeholderFormat('<a href=:url>@variable</a>', [':url' => $url, @variable => $variable]); * $this->placeholderFormat('<a href=:url>@variable</a>', [':url' => $url, '@variable' => $variable]);
* @endcode * @endcode
* When ":variable" comes from arbitrary user input, the result is secure, * When ":variable" comes from arbitrary user input, the result is secure,
* but not guaranteed to be a valid URL (which means the resulting output * but not guaranteed to be a valid URL (which means the resulting output

View file

@ -19,7 +19,6 @@ class UrlHelper {
/** /**
* Parses an array into a valid, rawurlencoded query string. * Parses an array into a valid, rawurlencoded query string.
* *
*
* rawurlencode() is RFC3986 compliant, and as a consequence RFC3987 * rawurlencode() is RFC3986 compliant, and as a consequence RFC3987
* compliant. The latter defines the required format of "URLs" in HTML5. * compliant. The latter defines the required format of "URLs" in HTML5.
* urlencode() is almost the same as rawurlencode(), except that it encodes * urlencode() is almost the same as rawurlencode(), except that it encodes

View file

@ -71,4 +71,3 @@ class DataCommand implements CommandInterface {
} }
} }

View file

@ -34,4 +34,3 @@ class AppRootFactory {
} }
} }

View file

@ -6,4 +6,3 @@ namespace Drupal\Core\Archiver;
* Defines an exception class for Drupal\Core\Archiver\ArchiverInterface. * Defines an exception class for Drupal\Core\Archiver\ArchiverInterface.
*/ */
class ArchiverException extends \Exception {} class ArchiverException extends \Exception {}

View file

@ -214,7 +214,7 @@ class AssetResolver implements AssetResolverInterface {
// hook_library_info_alter(). Additionally add the current language to // hook_library_info_alter(). Additionally add the current language to
// support translation of JavaScript files via hook_js_alter(). // support translation of JavaScript files via hook_js_alter().
$libraries_to_load = $this->getLibrariesToLoad($assets); $libraries_to_load = $this->getLibrariesToLoad($assets);
$cid = 'js:' . $theme_info->getName() . ':' . $this->languageManager->getCurrentLanguage()->getId() . ':' . Crypt::hashBase64(serialize($libraries_to_load)) . (int) (count($assets->getSettings()) > 0) . (int) $optimize; $cid = 'js:' . $theme_info->getName() . ':' . $this->languageManager->getCurrentLanguage()->getId() . ':' . Crypt::hashBase64(serialize($libraries_to_load) . serialize($assets->getLibraries())) . (int) (count($assets->getSettings()) > 0) . (int) $optimize;
if ($cached = $this->cache->get($cid)) { if ($cached = $this->cache->get($cid)) {
list($js_assets_header, $js_assets_footer, $settings, $settings_in_header) = $cached->data; list($js_assets_header, $js_assets_footer, $settings, $settings_in_header) = $cached->data;

View file

@ -12,8 +12,8 @@ class CssCollectionGrouper implements AssetCollectionGrouperInterface {
* *
* Puts multiple items into the same group if they are groupable and if they * Puts multiple items into the same group if they are groupable and if they
* are for the same 'media' and 'browsers'. Items of the 'file' type are * are for the same 'media' and 'browsers'. Items of the 'file' type are
* groupable if their 'preprocess' flag is TRUE, items of the 'inline' type * groupable if their 'preprocess' flag is TRUE, and items of the 'external'
* are always groupable, and items of the 'external' type are never groupable. * type are never groupable.
* *
* Also ensures that the process of grouping items does not change their * Also ensures that the process of grouping items does not change their
* relative order. This requirement may result in multiple groups for the same * relative order. This requirement may result in multiple groups for the same
@ -55,11 +55,6 @@ class CssCollectionGrouper implements AssetCollectionGrouperInterface {
$group_keys = $item['preprocess'] ? array($item['type'], $item['group'], $item['media'], $item['browsers']) : FALSE; $group_keys = $item['preprocess'] ? array($item['type'], $item['group'], $item['media'], $item['browsers']) : FALSE;
break; break;
case 'inline':
// Always group inline items.
$group_keys = array($item['type'], $item['media'], $item['browsers']);
break;
case 'external': case 'external':
// Do not group external items. // Do not group external items.
$group_keys = FALSE; $group_keys = FALSE;

View file

@ -133,16 +133,6 @@ class CssCollectionOptimizer implements AssetCollectionOptimizerInterface {
} }
break; break;
case 'inline':
// We don't do any caching for inline CSS assets.
$data = '';
foreach ($css_group['items'] as $css_asset) {
$data .= $this->optimizer->optimize($css_asset);
}
unset($css_assets[$order]['data']['items']);
$css_assets[$order]['data'] = $data;
break;
case 'external': case 'external':
// We don't do any aggregation and hence also no caching for external // We don't do any aggregation and hence also no caching for external
// CSS assets. // CSS assets.

View file

@ -20,20 +20,15 @@ class CssOptimizer implements AssetOptimizerInterface {
* {@inheritdoc} * {@inheritdoc}
*/ */
public function optimize(array $css_asset) { public function optimize(array $css_asset) {
if (!in_array($css_asset['type'], array('file', 'inline'))) { if ($css_asset['type'] != 'file') {
throw new \Exception('Only file or inline CSS assets can be optimized.'); throw new \Exception('Only file CSS assets can be optimized.');
} }
if ($css_asset['type'] === 'file' && !$css_asset['preprocess']) { if (!$css_asset['preprocess']) {
throw new \Exception('Only file CSS assets with preprocessing enabled can be optimized.'); throw new \Exception('Only file CSS assets with preprocessing enabled can be optimized.');
} }
if ($css_asset['type'] === 'file') {
return $this->processFile($css_asset); return $this->processFile($css_asset);
} }
else {
return $this->processCss($css_asset['data'], $css_asset['preprocess']);
}
}
/** /**
* Processes the contents of a CSS asset for cleanup. * Processes the contents of a CSS asset for cleanup.
@ -241,14 +236,14 @@ class CssOptimizer implements AssetOptimizerInterface {
/** /**
* Prefixes all paths within a CSS file for processFile(). * Prefixes all paths within a CSS file for processFile().
* *
* @param array $matches
* An array of matches by a preg_replace_callback() call that scans for
* url() references in CSS files, except for external or absolute ones.
*
* Note: the only reason this method is public is so color.module can call it; * Note: the only reason this method is public is so color.module can call it;
* it is not on the AssetOptimizerInterface, so future refactorings can make * it is not on the AssetOptimizerInterface, so future refactorings can make
* it protected. * it protected.
* *
* @param array $matches
* An array of matches by a preg_replace_callback() call that scans for
* url() references in CSS files, except for external or absolute ones.
*
* @return string * @return string
* The file path. * The file path.
*/ */

View file

@ -12,8 +12,7 @@ class JsCollectionGrouper implements AssetCollectionGrouperInterface {
* *
* Puts multiple items into the same group if they are groupable and if they * Puts multiple items into the same group if they are groupable and if they
* are for the same browsers. Items of the 'file' type are groupable if their * are for the same browsers. Items of the 'file' type are groupable if their
* 'preprocess' flag is TRUE. Items of the 'inline', 'settings', or 'external' * 'preprocess' flag is TRUE. Items of the 'external' type are not groupable.
* type are not groupable.
* *
* Also ensures that the process of grouping items does not change their * Also ensures that the process of grouping items does not change their
* relative order. This requirement may result in multiple groups for the same * relative order. This requirement may result in multiple groups for the same
@ -43,9 +42,7 @@ class JsCollectionGrouper implements AssetCollectionGrouperInterface {
break; break;
case 'external': case 'external':
case 'setting': // Do not group external items.
case 'inline':
// Do not group external, settings, and inline items.
$group_keys = FALSE; $group_keys = FALSE;
break; break;
} }

View file

@ -138,10 +138,8 @@ class JsCollectionOptimizer implements AssetCollectionOptimizerInterface {
break; break;
case 'external': case 'external':
case 'setting': // We don't do any aggregation and hence also no caching for external
case 'inline': // JS assets.
// We don't do any aggregation and hence also no caching for external,
// setting or inline JS assets.
$uri = $js_group['items'][0]['data']; $uri = $js_group['items'][0]['data'];
$js_assets[$order]['data'] = $uri; $js_assets[$order]['data'] = $uri;
break; break;

View file

@ -16,7 +16,7 @@ class JsOptimizer implements AssetOptimizerInterface {
if ($js_asset['type'] !== 'file') { if ($js_asset['type'] !== 'file') {
throw new \Exception('Only file JavaScript assets can be optimized.'); throw new \Exception('Only file JavaScript assets can be optimized.');
} }
if ($js_asset['type'] === 'file' && !$js_asset['preprocess']) { if (!$js_asset['preprocess']) {
throw new \Exception('Only file JavaScript assets with preprocessing enabled can be optimized.'); throw new \Exception('Only file JavaScript assets with preprocessing enabled can be optimized.');
} }

View file

@ -0,0 +1,41 @@
<?php
namespace Drupal\Core\Cache\Context;
use Drupal\Core\Cache\CacheableMetadata;
/**
* Defines a cache context service for path parents.
*
* Cache context ID: 'url.path.parent'.
*
* This allows for caching based on the path, excluding everything after the
* last forward slash.
*/
class PathParentCacheContext extends RequestStackCacheContextBase implements CacheContextInterface {
/**
* {@inheritdoc}
*/
public static function getLabel() {
return t('Parent path');
}
/**
* {@inheritdoc}
*/
public function getContext() {
$request = $this->requestStack->getCurrentRequest();
$path_elements = explode('/', trim($request->getPathInfo(), '/'));
array_pop($path_elements);
return implode('/', $path_elements);
}
/**
* {@inheritdoc}
*/
public function getCacheableMetadata() {
return new CacheableMetadata();
}
}

View file

@ -49,4 +49,3 @@ class ConfigCrudEvent extends Event {
} }
} }

View file

@ -484,14 +484,17 @@ class ConfigImporter {
*/ */
public function doSyncStep($sync_step, &$context) { public function doSyncStep($sync_step, &$context) {
if (!is_array($sync_step) && method_exists($this, $sync_step)) { if (!is_array($sync_step) && method_exists($this, $sync_step)) {
\Drupal::service('config.installer')->setSyncing(TRUE);
$this->$sync_step($context); $this->$sync_step($context);
} }
elseif (is_callable($sync_step)) { elseif (is_callable($sync_step)) {
\Drupal::service('config.installer')->setSyncing(TRUE);
call_user_func_array($sync_step, array(&$context, $this)); call_user_func_array($sync_step, array(&$context, $this));
} }
else { else {
throw new \InvalidArgumentException('Invalid configuration synchronization step'); throw new \InvalidArgumentException('Invalid configuration synchronization step');
} }
\Drupal::service('config.installer')->setSyncing(FALSE);
} }
/** /**
@ -778,7 +781,6 @@ class ConfigImporter {
// Set the config installer to use the sync directory instead of the // Set the config installer to use the sync directory instead of the
// extensions own default config directories. // extensions own default config directories.
\Drupal::service('config.installer') \Drupal::service('config.installer')
->setSyncing(TRUE)
->setSourceStorage($this->storageComparer->getSourceStorage()); ->setSourceStorage($this->storageComparer->getSourceStorage());
if ($type == 'module') { if ($type == 'module') {
$this->moduleInstaller->$op(array($name), FALSE); $this->moduleInstaller->$op(array($name), FALSE);
@ -805,8 +807,6 @@ class ConfigImporter {
} }
$this->setProcessedExtension($type, $op, $name); $this->setProcessedExtension($type, $op, $name);
\Drupal::service('config.installer')
->setSyncing(FALSE);
} }
/** /**

View file

@ -100,4 +100,3 @@ class ConfigModuleOverridesEvent extends Event {
return $this; return $this;
} }
} }

View file

@ -17,10 +17,10 @@ use Drupal\Component\Utility\SortArray;
* The configuration dependency value is structured like this: * The configuration dependency value is structured like this:
* @code * @code
* array( * array(
* 'config => array( * 'config' => array(
* // An array of configuration entity object names. Recalculated on save. * // An array of configuration entity object names. Recalculated on save.
* ), * ),
* 'content => array( * 'content' => array(
* // An array of content entity configuration dependency names. The default * // An array of content entity configuration dependency names. The default
* // format is "ENTITY_TYPE_ID:BUNDLE:UUID". Recalculated on save. * // format is "ENTITY_TYPE_ID:BUNDLE:UUID". Recalculated on save.
* ), * ),
@ -291,10 +291,10 @@ class ConfigDependencyManager {
* The configuration dependencies. The array is structured like this: * The configuration dependencies. The array is structured like this:
* @code * @code
* array( * array(
* 'config => array( * 'config' => array(
* // An array of configuration entity object names. * // An array of configuration entity object names.
* ), * ),
* 'content => array( * 'content' => array(
* // An array of content entity configuration dependency names. The default * // An array of content entity configuration dependency names. The default
* // format is "ENTITY_TYPE_ID:BUNDLE:UUID". * // format is "ENTITY_TYPE_ID:BUNDLE:UUID".
* ), * ),

View file

@ -382,8 +382,7 @@ class ConfigEntityStorage extends EntityStorageBase implements ConfigEntityStora
* {@inheritdoc} * {@inheritdoc}
*/ */
public function importCreate($name, Config $new_config, Config $old_config) { public function importCreate($name, Config $new_config, Config $old_config) {
$entity = $this->createFromStorageRecord($new_config->get()); $entity = $this->_doCreateFromStorageRecord($new_config->get(), TRUE);
$entity->setSyncing(TRUE);
$entity->save(); $entity->save();
return TRUE; return TRUE;
} }
@ -425,6 +424,27 @@ class ConfigEntityStorage extends EntityStorageBase implements ConfigEntityStora
* {@inheritdoc} * {@inheritdoc}
*/ */
public function createFromStorageRecord(array $values) { public function createFromStorageRecord(array $values) {
return $this->_doCreateFromStorageRecord($values);
}
/**
* Helps create a configuration entity from storage values.
*
* Allows the configuration entity storage to massage storage values before
* creating an entity.
*
* @param array $values
* The array of values from the configuration storage.
* @param bool $is_syncing
* Is the configuration entity being created as part of a config sync.
*
* @return ConfigEntityInterface
* The configuration entity.
*
* @see \Drupal\Core\Config\Entity\ConfigEntityStorageInterface::createFromStorageRecord()
* @see \Drupal\Core\Config\Entity\ImportableEntityStorageInterface::importCreate()
*/
protected function _doCreateFromStorageRecord(array $values, $is_syncing = FALSE) {
// Assign a new UUID if there is none yet. // Assign a new UUID if there is none yet.
if ($this->uuidKey && $this->uuidService && !isset($values[$this->uuidKey])) { if ($this->uuidKey && $this->uuidService && !isset($values[$this->uuidKey])) {
$values[$this->uuidKey] = $this->uuidService->generate(); $values[$this->uuidKey] = $this->uuidService->generate();
@ -432,6 +452,7 @@ class ConfigEntityStorage extends EntityStorageBase implements ConfigEntityStora
$data = $this->mapFromStorageRecords(array($values)); $data = $this->mapFromStorageRecords(array($values));
$entity = current($data); $entity = current($data);
$entity->original = clone $entity; $entity->original = clone $entity;
$entity->setSyncing($is_syncing);
$entity->enforceIsNew(); $entity->enforceIsNew();
$entity->postCreate($this); $entity->postCreate($this);
@ -439,6 +460,7 @@ class ConfigEntityStorage extends EntityStorageBase implements ConfigEntityStora
// entity object, for instance to fill-in default values. // entity object, for instance to fill-in default values.
$this->invokeHook('create', $entity); $this->invokeHook('create', $entity);
return $entity; return $entity;
} }
/** /**

View file

@ -132,4 +132,3 @@ class ExtensionInstallStorage extends InstallStorage {
return $this->folders; return $this->folders;
} }
} }

View file

@ -60,13 +60,13 @@ abstract class StorableConfigBase extends ConfigBase {
/** /**
* Saves the configuration object. * Saves the configuration object.
* *
* Must invalidate the cache tags associated with the configuration object.
*
* @param bool $has_trusted_data * @param bool $has_trusted_data
* Set to TRUE if the configuration data has already been checked to ensure * Set to TRUE if the configuration data has already been checked to ensure
* it conforms to schema. Generally this is only used during module and * it conforms to schema. Generally this is only used during module and
* theme installation. * theme installation.
* *
* Must invalidate the cache tags associated with the configuration object.
*
* @return $this * @return $this
* *
* @see \Drupal\Core\Config\ConfigInstaller::createConfiguration() * @see \Drupal\Core\Config\ConfigInstaller::createConfiguration()

View file

@ -68,7 +68,7 @@ class ControllerResolver extends BaseControllerResolver implements ControllerRes
return $controller; return $controller;
} }
elseif (method_exists($controller, '__invoke')) { elseif (method_exists($controller, '__invoke')) {
return new $controller; return new $controller();
} }
} }

View file

@ -11,4 +11,3 @@ namespace Drupal\Core\Database;
* developers should account for it separately. * developers should account for it separately.
*/ */
interface DatabaseException { } interface DatabaseException { }

View file

@ -22,8 +22,8 @@ class Log {
* *
* array( * array(
* $logging_key = array( * $logging_key = array(
* array(query => '', args => array(), caller => '', target => '', time => 0), * array('query' => '', 'args' => array(), 'caller' => '', 'target' => '', 'time' => 0),
* array(query => '', args => array(), caller => '', target => '', time => 0), * array('query' => '', 'args' => array(), 'caller' => '', 'target' => '', 'time' => 0),
* ), * ),
* ); * );
* *

View file

@ -531,4 +531,3 @@ class DateHelper {
} }
} }

View file

@ -70,4 +70,3 @@ abstract class DateElementBase extends FormElement {
} }
} }

View file

@ -61,7 +61,12 @@ class Datelist extends DateElementBase {
unset($input['ampm']); unset($input['ampm']);
} }
$timezone = !empty($element['#date_timezone']) ? $element['#date_timezone'] : NULL; $timezone = !empty($element['#date_timezone']) ? $element['#date_timezone'] : NULL;
try {
$date = DrupalDateTime::createFromArray($input, $timezone); $date = DrupalDateTime::createFromArray($input, $timezone);
}
catch (\Exception $e) {
$form_state->setError($element, t('Selected combination of day and month is not valid.'));
}
if ($date instanceof DrupalDateTime && !$date->hasErrors()) { if ($date instanceof DrupalDateTime && !$date->hasErrors()) {
static::incrementRound($date, $increment); static::incrementRound($date, $increment);
} }
@ -318,8 +323,8 @@ class Datelist extends DateElementBase {
if ($date instanceof DrupalDateTime && !$date->hasErrors()) { if ($date instanceof DrupalDateTime && !$date->hasErrors()) {
$form_state->setValueForElement($element, $date); $form_state->setValueForElement($element, $date);
} }
// If the input is invalid, set an error. // If the input is invalid and an error doesn't exist, set one.
else { elseif ($form_state->getError($element) === NULL) {
$form_state->setError($element, t('The %field date is invalid.', array('%field' => !empty($element['#title']) ? $element['#title'] : ''))); $form_state->setError($element, t('The %field date is invalid.', array('%field' => !empty($element['#title']) ? $element['#title'] : '')));
} }
} }

View file

@ -1,4 +1,5 @@
<?php <?php
// @codingStandardsIgnoreFile
namespace Drupal\Core\DependencyInjection; namespace Drupal\Core\DependencyInjection;

View file

@ -1,4 +1,5 @@
<?php <?php
// @codingStandardsIgnoreFile
namespace Drupal\Core\DependencyInjection; namespace Drupal\Core\DependencyInjection;

View file

@ -2,6 +2,7 @@
namespace Drupal\Core; namespace Drupal\Core;
use Drupal\Component\Assertion\Handle;
use Drupal\Component\FileCache\FileCacheFactory; use Drupal\Component\FileCache\FileCacheFactory;
use Drupal\Component\Utility\Unicode; use Drupal\Component\Utility\Unicode;
use Drupal\Component\Utility\UrlHelper; use Drupal\Component\Utility\UrlHelper;
@ -18,6 +19,7 @@ use Drupal\Core\Http\TrustedHostsRequestFactory;
use Drupal\Core\Language\Language; use Drupal\Core\Language\Language;
use Drupal\Core\Site\Settings; use Drupal\Core\Site\Settings;
use Symfony\Cmf\Component\Routing\RouteObjectInterface; use Symfony\Cmf\Component\Routing\RouteObjectInterface;
use Symfony\Component\ClassLoader\ApcClassLoader;
use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag; use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpFoundation\RedirectResponse;
@ -750,11 +752,20 @@ class DrupalKernel implements DrupalKernelInterface, TerminableInterface {
/** /**
* Returns the container cache key based on the environment. * Returns the container cache key based on the environment.
* *
* The 'environment' consists of:
* - The kernel environment string.
* - The Drupal version constant.
* - The deployment identifier from settings.php. This allows custom
* deployments to force a container rebuild.
* - The operating system running PHP. This allows compiler passes to optimize
* services for different operating systems.
* - The paths to any additional container YAMLs from settings.php.
*
* @return string * @return string
* The cache key used for the service container. * The cache key used for the service container.
*/ */
protected function getContainerCacheKey() { protected function getContainerCacheKey() {
$parts = array('service_container', $this->environment, \Drupal::VERSION, Settings::get('deployment_identifier'), serialize(Settings::get('container_yamls'))); $parts = array('service_container', $this->environment, \Drupal::VERSION, Settings::get('deployment_identifier'), PHP_OS, serialize(Settings::get('container_yamls')));
return implode(':', $parts); return implode(':', $parts);
} }
@ -914,11 +925,15 @@ class DrupalKernel implements DrupalKernelInterface, TerminableInterface {
assert_options(ASSERT_ACTIVE, TRUE); assert_options(ASSERT_ACTIVE, TRUE);
// Now synchronize PHP 5 and 7's handling of assertions as much as // Now synchronize PHP 5 and 7's handling of assertions as much as
// possible. // possible.
\Drupal\Component\Assertion\Handle::register(); Handle::register();
// Log fatal errors to the test site directory. // Log fatal errors to the test site directory.
ini_set('log_errors', 1); ini_set('log_errors', 1);
ini_set('error_log', DRUPAL_ROOT . '/sites/simpletest/' . substr($test_prefix, 10) . '/error.log'); ini_set('error_log', DRUPAL_ROOT . '/sites/simpletest/' . substr($test_prefix, 10) . '/error.log');
// Ensure that a rewritten settings.php is used if opcache is on.
ini_set('opcache.validate_timestamps', 'on');
ini_set('opcache.revalidate_freq', 0);
} }
else { else {
// Ensure that no other code defines this. // Ensure that no other code defines this.
@ -965,7 +980,7 @@ class DrupalKernel implements DrupalKernelInterface, TerminableInterface {
&& Settings::get('class_loader_auto_detect', TRUE) && Settings::get('class_loader_auto_detect', TRUE)
&& extension_loaded('apc')) { && extension_loaded('apc')) {
$prefix = Settings::getApcuPrefix('class_loader', $this->root); $prefix = Settings::getApcuPrefix('class_loader', $this->root);
$apc_loader = new \Symfony\Component\ClassLoader\ApcClassLoader($prefix, $this->classLoader); $apc_loader = new ApcClassLoader($prefix, $this->classLoader);
$this->classLoader->unregister(); $this->classLoader->unregister();
$apc_loader->register(); $apc_loader->register();
$this->classLoader = $apc_loader; $this->classLoader = $apc_loader;
@ -1204,7 +1219,7 @@ class DrupalKernel implements DrupalKernelInterface, TerminableInterface {
foreach ($this->serviceProviderClasses as $origin => $classes) { foreach ($this->serviceProviderClasses as $origin => $classes) {
foreach ($classes as $name => $class) { foreach ($classes as $name => $class) {
if (!is_object($class)) { if (!is_object($class)) {
$this->serviceProviders[$origin][$name] = new $class; $this->serviceProviders[$origin][$name] = new $class();
} }
else { else {
$this->serviceProviders[$origin][$name] = $class; $this->serviceProviders[$origin][$name] = $class;

View file

@ -23,4 +23,3 @@ class EntityListController extends ControllerBase {
} }
} }

View file

@ -55,7 +55,7 @@ interface EntityFormDisplayInterface extends EntityDisplayInterface {
* // For 'single-value' widgets: * // For 'single-value' widgets:
* '#theme' => 'field_multiple_value_form', * '#theme' => 'field_multiple_value_form',
* '#cardinality' => The field cardinality, * '#cardinality' => The field cardinality,
* '#cardinality_multiple => TRUE if the field can contain multiple * '#cardinality_multiple' => TRUE if the field can contain multiple
* items, FALSE otherwise. * items, FALSE otherwise.
* // One sub-array per copy of the widget, keyed by delta. * // One sub-array per copy of the widget, keyed by delta.
* 0 => array( * 0 => array(

View file

@ -121,7 +121,7 @@ class EntityManager implements EntityManagerInterface, ContainerAwareInterface {
* *
* @deprecated in Drupal 8.0.0, will be removed before Drupal 9.0.0. * @deprecated in Drupal 8.0.0, will be removed before Drupal 9.0.0.
*/ */
public function createHandlerInstance($class, EntityTypeInterface $definition = null) { public function createHandlerInstance($class, EntityTypeInterface $definition = NULL) {
return $this->container->get('entity_type.manager')->createHandlerInstance($class, $definition); return $this->container->get('entity_type.manager')->createHandlerInstance($class, $definition);
} }

View file

@ -81,9 +81,20 @@ class Tables implements TablesInterface {
$field_storage_definitions = $this->entityManager->getFieldStorageDefinitions($entity_type_id); $field_storage_definitions = $this->entityManager->getFieldStorageDefinitions($entity_type_id);
for ($key = 0; $key <= $count; $key++) { for ($key = 0; $key <= $count; $key++) {
// If there is revision support and only the current revision is being // This can either be the name of an entity base field or a configurable
// queried then use the revision id. Otherwise, the entity id will do. // field.
if (($revision_key = $entity_type->getKey('revision')) && $all_revisions) { $specifier = $specifiers[$key];
if (isset($field_storage_definitions[$specifier])) {
$field_storage = $field_storage_definitions[$specifier];
}
else {
$field_storage = FALSE;
}
// If there is revision support, only the current revisions are being
// queried, and the field is revisionable then use the revision id.
// Otherwise, the entity id will do.
if (($revision_key = $entity_type->getKey('revision')) && $all_revisions && $field_storage && $field_storage->isRevisionable()) {
// This contains the relevant SQL field to be used when joining entity // This contains the relevant SQL field to be used when joining entity
// tables. // tables.
$entity_id_field = $revision_key; $entity_id_field = $revision_key;
@ -95,15 +106,6 @@ class Tables implements TablesInterface {
$entity_id_field = $entity_type->getKey('id'); $entity_id_field = $entity_type->getKey('id');
$field_id_field = 'entity_id'; $field_id_field = 'entity_id';
} }
// This can either be the name of an entity base field or a configurable
// field.
$specifier = $specifiers[$key];
if (isset($field_storage_definitions[$specifier])) {
$field_storage = $field_storage_definitions[$specifier];
}
else {
$field_storage = FALSE;
}
/** @var \Drupal\Core\Entity\Sql\DefaultTableMapping $table_mapping */ /** @var \Drupal\Core\Entity\Sql\DefaultTableMapping $table_mapping */
$table_mapping = $this->entityManager->getStorage($entity_type_id)->getTableMapping(); $table_mapping = $this->entityManager->getStorage($entity_type_id)->getTableMapping();
@ -152,11 +154,18 @@ class Tables implements TablesInterface {
// finds the property first. The data table is preferred, which is why // finds the property first. The data table is preferred, which is why
// it gets added before the base table. // it gets added before the base table.
$entity_tables = array(); $entity_tables = array();
if ($data_table = $all_revisions ? $entity_type->getRevisionDataTable() : $entity_type->getDataTable()) { if ($all_revisions && $field_storage && $field_storage->isRevisionable()) {
$data_table = $entity_type->getRevisionDataTable();
$entity_base_table = $entity_type->getRevisionTable();
}
else {
$data_table = $entity_type->getDataTable();
$entity_base_table = $entity_type->getBaseTable();
}
if ($data_table) {
$this->sqlQuery->addMetaData('simple_query', FALSE); $this->sqlQuery->addMetaData('simple_query', FALSE);
$entity_tables[$data_table] = $this->getTableMapping($data_table, $entity_type_id); $entity_tables[$data_table] = $this->getTableMapping($data_table, $entity_type_id);
} }
$entity_base_table = $all_revisions ? $entity_type->getRevisionTable() : $entity_type->getBaseTable();
$entity_tables[$entity_base_table] = $this->getTableMapping($entity_base_table, $entity_type_id); $entity_tables[$entity_base_table] = $this->getTableMapping($entity_base_table, $entity_type_id);
$sql_column = $specifier; $sql_column = $specifier;

View file

@ -1263,7 +1263,9 @@ function hook_entity_query_alter(\Drupal\Core\Entity\Query\QueryInterface $query
* Act on entities being assembled before rendering. * Act on entities being assembled before rendering.
* *
* @param &$build * @param &$build
* A renderable array representing the entity content. * A renderable array representing the entity content. The module may add
* elements to $build prior to rendering. The structure of $build is a
* renderable array as expected by drupal_render().
* @param \Drupal\Core\Entity\EntityInterface $entity * @param \Drupal\Core\Entity\EntityInterface $entity
* The entity object. * The entity object.
* @param \Drupal\Core\Entity\Display\EntityViewDisplayInterface $display * @param \Drupal\Core\Entity\Display\EntityViewDisplayInterface $display
@ -1272,10 +1274,6 @@ function hook_entity_query_alter(\Drupal\Core\Entity\Query\QueryInterface $query
* @param $view_mode * @param $view_mode
* The view mode the entity is rendered in. * The view mode the entity is rendered in.
* *
* The module may add elements to $build prior to rendering. The
* structure of $build is a renderable array as expected by
* drupal_render().
*
* @see hook_entity_view_alter() * @see hook_entity_view_alter()
* @see hook_ENTITY_TYPE_view() * @see hook_ENTITY_TYPE_view()
* *
@ -1297,7 +1295,9 @@ function hook_entity_view(array &$build, \Drupal\Core\Entity\EntityInterface $en
* Act on entities of a particular type being assembled before rendering. * Act on entities of a particular type being assembled before rendering.
* *
* @param &$build * @param &$build
* A renderable array representing the entity content. * A renderable array representing the entity content. The module may add
* elements to $build prior to rendering. The structure of $build is a
* renderable array as expected by drupal_render().
* @param \Drupal\Core\Entity\EntityInterface $entity * @param \Drupal\Core\Entity\EntityInterface $entity
* The entity object. * The entity object.
* @param \Drupal\Core\Entity\Display\EntityViewDisplayInterface $display * @param \Drupal\Core\Entity\Display\EntityViewDisplayInterface $display
@ -1306,10 +1306,6 @@ function hook_entity_view(array &$build, \Drupal\Core\Entity\EntityInterface $en
* @param $view_mode * @param $view_mode
* The view mode the entity is rendered in. * The view mode the entity is rendered in.
* *
* The module may add elements to $build prior to rendering. The
* structure of $build is a renderable array as expected by
* drupal_render().
*
* @see hook_ENTITY_TYPE_view_alter() * @see hook_ENTITY_TYPE_view_alter()
* @see hook_entity_view() * @see hook_entity_view()
* *

View file

@ -68,4 +68,3 @@ class EntityRouteProviderSubscriber implements EventSubscriberInterface {
} }
} }

View file

@ -84,4 +84,3 @@ abstract class ExecutablePluginBase extends ContextAwarePluginBase implements Ex
return $this; return $this;
} }
} }

View file

@ -60,4 +60,3 @@ interface InfoParserInterface {
public function parse($filename); public function parse($filename);
} }

View file

@ -82,4 +82,3 @@ interface ModuleInstallerInterface {
public function validateUninstall(array $module_list); public function validateUninstall(array $module_list);
} }

View file

@ -894,6 +894,9 @@ function hook_updater_info_alter(&$updaters) {
* Module dependencies do not belong to these installation requirements, * Module dependencies do not belong to these installation requirements,
* but should be defined in the module's .info.yml file. * but should be defined in the module's .info.yml file.
* *
* During installation (when $phase == 'install'), if you need to load a class
* from your module, you'll need to include the class file directly.
*
* The 'runtime' phase is not limited to pure installation requirements * The 'runtime' phase is not limited to pure installation requirements
* but can also be used for more general status information like maintenance * but can also be used for more general status information like maintenance
* tasks and security issues. * tasks and security issues.

View file

@ -25,6 +25,13 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
*/ */
class EntityReferenceEntityFormatter extends EntityReferenceFormatterBase implements ContainerFactoryPluginInterface { class EntityReferenceEntityFormatter extends EntityReferenceFormatterBase implements ContainerFactoryPluginInterface {
/**
* The number of times this formatter allows rendering the same entity.
*
* @var int
*/
const RECURSIVE_RENDER_LIMIT = 20;
/** /**
* The logger factory. * The logger factory.
* *
@ -47,7 +54,19 @@ class EntityReferenceEntityFormatter extends EntityReferenceFormatterBase implem
protected $entityDisplayRepository; protected $entityDisplayRepository;
/** /**
* Constructs a StringFormatter instance. * An array of counters for the recursive rendering protection.
*
* Each counter takes into account all the relevant information about the
* field and the referenced entity that is being rendered.
*
* @see \Drupal\Core\Field\Plugin\Field\FieldFormatter\EntityReferenceEntityFormatter::viewElements()
*
* @var array
*/
protected static $recursiveRenderDepth = [];
/**
* Constructs a EntityReferenceEntityFormatter instance.
* *
* @param string $plugin_id * @param string $plugin_id
* The plugin_id for the formatter. * The plugin_id for the formatter.
@ -141,15 +160,35 @@ class EntityReferenceEntityFormatter extends EntityReferenceFormatterBase implem
$elements = array(); $elements = array();
foreach ($this->getEntitiesToView($items, $langcode) as $delta => $entity) { foreach ($this->getEntitiesToView($items, $langcode) as $delta => $entity) {
if ($entity->id()) {
// Due to render caching and delayed calls, the viewElements() method
// will be called later in the rendering process through a '#pre_render'
// callback, so we need to generate a counter that takes into account
// all the relevant information about this field and the referenced
// entity that is being rendered.
$recursive_render_id = $items->getFieldDefinition()->getTargetEntityTypeId()
. $items->getFieldDefinition()->getTargetBundle()
. $items->getName()
. $entity->id();
if (isset(static::$recursiveRenderDepth[$recursive_render_id])) {
static::$recursiveRenderDepth[$recursive_render_id]++;
}
else {
static::$recursiveRenderDepth[$recursive_render_id] = 1;
}
// Protect ourselves from recursive rendering. // Protect ourselves from recursive rendering.
static $depth = 0; if (static::$recursiveRenderDepth[$recursive_render_id] > static::RECURSIVE_RENDER_LIMIT) {
$depth++; $this->loggerFactory->get('entity')->error('Recursive rendering detected when rendering entity %entity_type: %entity_id, using the %field_name field on the %bundle_name bundle. Aborting rendering.', [
if ($depth > 20) { '%entity_type' => $entity->getEntityTypeId(),
$this->loggerFactory->get('entity')->error('Recursive rendering detected when rendering entity @entity_type @entity_id. Aborting rendering.', array('@entity_type' => $entity->getEntityTypeId(), '@entity_id' => $entity->id())); '%entity_id' => $entity->id(),
'%field_name' => $items->getName(),
'%bundle_name' => $items->getFieldDefinition()->getTargetBundle(),
]);
return $elements; return $elements;
} }
if ($entity->id()) {
$view_builder = $this->entityTypeManager->getViewBuilder($entity->getEntityTypeId()); $view_builder = $this->entityTypeManager->getViewBuilder($entity->getEntityTypeId());
$elements[$delta] = $view_builder->view($entity, $view_mode, $entity->language()->getId()); $elements[$delta] = $view_builder->view($entity, $view_mode, $entity->language()->getId());
@ -164,7 +203,6 @@ class EntityReferenceEntityFormatter extends EntityReferenceFormatterBase implem
// This is an "auto_create" item. // This is an "auto_create" item.
$elements[$delta] = array('#markup' => $entity->label()); $elements[$delta] = array('#markup' => $entity->label());
} }
$depth = 0;
} }
return $elements; return $elements;

View file

@ -120,4 +120,3 @@ class BooleanItem extends FieldItemBase implements OptionsProviderInterface {
return $values; return $values;
} }
} }

View file

@ -56,8 +56,8 @@ class TrustedHostsRequestFactory {
* *
* @return \Symfony\Component\HttpFoundation\Request * @return \Symfony\Component\HttpFoundation\Request
* A new request object. * A new request object.
**/ */
public function createRequest(array $query = array(), array $request = array(), array $attributes = array(), array $cookies = array(), array $files = array(), array $server = array(), $content = null) { public function createRequest(array $query = array(), array $request = array(), array $attributes = array(), array $cookies = array(), array $files = array(), array $server = array(), $content = NULL) {
if (empty($server['HTTP_HOST']) || ($server['HTTP_HOST'] === 'localhost' && $this->host !== 'localhost')) { if (empty($server['HTTP_HOST']) || ($server['HTTP_HOST'] === 'localhost' && $this->host !== 'localhost')) {
$server['HTTP_HOST'] = $this->host; $server['HTTP_HOST'] = $this->host;
} }

View file

@ -33,4 +33,17 @@ class InstallerKernel extends DrupalKernel {
$this->configStorage = NULL; $this->configStorage = NULL;
} }
/**
* Returns the active configuration storage used during early install.
*
* This override changes the visibility so that the installer can access
* config storage before the container is properly built.
*
* @return \Drupal\Core\Config\StorageInterface
* The config storage.
*/
public function getConfigStorage() {
return parent::getConfigStorage();
}
} }

View file

@ -14,4 +14,3 @@ class KeyValueExpirableFactory extends KeyValueFactory implements KeyValueExpira
const DEFAULT_SETTING = 'keyvalue_expirable_default'; const DEFAULT_SETTING = 'keyvalue_expirable_default';
} }

View file

@ -75,4 +75,3 @@ class KeyValueFactory implements KeyValueFactoryInterface {
} }
} }

View file

@ -19,4 +19,3 @@ interface KeyValueFactoryInterface {
public function get($collection); public function get($collection);
} }

View file

@ -2,6 +2,8 @@
namespace Drupal\Core\PageCache; namespace Drupal\Core\PageCache;
use Drupal\Core\PageCache\RequestPolicy\CommandLineOrUnsafeMethod;
use Drupal\Core\PageCache\RequestPolicy\NoSessionOpen;
use Drupal\Core\Session\SessionConfigurationInterface; use Drupal\Core\Session\SessionConfigurationInterface;
/** /**
@ -20,8 +22,8 @@ class DefaultRequestPolicy extends ChainRequestPolicy {
* The session configuration. * The session configuration.
*/ */
public function __construct(SessionConfigurationInterface $session_configuration) { public function __construct(SessionConfigurationInterface $session_configuration) {
$this->addPolicy(new RequestPolicy\CommandLineOrUnsafeMethod()); $this->addPolicy(new CommandLineOrUnsafeMethod());
$this->addPolicy(new RequestPolicy\NoSessionOpen($session_configuration)); $this->addPolicy(new NoSessionOpen($session_configuration));
} }
} }

View file

@ -42,4 +42,3 @@ class DenyNoCacheRoutes implements ResponsePolicyInterface {
} }
} }

View file

@ -64,4 +64,3 @@ class QueueFactory implements ContainerAwareInterface {
return $this->queues[$name]; return $this->queues[$name];
} }
} }

View file

@ -17,7 +17,7 @@ use Drupal\Core\Render\Element;
* $form['actions'] = array('#type' => 'actions'); * $form['actions'] = array('#type' => 'actions');
* $form['actions']['submit'] = array( * $form['actions']['submit'] = array(
* '#type' => 'submit', * '#type' => 'submit',
* '#value' => t('Save'), * '#value' => $this->t('Save'),
* ); * );
* @endcode * @endcode
* *

View file

@ -72,9 +72,8 @@ class Button extends FormElement {
* *
* @param array $element * @param array $element
* An associative array containing the properties of the element. * An associative array containing the properties of the element.
* Properties used: #attributes, #button_type, #name, #value. * Properties used: #attributes, #button_type, #name, #value. The
* * #button_type property accepts any value, though core themes have CSS that
* The #button_type property accepts any value, though core themes have CSS that
* styles the following button_types appropriately: 'primary', 'danger'. * styles the following button_types appropriately: 'primary', 'danger'.
* *
* @return array * @return array

View file

@ -15,7 +15,7 @@ use Drupal\Core\Render\Element;
* @code * @code
* $form['copy'] = array( * $form['copy'] = array(
* '#type' => 'checkbox', * '#type' => 'checkbox',
* '#title' => t('Send me a copy'), * '#title' => $this->t('Send me a copy'),
* ); * );
* @endcode * @endcode
* *

View file

@ -17,8 +17,8 @@ use Drupal\Core\Form\FormStateInterface;
* @code * @code
* $form['high_school']['tests_taken'] = array( * $form['high_school']['tests_taken'] = array(
* '#type' => 'checkboxes', * '#type' => 'checkboxes',
* '#options' => array('SAT' => t('SAT'), 'ACT' => t('ACT'))), * '#options' => array('SAT' => $this->t('SAT'), 'ACT' => $this->t('ACT'))),
* '#title' => t('What standardized tests did you take?'), * '#title' => $this->t('What standardized tests did you take?'),
* ... * ...
* ); * );
* @endcode * @endcode

View file

@ -16,7 +16,7 @@ use Drupal\Component\Utility\Color as ColorUtility;
* @code * @code
* $form['color'] = array( * $form['color'] = array(
* '#type' => 'color', * '#type' => 'color',
* '#title' => 'Color', * '#title' => $this->t('Color'),
* '#default_value' => '#ffffff', * '#default_value' => '#ffffff',
* ); * );
* @endcode * @endcode

View file

@ -15,7 +15,7 @@ use Drupal\Core\Form\FormStateInterface;
* @code * @code
* $form['needs_accommodation'] = array( * $form['needs_accommodation'] = array(
* '#type' => 'checkbox', * '#type' => 'checkbox',
* '#title' => 'Need Special Accommodations?', * '#title' => $this->t('Need Special Accommodations?'),
* ); * );
* *
* $form['accommodation'] = array( * $form['accommodation'] = array(
@ -32,7 +32,7 @@ use Drupal\Core\Form\FormStateInterface;
* *
* $form['accommodation']['diet'] = array( * $form['accommodation']['diet'] = array(
* '#type' => 'textfield', * '#type' => 'textfield',
* '#title' => t('Dietary Restrictions'), * '#title' => $this->t('Dietary Restrictions'),
* ); * );
* @endcode * @endcode
* *

View file

@ -15,7 +15,7 @@ use Drupal\Core\Render\Element;
* @code * @code
* $form['expiration'] = array( * $form['expiration'] = array(
* '#type' => 'date', * '#type' => 'date',
* '#title' => t('Content expiration'), * '#title' => $this->t('Content expiration'),
* '#default_value' => array('year' => 2020, 'month' => 2, 'day' => 15,) * '#default_value' => array('year' => 2020, 'month' => 2, 'day' => 15,)
* ); * );
* @endcode * @endcode
@ -76,11 +76,9 @@ class Date extends FormElement {
* @param array $element * @param array $element
* An associative array containing the properties of the element. * An associative array containing the properties of the element.
* Properties used: #title, #value, #options, #description, #required, * Properties used: #title, #value, #options, #description, #required,
* #attributes, #id, #name, #type, #min, #max, #step, #value, #size. * #attributes, #id, #name, #type, #min, #max, #step, #value, #size. The
* * #name property will be sanitized before output. This is currently done by
* Note: The input "name" attribute needs to be sanitized before output, which * initializing Drupal\Core\Template\Attribute with all the attributes.
* is currently done by initializing Drupal\Core\Template\Attribute with
* all the attributes.
* *
* @return array * @return array
* The $element with prepared variables ready for #theme 'input__date'. * The $element with prepared variables ready for #theme 'input__date'.

View file

@ -20,12 +20,12 @@ use Drupal\Core\Render\Element;
* @code * @code
* $form['author'] = array( * $form['author'] = array(
* '#type' => 'details', * '#type' => 'details',
* '#title' => 'Author', * '#title' => $this->t('Author'),
* ); * );
* *
* $form['author']['name'] = array( * $form['author']['name'] = array(
* '#type' => 'textfield', * '#type' => 'textfield',
* '#title' => t('Name'), * '#title' => $this->t('Name'),
* ); * );
* @endcode * @endcode
* *

View file

@ -15,7 +15,7 @@ use Drupal\Core\Render\Element;
* @code * @code
* $form['email'] = array( * $form['email'] = array(
* '#type' => 'email', * '#type' => 'email',
* '#title' => t('Email'), * '#title' => $this->t('Email'),
* ); * );
* @end * @end
* *

View file

@ -9,12 +9,12 @@ namespace Drupal\Core\Render\Element;
* @code * @code
* $form['author'] = array( * $form['author'] = array(
* '#type' => 'fieldset', * '#type' => 'fieldset',
* '#title' => 'Author', * '#title' => $this->t('Author'),
* ); * );
* *
* $form['author']['name'] = array( * $form['author']['name'] = array(
* '#type' => 'textfield', * '#type' => 'textfield',
* '#title' => t('Name'), * '#title' => $this->t('Name'),
* ); * );
* @endcode * @endcode
* *

View file

@ -21,7 +21,7 @@ use Drupal\Component\Utility\Number as NumberUtility;
* @code * @code
* $form['quantity'] = array( * $form['quantity'] = array(
* '#type' => 'number', * '#type' => 'number',
* '#title' => t('Quantity'), * '#title' => $this->t('Quantity'),
* ); * );
* @endcode * @endcode
* *

View file

@ -12,7 +12,7 @@ use Drupal\Core\Render\Element;
* @code * @code
* $form['pass'] = array( * $form['pass'] = array(
* '#type' => 'password', * '#type' => 'password',
* '#title => t('Password'), * '#title' => $this->t('Password'),
* '#size' => 25, * '#size' => 25,
* ); * );
* @endcode * @endcode

View file

@ -14,7 +14,7 @@ use Drupal\Core\Form\FormStateInterface;
* @code * @code
* $form['pass'] = array( * $form['pass'] = array(
* '#type' => 'password_confirm', * '#type' => 'password_confirm',
* '#title' => t('Password'), * '#title' => $this->t('Password'),
* '#size' => 25, * '#size' => 25,
* ); * );
* @endcode * @endcode

View file

@ -43,11 +43,9 @@ class Radio extends FormElement {
* @param array $element * @param array $element
* An associative array containing the properties of the element. * An associative array containing the properties of the element.
* Properties used: #required, #return_value, #value, #attributes, #title, * Properties used: #required, #return_value, #value, #attributes, #title,
* #description. * #description. The #name property will be sanitized before output. This is
* * currently done by initializing Drupal\Core\Template\Attribute with all
* Note: The input "name" attribute needs to be sanitized before output, which * the attributes.
* is currently done by initializing Drupal\Core\Template\Attribute with
* all the attributes.
* *
* @return array * @return array
* The $element with prepared variables ready for input.html.twig. * The $element with prepared variables ready for input.html.twig.

View file

@ -16,9 +16,9 @@ use Drupal\Component\Utility\Html as HtmlUtility;
* @code * @code
* $form['settings']['active'] = array( * $form['settings']['active'] = array(
* '#type' => 'radios', * '#type' => 'radios',
* '#title' => t('Poll status'), * '#title' => $this->t('Poll status'),
* '#default_value' => 1, * '#default_value' => 1,
* '#options' => array(0 => t('Closed'), 1 => t('Active')), * '#options' => array(0 => $this->t('Closed'), 1 => $this->t('Active')),
* ); * );
* @endcode * @endcode
* *

View file

@ -19,7 +19,7 @@ use Drupal\Core\Render\Element;
* @code * @code
* $form['quantity'] = array( * $form['quantity'] = array(
* '#type' => 'number', * '#type' => 'number',
* '#title' => t('Quantity'), * '#title' => $this->t('Quantity'),
* ); * );
* @endcode * @endcode
* *

View file

@ -11,7 +11,7 @@ use Drupal\Core\Render\Element;
* @code * @code
* $form['search'] = array( * $form['search'] = array(
* '#type' => 'search', * '#type' => 'search',
* '#title' => t('Search'), * '#title' => $this->t('Search'),
* ); * );
* @endcode * @endcode
* *

View file

@ -21,14 +21,14 @@ use Drupal\Core\Render\Element;
* @code * @code
* $form['example_select'] = [ * $form['example_select'] = [
* '#type' => 'select', * '#type' => 'select',
* '#title' => t('Select element'), * '#title' => $this->t('Select element'),
* '#options' => [ * '#options' => [
* '1' => t('One'), * '1' => $this->t('One'),
* '2' => [ * '2' => [
* '2.1' => t('Two point one'), * '2.1' => $this->t('Two point one'),
* '2.2' => t('Two point two'), * '2.2' => $this->t('Two point two'),
* ], * ],
* '3' => t('Three'), * '3' => $this->t('Three'),
* ], * ],
* ]; * ];
* @endcode * @endcode

View file

@ -29,20 +29,20 @@ use Drupal\Component\Utility\Html as HtmlUtility;
* @code * @code
* $form['contacts'] = array( * $form['contacts'] = array(
* '#type' => 'table', * '#type' => 'table',
* '#caption' => 'Sample Table', * '#caption' => $this->t('Sample Table'),
* '#header' => array('Name', 'Phone'), * '#header' => array($this->t('Name'), $this->t('Phone')),
* ); * );
* *
* for ($i=1; $i<=4; $i++) { * for ($i=1; $i<=4; $i++) {
* $form['contacts'][$i]['name'] = array( * $form['contacts'][$i]['name'] = array(
* '#type' => 'textfield', * '#type' => 'textfield',
* '#title' => t('Name'), * '#title' => $this->t('Name'),
* '#title_display' => 'invisible', * '#title_display' => 'invisible',
* ); * );
* *
* $form['contacts'][$i]['phone'] = array( * $form['contacts'][$i]['phone'] = array(
* '#type' => 'tel', * '#type' => 'tel',
* '#title' => t('Phone'), * '#title' => $this->t('Phone'),
* '#title_display' => 'invisible', * '#title_display' => 'invisible',
* ); * );
* } * }
@ -279,7 +279,7 @@ class Table extends FormElement {
* @code * @code
* $form['table'] = array( * $form['table'] = array(
* '#type' => 'table', * '#type' => 'table',
* '#header' => array(t('Title'), array('data' => t('Operations'), 'colspan' => '1')), * '#header' => array($this->t('Title'), array('data' => $this->t('Operations'), 'colspan' => '1')),
* // Optionally, to add tableDrag support: * // Optionally, to add tableDrag support:
* '#tabledrag' => array( * '#tabledrag' => array(
* array( * array(
@ -301,7 +301,7 @@ class Table extends FormElement {
* $form['table'][$row]['#attributes']['class'][] = 'draggable'; * $form['table'][$row]['#attributes']['class'][] = 'draggable';
* $form['table'][$row]['weight'] = array( * $form['table'][$row]['weight'] = array(
* '#type' => 'textfield', * '#type' => 'textfield',
* '#title' => t('Weight for @title', array('@title' => $thing['title'])), * '#title' => $this->t('Weight for @title', array('@title' => $thing['title'])),
* '#title_display' => 'invisible', * '#title_display' => 'invisible',
* '#size' => 4, * '#size' => 4,
* '#default_value' => $thing['weight'], * '#default_value' => $thing['weight'],
@ -312,7 +312,7 @@ class Table extends FormElement {
* // attribute in #header above. * // attribute in #header above.
* $form['table'][$row]['edit'] = array( * $form['table'][$row]['edit'] = array(
* '#type' => 'link', * '#type' => 'link',
* '#title' => t('Edit'), * '#title' => $this->t('Edit'),
* '#url' => Url::fromRoute('entity.test_entity.edit_form', ['test_entity' => $row]), * '#url' => Url::fromRoute('entity.test_entity.edit_form', ['test_entity' => $row]),
* ); * );
* } * }

View file

@ -26,8 +26,8 @@ use Drupal\Core\StringTranslation\TranslatableMarkup;
* Usage example: * Usage example:
* @code * @code
* $header = [ * $header = [
* 'first_name' => t('First Name'), * 'first_name' => $this->t('First Name'),
* 'last_name' => t('Last Name'), * 'last_name' => $this->t('Last Name'),
* ]; * ];
* *
* $options = [ * $options = [
@ -40,7 +40,7 @@ use Drupal\Core\StringTranslation\TranslatableMarkup;
* '#type' => 'tableselect', * '#type' => 'tableselect',
* '#header' => $header, * '#header' => $header,
* '#options' => $options, * '#options' => $options,
* '#empty' => t('No users found'), * '#empty' => $this->t('No users found'),
* ); * );
* @endcode * @endcode
* *
@ -118,28 +118,28 @@ class Tableselect extends Table {
* @code * @code
* $options = array( * $options = array(
* array( * array(
* 'title' => 'How to Learn Drupal', * 'title' => $this->t('How to Learn Drupal'),
* 'content_type' => 'Article', * 'content_type' => $this->t('Article'),
* 'status' => 'published', * 'status' => 'published',
* '#attributes' => array('class' => array('article-row')), * '#attributes' => array('class' => array('article-row')),
* ), * ),
* array( * array(
* 'title' => 'Privacy Policy', * 'title' => $this->t('Privacy Policy'),
* 'content_type' => 'Page', * 'content_type' => $this->t('Page'),
* 'status' => 'published', * 'status' => 'published',
* '#attributes' => array('class' => array('page-row')), * '#attributes' => array('class' => array('page-row')),
* ), * ),
* ); * );
* $header = array( * $header = array(
* 'title' => t('Title'), * 'title' => $this->t('Title'),
* 'content_type' => t('Content type'), * 'content_type' => $this->t('Content type'),
* 'status' => t('Status'), * 'status' => $this->t('Status'),
* ); * );
* $form['table'] = array( * $form['table'] = array(
* '#type' => 'tableselect', * '#type' => 'tableselect',
* '#header' => $header, * '#header' => $header,
* '#options' => $options, * '#options' => $options,
* '#empty' => t('No content available.'), * '#empty' => $this->t('No content available.'),
* ); * );
* @endcode * @endcode
* *

View file

@ -14,7 +14,7 @@ use Drupal\Core\Render\Element;
* @code * @code
* $form['phone'] = array( * $form['phone'] = array(
* '#type' => 'tel', * '#type' => 'tel',
* '#title' => t('Phone'), * '#title' => $this->t('Phone'),
* ); * );
* @endcode * @endcode
* *

View file

@ -17,7 +17,7 @@ use Drupal\Core\Form\FormStateInterface;
* @code * @code
* $form['text'] = array( * $form['text'] = array(
* '#type' => 'textarea', * '#type' => 'textarea',
* '#title' => t('Text'), * '#title' => $this->t('Text'),
* ); * );
* @endcode * @endcode
* *

View file

@ -20,7 +20,7 @@ use Drupal\Core\Render\Element;
* @code * @code
* $form['title'] = array( * $form['title'] = array(
* '#type' => 'textfield', * '#type' => 'textfield',
* '#title' => t('Subject'), * '#title' => $this->t('Subject'),
* '#default_value' => $node->title, * '#default_value' => $node->title,
* '#size' => 60, * '#size' => 60,
* '#maxlength' => 128, * '#maxlength' => 128,

View file

@ -16,7 +16,7 @@ use Drupal\Core\Render\Element;
* @code * @code
* $form['homepage'] = array( * $form['homepage'] = array(
* '#type' => 'url', * '#type' => 'url',
* '#title' => t('Home Page'), * '#title' => $this->t('Home Page'),
* '#size' => 30, * '#size' => 30,
* ... * ...
* ); * );

View file

@ -24,24 +24,24 @@ use Drupal\Core\Render\Element;
* *
* $form['author'] = array( * $form['author'] = array(
* '#type' => 'details', * '#type' => 'details',
* '#title' => 'Author', * '#title' => $this->t('Author'),
* '#group' => 'information', * '#group' => 'information',
* ); * );
* *
* $form['author']['name'] = array( * $form['author']['name'] = array(
* '#type' => 'textfield', * '#type' => 'textfield',
* '#title' => t('Name'), * '#title' => $this->t('Name'),
* ); * );
* *
* $form['publication'] = array( * $form['publication'] = array(
* '#type' => 'details', * '#type' => 'details',
* '#title' => t('Publication'), * '#title' => $this->t('Publication'),
* '#group' => 'information', * '#group' => 'information',
* ); * );
* *
* $form['publication']['publisher'] = array( * $form['publication']['publisher'] = array(
* '#type' => 'textfield', * '#type' => 'textfield',
* '#title' => t('Publisher'), * '#title' => $this->t('Publisher'),
* ); * );
* @endcode * @endcode
* *

View file

@ -18,7 +18,7 @@ use Drupal\Core\Form\FormStateInterface;
* @code * @code
* $form['weight'] = array( * $form['weight'] = array(
* '#type' => 'weight', * '#type' => 'weight',
* '#title' => t('Weight'), * '#title' => $this->t('Weight'),
* '#default_value' => $edit['weight'], * '#default_value' => $edit['weight'],
* '#delta' => 10, * '#delta' => 10,
* ); * );

View file

@ -92,6 +92,11 @@ class PlaceholderingRenderCache extends RenderCache {
* {@inheritdoc} * {@inheritdoc}
*/ */
public function get(array $elements) { public function get(array $elements) {
// @todo remove this check when https://www.drupal.org/node/2367555 lands.
if (!$this->requestStack->getCurrentRequest()->isMethodSafe()) {
return FALSE;
}
// When rendering placeholders, special case auto-placeholdered elements: // When rendering placeholders, special case auto-placeholdered elements:
// avoid retrieving them from cache again, or rendering them again. // avoid retrieving them from cache again, or rendering them again.
if (isset($elements['#create_placeholder']) && $elements['#create_placeholder'] === FALSE) { if (isset($elements['#create_placeholder']) && $elements['#create_placeholder'] === FALSE) {
@ -121,6 +126,11 @@ class PlaceholderingRenderCache extends RenderCache {
public function set(array &$elements, array $pre_bubbling_elements) { public function set(array &$elements, array $pre_bubbling_elements) {
$result = parent::set($elements, $pre_bubbling_elements); $result = parent::set($elements, $pre_bubbling_elements);
// @todo remove this check when https://www.drupal.org/node/2367555 lands.
if (!$this->requestStack->getCurrentRequest()->isMethodSafe()) {
return FALSE;
}
if ($this->placeholderGenerator->canCreatePlaceholder($pre_bubbling_elements) && $this->placeholderGenerator->shouldAutomaticallyPlaceholder($elements)) { if ($this->placeholderGenerator->canCreatePlaceholder($pre_bubbling_elements) && $this->placeholderGenerator->shouldAutomaticallyPlaceholder($elements)) {
// Overwrite $elements with a placeholder. The Renderer (which called this // Overwrite $elements with a placeholder. The Renderer (which called this
// method) will update the context with the bubbleable metadata of the // method) will update the context with the bubbleable metadata of the

View file

@ -338,7 +338,9 @@ class Renderer implements RendererInterface {
// If instructed to create a placeholder, and a #lazy_builder callback is // If instructed to create a placeholder, and a #lazy_builder callback is
// present (without such a callback, it would be impossible to replace the // present (without such a callback, it would be impossible to replace the
// placeholder), replace the current element with a placeholder. // placeholder), replace the current element with a placeholder.
if (isset($elements['#create_placeholder']) && $elements['#create_placeholder'] === TRUE) { // @todo remove the isMethodSafe() check when
// https://www.drupal.org/node/2367555 lands.
if (isset($elements['#create_placeholder']) && $elements['#create_placeholder'] === TRUE && $this->requestStack->getCurrentRequest()->isMethodSafe()) {
if (!isset($elements['#lazy_builder'])) { if (!isset($elements['#lazy_builder'])) {
throw new \LogicException('When #create_placeholder is set, a #lazy_builder callback must be present as well.'); throw new \LogicException('When #create_placeholder is set, a #lazy_builder callback must be present as well.');
} }

View file

@ -134,4 +134,3 @@ class AccessAwareRouter implements AccessAwareRouterInterface {
} }
} }

View file

@ -61,7 +61,7 @@ class CompiledRoute extends SymfonyCompiledRoute {
* @param array $variables * @param array $variables
* An array of variables (variables defined in the path and in the host patterns) * An array of variables (variables defined in the path and in the host patterns)
*/ */
public function __construct($fit, $pattern_outline, $num_parts, $staticPrefix, $regex, array $tokens, array $pathVariables, $hostRegex = null, array $hostTokens = array(), array $hostVariables = array(), array $variables = array()) { public function __construct($fit, $pattern_outline, $num_parts, $staticPrefix, $regex, array $tokens, array $pathVariables, $hostRegex = NULL, array $hostTokens = array(), array $hostVariables = array(), array $variables = array()) {
parent::__construct($staticPrefix, $regex, $tokens, $pathVariables, $hostRegex, $hostTokens, $hostVariables, $variables); parent::__construct($staticPrefix, $regex, $tokens, $pathVariables, $hostRegex, $hostTokens, $hostVariables, $variables);
$this->fit = $fit; $this->fit = $fit;

View file

@ -207,14 +207,14 @@ class RouteProvider implements PreloadableRouteProviderInterface, PagedRouteProv
else { else {
try { try {
$result = $this->connection->query('SELECT name, route FROM {' . $this->connection->escapeTable($this->tableName) . '} WHERE name IN ( :names[] )', array(':names[]' => $routes_to_load)); $result = $this->connection->query('SELECT name, route FROM {' . $this->connection->escapeTable($this->tableName) . '} WHERE name IN ( :names[] )', array(':names[]' => $routes_to_load));
}
catch (\Exception $e) {
$result = [];
}
$routes = $result->fetchAllKeyed(); $routes = $result->fetchAllKeyed();
$this->cache->set($cid, $routes, Cache::PERMANENT, ['routes']); $this->cache->set($cid, $routes, Cache::PERMANENT, ['routes']);
} }
catch (\Exception $e) {
$routes = [];
}
}
$this->serializedRoutes += $routes; $this->serializedRoutes += $routes;
} }

View file

@ -153,7 +153,6 @@ class UrlGenerator implements UrlGeneratorInterface {
* @param string $name * @param string $name
* The route name or other identifying string from ::getRouteDebugMessage(). * The route name or other identifying string from ::getRouteDebugMessage().
* *
*
* @return string * @return string
* The url path, without any base path, including possible query string. * The url path, without any base path, including possible query string.
* *

View file

@ -35,4 +35,3 @@ class SitePathFactory {
} }
} }

View file

@ -49,4 +49,3 @@ class KernelPreHandle implements HttpKernelInterface {
} }
} }

View file

@ -39,7 +39,7 @@ class NegotiationMiddleware implements HttpKernelInterface {
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function handle(Request $request, $type = self::MASTER_REQUEST, $catch = true) { public function handle(Request $request, $type = self::MASTER_REQUEST, $catch = TRUE) {
// Register available mime types. // Register available mime types.
foreach ($this->formats as $format => $mime_type) { foreach ($this->formats as $format => $mime_type) {
$request->setFormat($format, $mime_type); $request->setFormat($format, $mime_type);

View file

@ -52,7 +52,7 @@ class StringLoader implements \Twig_LoaderInterface, \Twig_ExistsLoaderInterface
* {@inheritdoc} * {@inheritdoc}
*/ */
public function isFresh($name, $time) { public function isFresh($name, $time) {
return true; return TRUE;
} }
} }

View file

@ -150,12 +150,12 @@ class TwigExtension extends \Twig_Extension {
new \Twig_SimpleFilter('placeholder', [$this, 'escapePlaceholder'], array('is_safe' => array('html'), 'needs_environment' => TRUE)), new \Twig_SimpleFilter('placeholder', [$this, 'escapePlaceholder'], array('is_safe' => array('html'), 'needs_environment' => TRUE)),
// Replace twig's escape filter with our own. // Replace twig's escape filter with our own.
new \Twig_SimpleFilter('drupal_escape', [$this, 'escapeFilter'], array('needs_environment' => true, 'is_safe_callback' => 'twig_escape_filter_is_safe')), new \Twig_SimpleFilter('drupal_escape', [$this, 'escapeFilter'], array('needs_environment' => TRUE, 'is_safe_callback' => 'twig_escape_filter_is_safe')),
// Implements safe joining. // Implements safe joining.
// @todo Make that the default for |join? Upstream issue: // @todo Make that the default for |join? Upstream issue:
// https://github.com/fabpot/Twig/issues/1420 // https://github.com/fabpot/Twig/issues/1420
new \Twig_SimpleFilter('safe_join', [$this, 'safeJoin'], ['needs_environment' => true, 'is_safe' => ['html']]), new \Twig_SimpleFilter('safe_join', [$this, 'safeJoin'], ['needs_environment' => TRUE, 'is_safe' => ['html']]),
// Array filters. // Array filters.
new \Twig_SimpleFilter('without', 'twig_without'), new \Twig_SimpleFilter('without', 'twig_without'),
@ -547,7 +547,7 @@ class TwigExtension extends \Twig_Extension {
*/ */
public function safeJoin(\Twig_Environment $env, $value, $glue = '') { public function safeJoin(\Twig_Environment $env, $value, $glue = '') {
if ($value instanceof \Traversable) { if ($value instanceof \Traversable) {
$value = iterator_to_array($value, false); $value = iterator_to_array($value, FALSE);
} }
return implode($glue, array_map(function($item) use ($env) { return implode($glue, array_map(function($item) use ($env) {

Some files were not shown because too many files have changed in this diff Show more