Update to drupal 8.0.0-rc1. For more information, see https://www.drupal.org/node/2582663

This commit is contained in:
Greg Anderson 2015-10-08 11:40:12 -07:00
parent eb34d130a8
commit f32e58e4b1
8476 changed files with 211648 additions and 170042 deletions

View file

@ -8,8 +8,9 @@
namespace Drupal\Core\Utility;
use Drupal\Component\Serialization\Json;
use Drupal\Component\Utility\Html;
use Drupal\Component\Utility\SafeMarkup;
use Drupal\Component\Utility\SafeStringInterface;
use Drupal\Component\Render\MarkupInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\GeneratedLink;
use Drupal\Core\Link;
@ -64,8 +65,8 @@ class LinkGenerator implements LinkGeneratorInterface {
/**
* {@inheritdoc}
*/
public function generateFromLink(Link $link, $collect_bubbleable_metadata = FALSE) {
return $this->generate($link->getText(), $link->getUrl(), $collect_bubbleable_metadata);
public function generateFromLink(Link $link) {
return $this->generate($link->getText(), $link->getUrl());
}
/**
@ -80,14 +81,18 @@ class LinkGenerator implements LinkGeneratorInterface {
*
* @see system_page_attachments()
*/
public function generate($text, Url $url, $collect_bubbleable_metadata = FALSE) {
public function generate($text, Url $url) {
// Performance: avoid Url::toString() needing to retrieve the URL generator
// service from the container.
$url->setUrlGenerator($this->urlGenerator);
if (is_array($text)) {
$text = $this->renderer->render($text);
}
// Start building a structured representation of our link to be altered later.
$variables = array(
'text' => is_array($text) ? $this->renderer->render($text) : $text,
'text' => $text,
'url' => $url,
'options' => $url->getOptions(),
);
@ -109,7 +114,7 @@ class LinkGenerator implements LinkGeneratorInterface {
// Ensure that query values are strings.
array_walk($variables['options']['query'], function(&$value) {
if ($value instanceof SafeStringInterface) {
if ($value instanceof MarkupInterface) {
$value = (string) $value;
}
});
@ -149,21 +154,26 @@ class LinkGenerator implements LinkGeneratorInterface {
unset($variables['options']['attributes']);
$url->setOptions($variables['options']);
if (!$collect_bubbleable_metadata) {
$url_string = $url->toString($collect_bubbleable_metadata);
// External URLs can not have cacheable metadata.
if ($url->isExternal()) {
$generated_link = new GeneratedLink();
$attributes['href'] = $url->toString(FALSE);
}
else {
$generated_url = $url->toString($collect_bubbleable_metadata);
$url_string = $generated_url->getGeneratedUrl();
$generated_url = $url->toString(TRUE);
$generated_link = GeneratedLink::createFromObject($generated_url);
// The result of the URL generator is a plain-text URL to use as the href
// attribute, and it is escaped by \Drupal\Core\Template\Attribute.
$attributes['href'] = $generated_url->getGeneratedUrl();
}
// The result of the URL generator is a plain-text URL to use as the href
// attribute, and it is escaped by \Drupal\Core\Template\Attribute.
$attributes['href'] = $url_string;
$result = SafeMarkup::format('<a@attributes>@text</a>', array('@attributes' => new Attribute($attributes), '@text' => $variables['text']));
return $collect_bubbleable_metadata ? $generated_link->setGeneratedLink($result) : $result;
if (!SafeMarkup::isSafe($variables['text'])) {
$variables['text'] = Html::escape($variables['text']);
}
$attributes = new Attribute($attributes);
// This is safe because Attribute does escaping and $variables['text'] is
// either rendered or escaped.
return $generated_link->setGeneratedLink('<a' . $attributes . '>' . $variables['text'] . '</a>');
}
}

View file

@ -31,7 +31,7 @@ interface LinkGeneratorInterface {
* However, for links enclosed in translatable text you should use t() and
* embed the HTML anchor tag directly in the translated string. For example:
* @code
* $text = t('Visit the <a href="@url">content types</a> page', array('@url' => \Drupal::url('entity.node_type.collection')));
* $text = t('Visit the <a href=":url">content types</a> page', array(':url' => \Drupal::url('entity.node_type.collection')));
* @endcode
* This keeps the context of the link title ('settings' in the example) for
* translators.
@ -60,14 +60,10 @@ interface LinkGeneratorInterface {
* class will be applied to the link. It is important to use this
* sparingly since it is usually unnecessary and requires extra
* processing.
* @param bool $collect_bubbleable_metadata
* (optional) Defaults to FALSE. When TRUE, both the generated link and its
* associated bubbleable metadata are returned.
*
* @return string|\Drupal\Core\GeneratedLink
* An HTML string containing a link to the given route and parameters.
* When $collect_bubbleable_metadata is TRUE, a GeneratedLink object is
* returned, containing the generated link plus bubbleable metadata.
* @return \Drupal\Core\GeneratedLink
* A GeneratedLink object containing a link to the given route and
* parameters and bubbleable metadata.
*
* @throws \Symfony\Component\Routing\Exception\RouteNotFoundException
* Thrown when the named route doesn't exist.
@ -77,22 +73,18 @@ interface LinkGeneratorInterface {
* Thrown when a parameter value for a placeholder is not correct because it
* does not match the requirement.
*/
public function generate($text, Url $url, $collect_bubbleable_metadata = FALSE);
public function generate($text, Url $url);
/**
* Renders a link from a link object.
*
* @param \Drupal\Core\Link $link
* A link object to convert to a string.
* @param bool $collect_bubbleable_metadata
* (optional) Defaults to FALSE. When TRUE, both the generated link and its
* associated bubbleable metadata are returned.
*
* @return string|\Drupal\Core\GeneratedLink
* An HTML string containing a link to the given route and parameters.
* When $collect_bubbleable_metadata is TRUE, a GeneratedLink object is
* returned, containing the generated link plus bubbleable metadata.
* @return \Drupal\Core\GeneratedLink
* A GeneratedLink object containing a link to the given route and
* parameters and bubbleable metadata.
*/
public function generateFromLink(Link $link, $collect_bubbleable_metadata = FALSE);
public function generateFromLink(Link $link);
}

View file

@ -19,15 +19,12 @@ class ProjectInfo {
/**
* Populates an array of project data.
*
* @todo https://www.drupal.org/node/2553909 update class since extensions can
* no longer be disabled.
*
* This iterates over a list of the installed modules or themes and groups
* them by project and status. A few parts of this function assume that
* enabled modules and themes are always processed first, and if disabled
* enabled modules and themes are always processed first, and if uninstalled
* modules or themes are being processed (there is a setting to control if
* disabled code should be included in the Available updates report or not),
* those are only processed after $projects has been populated with
* uninstalled code should be included in the Available updates report or
* not),those are only processed after $projects has been populated with
* information about the enabled code. 'Hidden' modules and themes are
* ignored if they are not installed. 'Hidden' Modules and themes in the
* "Testing" package are ignored regardless of installation status.
@ -43,8 +40,8 @@ class ProjectInfo {
* @param string $project_type
* The kind of data in the list. Can be 'module' or 'theme'.
* @param bool $status
* Boolean that controls what status (enabled or disabled) to process out of
* the $list and add to the $projects array.
* Boolean that controls what status (enabled or uninstalled) to process out
* of the $list and add to the $projects array.
* @param array $additional_whitelist
* (optional) Array of additional elements to be collected from the .info.yml
* file. Defaults to array().
@ -111,7 +108,7 @@ class ProjectInfo {
$project_display_type = $project_type;
}
if (empty($status)) {
// If we're processing disabled modules or themes, append a suffix.
// If we're processing uninstalled modules or themes, append a suffix.
$project_display_type .= '-disabled';
}
if (!isset($projects[$project_name])) {
@ -131,18 +128,19 @@ class ProjectInfo {
elseif ($projects[$project_name]['project_type'] == $project_display_type) {
// Only add the file we're processing to the 'includes' array for this
// project if it is of the same type and status (which is encoded in the
// $project_display_type). This prevents listing all the disabled
// $project_display_type). This prevents listing all the uninstalled
// modules included with an enabled project if we happen to be checking
// for disabled modules, too.
// for uninstalled modules, too.
$projects[$project_name]['includes'][$file->getName()] = $file->info['name'];
$projects[$project_name]['info']['_info_file_ctime'] = max($projects[$project_name]['info']['_info_file_ctime'], $file->info['_info_file_ctime']);
$projects[$project_name]['datestamp'] = max($projects[$project_name]['datestamp'], $file->info['datestamp']);
}
elseif (empty($status)) {
// If we have a project_name that matches, but the project_display_type
// does not, it means we're processing a disabled module or theme that
// belongs to a project that has some enabled code. In this case, we add
// the disabled thing into a separate array for separate display.
// does not, it means we're processing a uninstalled module or theme
// that belongs to a project that has some enabled code. In this case,
// we add the uninstalled thing into a separate array for separate
// display.
$projects[$project_name]['disabled'][$file->getName()] = $file->info['name'];
}
}

View file

@ -7,6 +7,8 @@
namespace Drupal\Core\Utility;
use Drupal\Component\Render\HtmlEscapedText;
use Drupal\Component\Render\MarkupInterface;
use Drupal\Core\Cache\Cache;
use Drupal\Core\Cache\CacheableDependencyInterface;
use Drupal\Core\Cache\CacheBackendInterface;
@ -141,7 +143,9 @@ class Token {
* Replaces all tokens in a given string with appropriate values.
*
* @param string $text
* A string potentially containing replaceable tokens.
* An HTML string containing replaceable tokens. The caller is responsible
* for calling \Drupal\Component\Utility\Html::escape() in case the $text
* was plain text.
* @param array $data
* (optional) An array of keyed objects. For simple replacement scenarios
* 'node', 'user', and others are common keys, with an accompanying node or
@ -154,18 +158,9 @@ class Token {
* - langcode: A language code to be used when generating locale-sensitive
* tokens.
* - callback: A callback function that will be used to post-process the
* array of token replacements after they are generated. For example, a
* module using tokens in a text-only email might provide a callback to
* strip HTML entities from token values before they are inserted into the
* final text.
* array of token replacements after they are generated.
* - clear: A boolean flag indicating that tokens should be removed from the
* final text if no replacement value can be generated.
* - sanitize: A boolean flag indicating that tokens should be sanitized for
* display to a web browser. Defaults to TRUE. Developers who set this
* option to FALSE assume responsibility for running
* \Drupal\Component\Utility\Xss::filter(),
* \Drupal\Component\Utility\SafeMarkup::checkPlain() or other appropriate
* scrubbing functions before displaying data to users.
* @param \Drupal\Core\Render\BubbleableMetadata $bubbleable_metadata|null
* (optional) An object to which static::generate() and the hooks and
* functions that it invokes will add their required bubbleable metadata.
@ -185,7 +180,13 @@ class Token {
* Renderer's currently active render context.
*
* @return string
* Text with tokens replaced.
* The token result is the entered HTML text with tokens replaced. The
* caller is responsible for choosing the right escaping / sanitization. If
* the result is intended to be used as plain text, using
* PlainTextOutput::renderFromHtml() is recommended. If the result is just
* printed as part of a template relying on Twig autoescaping is possible,
* otherwise for example the result can be put into #markup, in which case
* it would be sanitized by Xss::filterAdmin().
*/
public function replace($text, array $data = array(), array $options = array(), BubbleableMetadata $bubbleable_metadata = NULL) {
$text_tokens = $this->scan($text);
@ -204,6 +205,11 @@ class Token {
}
}
// Escape the tokens, unless they are explicitly markup.
foreach ($replacements as $token => $value) {
$replacements[$token] = $value instanceof MarkupInterface ? $value : new HtmlEscapedText($value);
}
// Optionally alter the list of replacement values.
if (!empty($options['callback'])) {
$function = $options['callback'];
@ -282,11 +288,6 @@ class Token {
* array of token replacements after they are generated. Can be used when
* modules require special formatting of token text, for example URL
* encoding or truncation to a specific length.
* - sanitize: A boolean flag indicating that tokens should be sanitized for
* display to a web browser. Developers who set this option to FALSE assume
* responsibility for running \Drupal\Component\Utility\Xss::filter(),
* \Drupal\Component\Utility\SafeMarkup::checkPlain() or other appropriate
* scrubbing functions before displaying data to users.
* @param \Drupal\Core\Render\BubbleableMetadata $bubbleable_metadata
* The bubbleable metadata. This is passed to the token replacement
* implementations so that they can attach their metadata.
@ -300,8 +301,6 @@ class Token {
* @see hook_tokens_alter()
*/
public function generate($type, array $tokens, array $data, array $options, BubbleableMetadata $bubbleable_metadata) {
$options += array('sanitize' => TRUE);
foreach ($data as $object) {
if ($object instanceof CacheableDependencyInterface || $object instanceof AttachmentsInterface) {
$bubbleable_metadata->addCacheableDependency($object);

View file

@ -115,11 +115,6 @@ class UnroutedUrlAssembler implements UnroutedUrlAssemblerInterface {
// https://www.drupal.org/node/2417459
$uri = substr($uri, 5);
// Strip leading slashes from internal paths to prevent them becoming
// external URLs without protocol. /example.com should not be turned into
// //example.com.
$uri = ltrim($uri, '/');
// Allow (outbound) path processing, if needed. A valid use case is the path
// alias overview form:
// @see \Drupal\path\Controller\PathController::adminOverview().
@ -128,6 +123,10 @@ class UnroutedUrlAssembler implements UnroutedUrlAssemblerInterface {
// want to include e.g. the request language in the processing.
$uri = $this->pathProcessor->processOutbound($uri, $options, NULL, $generated_url);
}
// Strip leading slashes from internal paths to prevent them becoming
// external URLs without protocol. /example.com should not be turned into
// //example.com.
$uri = ltrim($uri, '/');
// Add any subdirectory where Drupal is installed.
$current_base_path = $request->getBasePath() . '/';
@ -177,8 +176,7 @@ class UnroutedUrlAssembler implements UnroutedUrlAssemblerInterface {
// If the current request was made with the script name (eg, index.php) in
// it, then extract it, making sure the leading / is gone, and a trailing /
// is added, to allow simple string concatenation with other parts. This
// mirrors code from UrlGenerator::generateFromPath().
// is added, to allow simple string concatenation with other parts.
if (!empty($base_path_with_script)) {
$script_name = $request->getScriptName();
if (strpos($base_path_with_script, $script_name) !== FALSE) {

View file

@ -5,7 +5,6 @@
* Hooks related to the Token system.
*/
use Drupal\Component\Utility\Html;
use Drupal\user\Entity\User;
/**
@ -65,7 +64,9 @@ use Drupal\user\Entity\User;
*
* @return array
* An associative array of replacement values, keyed by the raw [type:token]
* strings from the original text.
* strings from the original text. The returned values must be either plain
* text strings, or an object implementing MarkupInterface if they are
* HTML-formatted.
*
* @see hook_token_info()
* @see hook_tokens_alter()
@ -81,8 +82,6 @@ function hook_tokens($type, $tokens, array $data, array $options, \Drupal\Core\R
else {
$langcode = NULL;
}
$sanitize = !empty($options['sanitize']);
$replacements = array();
if ($type == 'node' && !empty($data['node'])) {
@ -97,7 +96,7 @@ function hook_tokens($type, $tokens, array $data, array $options, \Drupal\Core\R
break;
case 'title':
$replacements[$original] = $sanitize ? Html::escape($node->getTitle()) : $node->getTitle();
$replacements[$original] = $node->getTitle();
break;
case 'edit-url':
@ -107,7 +106,7 @@ function hook_tokens($type, $tokens, array $data, array $options, \Drupal\Core\R
// Default values for the chained tokens handled below.
case 'author':
$account = $node->getOwner() ? $node->getOwner() : User::load(0);
$replacements[$original] = $sanitize ? Html::escape($account->label()) : $account->label();
$replacements[$original] = $account->label();
$bubbleable_metadata->addCacheableDependency($account);
break;