diff --git a/core/INSTALL.txt b/core/INSTALL.txt
index 6ae05b4..79c08bd 100644
--- a/core/INSTALL.txt
+++ b/core/INSTALL.txt
@@ -18,7 +18,7 @@ Drupal requires:
- A web server with PHP support, for example:
- Apache 2.0 (or greater) (http://httpd.apache.org/).
- Nginx 1.1 (or greater) (http://nginx.com/).
-- PHP 5.4.5 (or greater) (http://php.net/). For better security support it is
+- PHP 5.4.5 (or greater) (http://php.net/). For better security support its
recommended to update to at least 5.5.21 or 5.6.5.
- One of the following databases:
- MySQL 5.5.3 (or greater) (http://www.mysql.com/).
diff --git a/core/MAINTAINERS.txt b/core/MAINTAINERS.txt
index 7e6b0c7..c72d26b 100644
--- a/core/MAINTAINERS.txt
+++ b/core/MAINTAINERS.txt
@@ -371,7 +371,6 @@ REST module
Responsive Image module
- Peter Droogmans 'attiks' http://drupal.org/user/105002
- Marc Drummond 'mdrummond' http://www.drupal.org/user/360968/
-- Jelle Sebreghts 'Jelle_S' https://www.drupal.org/user/829198
Search module
- Jennifer Hodgdon 'jhodgdon' https://drupal.org/user/155601
diff --git a/core/lib/Drupal/Component/Utility/SafeMarkup.php b/core/lib/Drupal/Component/Utility/SafeMarkup.php
index 15d5223..d69daa5 100644
--- a/core/lib/Drupal/Component/Utility/SafeMarkup.php
+++ b/core/lib/Drupal/Component/Utility/SafeMarkup.php
@@ -282,4 +282,37 @@ public static function placeholder($text) {
return $string;
}
+ /**
+ * Replace all occurrences of the search string with the replacement string.
+ *
+ * Functions identically to str_replace, but marks the returned output as safe
+ * if all the inputs and the subject have also been marked as safe.
+ */
+ public static function replace($search, $replace, $subject) {
+ $output = str_replace($search, $replace, $subject);
+
+ if (!is_array($replace)) {
+ if (!SafeMarkup::isSafe($replace)) {
+ return $output;
+ }
+ }
+ else {
+ foreach ($replace as $replacement) {
+ if (!SafeMarkup::isSafe($replacement)) {
+ return $output;
+ }
+ }
+ }
+
+ // If we have reached this point, then all replacements were safe, and
+ // therefore if the subject was also safe, then the entire output is also
+ // safe, and should be marked as such.
+ if (SafeMarkup::isSafe($subject)) {
+ return SafeMarkup::set($output);
+ }
+ else {
+ return $output;
+ }
+ }
+
}
diff --git a/core/lib/Drupal/Core/Entity/Plugin/Validation/Constraint/CompositeConstraintBase.php b/core/lib/Drupal/Core/Entity/Plugin/Validation/Constraint/CompositeConstraintBase.php
deleted file mode 100644
index 3c605dc..0000000
--- a/core/lib/Drupal/Core/Entity/Plugin/Validation/Constraint/CompositeConstraintBase.php
+++ /dev/null
@@ -1,30 +0,0 @@
-' . $markup . '';
+ $element['#markup'] = SafeMarkup::format('', array('!markup' => $markup));
}
else {
$element['#markup'] = $markup;
diff --git a/core/lib/Drupal/Core/Render/Renderer.php b/core/lib/Drupal/Core/Render/Renderer.php
index b969a51..c253ae6 100644
--- a/core/lib/Drupal/Core/Render/Renderer.php
+++ b/core/lib/Drupal/Core/Render/Renderer.php
@@ -245,9 +245,8 @@ protected function doRender(&$elements, $is_root_call = FALSE) {
$elements['#children'] = '';
}
- // @todo Simplify after https://drupal.org/node/2273925
if (isset($elements['#markup'])) {
- $elements['#markup'] = SafeMarkup::set($elements['#markup']);
+ $elements['#markup'] = SafeMarkup::checkAdminXss($elements['#markup']);
}
// Assume that if #theme is set it represents an implemented hook.
@@ -545,7 +544,10 @@ public function generateCachePlaceholder($callback, array &$context) {
'token' => Crypt::randomBytesBase64(55),
];
- return '';
+ return SafeMarkup::format('', array(
+ '@callback' => $callback,
+ '@token' => $context['token'],
+ ));
}
}
diff --git a/core/modules/comment/src/CommentForm.php b/core/modules/comment/src/CommentForm.php
index 12f5bb8..9f47519 100644
--- a/core/modules/comment/src/CommentForm.php
+++ b/core/modules/comment/src/CommentForm.php
@@ -323,12 +323,9 @@ public function validate(array $form, FormStateInterface $form_state) {
foreach ($violations as $violation) {
$form_state->setErrorByName('date', $violation->getMessage());
}
- $violations = $comment->validate();
- // Filter out violations for the name path.
+ $violations = $comment->name->validate();
foreach ($violations as $violation) {
- if ($violation->getPropertyPath() === 'name') {
- $form_state->setErrorByName('name', $violation->getMessage());
- }
+ $form_state->setErrorByName('name', $violation->getMessage());
}
return $comment;
diff --git a/core/modules/comment/src/Entity/Comment.php b/core/modules/comment/src/Entity/Comment.php
index 2023448..f83f54b 100644
--- a/core/modules/comment/src/Entity/Comment.php
+++ b/core/modules/comment/src/Entity/Comment.php
@@ -54,9 +54,6 @@
* },
* bundle_entity_type = "comment_type",
* field_ui_base_route = "entity.comment_type.edit_form",
- * constraints = {
- * "CommentName" = {}
- * }
* )
*/
class Comment extends ContentEntityBase implements CommentInterface {
@@ -260,7 +257,8 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
->setDescription(t("The comment author's name."))
->setTranslatable(TRUE)
->setSetting('max_length', 60)
- ->setDefaultValue('');
+ ->setDefaultValue('')
+ ->addConstraint('CommentName', array());
$fields['mail'] = BaseFieldDefinition::create('email')
->setLabel(t('Email'))
diff --git a/core/modules/comment/src/Plugin/Validation/Constraint/CommentNameConstraint.php b/core/modules/comment/src/Plugin/Validation/Constraint/CommentNameConstraint.php
index 4de6726..d387542 100644
--- a/core/modules/comment/src/Plugin/Validation/Constraint/CommentNameConstraint.php
+++ b/core/modules/comment/src/Plugin/Validation/Constraint/CommentNameConstraint.php
@@ -7,18 +7,17 @@
namespace Drupal\comment\Plugin\Validation\Constraint;
-use Drupal\Core\Entity\Plugin\Validation\Constraint\CompositeConstraintBase;
+use Symfony\Component\Validator\Constraint;
/**
* Supports validating comment author names.
*
* @Plugin(
* id = "CommentName",
- * label = @Translation("Comment author name", context = "Validation"),
- * type = "entity:comment"
+ * label = @Translation("Comment author name", context = "Validation")
* )
*/
-class CommentNameConstraint extends CompositeConstraintBase {
+class CommentNameConstraint extends Constraint {
/**
* Message shown when an anonymous user comments using a registered name.
@@ -41,11 +40,4 @@ class CommentNameConstraint extends CompositeConstraintBase {
*/
public $messageMatch = 'The specified author name does not match the comment author.';
- /**
- * {@inheritdoc}
- */
- public function coversFields() {
- return ['name', 'uid'];
- }
-
}
diff --git a/core/modules/comment/src/Plugin/Validation/Constraint/CommentNameConstraintValidator.php b/core/modules/comment/src/Plugin/Validation/Constraint/CommentNameConstraintValidator.php
index 915d184..f6397e0 100644
--- a/core/modules/comment/src/Plugin/Validation/Constraint/CommentNameConstraintValidator.php
+++ b/core/modules/comment/src/Plugin/Validation/Constraint/CommentNameConstraintValidator.php
@@ -20,13 +20,6 @@
class CommentNameConstraintValidator extends ConstraintValidator implements ContainerInjectionInterface {
/**
- * Validator 2.5 and upwards compatible execution context.
- *
- * @var \Symfony\Component\Validator\Context\ExecutionContextInterface
- */
- protected $context;
-
- /**
* User storage handler.
*
* @var \Drupal\user\UserStorageInterface
@@ -53,36 +46,41 @@ public static function create(ContainerInterface $container) {
/**
* {@inheritdoc}
*/
- public function validate($entity, Constraint $constraint) {
- $author_name = $entity->name->value;
- $owner_id = (int) $entity->uid->target_id;
+ public function validate($items, Constraint $constraint) {
+ /** @var CommentNameConstraint $constraint */
+ if (!isset($items)) {
+ return;
+ }
+ /** @var CommentInterface $comment */
+ $comment = $items->getEntity();
+
+ if (!isset($comment)) {
+ // Looks like we are validating a field not being part of a comment,
+ // nothing we can do then.
+ return;
+ }
+ $author_name = $items->first()->value;
// Do not allow unauthenticated comment authors to use a name that is
// taken by a registered user.
- if (isset($author_name) && $author_name !== '' && $owner_id === 0) {
+ if (isset($author_name) && $author_name !== '' && $comment->getOwnerId() === 0) {
$users = $this->userStorage->loadByProperties(array('name' => $author_name));
if (!empty($users)) {
- $this->context->buildViolation($constraint->messageNameTaken, array('%name' => $author_name))
- ->atPath('name')
- ->addViolation();
+ $this->context->addViolation($constraint->messageNameTaken, array('%name' => $author_name));
}
}
// If an author name and owner are given, make sure they match.
- elseif (isset($author_name) && $author_name !== '' && $owner_id) {
- $owner = $this->userStorage->load($owner_id);
+ elseif (isset($author_name) && $author_name !== '' && $comment->getOwnerId()) {
+ $owner = $comment->getOwner();
if ($owner->getUsername() != $author_name) {
- $this->context->buildViolation($constraint->messageMatch)
- ->atPath('name')
- ->addViolation();
+ $this->context->addViolation($constraint->messageMatch);
}
}
// Anonymous account might be required - depending on field settings.
- if ($owner_id === 0 && empty($author_name) &&
- $this->getAnonymousContactDetailsSetting($entity) === COMMENT_ANONYMOUS_MUST_CONTACT) {
- $this->context->buildViolation($constraint->messageRequired)
- ->atPath('name')
- ->addViolation();
+ if ($comment->getOwnerId() === 0 && empty($author_name) &&
+ $this->getAnonymousContactDetailsSetting($comment) === COMMENT_ANONYMOUS_MUST_CONTACT) {
+ $this->context->addViolation($constraint->messageRequired);
}
}
diff --git a/core/modules/contextual/src/Element/ContextualLinksPlaceholder.php b/core/modules/contextual/src/Element/ContextualLinksPlaceholder.php
index d10078b..e148a1b 100644
--- a/core/modules/contextual/src/Element/ContextualLinksPlaceholder.php
+++ b/core/modules/contextual/src/Element/ContextualLinksPlaceholder.php
@@ -9,6 +9,7 @@
use Drupal\Core\Template\Attribute;
use Drupal\Core\Render\Element\RenderElement;
+use Drupal\Component\Utility\SafeMarkup;
/**
* Provides a contextual_links_placeholder element.
@@ -47,7 +48,11 @@ public function getInfo() {
* @see _contextual_links_to_id()
*/
public static function preRenderPlaceholder(array $element) {
- $element['#markup'] = '
$element['#id'])) . '>
';
+ // Because the only arguments to this markup will be instance of
+ // \Drupal\Core\Template\AttributeString, which is passed through
+ // \Drupal\Component\Utility\SafeMarkup::checkPlain() before being output
+ // this markup is safe, and is marked as such.
+ $element['#markup'] = SafeMarkup::set('
$element['#id'])) . '>
');
return $element;
}
diff --git a/core/modules/filter/src/Element/ProcessedText.php b/core/modules/filter/src/Element/ProcessedText.php
index d007b5f..4851a22 100644
--- a/core/modules/filter/src/Element/ProcessedText.php
+++ b/core/modules/filter/src/Element/ProcessedText.php
@@ -8,6 +8,7 @@
namespace Drupal\filter\Element;
use Drupal\Component\Utility\NestedArray;
+use Drupal\Component\Utility\SafeMarkup;
use Drupal\Core\Cache\Cache;
use Drupal\Core\Render\BubbleableMetadata;
use Drupal\Core\Render\Element\RenderElement;
@@ -118,9 +119,11 @@ public static function preRenderText($element) {
}
}
- // Filtering done, store in #markup, set the updated bubbleable rendering
- // metadata, and set the text format's cache tag.
- $element['#markup'] = $text;
+ // Filtering and sanitizing has been done in
+ // \Drupal\filter\Plugin\FilterInterface. Store its content in #markup,
+ // set the updated bubbleable rendering metadata, and set the text format's
+ // cache tag.
+ $element['#markup'] = SafeMarkup::set($text);
$metadata->applyTo($element);
$element['#cache']['tags'] = Cache::mergeTags($element['#cache']['tags'], $format->getCacheTags());
diff --git a/core/modules/hal/src/Normalizer/ContentEntityNormalizer.php b/core/modules/hal/src/Normalizer/ContentEntityNormalizer.php
index 14fdb0b..a3caa35 100644
--- a/core/modules/hal/src/Normalizer/ContentEntityNormalizer.php
+++ b/core/modules/hal/src/Normalizer/ContentEntityNormalizer.php
@@ -76,7 +76,7 @@ public function normalize($entity, $format = NULL, array $context = array()) {
'href' => $this->getEntityUri($entity),
),
'type' => array(
- 'href' => $this->linkManager->getTypeUri($entity->getEntityTypeId(), $entity->bundle(), $context),
+ 'href' => $this->linkManager->getTypeUri($entity->getEntityTypeId(), $entity->bundle()),
),
),
);
@@ -132,7 +132,7 @@ public function denormalize($data, $class, $format = NULL, array $context = arra
}
// Create the entity.
- $typed_data_ids = $this->getTypedDataIds($data['_links']['type'], $context);
+ $typed_data_ids = $this->getTypedDataIds($data['_links']['type']);
$entity_type = $this->entityManager->getDefinition($typed_data_ids['entity_type']);
$langcode_key = $entity_type->getKey('langcode');
$values = array();
@@ -210,14 +210,13 @@ protected function getEntityUri($entity) {
*
* @param array $types
* The type array(s) (value of the 'type' attribute of the incoming data).
- * @param array $context
- * Context from the normalizer/serializer operation.
*
* @return array
* The typed data IDs.
*
+ * @throws \Symfony\Component\Serializer\Exception\UnexpectedValueException
*/
- protected function getTypedDataIds($types, $context = array()) {
+ protected function getTypedDataIds($types) {
// The 'type' can potentially contain an array of type objects. By default,
// Drupal only uses a single type in serializing, but allows for multiple
// types when deserializing.
@@ -232,7 +231,7 @@ protected function getTypedDataIds($types, $context = array()) {
$type_uri = $type['href'];
// Check whether the URI corresponds to a known type on this site. Break
// once one does.
- if ($typed_data_ids = $this->linkManager->getTypeInternalIds($type['href'], $context)) {
+ if ($typed_data_ids = $this->linkManager->getTypeInternalIds($type['href'])) {
break;
}
}
diff --git a/core/modules/hal/src/Normalizer/EntityReferenceItemNormalizer.php b/core/modules/hal/src/Normalizer/EntityReferenceItemNormalizer.php
index 5160b68..4b5344a 100644
--- a/core/modules/hal/src/Normalizer/EntityReferenceItemNormalizer.php
+++ b/core/modules/hal/src/Normalizer/EntityReferenceItemNormalizer.php
@@ -85,7 +85,7 @@ public function normalize($field_item, $format = NULL, array $context = array())
// objects.
$field_name = $field_item->getParent()->getName();
$entity = $field_item->getEntity();
- $field_uri = $this->linkManager->getRelationUri($entity->getEntityTypeId(), $entity->bundle(), $field_name, $context);
+ $field_uri = $this->linkManager->getRelationUri($entity->getEntityTypeId(), $entity->bundle(), $field_name);
return array(
'_links' => array(
$field_uri => array($link),
diff --git a/core/modules/hal/src/Tests/FileNormalizeTest.php b/core/modules/hal/src/Tests/FileNormalizeTest.php
index 64ffd07..2b50381 100644
--- a/core/modules/hal/src/Tests/FileNormalizeTest.php
+++ b/core/modules/hal/src/Tests/FileNormalizeTest.php
@@ -39,7 +39,8 @@ protected function setUp() {
$this->installEntitySchema('file');
$entity_manager = \Drupal::entityManager();
- $link_manager = new LinkManager(new TypeLinkManager(new MemoryBackend('default'), \Drupal::moduleHandler(), \Drupal::service('config.factory'), \Drupal::service('request_stack')), new RelationLinkManager(new MemoryBackend('default'), $entity_manager, \Drupal::moduleHandler(), \Drupal::service('config.factory'), \Drupal::service('request_stack')));
+ $url_assembler = \Drupal::service('unrouted_url_assembler');
+ $link_manager = new LinkManager(new TypeLinkManager(new MemoryBackend('default'), $url_assembler), new RelationLinkManager(new MemoryBackend('default'), $entity_manager, $url_assembler));
// Set up the mock serializer.
$normalizers = array(
diff --git a/core/modules/hal/src/Tests/NormalizerTestBase.php b/core/modules/hal/src/Tests/NormalizerTestBase.php
index aea5b25..43f10b1 100644
--- a/core/modules/hal/src/Tests/NormalizerTestBase.php
+++ b/core/modules/hal/src/Tests/NormalizerTestBase.php
@@ -83,7 +83,6 @@ protected function setUp() {
$class = get_parent_class($class);
}
$this->installConfig(array('field', 'language'));
- \Drupal::service('router.builder')->rebuild();
// Add German as a language.
ConfigurableLanguage::create(array(
@@ -135,7 +134,8 @@ protected function setUp() {
))->save();
$entity_manager = \Drupal::entityManager();
- $link_manager = new LinkManager(new TypeLinkManager(new MemoryBackend('default'), \Drupal::moduleHandler(), \Drupal::service('config.factory'), \Drupal::service('request_stack')), new RelationLinkManager(new MemoryBackend('default'), $entity_manager, \Drupal::moduleHandler(), \Drupal::service('config.factory'), \Drupal::service('request_stack')));
+ $url_assembler = \Drupal::service('unrouted_url_assembler');
+ $link_manager = new LinkManager(new TypeLinkManager(new MemoryBackend('default'), $url_assembler), new RelationLinkManager(new MemoryBackend('default'), $entity_manager, $url_assembler));
$chain_resolver = new ChainEntityResolver(array(new UuidResolver($entity_manager), new TargetIdResolver()));
diff --git a/core/modules/rest/config/install/rest.settings.yml b/core/modules/rest/config/install/rest.settings.yml
index 0c388ca..0a44346 100644
--- a/core/modules/rest/config/install/rest.settings.yml
+++ b/core/modules/rest/config/install/rest.settings.yml
@@ -44,7 +44,3 @@ resources:
#
# The full documentation is located at
# https://drupal.org/documentation/modules/rest
-
-# Set the domain for REST type and relation links.
-# If left blank, the site's domain will be used
-link_domain: ~
diff --git a/core/modules/rest/config/schema/rest.schema.yml b/core/modules/rest/config/schema/rest.schema.yml
index 8014b31..8421d13 100644
--- a/core/modules/rest/config/schema/rest.schema.yml
+++ b/core/modules/rest/config/schema/rest.schema.yml
@@ -10,9 +10,6 @@ rest.settings:
sequence:
type: rest_resource
label: 'Resource'
- link_domain:
- type: string
- label: 'Domain of the relation'
rest_resource:
type: mapping
diff --git a/core/modules/rest/rest.api.php b/core/modules/rest/rest.api.php
index fb8993d..2f3f6ee 100644
--- a/core/modules/rest/rest.api.php
+++ b/core/modules/rest/rest.api.php
@@ -29,52 +29,5 @@ function hook_rest_resource_alter(&$definitions) {
}
/**
- * Alter the REST type URI.
- *
- * Modules may wish to alter the type URI generated for a resource based on the
- * context of the serializer/normalizer operation.
- *
- * @param string $uri
- * The URI to alter.
- * @param array $context
- * The context from the serializer/normalizer operation.
- *
- * @see \Symfony\Component\Serializer\SerializerInterface::serialize()
- * @see \Symfony\Component\Serializer\SerializerInterface::deserialize()
- * @see \Symfony\Component\Serializer\NormalizerInterface::normalize()
- * @see \Symfony\Component\Serializer\DenormalizerInterface::denormalize()
- */
-function hook_rest_type_uri_alter(&$uri, $context = array()) {
- if ($context['mymodule'] == TRUE) {
- $base = \Drupal::config('rest.settings')->get('link_domain');
- $uri = str_replace($base, 'http://mymodule.domain', $uri);
- }
-}
-
-
-/**
- * Alter the REST relation URI.
- *
- * Modules may wish to alter the relation URI generated for a resource based on
- * the context of the serializer/normalizer operation.
- *
- * @param string $uri
- * The URI to alter.
- * @param array $context
- * The context from the serializer/normalizer operation.
- *
- * @see \Symfony\Component\Serializer\SerializerInterface::serialize()
- * @see \Symfony\Component\Serializer\SerializerInterface::deserialize()
- * @see \Symfony\Component\Serializer\NormalizerInterface::normalize()
- * @see \Symfony\Component\Serializer\DenormalizerInterface::denormalize()
- */
-function hook_rest_relation_uri_alter(&$uri, $context = array()) {
- if ($context['mymodule'] == TRUE) {
- $base = \Drupal::config('rest.settings')->get('link_domain');
- $uri = str_replace($base, 'http://mymodule.domain', $uri);
- }
-}
-
-/**
* @} End of "addtogroup hooks".
*/
diff --git a/core/modules/rest/rest.services.yml b/core/modules/rest/rest.services.yml
index 04f5f1d..bfba7bb 100644
--- a/core/modules/rest/rest.services.yml
+++ b/core/modules/rest/rest.services.yml
@@ -19,10 +19,10 @@ services:
arguments: ['@rest.link_manager.type', '@rest.link_manager.relation']
rest.link_manager.type:
class: Drupal\rest\LinkManager\TypeLinkManager
- arguments: ['@cache.default', '@module_handler', '@config.factory', '@request_stack']
+ arguments: ['@cache.default', '@unrouted_url_assembler']
rest.link_manager.relation:
class: Drupal\rest\LinkManager\RelationLinkManager
- arguments: ['@cache.default', '@entity.manager', '@module_handler', '@config.factory', '@request_stack']
+ arguments: ['@cache.default', '@entity.manager', '@unrouted_url_assembler']
rest.resource_routes:
class: Drupal\rest\Routing\ResourceRoutes
arguments: ['@plugin.manager.rest', '@config.factory', '@logger.channel.rest']
diff --git a/core/modules/rest/src/LinkManager/ConfigurableLinkManagerInterface.php b/core/modules/rest/src/LinkManager/ConfigurableLinkManagerInterface.php
deleted file mode 100644
index 0505811..0000000
--- a/core/modules/rest/src/LinkManager/ConfigurableLinkManagerInterface.php
+++ /dev/null
@@ -1,25 +0,0 @@
-typeLinkManager->getTypeUri($entity_type, $bundle, $context);
+ public function getTypeUri($entity_type, $bundle) {
+ return $this->typeLinkManager->getTypeUri($entity_type, $bundle);
}
/**
* Implements \Drupal\rest\LinkManager\TypeLinkManagerInterface::getTypeInternalIds().
*/
- public function getTypeInternalIds($type_uri, $context = array()) {
- return $this->typeLinkManager->getTypeInternalIds($type_uri, $context);
+ public function getTypeInternalIds($type_uri) {
+ return $this->typeLinkManager->getTypeInternalIds($type_uri);
}
/**
* Implements \Drupal\rest\LinkManager\RelationLinkManagerInterface::getRelationUri().
*/
- public function getRelationUri($entity_type, $bundle, $field_name, $context = array()) {
- return $this->relationLinkManager->getRelationUri($entity_type, $bundle, $field_name, $context);
+ public function getRelationUri($entity_type, $bundle, $field_name) {
+ return $this->relationLinkManager->getRelationUri($entity_type, $bundle, $field_name);
}
/**
@@ -63,13 +63,4 @@ public function getRelationInternalIds($relation_uri) {
return $this->relationLinkManager->getRelationInternalIds($relation_uri);
}
- /**
- * {@inheritdoc}
- */
- public function setLinkDomain($domain) {
- $this->relationLinkManager->setLinkDomain($domain);
- $this->typeLinkManager->setLinkDomain($domain);
- return $this;
- }
-
}
diff --git a/core/modules/rest/src/LinkManager/LinkManagerBase.php b/core/modules/rest/src/LinkManager/LinkManagerBase.php
deleted file mode 100644
index f93f6fd..0000000
--- a/core/modules/rest/src/LinkManager/LinkManagerBase.php
+++ /dev/null
@@ -1,64 +0,0 @@
-linkDomain = rtrim($domain, '/');
- return $this;
- }
-
- /**
- * Gets the link domain.
- *
- * @return string
- * The link domain.
- */
- protected function getLinkDomain() {
- if (empty($this->linkDomain)) {
- if ($domain = $this->configFactory->get('rest.settings')->get('link_domain')) {
- $this->linkDomain = rtrim($domain, '/');
- }
- else {
- $request = $this->requestStack->getCurrentRequest();
- $this->linkDomain = $request->getSchemeAndHttpHost() . $request->getBasePath();
- }
- }
- return $this->linkDomain;
- }
-
-}
diff --git a/core/modules/rest/src/LinkManager/RelationLinkManager.php b/core/modules/rest/src/LinkManager/RelationLinkManager.php
index 9cdd5c4..38bf4cf 100644
--- a/core/modules/rest/src/LinkManager/RelationLinkManager.php
+++ b/core/modules/rest/src/LinkManager/RelationLinkManager.php
@@ -9,13 +9,11 @@
use Drupal\Core\Cache\Cache;
use Drupal\Core\Cache\CacheBackendInterface;
-use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Entity\ContentEntityTypeInterface;
use Drupal\Core\Entity\EntityManagerInterface;
-use Drupal\Core\Extension\ModuleHandlerInterface;
-use Symfony\Component\HttpFoundation\RequestStack;
+use Drupal\Core\Utility\UnroutedUrlAssemblerInterface;
-class RelationLinkManager extends LinkManagerBase implements RelationLinkManagerInterface {
+class RelationLinkManager implements RelationLinkManagerInterface {
/**
* @var \Drupal\Core\Cache\CacheBackendInterface;
@@ -30,11 +28,11 @@ class RelationLinkManager extends LinkManagerBase implements RelationLinkManager
protected $entityManager;
/**
- * Module handler service.
+ * The unrouted URL assembler.
*
- * @var \Drupal\Core\Extension\ModuleHandlerInterface
+ * @var \Drupal\Core\Utility\UnroutedUrlAssemblerInterface
*/
- protected $moduleHandler;
+ protected $urlAssembler;
/**
* Constructor.
@@ -43,35 +41,27 @@ class RelationLinkManager extends LinkManagerBase implements RelationLinkManager
* The cache of relation URIs and their associated Typed Data IDs.
* @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
* The entity manager.
- * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
- * The module handler service.
- * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
- * The config factory service.
- * @param \Symfony\Component\HttpFoundation\RequestStack $request_stack
- * The request stack.
+ * @param \Drupal\Core\Utility\UnroutedUrlAssemblerInterface $url_assembler
+ * The unrouted URL assembler.
*/
- public function __construct(CacheBackendInterface $cache, EntityManagerInterface $entity_manager, ModuleHandlerInterface $module_handler, ConfigFactoryInterface $config_factory, RequestStack $request_stack) {
+ public function __construct(CacheBackendInterface $cache, EntityManagerInterface $entity_manager, UnroutedUrlAssemblerInterface $url_assembler) {
$this->cache = $cache;
$this->entityManager = $entity_manager;
- $this->configFactory = $config_factory;
- $this->moduleHandler = $module_handler;
- $this->requestStack = $request_stack;
+ $this->urlAssembler = $url_assembler;
}
/**
* {@inheritdoc}
*/
- public function getRelationUri($entity_type, $bundle, $field_name, $context = array()) {
- $uri = $this->getLinkDomain() . "/rest/relation/$entity_type/$bundle/$field_name";
- $this->moduleHandler->alter('rest_relation_uri', $uri, $context);
- return $uri;
+ public function getRelationUri($entity_type, $bundle, $field_name) {
+ return $this->urlAssembler->assemble("base:rest/relation/$entity_type/$bundle/$field_name", array('absolute' => TRUE));
}
/**
* {@inheritdoc}
*/
- public function getRelationInternalIds($relation_uri, $context = array()) {
- $relations = $this->getRelations($context);
+ public function getRelationInternalIds($relation_uri) {
+ $relations = $this->getRelations();
if (isset($relations[$relation_uri])) {
return $relations[$relation_uri];
}
@@ -87,18 +77,15 @@ public function getRelationInternalIds($relation_uri, $context = array()) {
* even primitives, are given a relation URI. It is up to the caller to
* determine which URIs to use.
*
- * @param array $context
- * Context from the normalizer/serializer operation.
- *
* @return array
* An array of typed data ids (entity_type, bundle, and field name) keyed
* by corresponding relation URI.
*/
- protected function getRelations($context = array()) {
+ protected function getRelations() {
$cid = 'rest:links:relations';
$cache = $this->cache->get($cid);
if (!$cache) {
- $this->writeCache($context);
+ $this->writeCache();
$cache = $this->cache->get($cid);
}
return $cache->data;
@@ -106,18 +93,15 @@ protected function getRelations($context = array()) {
/**
* Writes the cache of relation links.
- *
- * @param array $context
- * Context from the normalizer/serializer operation.
*/
- protected function writeCache($context = array()) {
+ protected function writeCache() {
$data = array();
foreach ($this->entityManager->getDefinitions() as $entity_type) {
if ($entity_type instanceof ContentEntityTypeInterface) {
foreach ($this->entityManager->getBundleInfo($entity_type->id()) as $bundle => $bundle_info) {
foreach ($this->entityManager->getFieldDefinitions($entity_type->id(), $bundle) as $field_definition) {
- $relation_uri = $this->getRelationUri($entity_type->id(), $bundle, $field_definition->getName(), $context);
+ $relation_uri = $this->getRelationUri($entity_type->id(), $bundle, $field_definition->getName());
$data[$relation_uri] = array(
'entity_type' => $entity_type,
'bundle' => $bundle,
diff --git a/core/modules/rest/src/LinkManager/RelationLinkManagerInterface.php b/core/modules/rest/src/LinkManager/RelationLinkManagerInterface.php
index f99e43e..2dc175c 100644
--- a/core/modules/rest/src/LinkManager/RelationLinkManagerInterface.php
+++ b/core/modules/rest/src/LinkManager/RelationLinkManagerInterface.php
@@ -7,7 +7,7 @@
namespace Drupal\rest\LinkManager;
-interface RelationLinkManagerInterface extends ConfigurableLinkManagerInterface {
+interface RelationLinkManagerInterface {
/**
* Gets the URI that corresponds to a field.
@@ -18,13 +18,11 @@
* The bundle name.
* @param string $field_name
* The field name.
- * @param array $context
- * (optional) Optional serializer/normalizer context.
*
* @return string
* The corresponding URI for the field.
*/
- public function getRelationUri($entity_type, $bundle, $field_name, $context = array());
+ public function getRelationUri($entity_type, $bundle, $field_name);
/**
* Translates a REST URI into internal IDs.
diff --git a/core/modules/rest/src/LinkManager/TypeLinkManager.php b/core/modules/rest/src/LinkManager/TypeLinkManager.php
index 3c9f665..4160b2b 100644
--- a/core/modules/rest/src/LinkManager/TypeLinkManager.php
+++ b/core/modules/rest/src/LinkManager/TypeLinkManager.php
@@ -9,11 +9,9 @@
use Drupal\Core\Cache\Cache;
use Drupal\Core\Cache\CacheBackendInterface;
-use Drupal\Core\Config\ConfigFactoryInterface;
-use Drupal\Core\Extension\ModuleHandlerInterface;
-use Symfony\Component\HttpFoundation\RequestStack;
+use Drupal\Core\Utility\UnroutedUrlAssemblerInterface;
-class TypeLinkManager extends LinkManagerBase implements TypeLinkManagerInterface {
+class TypeLinkManager implements TypeLinkManagerInterface {
/**
* Injected cache backend.
@@ -23,29 +21,23 @@ class TypeLinkManager extends LinkManagerBase implements TypeLinkManagerInterfac
protected $cache;
/**
- * Module handler service.
+ * The unrouted URL assembler.
*
- * @var \Drupal\Core\Extension\ModuleHandlerInterface
+ * @var \Drupal\Core\Utility\UnroutedUrlAssemblerInterface
*/
- protected $moduleHandler;
+ protected $urlAssembler;
/**
* Constructor.
*
* @param \Drupal\Core\Cache\CacheBackendInterface $cache
* The injected cache backend for caching type URIs.
- * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
- * The module handler service.
- * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
- * The config factory service.
- * @param \Symfony\Component\HttpFoundation\RequestStack $request_stack
- * The request stack.
+ * @param \Drupal\Core\Utility\UnroutedUrlAssemblerInterface $url_assembler
+ * The unrouted URL assembler.
*/
- public function __construct(CacheBackendInterface $cache, ModuleHandlerInterface $module_handler, ConfigFactoryInterface $config_factory, RequestStack $request_stack) {
+ public function __construct(CacheBackendInterface $cache, UnroutedUrlAssemblerInterface $url_assembler) {
$this->cache = $cache;
- $this->configFactory = $config_factory;
- $this->moduleHandler = $module_handler;
- $this->requestStack = $request_stack;
+ $this->urlAssembler = $url_assembler;
}
/**
@@ -55,23 +47,20 @@ public function __construct(CacheBackendInterface $cache, ModuleHandlerInterface
* The bundle's entity type.
* @param string $bundle
* The name of the bundle.
- * @param array $context
- * Context of normalizer/serializer.
*
- * @return string
+ * @return array
* The URI that identifies this bundle.
*/
- public function getTypeUri($entity_type, $bundle, $context = array()) {
- $uri = $this->getLinkDomain() . "/rest/type/$entity_type/$bundle";
- $this->moduleHandler->alter('rest_type_uri', $uri, $context);
- return $uri;
+ public function getTypeUri($entity_type, $bundle) {
+ // @todo Make the base path configurable.
+ return $this->urlAssembler->assemble("base:rest/type/$entity_type/$bundle", array('absolute' => TRUE));
}
/**
* Implements \Drupal\rest\LinkManager\TypeLinkManagerInterface::getTypeInternalIds().
*/
- public function getTypeInternalIds($type_uri, $context = array()) {
- $types = $this->getTypes($context);
+ public function getTypeInternalIds($type_uri) {
+ $types = $this->getTypes();
if (isset($types[$type_uri])) {
return $types[$type_uri];
}
@@ -81,18 +70,15 @@ public function getTypeInternalIds($type_uri, $context = array()) {
/**
* Get the array of type links.
*
- * @param array $context
- * Context from the normalizer/serializer operation.
- *
* @return array
* An array of typed data ids (entity_type and bundle) keyed by
* corresponding type URI.
*/
- protected function getTypes($context = array()) {
+ protected function getTypes() {
$cid = 'rest:links:types';
$cache = $this->cache->get($cid);
if (!$cache) {
- $this->writeCache($context);
+ $this->writeCache();
$cache = $this->cache->get($cid);
}
return $cache->data;
@@ -100,11 +86,8 @@ protected function getTypes($context = array()) {
/**
* Writes the cache of type links.
- *
- * @param array $context
- * Context from the normalizer/serializer operation.
*/
- protected function writeCache($context = array()) {
+ protected function writeCache() {
$data = array();
// Type URIs correspond to bundles. Iterate through the bundles to get the
@@ -118,7 +101,7 @@ protected function writeCache($context = array()) {
}
foreach ($bundles as $bundle => $bundle_info) {
// Get a type URI for the bundle.
- $bundle_uri = $this->getTypeUri($entity_type_id, $bundle, $context);
+ $bundle_uri = $this->getTypeUri($entity_type_id, $bundle);
$data[$bundle_uri] = array(
'entity_type' => $entity_type_id,
'bundle' => $bundle,
@@ -129,5 +112,4 @@ protected function writeCache($context = array()) {
// and only clear it when entity_info is cleared.
$this->cache->set('rest:links:types', $data, Cache::PERMANENT, array('entity_types'));
}
-
}
diff --git a/core/modules/rest/src/LinkManager/TypeLinkManagerInterface.php b/core/modules/rest/src/LinkManager/TypeLinkManagerInterface.php
index 3459d06..9c2d942 100644
--- a/core/modules/rest/src/LinkManager/TypeLinkManagerInterface.php
+++ b/core/modules/rest/src/LinkManager/TypeLinkManagerInterface.php
@@ -7,7 +7,7 @@
namespace Drupal\rest\LinkManager;
-interface TypeLinkManagerInterface extends ConfigurableLinkManagerInterface {
+interface TypeLinkManagerInterface {
/**
* Gets the URI that corresponds to a bundle.
@@ -20,25 +20,21 @@
* The bundle's entity type.
* @param $bundle
* The bundle name.
- * @param array $context
- * (optional) Optional serializer/normalizer context.
*
* @return string
* The corresponding URI for the bundle.
*/
- public function getTypeUri($entity_type, $bundle, $context = array());
+ public function getTypeUri($entity_type, $bundle);
/**
* Get a bundle's Typed Data IDs based on a URI.
*
* @param string $type_uri
* The type URI.
- * @param array $context
- * Context from the normalizer/serializer operation.
*
* @return array | boolean
* If the URI matches a bundle, returns an array containing entity_type and
* bundle. Otherwise, returns false.
*/
- public function getTypeInternalIds($type_uri, $context = array());
+ public function getTypeInternalIds($type_uri);
}
diff --git a/core/modules/rest/src/Plugin/views/display/RestExport.php b/core/modules/rest/src/Plugin/views/display/RestExport.php
index 8af1a75..0cd43e9 100644
--- a/core/modules/rest/src/Plugin/views/display/RestExport.php
+++ b/core/modules/rest/src/Plugin/views/display/RestExport.php
@@ -278,7 +278,7 @@ public function execute() {
$header = [];
$header['Content-type'] = $this->getMimeType();
- $response = new CacheableResponse($this->renderer->renderRoot($output), 200);
+ $response = new CacheableResponse($output['#markup'], 200);
$cache_metadata = CacheableMetadata::createFromRenderArray($output);
$response->addCacheableDependency($cache_metadata);
diff --git a/core/modules/rest/src/Plugin/views/style/Serializer.php b/core/modules/rest/src/Plugin/views/style/Serializer.php
index 09e94e6..6078c9f 100644
--- a/core/modules/rest/src/Plugin/views/style/Serializer.php
+++ b/core/modules/rest/src/Plugin/views/style/Serializer.php
@@ -7,7 +7,9 @@
namespace Drupal\rest\Plugin\views\style;
+use Drupal\Component\Utility\SafeMarkup;
use Drupal\Core\Form\FormStateInterface;
+use Drupal\rest\Plugin\views\row\DataFieldRow;
use Drupal\views\ViewExecutable;
use Drupal\views\Plugin\views\display\DisplayPluginBase;
use Drupal\views\Plugin\views\style\StylePluginBase;
diff --git a/core/modules/rest/src/Tests/RestLinkManagerTest.php b/core/modules/rest/src/Tests/RestLinkManagerTest.php
deleted file mode 100644
index 4adee7c..0000000
--- a/core/modules/rest/src/Tests/RestLinkManagerTest.php
+++ /dev/null
@@ -1,90 +0,0 @@
-installSchema('system', ['router']);
- \Drupal::service('router.builder')->rebuild();
- }
-
- /**
- * Tests that type hooks work as expected.
- */
- public function testRestLinkManagers() {
- \Drupal::moduleHandler()->invoke('rest', 'install');
- /* @var \Drupal\rest\LinkManager\TypeLinkManagerInterface $type_manager */
- $type_manager = \Drupal::service('rest.link_manager.type');
- $base = Url::fromRoute('', [], ['absolute' => TRUE])->toString();
- $link = $type_manager->getTypeUri('node', 'page');
- $this->assertEqual($link, $base . 'rest/type/node/page');
- // Now with optional context.
- $link = $type_manager->getTypeUri('node', 'page', ['rest_test' => TRUE]);
- $this->assertEqual($link, 'rest_test_type');
-
- /* @var \Drupal\rest\LinkManager\RelationLinkManagerInterface $relation_manager */
- $relation_manager = \Drupal::service('rest.link_manager.relation');
- $link = $relation_manager->getRelationUri('node', 'page', 'field_ref');
- $this->assertEqual($link, $base . 'rest/relation/node/page/field_ref');
- // Now with optional context.
- $link = $relation_manager->getRelationUri('node', 'page', 'foobar', ['rest_test' => TRUE]);
- $this->assertEqual($link, 'rest_test_relation');
- }
-
- /**
- * Tests that type hooks work as expected even without install hook.
- */
- public function testRestLinkManagersNoInstallHook() {
- /* @var \Drupal\rest\LinkManager\TypeLinkManagerInterface $type_manager */
- $type_manager = \Drupal::service('rest.link_manager.type');
- $base = Url::fromRoute('', [], ['absolute' => TRUE])->toString();
- $link = $type_manager->getTypeUri('node', 'page');
- $this->assertEqual($link, $base . 'rest/type/node/page');
- // Now with optional context.
- $link = $type_manager->getTypeUri('node', 'page', ['rest_test' => TRUE]);
- $this->assertEqual($link, 'rest_test_type');
-
- /* @var \Drupal\rest\LinkManager\RelationLinkManagerInterface $relation_manager */
- $relation_manager = \Drupal::service('rest.link_manager.relation');
- $link = $relation_manager->getRelationUri('node', 'page', 'field_ref');
- $this->assertEqual($link, $base . 'rest/relation/node/page/field_ref');
- // Now with optional context.
- $link = $relation_manager->getRelationUri('node', 'page', 'foobar', ['rest_test' => TRUE]);
- $this->assertEqual($link, 'rest_test_relation');
- }
-
- /**
- * Tests \Drupal\rest\LinkManager\LinkManager::setLinkDomain().
- */
- public function testRestLinkManagersSetLinkDomain() {
- /* @var \Drupal\rest\LinkManager\LinkManager $link_manager */
- $link_manager = \Drupal::service('rest.link_manager');
- $link_manager->setLinkDomain('http://example.com/');
- $link = $link_manager->getTypeUri('node', 'page');
- $this->assertEqual($link, 'http://example.com/rest/type/node/page');
- $link = $link_manager->getRelationUri('node', 'page', 'field_ref');
- $this->assertEqual($link, 'http://example.com/rest/relation/node/page/field_ref');
- }
-
-}
diff --git a/core/modules/rest/src/Tests/Views/StyleSerializerTest.php b/core/modules/rest/src/Tests/Views/StyleSerializerTest.php
index 137e8f0..e16556c 100644
--- a/core/modules/rest/src/Tests/Views/StyleSerializerTest.php
+++ b/core/modules/rest/src/Tests/Views/StyleSerializerTest.php
@@ -335,6 +335,16 @@ public function testFieldapiField() {
$result = $this->drupalGetJSON('test/serialize/node-field');
$this->assertEqual($result[0]['nid'], $node->id());
$this->assertEqual($result[0]['body'], $node->body->processed);
- }
+ // Make sure that serialized fields are not exposed to XSS.
+ $node = $this->drupalCreateNode();
+ $node->body = array(
+ 'value' => '' . $this->randomMachineName(32),
+ 'format' => filter_default_format(),
+ );
+ $node->save();
+ $result = $this->drupalGetJSON('test/serialize/node-field');
+ $this->assertEqual($result[1]['nid'], $node->id());
+ $this->assertTrue(strpos($this->getRawContent(), " test"],
+ ], "This is alert('XSS') test"];
// #children set but empty, and renderable children.
$data[] = [[
'#children' => '',
diff --git a/core/tests/Drupal/Tests/Core/Render/RendererTestBase.php b/core/tests/Drupal/Tests/Core/Render/RendererTestBase.php
index 903adce..fb0aeb9 100644
--- a/core/tests/Drupal/Tests/Core/Render/RendererTestBase.php
+++ b/core/tests/Drupal/Tests/Core/Render/RendererTestBase.php
@@ -255,7 +255,7 @@ public static function callback(array $element, array $context) {
public static function placeholder(array $element, array $context) {
$placeholder = \Drupal::service('renderer')->generateCachePlaceholder(__NAMESPACE__ . '\\PostRenderCache::placeholder', $context);
$replace_element = array(
- '#markup' => '' . $context['bar'] . '',
+ '#markup' => '' . $context['bar'] . '',
'#attached' => array(
'drupalSettings' => [
'common_test' => $context,