Update to Drupal 8.1.8. For more information, see https://www.drupal.org/project/drupal/releases/8.1.8
This commit is contained in:
parent
e9f047ccf8
commit
f9f23cdf38
312 changed files with 6751 additions and 1546 deletions
|
@ -95,7 +95,10 @@ abstract class ConfigFactoryOverrideBase implements EventSubscriberInterface {
|
|||
elseif (is_array($override_data[$key])) {
|
||||
if (is_array($original_data[$key])) {
|
||||
// Do the filtering one level deeper.
|
||||
$changed = $this->filterNestedArray($original_data[$key], $override_data[$key]);
|
||||
// Ensure that we track $changed along the way.
|
||||
if ($this->filterNestedArray($original_data[$key], $override_data[$key])) {
|
||||
$changed = TRUE;
|
||||
}
|
||||
// If no overrides are left under this level, remove the level.
|
||||
if (empty($override_data[$key])) {
|
||||
unset($override_data[$key]);
|
||||
|
|
|
@ -159,7 +159,8 @@ class Cron implements CronInterface {
|
|||
$queue_worker = $this->queueManager->createInstance($queue_name);
|
||||
$end = time() + (isset($info['cron']['time']) ? $info['cron']['time'] : 15);
|
||||
$queue = $this->queueFactory->get($queue_name);
|
||||
while (time() < $end && ($item = $queue->claimItem())) {
|
||||
$lease_time = isset($info['cron']['time']) ?: NULL;
|
||||
while (time() < $end && ($item = $queue->claimItem($lease_time))) {
|
||||
try {
|
||||
$queue_worker->processItem($item->data);
|
||||
$queue->deleteItem($item);
|
||||
|
|
|
@ -660,7 +660,7 @@ class Select extends Query implements SelectInterface {
|
|||
* {@inheritdoc}
|
||||
*/
|
||||
public function range($start = NULL, $length = NULL) {
|
||||
$this->range = func_num_args() ? array('start' => $start, 'length' => $length) : array();
|
||||
$this->range = $start !== NULL ? array('start' => $start, 'length' => $length) : array();
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
@ -860,6 +860,14 @@ class Select extends Query implements SelectInterface {
|
|||
$query .= "\nHAVING " . $this->having;
|
||||
}
|
||||
|
||||
// UNION is a little odd, as the select queries to combine are passed into
|
||||
// this query, but syntactically they all end up on the same level.
|
||||
if ($this->union) {
|
||||
foreach ($this->union as $union) {
|
||||
$query .= ' ' . $union['type'] . ' ' . (string) $union['query'];
|
||||
}
|
||||
}
|
||||
|
||||
// ORDER BY
|
||||
if ($this->order) {
|
||||
$query .= "\nORDER BY ";
|
||||
|
@ -879,14 +887,6 @@ class Select extends Query implements SelectInterface {
|
|||
$query .= "\nLIMIT " . (int) $this->range['length'] . " OFFSET " . (int) $this->range['start'];
|
||||
}
|
||||
|
||||
// UNION is a little odd, as the select queries to combine are passed into
|
||||
// this query, but syntactically they all end up on the same level.
|
||||
if ($this->union) {
|
||||
foreach ($this->union as $union) {
|
||||
$query .= ' ' . $union['type'] . ' ' . (string) $union['query'];
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->forUpdate) {
|
||||
$query .= ' FOR UPDATE';
|
||||
}
|
||||
|
|
|
@ -1032,6 +1032,11 @@ abstract class ContentEntityBase extends Entity implements \IteratorAggregate, C
|
|||
$this->clearTranslationCache();
|
||||
$translations = $this->translations;
|
||||
$this->translations = &$translations;
|
||||
|
||||
// Ensure the enforceIsNew property is actually cloned by overwriting the
|
||||
// original reference with one pointing to a copy of it.
|
||||
$enforce_is_new = $this->enforceIsNew;
|
||||
$this->enforceIsNew = &$enforce_is_new;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -222,7 +222,9 @@ abstract class Entity implements EntityInterface {
|
|||
->setOption('entity', $this);
|
||||
|
||||
// Display links by default based on the current language.
|
||||
if ($rel !== 'collection') {
|
||||
// Link relations that do not require an existing entity should not be
|
||||
// affected by this entity's language, however.
|
||||
if (!in_array($rel, ['collection', 'add-page', 'add-form'], TRUE)) {
|
||||
$options += ['language' => $this->language()];
|
||||
}
|
||||
|
||||
|
@ -302,10 +304,14 @@ abstract class Entity implements EntityInterface {
|
|||
protected function urlRouteParameters($rel) {
|
||||
$uri_route_parameters = [];
|
||||
|
||||
if ($rel != 'collection') {
|
||||
if (!in_array($rel, ['collection', 'add-page', 'add-form'], TRUE)) {
|
||||
// The entity ID is needed as a route parameter.
|
||||
$uri_route_parameters[$this->getEntityTypeId()] = $this->id();
|
||||
}
|
||||
if ($rel === 'add-form' && ($this->getEntityType()->hasKey('bundle'))) {
|
||||
$parameter_name = $this->getEntityType()->getBundleEntityType() ?: $this->getEntityType()->getKey('bundle');
|
||||
$uri_route_parameters[$parameter_name] = $this->bundle();
|
||||
}
|
||||
if ($rel === 'revision' && $this instanceof RevisionableInterface) {
|
||||
$uri_route_parameters[$this->getEntityTypeId() . '_revision'] = $this->getRevisionId();
|
||||
}
|
||||
|
|
|
@ -277,7 +277,7 @@ class EntityViewDisplay extends EntityDisplayBase implements EntityViewDisplayIn
|
|||
'view_mode' => $this->originalMode,
|
||||
'display' => $this,
|
||||
);
|
||||
\Drupal::moduleHandler()->alter('entity_display_build', $build_list[$key], $context);
|
||||
\Drupal::moduleHandler()->alter('entity_display_build', $build_list[$id], $context);
|
||||
}
|
||||
|
||||
return $build_list;
|
||||
|
|
|
@ -172,7 +172,7 @@ class EntityResolverManager {
|
|||
// First try to figure out whether there is already a parameter upcasting
|
||||
// the same entity type already.
|
||||
foreach ($parameter_definitions as $info) {
|
||||
if (isset($info['type'])) {
|
||||
if (isset($info['type']) && (strpos($info['type'], 'entity:') === 0)) {
|
||||
// The parameter types are in the form 'entity:$entity_type'.
|
||||
list(, $parameter_entity_type) = explode(':', $info['type'], 2);
|
||||
if ($parameter_entity_type == $entity_type) {
|
||||
|
|
|
@ -515,15 +515,29 @@ class SqlContentEntityStorage extends ContentEntityStorageBase implements SqlEnt
|
|||
// Find revisioned fields that are not entity keys. Exclude the langcode
|
||||
// key as the base table holds only the default language.
|
||||
$base_fields = array_diff($table_mapping->getFieldNames($this->baseTable), array($this->langcodeKey));
|
||||
$fields = array_diff($table_mapping->getFieldNames($this->revisionDataTable), $base_fields);
|
||||
$revisioned_fields = array_diff($table_mapping->getFieldNames($this->revisionDataTable), $base_fields);
|
||||
|
||||
// Find fields that are not revisioned or entity keys. Data fields have
|
||||
// the same value regardless of entity revision.
|
||||
$data_fields = array_diff($table_mapping->getFieldNames($this->dataTable), $fields, $base_fields);
|
||||
$data_fields = array_diff($table_mapping->getFieldNames($this->dataTable), $revisioned_fields, $base_fields);
|
||||
// If there are no data fields then only revisioned fields are needed
|
||||
// else both data fields and revisioned fields are needed to map the
|
||||
// entity values.
|
||||
$all_fields = $revisioned_fields;
|
||||
if ($data_fields) {
|
||||
$fields = array_merge($fields, $data_fields);
|
||||
$all_fields = array_merge($revisioned_fields, $data_fields);
|
||||
$query->leftJoin($this->dataTable, 'data', "(revision.$this->idKey = data.$this->idKey)");
|
||||
$query->fields('data', $data_fields);
|
||||
$column_names = [];
|
||||
// Some fields can have more then one columns in the data table so
|
||||
// column names are needed.
|
||||
foreach ($data_fields as $data_field) {
|
||||
// \Drupal\Core\Entity\Sql\TableMappingInterface:: getColumNames()
|
||||
// returns an array keyed by property names so remove the keys
|
||||
// before array_merge() to avoid losing data with fields having the
|
||||
// same columns i.e. value.
|
||||
$column_names = array_merge($column_names, array_values($table_mapping->getColumnNames($data_field)));
|
||||
}
|
||||
$query->fields('data', $column_names);
|
||||
}
|
||||
|
||||
// Get the revision IDs.
|
||||
|
@ -534,7 +548,7 @@ class SqlContentEntityStorage extends ContentEntityStorageBase implements SqlEnt
|
|||
$query->condition('revision.' . $this->revisionKey, $revision_ids, 'IN');
|
||||
}
|
||||
else {
|
||||
$fields = $table_mapping->getFieldNames($this->dataTable);
|
||||
$all_fields = $table_mapping->getFieldNames($this->dataTable);
|
||||
}
|
||||
|
||||
$result = $query->execute();
|
||||
|
@ -547,7 +561,7 @@ class SqlContentEntityStorage extends ContentEntityStorageBase implements SqlEnt
|
|||
|
||||
$translations[$id][$langcode] = TRUE;
|
||||
|
||||
foreach ($fields as $field_name) {
|
||||
foreach ($all_fields as $field_name) {
|
||||
$columns = $table_mapping->getColumnNames($field_name);
|
||||
// Do not key single-column fields by property name.
|
||||
if (count($columns) == 1) {
|
||||
|
|
|
@ -45,7 +45,11 @@ interface TableMappingInterface {
|
|||
public function getAllColumns($table_name);
|
||||
|
||||
/**
|
||||
* Gets a list of names of fields stored in the specified table.
|
||||
* Gets a list of names for entity fields stored in the specified table.
|
||||
*
|
||||
* The return list is contains the entity field names, not database field
|
||||
* (i.e. column) names. To get the mapping of specific entity field to
|
||||
* database columns use ::getColumnNames().
|
||||
*
|
||||
* @param string $table_name
|
||||
* The name of the table to return the field names for.
|
||||
|
|
|
@ -717,7 +717,7 @@ function hook_entity_view_mode_info_alter(&$view_modes) {
|
|||
* - translatable: (optional) A boolean value specifying whether this bundle
|
||||
* has translation support enabled. Defaults to FALSE.
|
||||
*
|
||||
* @see entity_get_bundles()
|
||||
* @see \Drupal\Core\Entity\EntityTypeBundleInfo::getBundleInfo()
|
||||
* @see hook_entity_bundle_info_alter()
|
||||
*/
|
||||
function hook_entity_bundle_info() {
|
||||
|
@ -731,7 +731,7 @@ function hook_entity_bundle_info() {
|
|||
* @param array $bundles
|
||||
* An array of bundles, keyed first by entity type, then by bundle name.
|
||||
*
|
||||
* @see entity_get_bundles()
|
||||
* @see Drupal\Core\Entity\EntityTypeBundleInfo::getBundleInfo()
|
||||
* @see hook_entity_bundle_info()
|
||||
*/
|
||||
function hook_entity_bundle_info_alter(&$bundles) {
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Core\EventSubscriber;
|
||||
|
||||
use Drupal\Component\Utility\Html;
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
|
||||
use Symfony\Component\HttpKernel\KernelEvents;
|
||||
|
||||
/**
|
||||
* Subscribes to filter RSS responses, to make relative URIs absolute.
|
||||
*/
|
||||
class RssResponseRelativeUrlFilter implements EventSubscriberInterface {
|
||||
|
||||
/**
|
||||
* Converts relative URLs to absolute URLs.
|
||||
*
|
||||
* @param \Symfony\Component\HttpKernel\Event\FilterResponseEvent $event
|
||||
* The response event.
|
||||
*/
|
||||
public function onResponse(FilterResponseEvent $event) {
|
||||
// Only care about RSS responses.
|
||||
if (stripos($event->getResponse()->headers->get('Content-Type'), 'application/rss+xml') === FALSE) {
|
||||
return;
|
||||
}
|
||||
|
||||
$response = $event->getResponse();
|
||||
$response->setContent($this->transformRootRelativeUrlsToAbsolute($response->getContent(), $event->getRequest()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts all root-relative URLs to absolute URLs in RSS markup.
|
||||
*
|
||||
* Does not change any existing protocol-relative or absolute URLs.
|
||||
*
|
||||
* @param string $rss_markup
|
||||
* The RSS markup to update.
|
||||
* @param \Symfony\Component\HttpFoundation\Request $request
|
||||
* The current request.
|
||||
*
|
||||
* @return string
|
||||
* The updated RSS markup.
|
||||
*/
|
||||
protected function transformRootRelativeUrlsToAbsolute($rss_markup, Request $request) {
|
||||
$rss_dom = new \DOMDocument();
|
||||
$rss_dom->loadXML($rss_markup);
|
||||
|
||||
// Invoke Html::transformRootRelativeUrlsToAbsolute() on all HTML content
|
||||
// embedded in this RSS feed.
|
||||
foreach ($rss_dom->getElementsByTagName('description') as $node) {
|
||||
$html_markup = $node->nodeValue;
|
||||
if (!empty($html_markup)) {
|
||||
$node->nodeValue = Html::transformRootRelativeUrlsToAbsolute($html_markup, $request->getSchemeAndHttpHost());
|
||||
}
|
||||
}
|
||||
|
||||
return $rss_dom->saveXML();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function getSubscribedEvents() {
|
||||
// Should run after any other response subscriber that modifies the markup.
|
||||
// @see \Drupal\Core\EventSubscriber\ActiveLinkResponseFilter
|
||||
$events[KernelEvents::RESPONSE][] = ['onResponse', -512];
|
||||
|
||||
return $events;
|
||||
}
|
||||
|
||||
}
|
|
@ -175,7 +175,7 @@ function hook_module_preinstall($module) {
|
|||
* This function differs from hook_install() in that it gives all other modules
|
||||
* a chance to perform actions when a module is installed, whereas
|
||||
* hook_install() is only called on the module actually being installed. See
|
||||
* \Drupal\Core\Extension\ModuleHandler::install() for a detailed description of
|
||||
* \Drupal\Core\Extension\ModuleInstaller::install() for a detailed description of
|
||||
* the order in which install hooks are invoked.
|
||||
*
|
||||
* This hook should be implemented in a .module file, not in an .install file.
|
||||
|
@ -183,7 +183,7 @@ function hook_module_preinstall($module) {
|
|||
* @param $modules
|
||||
* An array of the modules that were installed.
|
||||
*
|
||||
* @see \Drupal\Core\Extension\ModuleHandler::install()
|
||||
* @see \Drupal\Core\Extension\ModuleInstaller::install()
|
||||
* @see hook_install()
|
||||
*/
|
||||
function hook_modules_installed($modules) {
|
||||
|
@ -223,7 +223,7 @@ function hook_modules_installed($modules) {
|
|||
* be removed during uninstall should be removed with hook_uninstall().
|
||||
*
|
||||
* @see hook_schema()
|
||||
* @see \Drupal\Core\Extension\ModuleHandler::install()
|
||||
* @see \Drupal\Core\Extension\ModuleInstaller::install()
|
||||
* @see hook_uninstall()
|
||||
* @see hook_modules_installed()
|
||||
*/
|
||||
|
|
|
@ -236,13 +236,15 @@ interface FieldStorageDefinitionInterface extends CacheableDependencyInterface {
|
|||
*
|
||||
* @return array[]
|
||||
* The field schema, as an array of key/value pairs in the format returned
|
||||
* by hook_field_schema():
|
||||
* by \Drupal\Core\Field\FieldItemInterface::schema():
|
||||
* - columns: An array of Schema API column specifications, keyed by column
|
||||
* name. This specifies what comprises a single value for a given field.
|
||||
* No assumptions should be made on how storage backends internally use
|
||||
* the original column name to structure their storage.
|
||||
* - indexes: An array of Schema API index definitions. Some storage
|
||||
* backends might not support indexes.
|
||||
* - unique keys: An array of Schema API unique key definitions. Some
|
||||
* storage backends might not support unique keys.
|
||||
* - foreign keys: An array of Schema API foreign key definitions. Note,
|
||||
* however, that depending on the storage backend specified for the field,
|
||||
* the field data is not necessarily stored in SQL.
|
||||
|
|
|
@ -160,48 +160,42 @@ class EntityReferenceEntityFormatter extends EntityReferenceFormatterBase implem
|
|||
$elements = array();
|
||||
|
||||
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();
|
||||
// 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.
|
||||
if (static::$recursiveRenderDepth[$recursive_render_id] > static::RECURSIVE_RENDER_LIMIT) {
|
||||
$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.', [
|
||||
'%entity_type' => $entity->getEntityTypeId(),
|
||||
'%entity_id' => $entity->id(),
|
||||
'%field_name' => $items->getName(),
|
||||
'%bundle_name' => $items->getFieldDefinition()->getTargetBundle(),
|
||||
]);
|
||||
return $elements;
|
||||
}
|
||||
|
||||
$view_builder = $this->entityTypeManager->getViewBuilder($entity->getEntityTypeId());
|
||||
$elements[$delta] = $view_builder->view($entity, $view_mode, $entity->language()->getId());
|
||||
|
||||
// Add a resource attribute to set the mapping property's value to the
|
||||
// entity's url. Since we don't know what the markup of the entity will
|
||||
// be, we shouldn't rely on it for structured data such as RDFa.
|
||||
if (!empty($items[$delta]->_attributes)) {
|
||||
$items[$delta]->_attributes += array('resource' => $entity->url());
|
||||
}
|
||||
if (isset(static::$recursiveRenderDepth[$recursive_render_id])) {
|
||||
static::$recursiveRenderDepth[$recursive_render_id]++;
|
||||
}
|
||||
else {
|
||||
// This is an "auto_create" item.
|
||||
$elements[$delta] = array('#markup' => $entity->label());
|
||||
static::$recursiveRenderDepth[$recursive_render_id] = 1;
|
||||
}
|
||||
|
||||
// Protect ourselves from recursive rendering.
|
||||
if (static::$recursiveRenderDepth[$recursive_render_id] > static::RECURSIVE_RENDER_LIMIT) {
|
||||
$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.', [
|
||||
'%entity_type' => $entity->getEntityTypeId(),
|
||||
'%entity_id' => $entity->id(),
|
||||
'%field_name' => $items->getName(),
|
||||
'%bundle_name' => $items->getFieldDefinition()->getTargetBundle(),
|
||||
]);
|
||||
return $elements;
|
||||
}
|
||||
|
||||
$view_builder = $this->entityTypeManager->getViewBuilder($entity->getEntityTypeId());
|
||||
$elements[$delta] = $view_builder->view($entity, $view_mode, $entity->language()->getId());
|
||||
|
||||
// Add a resource attribute to set the mapping property's value to the
|
||||
// entity's url. Since we don't know what the markup of the entity will
|
||||
// be, we shouldn't rely on it for structured data such as RDFa.
|
||||
if (!empty($items[$delta]->_attributes) && !$entity->isNew() && $entity->hasLinkTemplate('canonical')) {
|
||||
$items[$delta]->_attributes += array('resource' => $entity->toUrl()->toString());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -53,8 +53,12 @@ class MimeTypeGuesser implements MimeTypeGuesserInterface {
|
|||
*/
|
||||
public function guess($path) {
|
||||
if ($wrapper = $this->streamWrapperManager->getViaUri($path)) {
|
||||
// Get the real path from the stream wrapper.
|
||||
$path = $wrapper->realpath();
|
||||
// Get the real path from the stream wrapper, if available. Files stored
|
||||
// in remote file systems will not have one.
|
||||
$real_path = $wrapper->realpath();
|
||||
if ($real_path !== FALSE) {
|
||||
$path = $real_path;
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->sortedGuessers === NULL) {
|
||||
|
|
|
@ -73,7 +73,7 @@ class InstallerServiceProvider implements ServiceProviderInterface, ServiceModif
|
|||
// No service may persist when the early installer kernel is rebooted into
|
||||
// the production environment.
|
||||
// @todo The DrupalKernel reboot performed by drupal_install_system() is
|
||||
// actually not a "regular" reboot (like ModuleHandler::install()), so
|
||||
// actually not a "regular" reboot (like ModuleInstaller::install()), so
|
||||
// services are not actually persisted.
|
||||
foreach ($container->findTaggedServiceIds('persist') as $id => $tags) {
|
||||
$definition = $container->getDefinition($id);
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
namespace Drupal\Core\ParamConverter;
|
||||
|
||||
use Drupal\Core\Entity\EntityRepositoryInterface;
|
||||
use Drupal\Core\Entity\EntityTypeManagerInterface;
|
||||
use Symfony\Component\Routing\Route;
|
||||
|
||||
|
@ -31,14 +32,24 @@ class EntityRevisionParamConverter implements ParamConverterInterface {
|
|||
*/
|
||||
protected $entityTypeManager;
|
||||
|
||||
/**
|
||||
* The entity repository.
|
||||
*
|
||||
* @var \Drupal\Core\Entity\EntityRepositoryInterface
|
||||
*/
|
||||
protected $entityRepository;
|
||||
|
||||
/**
|
||||
* Creates a new EntityRevisionParamConverter instance.
|
||||
*
|
||||
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
|
||||
* The entity type manager.
|
||||
* @param \Drupal\Core\Entity\EntityRepositoryInterface $entity_repository
|
||||
* The entity repository.
|
||||
*/
|
||||
public function __construct(EntityTypeManagerInterface $entity_type_manager) {
|
||||
public function __construct(EntityTypeManagerInterface $entity_type_manager, EntityRepositoryInterface $entity_repository) {
|
||||
$this->entityTypeManager = $entity_type_manager;
|
||||
$this->entityRepository = $entity_repository;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -46,8 +57,8 @@ class EntityRevisionParamConverter implements ParamConverterInterface {
|
|||
*/
|
||||
public function convert($value, $definition, $name, array $defaults) {
|
||||
list (, $entity_type_id) = explode(':', $definition['type'], 2);
|
||||
$entity_storage = $this->entityTypeManager->getStorage($entity_type_id);
|
||||
return $entity_storage->loadRevision($value);
|
||||
$entity = $this->entityTypeManager->getStorage($entity_type_id)->loadRevision($value);
|
||||
return $this->entityRepository->getTranslationFromContext($entity);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -25,7 +25,7 @@ interface AttachmentsResponseProcessorInterface {
|
|||
* $build['#attached']['library'][] = [
|
||||
* 'library' => ['core/jquery']
|
||||
* ];
|
||||
* $build['#attached']['http_header'][] = [
|
||||
* $build['#attached']['http_header'] = [
|
||||
* ['Content-Type', 'application/rss+xml; charset=utf-8'],
|
||||
* ];
|
||||
* @endcode
|
||||
|
|
|
@ -636,8 +636,33 @@ class Renderer implements RendererInterface {
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
foreach (array_keys($elements['#attached']['placeholders']) as $placeholder) {
|
||||
$elements = $this->renderPlaceholder($placeholder, $elements);
|
||||
// The 'status messages' placeholder needs to be special cased, because it
|
||||
// depends on global state that can be modified when other placeholders are
|
||||
// being rendered: any code can add messages to render.
|
||||
// This violates the principle that each lazy builder must be able to render
|
||||
// itself in isolation, and therefore in any order. However, we cannot
|
||||
// change the way drupal_set_message() works in the Drupal 8 cycle. So we
|
||||
// have to accommodate its special needs.
|
||||
// Allowing placeholders to be rendered in a particular order (in this case:
|
||||
// last) would violate this isolation principle. Thus a monopoly is granted
|
||||
// to this one special case, with this hard-coded solution.
|
||||
// @see \Drupal\Core\Render\Element\StatusMessages
|
||||
// @see https://www.drupal.org/node/2712935#comment-11368923
|
||||
|
||||
// First render all placeholders except 'status messages' placeholders.
|
||||
$message_placeholders = [];
|
||||
foreach ($elements['#attached']['placeholders'] as $placeholder => $placeholder_element) {
|
||||
if (isset($placeholder_element['#lazy_builder']) && $placeholder_element['#lazy_builder'][0] === 'Drupal\Core\Render\Element\StatusMessages::renderMessages') {
|
||||
$message_placeholders[] = $placeholder;
|
||||
}
|
||||
else {
|
||||
$elements = $this->renderPlaceholder($placeholder, $elements);
|
||||
}
|
||||
}
|
||||
|
||||
// Then render 'status messages' placeholders.
|
||||
foreach ($message_placeholders as $message_placeholder) {
|
||||
$elements = $this->renderPlaceholder($message_placeholder, $elements);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
|
|
@ -788,17 +788,17 @@ function hook_render_template($template_file, $variables) {
|
|||
* A module may implement this hook in order to alter the element type defaults
|
||||
* defined by a module.
|
||||
*
|
||||
* @param array $types
|
||||
* @param array $info
|
||||
* An associative array with structure identical to that of the return value
|
||||
* of \Drupal\Core\Render\ElementInfoManagerInterface::getInfo().
|
||||
*
|
||||
* @see \Drupal\Core\Render\ElementInfoManager
|
||||
* @see \Drupal\Core\Render\Element\ElementInterface
|
||||
*/
|
||||
function hook_element_info_alter(array &$types) {
|
||||
function hook_element_info_alter(array &$info) {
|
||||
// Decrease the default size of textfields.
|
||||
if (isset($types['textfield']['#size'])) {
|
||||
$types['textfield']['#size'] = 40;
|
||||
if (isset($info['textfield']['#size'])) {
|
||||
$info['textfield']['#size'] = 40;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -15,6 +15,13 @@ namespace Drupal\Core\StreamWrapper;
|
|||
*/
|
||||
abstract class LocalReadOnlyStream extends LocalStream {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function getType() {
|
||||
return StreamWrapperInterface::READ_VISIBLE | StreamWrapperInterface::LOCAL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Support for fopen(), file_get_contents(), etc.
|
||||
*
|
||||
|
|
Reference in a new issue