Update to Drupal 8.0.0 beta 14. For more information, see https://drupal.org/node/2544542
This commit is contained in:
parent
3b2511d96d
commit
81ccda77eb
17
.htaccess
17
.htaccess
|
@ -18,9 +18,6 @@ Options -Indexes
|
|||
# Follow symbolic links in this directory.
|
||||
Options +FollowSymLinks
|
||||
|
||||
# Make Drupal handle any 404 errors.
|
||||
ErrorDocument 404 /index.php
|
||||
|
||||
# Set the default handler.
|
||||
DirectoryIndex index.php index.html index.htm
|
||||
|
||||
|
@ -28,13 +25,14 @@ DirectoryIndex index.php index.html index.htm
|
|||
AddType image/svg+xml svg svgz
|
||||
AddEncoding gzip svgz
|
||||
|
||||
# Override PHP settings that cannot be changed at runtime. See
|
||||
# Most of the following PHP settings cannot be changed at runtime. See
|
||||
# sites/default/default.settings.php and
|
||||
# Drupal\Core\DrupalKernel::bootEnvironment() for settings that can be
|
||||
# changed at runtime.
|
||||
|
||||
# PHP 5, Apache 1 and 2.
|
||||
<IfModule mod_php5.c>
|
||||
php_value assert.active 0
|
||||
php_flag session.auto_start off
|
||||
php_value mbstring.http_input pass
|
||||
php_value mbstring.http_output pass
|
||||
|
@ -62,6 +60,14 @@ AddEncoding gzip svgz
|
|||
</FilesMatch>
|
||||
</IfModule>
|
||||
|
||||
# Set a fallback resource if mod_rewrite is not enabled. This allows Drupal to
|
||||
# work without clean URLs. This requires Apache version >= 2.2.16. If Drupal is
|
||||
# not accessed by the top level URL (i.e.: http://example.com/drupal/ instead of
|
||||
# http://example.com/), the path to index.php will need to be adjusted.
|
||||
<IfModule !mod_rewrite.c>
|
||||
FallbackResource /index.php
|
||||
</IfModule>
|
||||
|
||||
# Various rewrite rules.
|
||||
<IfModule mod_rewrite.c>
|
||||
RewriteEngine on
|
||||
|
@ -125,6 +131,9 @@ AddEncoding gzip svgz
|
|||
RewriteCond %{REQUEST_URI} !core
|
||||
RewriteRule ^ %1/core/%2 [L,QSA,R=301]
|
||||
|
||||
# Rewrite install.php during installation to see if mod_rewrite is working
|
||||
RewriteRule ^core/install.php core/install.php?rewrite=ok [QSA,L]
|
||||
|
||||
# Pass all requests not referring directly to files in the filesystem to
|
||||
# index.php.
|
||||
RewriteCond %{REQUEST_FILENAME} !-f
|
||||
|
|
3
core/.gitignore
vendored
3
core/.gitignore
vendored
|
@ -14,3 +14,6 @@ vendor/symfony/translation/Symfony/Component/Translation/*
|
|||
|
||||
# PHPUnit provides some binary dependencies that are already available.
|
||||
vendor/phpunit/phpunit/build/dependencies
|
||||
|
||||
# The PHAR file below contains CRLF characters that cause a problem with PIFR.
|
||||
vendor/symfony/dependency-injection/Tests/Fixtures/includes/ProjectWithXsdExtensionInPhar.phar
|
||||
|
|
|
@ -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.5.9 (or greater) (http://php.net/). For better security support it is
|
||||
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/).
|
||||
|
@ -121,34 +121,41 @@ INSTALLATION
|
|||
|
||||
a. Missing files directory.
|
||||
|
||||
The install script will attempt to create a file storage directory in
|
||||
the default location at sites/default/files (the location of the files
|
||||
The install script will attempt to create a public file storage directory
|
||||
in the default location at sites/default/files (the location of the files
|
||||
directory may be changed after Drupal is installed).
|
||||
|
||||
If auto-creation fails, you can make it work by changing permissions on
|
||||
the sites/default directory so that the web server can create the files
|
||||
directory within it for you. (If you are creating a multisite
|
||||
installation, substitute the correct sites directory for sites/default;
|
||||
see the Multisite Configuration section of this file, below.)
|
||||
If auto-creation fails, you can create the directory yourself. (If you are
|
||||
creating a multisite installation, substitute the correct sites directory
|
||||
for sites/default; see the Multisite Configuration section of this file,
|
||||
below.) Sample commands from a Unix/Linux command line:
|
||||
|
||||
For example, on a Unix/Linux command line, you can grant everyone
|
||||
mkdir sites/default/files
|
||||
chmod a+w sites/default/files
|
||||
|
||||
Alternatively, you can make the install script work by changing
|
||||
permissions on the sites/default directory. The web server can then
|
||||
create the files directory within it for you.
|
||||
|
||||
For example, on a Unix/Linux command line, you can you can grant everyone
|
||||
(including the web server) permission to write to the sites/default
|
||||
directory with this command:
|
||||
|
||||
chmod a+w sites/default
|
||||
|
||||
Be sure to set the permissions back after the installation is finished!
|
||||
Then re-run install.php (e.g. by clicking "try again" at the bottom of
|
||||
the Requirements problem page. Once the files directory is created, you
|
||||
will need to grant everyone (including the web server) permission to
|
||||
write to it with this command:
|
||||
|
||||
chmod a+w sites/default/files
|
||||
|
||||
Be sure to set the permissions for the default directory back after the
|
||||
installation is finished! (Leave the files directory writeable.)
|
||||
Sample command:
|
||||
|
||||
chmod go-w sites/default
|
||||
|
||||
Alternatively, instead of allowing the web server to create the files
|
||||
directory for you as described above, you can create it yourself. Sample
|
||||
commands from a Unix/Linux command line:
|
||||
|
||||
mkdir sites/default/files
|
||||
chmod a+w sites/default/files
|
||||
|
||||
b. Missing settings file.
|
||||
|
||||
Drupal will try to automatically create settings.php and services.yml
|
||||
|
|
|
@ -108,7 +108,6 @@ Database update system
|
|||
Entity system
|
||||
- Wolfgang Ziegler 'fago' https://www.drupal.org/u/fago
|
||||
- Nathaniel Catchpole 'catch' https://www.drupal.org/u/catch
|
||||
- Franz Heinzmann 'Frando' https://www.drupal.org/u/frando
|
||||
- Sascha Grossenbacher 'Berdir' https://www.drupal.org/u/berdir
|
||||
|
||||
Extension system
|
||||
|
@ -128,7 +127,6 @@ Form system
|
|||
- Wolfgang Ziegler 'fago' https://www.drupal.org/u/fago
|
||||
- Daniel F. Kudwien 'sun' https://www.drupal.org/u/sun
|
||||
- Tim Plunkett 'tim.plunkett' https://www.drupal.org/u/tim.plunkett
|
||||
- Franz Heinzmann 'Frando' https://www.drupal.org/u/frando
|
||||
|
||||
Image system
|
||||
- Claudiu Cristea 'claudiu.cristea' https://www.drupal.org/u/claudiu.cristea
|
||||
|
@ -182,7 +180,6 @@ Queue system
|
|||
Render system
|
||||
- Moshe Weitzman 'moshe weitzman' https://www.drupal.org/u/moshe-weitzman
|
||||
- Alex Bronstein 'effulgentsia' https://www.drupal.org/u/effulgentsia
|
||||
- Franz Heinzmann 'Frando' https://www.drupal.org/u/frando
|
||||
|
||||
Request processing system
|
||||
- Larry Garfield 'Crell' https://www.drupal.org/u/crell
|
||||
|
@ -298,7 +295,8 @@ Configuration Translation module
|
|||
|
||||
Contact module
|
||||
- Lee Rowlands 'larowlan' https://www.drupal.org/u/larowlan
|
||||
- Tim Eisenhuth 'tim-e' https://www.drupal.org/u/tim-e
|
||||
- Jibran Ijaz 'jibran' https://www.drupal.org/u/jibran
|
||||
- Andrey Postnikov 'andypost' https://www.drupal.org/u/andypost
|
||||
|
||||
Content Translation module
|
||||
- Francesco Placella 'plach' https://www.drupal.org/u/plach
|
||||
|
|
|
@ -67,6 +67,9 @@ following the instructions in the INTRODUCTION section at the top of this file:
|
|||
Sometimes an update includes changes to default.settings.php (this will be
|
||||
noted in the release notes). If that's the case, follow these steps:
|
||||
|
||||
- Locate your settings.php file in the /sites/* directory. (Typically
|
||||
sites/default.)
|
||||
|
||||
- Make a backup copy of your settings.php file, with a different file name.
|
||||
|
||||
- Make a copy of the new default.settings.php file, and name the copy
|
||||
|
@ -77,6 +80,13 @@ following the instructions in the INTRODUCTION section at the top of this file:
|
|||
database information, and you will also want to copy in any other
|
||||
customizations you have added.
|
||||
|
||||
You can find the release notes for your version at
|
||||
https://www.drupal.org/project/drupal. At bottom of the project page under
|
||||
"Downloads" use the link for your version of Drupal to view the release
|
||||
notes. If your version is not listed, use the 'View all releases' link. From
|
||||
this page you can scroll down or use the filter to find your version and its
|
||||
release notes.
|
||||
|
||||
4. Download the latest Drupal 8.x release from https://www.drupal.org to a
|
||||
directory outside of your web root. Extract the archive and copy the files
|
||||
into your Drupal directory.
|
||||
|
|
2
core/assets/vendor/backbone/backbone-min.js
vendored
2
core/assets/vendor/backbone/backbone-min.js
vendored
File diff suppressed because one or more lines are too long
2
core/assets/vendor/backbone/backbone-min.map
vendored
2
core/assets/vendor/backbone/backbone-min.map
vendored
File diff suppressed because one or more lines are too long
1873
core/assets/vendor/backbone/backbone.js
vendored
Normal file
1873
core/assets/vendor/backbone/backbone.js
vendored
Normal file
File diff suppressed because it is too large
Load diff
|
@ -4,8 +4,7 @@
|
|||
"type": "drupal-core",
|
||||
"license": "GPL-2.0+",
|
||||
"require": {
|
||||
"php": ">=5.4.5",
|
||||
"sdboyer/gliph": "0.1.*",
|
||||
"php": ">=5.5.9",
|
||||
"symfony/class-loader": "2.7.*",
|
||||
"symfony/console": "2.7.*",
|
||||
"symfony/css-selector": "2.7.*",
|
||||
|
@ -22,18 +21,20 @@
|
|||
"twig/twig": "1.18.*",
|
||||
"doctrine/common": "~2.4.2",
|
||||
"doctrine/annotations": "1.2.*",
|
||||
"guzzlehttp/guzzle": "~5.0",
|
||||
"guzzlehttp/guzzle": "dev-master#1879fbe853b0c64d109e369c7aeff09849e62d1e",
|
||||
"symfony-cmf/routing": "1.3.*",
|
||||
"easyrdf/easyrdf": "0.9.*",
|
||||
"phpunit/phpunit": "4.6.*",
|
||||
"zendframework/zend-feed": "2.4.*",
|
||||
"mikey179/vfsStream": "1.*",
|
||||
"mikey179/vfsStream": "~1.2",
|
||||
"stack/builder": "1.0.*",
|
||||
"egulias/email-validator": "1.2.*",
|
||||
"behat/mink": "~1.6",
|
||||
"behat/mink-goutte-driver": "~1.1",
|
||||
"fabpot/goutte": "^2.0.3",
|
||||
"masterminds/html5": "~2.1"
|
||||
"behat/mink-goutte-driver": "dev-master#cc5ce119b5a8e06662f634b35967aff0b0c7dfdd",
|
||||
"fabpot/goutte": "~3.1",
|
||||
"masterminds/html5": "~2.1",
|
||||
"symfony/psr-http-message-bridge": "v0.2",
|
||||
"zendframework/zend-diactoros": "1.1.0"
|
||||
},
|
||||
"replace": {
|
||||
"drupal/action": "self.version",
|
||||
|
|
583
core/composer.lock
generated
583
core/composer.lock
generated
File diff suppressed because it is too large
Load diff
|
@ -56,6 +56,11 @@ label:
|
|||
label: 'Label'
|
||||
translatable: true
|
||||
|
||||
# String containing plural variants, separated by EXT.
|
||||
plural_label:
|
||||
type: label
|
||||
label: 'Plural variants'
|
||||
|
||||
# Internal Drupal path
|
||||
path:
|
||||
type: string
|
||||
|
|
|
@ -57,6 +57,7 @@
|
|||
* - @link queue Queue API @endlink
|
||||
* - @link typed_data Typed Data @endlink
|
||||
* - @link testing Automated tests @endlink
|
||||
* - @link php_assert PHP Runtime Assert Statements @endlink
|
||||
* - @link third_party Integrating third-party applications @endlink
|
||||
*
|
||||
* @section more_info Further information
|
||||
|
@ -982,6 +983,55 @@
|
|||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup php_assert PHP Runtime Assert Statements
|
||||
* @{
|
||||
* Use of the assert() statement in Drupal.
|
||||
*
|
||||
* Unit tests also use the term "assertion" to refer to test conditions, so to
|
||||
* avoid confusion the term "runtime assertion" will be used for the assert()
|
||||
* statement throughout the documentation.
|
||||
*
|
||||
* A runtime assertion is a statement that is expected to always be true at
|
||||
* the point in the code it appears at. They are tested using PHP's internal
|
||||
* @link http://www.php.net/assert assert() @endlink statement. If an
|
||||
* assertion is ever FALSE it indicates an error in the code or in module or
|
||||
* theme configuration files. User-provided configuration files should be
|
||||
* verified with standard control structures at all times, not just checked in
|
||||
* development environments with assert() statements on.
|
||||
*
|
||||
* When runtime assertions fail in PHP 7 an \AssertionException is thrown.
|
||||
* Drupal uses an assertion callback to do the same in PHP 5.x so that unit
|
||||
* tests involving runtime assertions will work uniformly across both versions.
|
||||
*
|
||||
* The Drupal project primarily uses runtime assertions to enforce the
|
||||
* expectations of the API by failing when incorrect calls are made by code
|
||||
* under development. While PHP type hinting does this for objects and arrays,
|
||||
* runtime assertions do this for scalars (strings, integers, floats, etc.) and
|
||||
* complex data structures such as cache and render arrays. They ensure that
|
||||
* methods' return values are the documented datatypes. They also verify that
|
||||
* objects have been properly configured and set up by the service container.
|
||||
* Runtime assertions are checked throughout development. They supplement unit
|
||||
* tests by checking scenarios that do not have unit tests written for them,
|
||||
* and by testing the API calls made by all the code in the system.
|
||||
*
|
||||
* When using assert() keep the following in mind:
|
||||
* - Runtime assertions are disabled by default in production and enabled in
|
||||
* development, so they can't be used as control structures. Use exceptions
|
||||
* for errors that can occur in production no matter how unlikely they are.
|
||||
* - Assert() functions in a buggy manner prior to PHP 7. If you do not use a
|
||||
* string for the first argument of the statement but instead use a function
|
||||
* call or expression then that code will be evaluated even when runtime
|
||||
* assertions are turned off. To avoid this you must use a string as the
|
||||
* first argument, and assert will pass this string to the eval() statement.
|
||||
* - Since runtime assertion strings are parsed by eval() use caution when
|
||||
* using them to work with data that may be unsanitized.
|
||||
*
|
||||
* See https://www.drupal.org/node/2492225 for more information on runtime
|
||||
* assertions.
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup info_types Information types
|
||||
* @{
|
||||
|
@ -2054,12 +2104,6 @@ function hook_validation_constraint_alter(array &$definitions) {
|
|||
* an array. Here are the details of its elements, all of which are optional:
|
||||
* - callback: The callback to invoke to handle the server side of the
|
||||
* Ajax event. More information on callbacks is below in @ref sub_callback.
|
||||
* - path: The URL path to use for the request. If omitted, defaults to
|
||||
* 'system/ajax', which invokes the default Drupal Ajax processing (this will
|
||||
* call the callback supplied in the 'callback' element). If you supply a
|
||||
* path, you must set up a routing entry to handle the request yourself and
|
||||
* return output described in @ref sub_callback below. See the
|
||||
* @link menu Routing topic @endlink for more information on routing.
|
||||
* - wrapper: The HTML 'id' attribute of the area where the content returned by
|
||||
* the callback should be placed. Note that callbacks have a choice of
|
||||
* returning content or JavaScript commands; 'wrapper' is used for content
|
||||
|
@ -2085,6 +2129,13 @@ function hook_validation_constraint_alter(array &$definitions) {
|
|||
* - message: Translated message to display.
|
||||
* - url: For a bar progress indicator, URL path for determining progress.
|
||||
* - interval: For a bar progress indicator, how often to update it.
|
||||
* - url: A \Drupal\Core\Url to which to submit the Ajax request. If omitted,
|
||||
* defaults to either the same URL as the form or link destination is for
|
||||
* someone with JavaScript disabled, or a slightly modified version (e.g.,
|
||||
* with a query parameter added, removed, or changed) of that URL if
|
||||
* necessary to support Drupal's content negotiation. It is recommended to
|
||||
* omit this key and use Drupal's content negotiation rather than using
|
||||
* substantially different URLs between Ajax and non-Ajax.
|
||||
*
|
||||
* @subsection sub_callback Setting up a callback to process Ajax
|
||||
* Once you have set up your form to trigger an Ajax response (see @ref sub_form
|
||||
|
@ -2186,6 +2237,13 @@ function hook_validation_constraint_alter(array &$definitions) {
|
|||
* at the end of a request to finalize operations, if this service was
|
||||
* instantiated. Services should implement \Drupal\Core\DestructableInterface
|
||||
* in this case.
|
||||
* - context_provider: Indicates a block context provider, used for example
|
||||
* by block conditions. It has to implement
|
||||
* \Drupal\Core\Plugin\Context\ContextProviderInterface.
|
||||
* - http_client_middleware: Indicates that the service provides a guzzle
|
||||
* middleware, see
|
||||
* https://guzzle.readthedocs.org/en/latest/handlers-and-middleware.html for
|
||||
* more information.
|
||||
*
|
||||
* Creating a tag for a service does not do anything on its own, but tags
|
||||
* can be discovered or queried in a compiler pass when the container is built,
|
||||
|
|
|
@ -2,10 +2,10 @@
|
|||
|
||||
backbone:
|
||||
remote: https://github.com/jashkenas/backbone
|
||||
version: "1.1.2"
|
||||
version: "1.2.1"
|
||||
license:
|
||||
name: MIT
|
||||
url: https://github.com/jashkenas/backbone/blob/1.1.2/LICENSE
|
||||
url: https://github.com/jashkenas/backbone/blob/1.2.1/LICENSE
|
||||
gpl-compatible: true
|
||||
js:
|
||||
assets/vendor/backbone/backbone-min.js: { weight: -19, minified: true }
|
||||
|
@ -133,6 +133,15 @@ drupal.collapse:
|
|||
- core/drupal.form
|
||||
- core/jquery.once
|
||||
|
||||
drupal.date:
|
||||
version: VERSION
|
||||
js:
|
||||
misc/date.js: {}
|
||||
dependencies:
|
||||
- core/drupal
|
||||
- core/modernizr
|
||||
- core/jquery.ui.datepicker
|
||||
|
||||
drupal.debounce:
|
||||
version: VERSION
|
||||
js:
|
||||
|
|
|
@ -2,11 +2,25 @@ parameters:
|
|||
session.storage.options: {}
|
||||
twig.config: {}
|
||||
renderer.config:
|
||||
required_cache_contexts: ['languages:language_interface', 'theme']
|
||||
required_cache_contexts: ['languages:language_interface', 'theme', 'user.permissions']
|
||||
factory.keyvalue:
|
||||
default: keyvalue.database
|
||||
factory.keyvalue.expirable:
|
||||
default: keyvalue.expirable.database
|
||||
filter_protocols:
|
||||
- http
|
||||
- https
|
||||
- ftp
|
||||
- news
|
||||
- nntp
|
||||
- tel
|
||||
- telnet
|
||||
- mailto
|
||||
- irc
|
||||
- ssh
|
||||
- sftp
|
||||
- webcal
|
||||
- rtsp
|
||||
services:
|
||||
# Simple cache contexts, directly derived from the request context.
|
||||
cache_context.ip:
|
||||
|
@ -24,6 +38,11 @@ services:
|
|||
arguments: ['@request_stack']
|
||||
tags:
|
||||
- { name: cache.context }
|
||||
cache_context.session:
|
||||
class: Drupal\Core\Cache\Context\SessionCacheContext
|
||||
arguments: ['@request_stack']
|
||||
tags:
|
||||
- { name: cache.context}
|
||||
cache_context.request_format:
|
||||
class: Drupal\Core\Cache\Context\RequestFormatCacheContext
|
||||
arguments: ['@request_stack']
|
||||
|
@ -266,6 +285,9 @@ services:
|
|||
context.handler:
|
||||
class: Drupal\Core\Plugin\Context\ContextHandler
|
||||
arguments: ['@typed_data_manager']
|
||||
context.repository:
|
||||
class: Drupal\Core\Plugin\Context\LazyContextRepository
|
||||
arguments: ['@service_container']
|
||||
cron:
|
||||
class: Drupal\Core\Cron
|
||||
arguments: ['@module_handler', '@lock', '@queue', '@state', '@account_switcher', '@logger.channel.cron', '@plugin.manager.queue_worker']
|
||||
|
@ -371,10 +393,21 @@ services:
|
|||
path.current:
|
||||
class: Drupal\Core\Path\CurrentPathStack
|
||||
arguments: ['@request_stack']
|
||||
http_handler_stack:
|
||||
class: GuzzleHttp\HandlerStack
|
||||
public: false
|
||||
factory: GuzzleHttp\HandlerStack::create
|
||||
configurator: ['@http_handler_stack_configurator', configure]
|
||||
http_handler_stack_configurator:
|
||||
class: Drupal\Core\Http\HandlerStackConfigurator
|
||||
public: false
|
||||
arguments: ['@service_container']
|
||||
http_client:
|
||||
class: Drupal\Core\Http\Client
|
||||
tags:
|
||||
- { name: service_collector, tag: http_client_subscriber, call: attach }
|
||||
class: GuzzleHttp\Client
|
||||
factory: http_client_factory:fromOptions
|
||||
http_client_factory:
|
||||
class: Drupal\Core\Http\ClientFactory
|
||||
arguments: ['@http_handler_stack']
|
||||
theme.negotiator:
|
||||
class: Drupal\Core\Theme\ThemeNegotiator
|
||||
arguments: ['@access_check.theme']
|
||||
|
@ -596,9 +629,18 @@ services:
|
|||
- { name: http_middleware, priority: 50 }
|
||||
calls:
|
||||
- [setContainer, ['@service_container']]
|
||||
psr7.http_foundation_factory:
|
||||
class: Symfony\Bridge\PsrHttpMessage\Factory\HttpFoundationFactory
|
||||
psr7.http_message_factory:
|
||||
class: Symfony\Bridge\PsrHttpMessage\Factory\DiactorosFactory
|
||||
language_manager:
|
||||
class: Drupal\Core\Language\LanguageManager
|
||||
arguments: ['@language.default']
|
||||
language.current_language_context:
|
||||
class: Drupal\Core\Language\ContextProvider\CurrentLanguageContext
|
||||
arguments: ['@language_manager']
|
||||
tags:
|
||||
- { name: 'context_provider' }
|
||||
language.default:
|
||||
class: Drupal\Core\Language\LanguageDefault
|
||||
arguments: ['%language.default_values%']
|
||||
|
@ -682,9 +724,15 @@ services:
|
|||
arguments: ['@route_filter.lazy_collector']
|
||||
tags:
|
||||
- { name: event_subscriber }
|
||||
url_generator:
|
||||
url_generator.non_bubbling:
|
||||
class: Drupal\Core\Routing\UrlGenerator
|
||||
arguments: ['@router.route_provider', '@path_processor_manager', '@route_processor_manager', '@config.factory', '@request_stack']
|
||||
arguments: ['@router.route_provider', '@path_processor_manager', '@route_processor_manager', '@request_stack', '%filter_protocols%']
|
||||
public: false
|
||||
calls:
|
||||
- [setContext, ['@?router.request_context']]
|
||||
url_generator:
|
||||
class: Drupal\Core\Render\MetadataBubblingUrlGenerator
|
||||
arguments: ['@url_generator.non_bubbling', '@renderer']
|
||||
calls:
|
||||
- [setContext, ['@?router.request_context']]
|
||||
redirect.destination:
|
||||
|
@ -692,10 +740,10 @@ services:
|
|||
arguments: ['@request_stack', '@url_generator']
|
||||
unrouted_url_assembler:
|
||||
class: Drupal\Core\Utility\UnroutedUrlAssembler
|
||||
arguments: ['@request_stack', '@config.factory', '@path_processor_manager']
|
||||
arguments: ['@request_stack', '@path_processor_manager', '%filter_protocols%']
|
||||
link_generator:
|
||||
class: Drupal\Core\Utility\LinkGenerator
|
||||
arguments: ['@url_generator', '@module_handler']
|
||||
arguments: ['@url_generator', '@module_handler', '@renderer']
|
||||
router:
|
||||
class: Drupal\Core\Routing\AccessAwareRouter
|
||||
arguments: ['@router.no_access_checks', '@access_manager', '@current_user']
|
||||
|
@ -729,6 +777,9 @@ services:
|
|||
arguments: ['@database']
|
||||
tags:
|
||||
- { name: backend_overridable }
|
||||
pgsql.entity.query.sql:
|
||||
class: Drupal\Core\Entity\Query\Sql\pgsql\QueryFactory
|
||||
arguments: ['@database']
|
||||
entity.query.null:
|
||||
class: Drupal\Core\Entity\Query\Null\QueryFactory
|
||||
entity.query.keyvalue:
|
||||
|
@ -856,6 +907,11 @@ services:
|
|||
class: Drupal\Core\EventSubscriber\RouteMethodSubscriber
|
||||
tags:
|
||||
- { name: event_subscriber }
|
||||
psr_response_view_subscriber:
|
||||
class: Drupal\Core\EventSubscriber\PsrResponseSubscriber
|
||||
arguments: ['@psr7.http_foundation_factory']
|
||||
tags:
|
||||
- { name: event_subscriber }
|
||||
|
||||
# Main content view subscriber plus the renderers it uses.
|
||||
main_content_view_subscriber:
|
||||
|
@ -1003,6 +1059,10 @@ services:
|
|||
arguments: ['@url_generator', '@router.request_context']
|
||||
tags:
|
||||
- { name: event_subscriber }
|
||||
redirect_leading_slashes_subscriber:
|
||||
class: Drupal\Core\EventSubscriber\RedirectLeadingSlashesSubscriber
|
||||
tags:
|
||||
- { name: event_subscriber }
|
||||
request_close_subscriber:
|
||||
class: Drupal\Core\EventSubscriber\RequestCloseSubscriber
|
||||
tags:
|
||||
|
@ -1031,7 +1091,7 @@ services:
|
|||
class: Drupal\Core\EventSubscriber\DefaultExceptionSubscriber
|
||||
tags:
|
||||
- { name: event_subscriber }
|
||||
arguments: ['@config.factory', '@bare_html_page_renderer']
|
||||
arguments: ['@config.factory']
|
||||
exception.logger:
|
||||
class: Drupal\Core\EventSubscriber\ExceptionLoggingSubscriber
|
||||
tags:
|
||||
|
@ -1152,7 +1212,7 @@ services:
|
|||
- { name: service_collector, tag: breadcrumb_builder, call: addBuilder }
|
||||
token:
|
||||
class: Drupal\Core\Utility\Token
|
||||
arguments: ['@module_handler', '@cache.discovery', '@language_manager', '@cache_tags.invalidator']
|
||||
arguments: ['@module_handler', '@cache.discovery', '@language_manager', '@cache_tags.invalidator', '@renderer']
|
||||
batch.storage:
|
||||
class: Drupal\Core\Batch\BatchStorage
|
||||
arguments: ['@database', '@session', '@csrf_token']
|
||||
|
@ -1179,50 +1239,71 @@ services:
|
|||
calls:
|
||||
- [setContainer, ['@service_container']]
|
||||
arguments: ['feed.writer.']
|
||||
# Zend Feed reader plugins
|
||||
# Zend Feed reader plugins. Plugins should be set as prototype scope.
|
||||
feed.reader.dublincoreentry:
|
||||
class: Zend\Feed\Reader\Extension\DublinCore\Entry
|
||||
scope: prototype
|
||||
feed.reader.dublincorefeed:
|
||||
class: Zend\Feed\Reader\Extension\DublinCore\Feed
|
||||
scope: prototype
|
||||
feed.reader.contententry:
|
||||
class: Zend\Feed\Reader\Extension\Content\Entry
|
||||
scope: prototype
|
||||
feed.reader.atomentry:
|
||||
class: Zend\Feed\Reader\Extension\Atom\Entry
|
||||
scope: prototype
|
||||
feed.reader.atomfeed:
|
||||
class: Zend\Feed\Reader\Extension\Atom\Feed
|
||||
scope: prototype
|
||||
feed.reader.slashentry:
|
||||
class: Zend\Feed\Reader\Extension\Slash\Entry
|
||||
scope: prototype
|
||||
feed.reader.wellformedwebentry:
|
||||
class: Zend\Feed\Reader\Extension\WellFormedWeb\Entry
|
||||
scope: prototype
|
||||
feed.reader.threadentry:
|
||||
class: Zend\Feed\Reader\Extension\Thread\Entry
|
||||
scope: prototype
|
||||
feed.reader.podcastentry:
|
||||
class: Zend\Feed\Reader\Extension\Podcast\Entry
|
||||
scope: prototype
|
||||
feed.reader.podcastfeed:
|
||||
class: Zend\Feed\Reader\Extension\Podcast\Feed
|
||||
# Zend Feed writer plugins
|
||||
scope: prototype
|
||||
# Zend Feed writer plugins. Plugins should be set as prototype scope.
|
||||
feed.writer.atomrendererfeed:
|
||||
class: Zend\Feed\Writer\Extension\Atom\Renderer\Feed
|
||||
scope: prototype
|
||||
feed.writer.contentrendererentry:
|
||||
class: Zend\Feed\Writer\Extension\Content\Renderer\Entry
|
||||
scope: prototype
|
||||
feed.writer.dublincorerendererentry:
|
||||
class: Zend\Feed\Writer\Extension\DublinCore\Renderer\Entry
|
||||
scope: prototype
|
||||
feed.writer.dublincorerendererfeed:
|
||||
class: Zend\Feed\Writer\Extension\DublinCore\Renderer\Feed
|
||||
scope: prototype
|
||||
feed.writer.itunesentry:
|
||||
class: Zend\Feed\Writer\Extension\ITunes\Entry
|
||||
scope: prototype
|
||||
feed.writer.itunesfeed:
|
||||
class: Zend\Feed\Writer\Extension\ITunes\Feed
|
||||
scope: prototype
|
||||
feed.writer.itunesrendererentry:
|
||||
class: Zend\Feed\Writer\Extension\ITunes\Renderer\Entry
|
||||
scope: prototype
|
||||
feed.writer.itunesrendererfeed:
|
||||
class: Zend\Feed\Writer\Extension\ITunes\Renderer\Feed
|
||||
scope: prototype
|
||||
feed.writer.slashrendererentry:
|
||||
class: Zend\Feed\Writer\Extension\Slash\Renderer\Entry
|
||||
scope: prototype
|
||||
feed.writer.threadingrendererentry:
|
||||
class: Zend\Feed\Writer\Extension\Threading\Renderer\Entry
|
||||
scope: prototype
|
||||
feed.writer.wellformedwebrendererentry:
|
||||
class: Zend\Feed\Writer\Extension\WellFormedWeb\Renderer\Entry
|
||||
scope: prototype
|
||||
theme.manager:
|
||||
class: Drupal\Core\Theme\ThemeManager
|
||||
arguments: ['@app.root', '@theme.negotiator', '@theme.initialization', '@request_stack', '@module_handler']
|
||||
|
@ -1240,6 +1321,9 @@ services:
|
|||
- [setThemeManager, ['@theme.manager']]
|
||||
authentication:
|
||||
class: Drupal\Core\Authentication\AuthenticationManager
|
||||
arguments: ['@authentication_collector']
|
||||
authentication_collector:
|
||||
class: Drupal\Core\Authentication\AuthenticationCollector
|
||||
tags:
|
||||
- { name: service_collector, tag: authentication_provider, call: addProvider }
|
||||
authentication_subscriber:
|
||||
|
@ -1337,7 +1421,7 @@ services:
|
|||
class: Drupal\Core\Extension\InfoParser
|
||||
twig:
|
||||
class: Drupal\Core\Template\TwigEnvironment
|
||||
arguments: ['@app.root', '@twig.loader', '%twig.config%']
|
||||
arguments: ['@app.root', '@cache.default', '@twig.loader', '%twig.config%']
|
||||
tags:
|
||||
- { name: service_collector, tag: 'twig.extension', call: addExtension }
|
||||
twig.extension:
|
||||
|
@ -1377,6 +1461,7 @@ services:
|
|||
alias: plugin.manager.element_info
|
||||
file.mime_type.guesser:
|
||||
class: Drupal\Core\File\MimeType\MimeTypeGuesser
|
||||
arguments: ['@stream_wrapper_manager']
|
||||
tags:
|
||||
- { name: service_collector, tag: mime_type_guesser, call: addGuesser }
|
||||
lazy: true
|
||||
|
@ -1391,7 +1476,12 @@ services:
|
|||
arguments: ['@request_stack', '@cache_factory', '@cache_contexts_manager']
|
||||
renderer:
|
||||
class: Drupal\Core\Render\Renderer
|
||||
arguments: ['@controller_resolver', '@theme.manager', '@plugin.manager.element_info', '@render_cache', '%renderer.config%']
|
||||
arguments: ['@controller_resolver', '@theme.manager', '@plugin.manager.element_info', '@render_cache', '@request_stack', '%renderer.config%']
|
||||
early_rendering_controller_wrapper_subscriber:
|
||||
class: Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber
|
||||
arguments: ['@controller_resolver', '@renderer']
|
||||
tags:
|
||||
- { name: event_subscriber }
|
||||
email.validator:
|
||||
class: Egulias\EmailValidator\EmailValidator
|
||||
|
||||
|
|
|
@ -165,7 +165,7 @@ function _batch_progress_page() {
|
|||
$query_options['op'] = $new_op;
|
||||
$batch['url']->setOption('query', $query_options);
|
||||
|
||||
$url = $batch['url']->toString();
|
||||
$url = $batch['url']->toString(TRUE)->getGeneratedUrl();
|
||||
|
||||
$build = array(
|
||||
'#theme' => 'progress_bar',
|
||||
|
|
|
@ -23,7 +23,7 @@ use Drupal\Core\Language\LanguageInterface;
|
|||
/**
|
||||
* Minimum supported version of PHP.
|
||||
*/
|
||||
const DRUPAL_MINIMUM_PHP = '5.4.5';
|
||||
const DRUPAL_MINIMUM_PHP = '5.5.9';
|
||||
|
||||
/**
|
||||
* Minimum recommended value of PHP memory_limit.
|
||||
|
@ -174,7 +174,7 @@ function config_get_config_directory($type = CONFIG_ACTIVE_DIRECTORY) {
|
|||
if (!empty($config_directories[$type])) {
|
||||
return $config_directories[$type];
|
||||
}
|
||||
throw new \Exception(format_string('The configuration directory type %type does not exist.', array('%type' => $type)));
|
||||
throw new \Exception("The configuration directory type '$type' does not exist");
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -563,7 +563,7 @@ function drupal_set_message($message = NULL, $type = 'status', $repeat = FALSE)
|
|||
|
||||
$new = array(
|
||||
'safe' => SafeMarkup::isSafe($message),
|
||||
'message' => $message,
|
||||
'message' => (string) $message,
|
||||
);
|
||||
if ($repeat || !in_array($new, $_SESSION['messages'][$type])) {
|
||||
$_SESSION['messages'][$type][] = $new;
|
||||
|
@ -679,7 +679,7 @@ function _drupal_error_handler($error_level, $message, $filename, $line, $contex
|
|||
* always fatal: the execution of the script will stop as soon as the exception
|
||||
* handler exits.
|
||||
*
|
||||
* @param \Exception|\BaseException $exception
|
||||
* @param \Exception|\Throwable $exception
|
||||
* The exception object that was thrown.
|
||||
*/
|
||||
function _drupal_exception_handler($exception) {
|
||||
|
@ -689,12 +689,13 @@ function _drupal_exception_handler($exception) {
|
|||
// Log the message to the watchdog and return an error page to the user.
|
||||
_drupal_log_error(Error::decodeException($exception), TRUE);
|
||||
}
|
||||
// PHP 7 introduces BaseExceptions.
|
||||
catch (BaseException $exception2) {
|
||||
_drupal_exception_handler_additional($exception, $exception2);
|
||||
// PHP 7 introduces Throwable, which covers both Error and
|
||||
// Exception throwables.
|
||||
catch (\Throwable $error) {
|
||||
_drupal_exception_handler_additional($exception, $error);
|
||||
}
|
||||
// In order to be compatibile with PHP 5 we also catch regular Exceptions.
|
||||
catch (Exception $exception2) {
|
||||
catch (\Exception $exception2) {
|
||||
_drupal_exception_handler_additional($exception, $exception2);
|
||||
}
|
||||
}
|
||||
|
@ -702,9 +703,9 @@ function _drupal_exception_handler($exception) {
|
|||
/**
|
||||
* Displays any additional errors caught while handling an exception.
|
||||
*
|
||||
* @param \Exception|\BaseException $exception
|
||||
* @param \Exception|\Throwable $exception
|
||||
* The first exception object that was thrown.
|
||||
* @param \Exception|\BaseException $exception
|
||||
* @param \Exception|\Throwable $exception2
|
||||
* The second exception object that was thrown.
|
||||
*/
|
||||
function _drupal_exception_handler_additional($exception, $exception2) {
|
||||
|
@ -1098,12 +1099,13 @@ function _drupal_shutdown_function() {
|
|||
call_user_func_array($callback['callback'], $callback['arguments']);
|
||||
}
|
||||
}
|
||||
// PHP 7 introduces BaseExceptions.
|
||||
catch (BaseException $exception) {
|
||||
_drupal_shutdown_function_handle_exception($exception);
|
||||
// PHP 7 introduces Throwable, which covers both Error and
|
||||
// Exception throwables.
|
||||
catch (\Throwable $error) {
|
||||
_drupal_shutdown_function_handle_exception($error);
|
||||
}
|
||||
// In order to be compatibile with PHP 5 we also catch regular Exceptions.
|
||||
catch (Exception $exception) {
|
||||
catch (\Exception $exception) {
|
||||
_drupal_shutdown_function_handle_exception($exception);
|
||||
}
|
||||
}
|
||||
|
@ -1111,7 +1113,7 @@ function _drupal_shutdown_function() {
|
|||
/**
|
||||
* Displays and logs any errors that may happen during shutdown.
|
||||
*
|
||||
* @param \Exception|\BaseException $exception
|
||||
* @param \Exception|\Throwable $exception
|
||||
* The exception object that was thrown.
|
||||
*
|
||||
* @see _drupal_shutdown_function()
|
||||
|
|
|
@ -856,9 +856,9 @@ function drupal_process_states(&$elements) {
|
|||
* foreach ($regions as $region) {
|
||||
* drupal_attach_tabledrag('my-module-table', array(
|
||||
* 'action' => 'order',
|
||||
* 'relationship' => sibling',
|
||||
* 'relationship' => 'sibling',
|
||||
* 'group' => 'my-elements-weight',
|
||||
* 'subgroup' => my-elements-weight-' . $region,
|
||||
* 'subgroup' => 'my-elements-weight-' . $region,
|
||||
* ));
|
||||
* }
|
||||
* @endcode
|
||||
|
@ -1036,7 +1036,7 @@ function drupal_pre_render_links($element) {
|
|||
$child = &$element[$key];
|
||||
// If the child has links which have not been printed yet and the user has
|
||||
// access to it, merge its links in to the parent.
|
||||
if (isset($child['#links']) && empty($child['#printed']) && (!isset($child['#access']) || $child['#access'])) {
|
||||
if (isset($child['#links']) && empty($child['#printed']) && Element::isVisibleElement($child)) {
|
||||
$element['#links'] += $child['#links'];
|
||||
// Mark the child as having been printed already (so that its links
|
||||
// cannot be mistakenly rendered twice).
|
||||
|
@ -1295,8 +1295,10 @@ function drupal_flush_all_caches() {
|
|||
// Reset all static caches.
|
||||
drupal_static_reset();
|
||||
|
||||
// Wipe the PHP Storage caches.
|
||||
PhpStorageFactory::get('service_container')->deleteAll();
|
||||
// Invalidate the container.
|
||||
\Drupal::service('kernel')->invalidateContainer();
|
||||
|
||||
// Wipe the Twig PHP Storage cache.
|
||||
PhpStorageFactory::get('twig')->deleteAll();
|
||||
|
||||
// Rebuild module and theme data.
|
||||
|
|
|
@ -1,9 +1,5 @@
|
|||
<?php
|
||||
|
||||
use Drupal\Core\Database\Database;
|
||||
use Drupal\Core\Database\Query\Condition;
|
||||
use Drupal\Core\Site\Settings;
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Core systems for the database layer.
|
||||
|
@ -13,6 +9,10 @@ use Drupal\Core\Site\Settings;
|
|||
* file only, as they cannot auto-load the way classes can.
|
||||
*/
|
||||
|
||||
use Drupal\Core\Database\Database;
|
||||
use Drupal\Core\Database\Query\Condition;
|
||||
use Drupal\Core\Site\Settings;
|
||||
|
||||
/**
|
||||
* @addtogroup database
|
||||
* @{
|
||||
|
@ -28,23 +28,29 @@ use Drupal\Core\Site\Settings;
|
|||
* Do not use this function for INSERT, UPDATE, or DELETE queries. Those should
|
||||
* be handled via db_insert(), db_update() and db_delete() respectively.
|
||||
*
|
||||
* @param $query
|
||||
* @param string|\Drupal\Core\Database\StatementInterface $query
|
||||
* The prepared statement query to run. Although it will accept both named and
|
||||
* unnamed placeholders, named placeholders are strongly preferred as they are
|
||||
* more self-documenting. If the argument corresponding to a placeholder is
|
||||
* an array of values to be expanded, e.g. for an IN query, the placeholder
|
||||
* should be named with a trailing bracket like :example[]
|
||||
* @param $args
|
||||
* @param array $args
|
||||
* An array of values to substitute into the query. If the query uses named
|
||||
* placeholders, this is an associative array in any order. If the query uses
|
||||
* unnamed placeholders (?), this is an indexed array and the order must match
|
||||
* the order of placeholders in the query string.
|
||||
* @param $options
|
||||
* @param array $options
|
||||
* An array of options to control how the query operates.
|
||||
*
|
||||
* @return \Drupal\Core\Database\StatementInterface
|
||||
* A prepared statement object, already executed.
|
||||
*
|
||||
* @deprecated as of Drupal 8.0.x, will be removed in Drupal 9.0.0. Instead, get
|
||||
* a database connection injected into your service from the container and
|
||||
* call query() on it. E.g.
|
||||
* $injected_database->query($query, $args, $options);
|
||||
*
|
||||
* @see \Drupal\Core\Database\Connection::query()
|
||||
* @see \Drupal\Core\Database\Connection::defaultOptions()
|
||||
*/
|
||||
function db_query($query, array $args = array(), array $options = array()) {
|
||||
|
@ -58,7 +64,7 @@ function db_query($query, array $args = array(), array $options = array()) {
|
|||
/**
|
||||
* Executes a query against the active database, restricted to a range.
|
||||
*
|
||||
* @param $query
|
||||
* @param string $query
|
||||
* The prepared statement query to run. Although it will accept both named and
|
||||
* unnamed placeholders, named placeholders are strongly preferred as they are
|
||||
* more self-documenting.
|
||||
|
@ -66,17 +72,23 @@ function db_query($query, array $args = array(), array $options = array()) {
|
|||
* The first record from the result set to return.
|
||||
* @param $count
|
||||
* The number of records to return from the result set.
|
||||
* @param $args
|
||||
* @param array $args
|
||||
* An array of values to substitute into the query. If the query uses named
|
||||
* placeholders, this is an associative array in any order. If the query uses
|
||||
* unnamed placeholders (?), this is an indexed array and the order must match
|
||||
* the order of placeholders in the query string.
|
||||
* @param $options
|
||||
* @param array $options
|
||||
* An array of options to control how the query operates.
|
||||
*
|
||||
* @return \Drupal\Core\Database\StatementInterface
|
||||
* A prepared statement object, already executed.
|
||||
*
|
||||
* @deprecated as of Drupal 8.0.x, will be removed in Drupal 9.0.0. Instead, get
|
||||
* a database connection injected into your service from the container and
|
||||
* call queryRange() on it. E.g.
|
||||
* $injected_database->queryRange($query, $from, $count, $args, $options);
|
||||
*
|
||||
* @see \Drupal\Core\Database\Connection::queryRange()
|
||||
* @see \Drupal\Core\Database\Connection::defaultOptions()
|
||||
*/
|
||||
function db_query_range($query, $from, $count, array $args = array(), array $options = array()) {
|
||||
|
@ -92,21 +104,27 @@ function db_query_range($query, $from, $count, array $args = array(), array $opt
|
|||
*
|
||||
* The execution of the query string happens against the active database.
|
||||
*
|
||||
* @param $query
|
||||
* @param string $query
|
||||
* The prepared SELECT statement query to run. Although it will accept both
|
||||
* named and unnamed placeholders, named placeholders are strongly preferred
|
||||
* as they are more self-documenting.
|
||||
* @param $args
|
||||
* @param array $args
|
||||
* An array of values to substitute into the query. If the query uses named
|
||||
* placeholders, this is an associative array in any order. If the query uses
|
||||
* unnamed placeholders (?), this is an indexed array and the order must match
|
||||
* the order of placeholders in the query string.
|
||||
* @param $options
|
||||
* @param array $options
|
||||
* An array of options to control how the query operates.
|
||||
*
|
||||
* @return
|
||||
* The name of the temporary table.
|
||||
*
|
||||
* @deprecated as of Drupal 8.0.x, will be removed in Drupal 9.0.0. Instead, get
|
||||
* a database connection injected into your service from the container and
|
||||
* call queryTemporary() on it. E.g.
|
||||
* $injected_database->queryTemporary($query, $args, $options);
|
||||
*
|
||||
* @see \Drupal\Core\Database\Connection::queryTemporary()
|
||||
* @see \Drupal\Core\Database\Connection::defaultOptions()
|
||||
*/
|
||||
function db_query_temporary($query, array $args = array(), array $options = array()) {
|
||||
|
@ -120,13 +138,20 @@ function db_query_temporary($query, array $args = array(), array $options = arra
|
|||
/**
|
||||
* Returns a new InsertQuery object for the active database.
|
||||
*
|
||||
* @param $table
|
||||
* @param string $table
|
||||
* The table into which to insert.
|
||||
* @param $options
|
||||
* @param array $options
|
||||
* An array of options to control how the query operates.
|
||||
*
|
||||
* @return \Drupal\Core\Database\Query\Insert
|
||||
* A new Insert object for this connection.
|
||||
*
|
||||
* @deprecated as of Drupal 8.0.x, will be removed in Drupal 9.0.0. Instead, get
|
||||
* a database connection injected into your service from the container and
|
||||
* call insert() on it. E.g. $injected_database->insert($table, $options);
|
||||
*
|
||||
* @see \Drupal\Core\Database\Connection::insert()
|
||||
* @see \Drupal\Core\Database\Connection::defaultOptions()
|
||||
*/
|
||||
function db_insert($table, array $options = array()) {
|
||||
if (empty($options['target']) || $options['target'] == 'replica') {
|
||||
|
@ -138,13 +163,20 @@ function db_insert($table, array $options = array()) {
|
|||
/**
|
||||
* Returns a new MergeQuery object for the active database.
|
||||
*
|
||||
* @param $table
|
||||
* The table into which to merge.
|
||||
* @param $options
|
||||
* @param string $table
|
||||
* Name of the table to associate with this query.
|
||||
* @param array $options
|
||||
* An array of options to control how the query operates.
|
||||
*
|
||||
* @return \Drupal\Core\Database\Query\Merge
|
||||
* A new Merge object for this connection.
|
||||
*
|
||||
* @deprecated as of Drupal 8.0.x, will be removed in Drupal 9.0.0. Instead, get
|
||||
* a database connection injected into your service from the container and
|
||||
* call merge() on it. E.g. $injected_database->merge($table, $options);
|
||||
*
|
||||
* @see \Drupal\Core\Database\Connection::merge()
|
||||
* @see \Drupal\Core\Database\Connection::defaultOptions()
|
||||
*/
|
||||
function db_merge($table, array $options = array()) {
|
||||
if (empty($options['target']) || $options['target'] == 'replica') {
|
||||
|
@ -156,13 +188,20 @@ function db_merge($table, array $options = array()) {
|
|||
/**
|
||||
* Returns a new UpdateQuery object for the active database.
|
||||
*
|
||||
* @param $table
|
||||
* @param string $table
|
||||
* The table to update.
|
||||
* @param $options
|
||||
* @param array $options
|
||||
* An array of options to control how the query operates.
|
||||
*
|
||||
* @return \Drupal\Core\Database\Query\Update
|
||||
* A new Update object for this connection.
|
||||
*
|
||||
* @deprecated as of Drupal 8.0.x, will be removed in Drupal 9.0.0. Instead, get
|
||||
* a database connection injected into your service from the container and
|
||||
* call update() on it. E.g. $injected_database->update($table, $options);
|
||||
*
|
||||
* @see \Drupal\Core\Database\Connection::update()
|
||||
* @see \Drupal\Core\Database\Connection::defaultOptions()
|
||||
*/
|
||||
function db_update($table, array $options = array()) {
|
||||
if (empty($options['target']) || $options['target'] == 'replica') {
|
||||
|
@ -174,13 +213,20 @@ function db_update($table, array $options = array()) {
|
|||
/**
|
||||
* Returns a new DeleteQuery object for the active database.
|
||||
*
|
||||
* @param $table
|
||||
* @param string $table
|
||||
* The table from which to delete.
|
||||
* @param $options
|
||||
* @param array $options
|
||||
* An array of options to control how the query operates.
|
||||
*
|
||||
* @return \Drupal\Core\Database\Query\Delete
|
||||
* A new Delete object for this connection.
|
||||
*
|
||||
* @deprecated as of Drupal 8.0.x, will be removed in Drupal 9.0.0. Instead, get
|
||||
* a database connection injected into your service from the container and
|
||||
* call delete() on it. E.g. $injected_database->delete($table, $options);
|
||||
*
|
||||
* @see \Drupal\Core\Database\Connection::delete()
|
||||
* @see \Drupal\Core\Database\Connection::defaultOptions()
|
||||
*/
|
||||
function db_delete($table, array $options = array()) {
|
||||
if (empty($options['target']) || $options['target'] == 'replica') {
|
||||
|
@ -192,13 +238,20 @@ function db_delete($table, array $options = array()) {
|
|||
/**
|
||||
* Returns a new TruncateQuery object for the active database.
|
||||
*
|
||||
* @param $table
|
||||
* The table from which to delete.
|
||||
* @param $options
|
||||
* @param string $table
|
||||
* The table from which to truncate.
|
||||
* @param array $options
|
||||
* An array of options to control how the query operates.
|
||||
*
|
||||
* @return \Drupal\Core\Database\Query\Truncate
|
||||
* A new Truncate object for this connection.
|
||||
*
|
||||
* @deprecated as of Drupal 8.0.x, will be removed in Drupal 9.0.0. Instead, get
|
||||
* a database connection injected into your service from the container and
|
||||
* call truncate() on it. E.g. $injected_database->truncate($table, $options);
|
||||
*
|
||||
* @see \Drupal\Core\Database\Connection::truncate()
|
||||
* @see \Drupal\Core\Database\Connection::defaultOptions()
|
||||
*/
|
||||
function db_truncate($table, array $options = array()) {
|
||||
if (empty($options['target']) || $options['target'] == 'replica') {
|
||||
|
@ -210,16 +263,25 @@ function db_truncate($table, array $options = array()) {
|
|||
/**
|
||||
* Returns a new SelectQuery object for the active database.
|
||||
*
|
||||
* @param $table
|
||||
* The base table for this query. May be a string or another SelectQuery
|
||||
* object. If a query object is passed, it will be used as a subselect.
|
||||
* @param $alias
|
||||
* @param string|\Drupal\Core\Database\Query\SelectInterface $table
|
||||
* The base table for this query. May be a string or another SelectInterface
|
||||
* object. If a SelectInterface object is passed, it will be used as a
|
||||
* subselect.
|
||||
* @param string $alias
|
||||
* (optional) The alias for the base table of this query.
|
||||
* @param $options
|
||||
* @param array $options
|
||||
* (optional) An array of options to control how the query operates.
|
||||
*
|
||||
* @return \Drupal\Core\Database\Query\Select
|
||||
* A new Select object for this connection.
|
||||
*
|
||||
* @deprecated as of Drupal 8.0.x, will be removed in Drupal 9.0.0. Instead, get
|
||||
* a database connection injected into your service from the container and
|
||||
* call select() on it. E.g.
|
||||
* $injected_database->select($table, $alias, $options);
|
||||
*
|
||||
* @see \Drupal\Core\Database\Connection::select()
|
||||
* @see \Drupal\Core\Database\Connection::defaultOptions()
|
||||
*/
|
||||
function db_select($table, $alias = NULL, array $options = array()) {
|
||||
if (empty($options['target'])) {
|
||||
|
@ -239,6 +301,14 @@ function db_select($table, $alias = NULL, array $options = array()) {
|
|||
*
|
||||
* @return \Drupal\Core\Database\Transaction
|
||||
* A new Transaction object for this connection.
|
||||
*
|
||||
* @deprecated as of Drupal 8.0.x, will be removed in Drupal 9.0.0. Instead, get
|
||||
* a database connection injected into your service from the container and
|
||||
* call startTransaction() on it. E.g.
|
||||
* $injected_database->startTransaction($name);
|
||||
*
|
||||
* @see \Drupal\Core\Database\Connection::startTransaction()
|
||||
* @see \Drupal\Core\Database\Connection::defaultOptions()
|
||||
*/
|
||||
function db_transaction($name = NULL, array $options = array()) {
|
||||
if (empty($options['target'])) {
|
||||
|
@ -253,8 +323,11 @@ function db_transaction($name = NULL, array $options = array()) {
|
|||
* @param $key
|
||||
* The key in the $databases array to set as the default database.
|
||||
*
|
||||
* @return
|
||||
* @return string|null
|
||||
* The key of the formerly active database.
|
||||
*
|
||||
* @deprecated as of Drupal 8.0.x, will be removed in Drupal 9.0.0. Use
|
||||
* \Drupal\Core\Database\Database::setActiveConnection().
|
||||
*/
|
||||
function db_set_active($key = 'default') {
|
||||
return Database::setActiveConnection($key);
|
||||
|
@ -268,8 +341,14 @@ function db_set_active($key = 'default') {
|
|||
* @param $table
|
||||
* The table name to escape.
|
||||
*
|
||||
* @return
|
||||
* @return string
|
||||
* The escaped table name as a string.
|
||||
*
|
||||
* @deprecated as of Drupal 8.0.x, will be removed in Drupal 9.0.0. Instead, get
|
||||
* a database connection injected into your service from the container and
|
||||
* call escapeTable() on it. E.g. $injected_database->escapeTable($table);
|
||||
*
|
||||
* @see \Drupal\Core\Database\Connection::escapeTable()
|
||||
*/
|
||||
function db_escape_table($table) {
|
||||
return Database::getConnection()->escapeTable($table);
|
||||
|
@ -280,11 +359,17 @@ function db_escape_table($table) {
|
|||
*
|
||||
* Only keeps alphanumeric and underscores.
|
||||
*
|
||||
* @param $field
|
||||
* @param string $field
|
||||
* The field name to escape.
|
||||
*
|
||||
* @return
|
||||
* @return string
|
||||
* The escaped field name as a string.
|
||||
*
|
||||
* @deprecated as of Drupal 8.0.x, will be removed in Drupal 9.0.0. Instead, get
|
||||
* a database connection injected into your service from the container and
|
||||
* call escapeTable() on it. E.g. $injected_database->escapeTable($table);
|
||||
*
|
||||
* @see \Drupal\Core\Database\Connection::escapeField()
|
||||
*/
|
||||
function db_escape_field($field) {
|
||||
return Database::getConnection()->escapeField($field);
|
||||
|
@ -314,11 +399,17 @@ function db_escape_field($field) {
|
|||
* Backslash is defined as escape character for LIKE patterns in
|
||||
* DatabaseCondition::mapConditionOperator().
|
||||
*
|
||||
* @param $string
|
||||
* @param string $string
|
||||
* The string to escape.
|
||||
*
|
||||
* @return
|
||||
* @return string
|
||||
* The escaped string.
|
||||
*
|
||||
* @deprecated as of Drupal 8.0.x, will be removed in Drupal 9.0.0. Instead, get
|
||||
* a database connection injected into your service from the container and
|
||||
* call escapeLike() on it. E.g. $injected_database->escapeLike($string);
|
||||
*
|
||||
* @see \Drupal\Core\Database\Connection::escapeLike()
|
||||
*/
|
||||
function db_like($string) {
|
||||
return Database::getConnection()->escapeLike($string);
|
||||
|
@ -327,8 +418,14 @@ function db_like($string) {
|
|||
/**
|
||||
* Retrieves the name of the currently active database driver.
|
||||
*
|
||||
* @return
|
||||
* @return string
|
||||
* The name of the currently active database driver.
|
||||
*
|
||||
* @deprecated as of Drupal 8.0.x, will be removed in Drupal 9.0.0. Instead, get
|
||||
* a database connection injected into your service from the container and
|
||||
* call driver() on it. E.g. $injected_database->driver($string);
|
||||
*
|
||||
* @see \Drupal\Core\Database\Connection::driver()
|
||||
*/
|
||||
function db_driver() {
|
||||
return Database::getConnection()->driver();
|
||||
|
@ -337,9 +434,14 @@ function db_driver() {
|
|||
/**
|
||||
* Closes the active database connection.
|
||||
*
|
||||
* @param $options
|
||||
* @param array $options
|
||||
* An array of options to control which connection is closed. Only the target
|
||||
* key has any meaning in this case.
|
||||
*
|
||||
* @deprecated as of Drupal 8.0.x, will be removed in Drupal 9.0.0. Use
|
||||
* \Drupal\Core\Database\Database::closeConnection($target).
|
||||
*
|
||||
* @see \Drupal\Core\Database\Database::closeConnection()
|
||||
*/
|
||||
function db_close(array $options = array()) {
|
||||
if (empty($options['target'])) {
|
||||
|
@ -355,13 +457,19 @@ function db_close(array $options = array()) {
|
|||
* serial field is preferred, and InsertQuery::execute() returns the value of
|
||||
* the last ID inserted.
|
||||
*
|
||||
* @param $existing_id
|
||||
* @param int $existing_id
|
||||
* After a database import, it might be that the sequences table is behind, so
|
||||
* by passing in a minimum ID, it can be assured that we never issue the same
|
||||
* ID.
|
||||
*
|
||||
* @return
|
||||
* @return int
|
||||
* An integer number larger than any number returned before for this sequence.
|
||||
*
|
||||
* @deprecated as of Drupal 8.0.x, will be removed in Drupal 9.0.0. Instead, get
|
||||
* a database connection injected into your service from the container and
|
||||
* call nextId() on it. E.g. $injected_database->nextId($existing_id);
|
||||
*
|
||||
* @see \Drupal\Core\Database\Connection::nextId()
|
||||
*/
|
||||
function db_next_id($existing_id = 0) {
|
||||
return Database::getConnection()->nextId($existing_id);
|
||||
|
@ -372,6 +480,12 @@ function db_next_id($existing_id = 0) {
|
|||
*
|
||||
* @return \Drupal\Core\Database\Query\Condition
|
||||
* A new Condition object, set to "OR" all conditions together.
|
||||
*
|
||||
* @deprecated as of Drupal 8.0.x, will be removed in Drupal 9.0.0. Create
|
||||
* a \Drupal\Core\Database\Query\Condition object, specifying an OR
|
||||
* conjunction: new Condition('OR');
|
||||
*
|
||||
* @see \Drupal\Core\Database\Query\Condition
|
||||
*/
|
||||
function db_or() {
|
||||
return new Condition('OR');
|
||||
|
@ -382,6 +496,12 @@ function db_or() {
|
|||
*
|
||||
* @return \Drupal\Core\Database\Query\Condition
|
||||
* A new Condition object, set to "AND" all conditions together.
|
||||
*
|
||||
* @deprecated as of Drupal 8.0.x, will be removed in Drupal 9.0.0. Create
|
||||
* a \Drupal\Core\Database\Query\Condition object, specifying an AND
|
||||
* conjunction: new Condition('AND');
|
||||
*
|
||||
* @see \Drupal\Core\Database\Query\Condition
|
||||
*/
|
||||
function db_and() {
|
||||
return new Condition('AND');
|
||||
|
@ -392,6 +512,12 @@ function db_and() {
|
|||
*
|
||||
* @return \Drupal\Core\Database\Query\Condition
|
||||
* A new Condition object, set to "XOR" all conditions together.
|
||||
*
|
||||
* @deprecated as of Drupal 8.0.x, will be removed in Drupal 9.0.0. Create
|
||||
* a \Drupal\Core\Database\Query\Condition object, specifying an XOR
|
||||
* conjunction: new Condition('XOR');
|
||||
*
|
||||
* @see \Drupal\Core\Database\Query\Condition
|
||||
*/
|
||||
function db_xor() {
|
||||
return new Condition('XOR');
|
||||
|
@ -403,11 +529,17 @@ function db_xor() {
|
|||
* Internal API function call. The db_and(), db_or(), and db_xor()
|
||||
* functions are preferred.
|
||||
*
|
||||
* @param $conjunction
|
||||
* @param string $conjunction
|
||||
* The conjunction to use for query conditions (AND, OR or XOR).
|
||||
*
|
||||
* @return \Drupal\Core\Database\Query\Condition
|
||||
* A new Condition object, set to the specified conjunction.
|
||||
*
|
||||
* @deprecated as of Drupal 8.0.x, will be removed in Drupal 9.0.0. Create
|
||||
* a \Drupal\Core\Database\Query\Condition object, specifying the desired
|
||||
* conjunction: new Condition($conjunctin);
|
||||
*
|
||||
* @see \Drupal\Core\Database\Query\Condition
|
||||
*/
|
||||
function db_condition($conjunction) {
|
||||
return new Condition($conjunction);
|
||||
|
@ -426,10 +558,17 @@ function db_condition($conjunction) {
|
|||
/**
|
||||
* Creates a new table from a Drupal table definition.
|
||||
*
|
||||
* @param $name
|
||||
* @param string $name
|
||||
* The name of the table to create.
|
||||
* @param $table
|
||||
* @param array $table
|
||||
* A Schema API table definition array.
|
||||
*
|
||||
* @deprecated as of Drupal 8.0.x, will be removed in Drupal 9.0.0. Instead, get
|
||||
* a database connection injected into your service from the container, get
|
||||
* its schema driver, and call createTable() on it. E.g.
|
||||
* $injected_database->schema()->createTable($name, $table);
|
||||
*
|
||||
* @see \Drupal\Core\Database\Schema::createTable()
|
||||
*/
|
||||
function db_create_table($name, $table) {
|
||||
return Database::getConnection()->schema()->createTable($name, $table);
|
||||
|
@ -441,11 +580,18 @@ function db_create_table($name, $table) {
|
|||
* This is usually an identity function but if a key/index uses a column prefix
|
||||
* specification, this function extracts just the name.
|
||||
*
|
||||
* @param $fields
|
||||
* @param array $fields
|
||||
* An array of key/index column specifiers.
|
||||
*
|
||||
* @return
|
||||
* @return array
|
||||
* An array of field names.
|
||||
*
|
||||
* @deprecated as of Drupal 8.0.x, will be removed in Drupal 9.0.0. Instead, get
|
||||
* a database connection injected into your service from the container, get
|
||||
* its schema driver, and call fieldNames() on it. E.g.
|
||||
* $injected_database->schema()->fieldNames($fields);
|
||||
*
|
||||
* @see \Drupal\Core\Database\Schema::fieldNames()
|
||||
*/
|
||||
function db_field_names($fields) {
|
||||
return Database::getConnection()->schema()->fieldNames($fields);
|
||||
|
@ -454,13 +600,20 @@ function db_field_names($fields) {
|
|||
/**
|
||||
* Checks if an index exists in the given table.
|
||||
*
|
||||
* @param $table
|
||||
* @param string $table
|
||||
* The name of the table in drupal (no prefixing).
|
||||
* @param $name
|
||||
* @param string $name
|
||||
* The name of the index in drupal (no prefixing).
|
||||
*
|
||||
* @return
|
||||
* @return bool
|
||||
* TRUE if the given index exists, otherwise FALSE.
|
||||
*
|
||||
* @deprecated as of Drupal 8.0.x, will be removed in Drupal 9.0.0. Instead, get
|
||||
* a database connection injected into your service from the container, get
|
||||
* its schema driver, and call indexExists() on it. E.g.
|
||||
* $injected_database->schema()->indexExists($table, $name);
|
||||
*
|
||||
* @see \Drupal\Core\Database\Schema::indexExists()
|
||||
*/
|
||||
function db_index_exists($table, $name) {
|
||||
return Database::getConnection()->schema()->indexExists($table, $name);
|
||||
|
@ -469,11 +622,18 @@ function db_index_exists($table, $name) {
|
|||
/**
|
||||
* Checks if a table exists.
|
||||
*
|
||||
* @param $table
|
||||
* @param string $table
|
||||
* The name of the table in drupal (no prefixing).
|
||||
*
|
||||
* @return
|
||||
* @return bool
|
||||
* TRUE if the given table exists, otherwise FALSE.
|
||||
*
|
||||
* @deprecated as of Drupal 8.0.x, will be removed in Drupal 9.0.0. Instead, get
|
||||
* a database connection injected into your service from the container, get
|
||||
* its schema driver, and call tableExists() on it. E.g.
|
||||
* $injected_database->schema()->tableExists($table);
|
||||
*
|
||||
* @see \Drupal\Core\Database\Schema::tableExists()
|
||||
*/
|
||||
function db_table_exists($table) {
|
||||
return Database::getConnection()->schema()->tableExists($table);
|
||||
|
@ -487,8 +647,15 @@ function db_table_exists($table) {
|
|||
* @param $field
|
||||
* The name of the field.
|
||||
*
|
||||
* @return
|
||||
* @return bool
|
||||
* TRUE if the given column exists, otherwise FALSE.
|
||||
*
|
||||
* @deprecated as of Drupal 8.0.x, will be removed in Drupal 9.0.0. Instead, get
|
||||
* a database connection injected into your service from the container, get
|
||||
* its schema driver, and call fieldExists() on it. E.g.
|
||||
* $injected_database->schema()->fieldExists($table, $field);
|
||||
*
|
||||
* @see \Drupal\Core\Database\Schema::fieldExists()
|
||||
*/
|
||||
function db_field_exists($table, $field) {
|
||||
return Database::getConnection()->schema()->fieldExists($table, $field);
|
||||
|
@ -497,21 +664,24 @@ function db_field_exists($table, $field) {
|
|||
/**
|
||||
* Finds all tables that are like the specified base table name.
|
||||
*
|
||||
* @param $table_expression
|
||||
* @param string $table_expression
|
||||
* An SQL expression, for example "simpletest%" (without the quotes).
|
||||
* BEWARE: this is not prefixed, the caller should take care of that.
|
||||
*
|
||||
* @return
|
||||
* @return array
|
||||
* Array, both the keys and the values are the matching tables.
|
||||
*
|
||||
* @deprecated as of Drupal 8.0.x, will be removed in Drupal 9.0.0. Instead, get
|
||||
* a database connection injected into your service from the container, get
|
||||
* its schema driver, and call findTables() on it. E.g.
|
||||
* $injected_database->schema()->findTables($table_expression);
|
||||
*
|
||||
* @see \Drupal\Core\Database\Schema::findTables()
|
||||
*/
|
||||
function db_find_tables($table_expression) {
|
||||
return Database::getConnection()->schema()->findTables($table_expression);
|
||||
}
|
||||
|
||||
function _db_create_keys_sql($spec) {
|
||||
return Database::getConnection()->schema()->createKeysSql($spec);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renames a table.
|
||||
*
|
||||
|
@ -519,6 +689,13 @@ function _db_create_keys_sql($spec) {
|
|||
* The current name of the table to be renamed.
|
||||
* @param $new_name
|
||||
* The new name for the table.
|
||||
*
|
||||
* @deprecated as of Drupal 8.0.x, will be removed in Drupal 9.0.0. Instead, get
|
||||
* a database connection injected into your service from the container, get
|
||||
* its schema driver, and call renameTable() on it. E.g.
|
||||
* $injected_database->schema()->renameTable($table, $new_name);
|
||||
*
|
||||
* @see \Drupal\Core\Database\Schema::renameTable()
|
||||
*/
|
||||
function db_rename_table($table, $new_name) {
|
||||
return Database::getConnection()->schema()->renameTable($table, $new_name);
|
||||
|
@ -529,6 +706,13 @@ function db_rename_table($table, $new_name) {
|
|||
*
|
||||
* @param $table
|
||||
* The table to be dropped.
|
||||
*
|
||||
* @deprecated as of Drupal 8.0.x, will be removed in Drupal 9.0.0. Instead, get
|
||||
* a database connection injected into your service from the container, get
|
||||
* its schema driver, and call dropTable() on it. E.g.
|
||||
* $injected_database->schema()->dropTable($table);
|
||||
*
|
||||
* @see \Drupal\Core\Database\Schema::dropTable()
|
||||
*/
|
||||
function db_drop_table($table) {
|
||||
return Database::getConnection()->schema()->dropTable($table);
|
||||
|
@ -541,18 +725,24 @@ function db_drop_table($table) {
|
|||
* Name of the table to be altered.
|
||||
* @param $field
|
||||
* Name of the field to be added.
|
||||
* @param $spec
|
||||
* @param array $spec
|
||||
* The field specification array, as taken from a schema definition. The
|
||||
* specification may also contain the key 'initial'; the newly-created field
|
||||
* will be set to the value of the key in all rows. This is most useful for
|
||||
* creating NOT NULL columns with no default value in existing tables.
|
||||
* @param $keys_new
|
||||
* @param array $keys_new
|
||||
* (optional) Keys and indexes specification to be created on the table along
|
||||
* with adding the field. The format is the same as a table specification, but
|
||||
* without the 'fields' element. If you are adding a type 'serial' field, you
|
||||
* MUST specify at least one key or index including it in this array. See
|
||||
* db_change_field() for more explanation why.
|
||||
*
|
||||
* @deprecated as of Drupal 8.0.x, will be removed in Drupal 9.0.0. Instead, get
|
||||
* a database connection injected into your service from the container, get
|
||||
* its schema driver, and call addField() on it. E.g.
|
||||
* $injected_database->schema()->addField($table, $field, $spec, $keys_new);
|
||||
*
|
||||
* @see \Drupal\Core\Database\Schema::addField()
|
||||
* @see db_change_field()
|
||||
*/
|
||||
function db_add_field($table, $field, $spec, $keys_new = array()) {
|
||||
|
@ -566,6 +756,17 @@ function db_add_field($table, $field, $spec, $keys_new = array()) {
|
|||
* The table to be altered.
|
||||
* @param $field
|
||||
* The field to be dropped.
|
||||
*
|
||||
* @return bool
|
||||
* TRUE if the field was successfully dropped, FALSE if there was no field by
|
||||
* that name to begin with.
|
||||
*
|
||||
* @deprecated as of Drupal 8.0.x, will be removed in Drupal 9.0.0. Instead, get
|
||||
* a database connection injected into your service from the container, get
|
||||
* its schema driver, and call dropField() on it. E.g.
|
||||
* $injected_database->schema()->dropField($table, $field);
|
||||
*
|
||||
* @see \Drupal\Core\Database\Schema::dropField()
|
||||
*/
|
||||
function db_drop_field($table, $field) {
|
||||
return Database::getConnection()->schema()->dropField($table, $field);
|
||||
|
@ -580,6 +781,13 @@ function db_drop_field($table, $field) {
|
|||
* The field to be altered.
|
||||
* @param $default
|
||||
* Default value to be set. NULL for 'default NULL'.
|
||||
*
|
||||
* @deprecated as of Drupal 8.0.x, will be removed in Drupal 9.0.0. Instead, get
|
||||
* a database connection injected into your service from the container, get
|
||||
* its schema driver, and call fieldSetDefault() on it. E.g.
|
||||
* $injected_database->schema()->fieldSetDefault($table, $field, $default);
|
||||
*
|
||||
* @see \Drupal\Core\Database\Schema::fieldSetDefault()
|
||||
*/
|
||||
function db_field_set_default($table, $field, $default) {
|
||||
return Database::getConnection()->schema()->fieldSetDefault($table, $field, $default);
|
||||
|
@ -592,6 +800,13 @@ function db_field_set_default($table, $field, $default) {
|
|||
* The table to be altered.
|
||||
* @param $field
|
||||
* The field to be altered.
|
||||
*
|
||||
* @deprecated as of Drupal 8.0.x, will be removed in Drupal 9.0.0. Instead, get
|
||||
* a database connection injected into your service from the container, get
|
||||
* its schema driver, and call fieldSetNoDefault() on it. E.g.
|
||||
* $injected_database->schema()->fieldSetNoDefault($table, $field);
|
||||
*
|
||||
* @see \Drupal\Core\Database\Schema::fieldSetNoDefault()
|
||||
*/
|
||||
function db_field_set_no_default($table, $field) {
|
||||
return Database::getConnection()->schema()->fieldSetNoDefault($table, $field);
|
||||
|
@ -604,6 +819,13 @@ function db_field_set_no_default($table, $field) {
|
|||
* Name of the table to be altered.
|
||||
* @param $fields
|
||||
* Array of fields for the primary key.
|
||||
*
|
||||
* @deprecated as of Drupal 8.0.x, will be removed in Drupal 9.0.0. Instead, get
|
||||
* a database connection injected into your service from the container, get
|
||||
* its schema driver, and call addPrimaryKey() on it. E.g.
|
||||
* $injected_database->schema()->addPrimaryKey($table, $fields);
|
||||
*
|
||||
* @see \Drupal\Core\Database\Schema::addPrimaryKey()
|
||||
*/
|
||||
function db_add_primary_key($table, $fields) {
|
||||
return Database::getConnection()->schema()->addPrimaryKey($table, $fields);
|
||||
|
@ -614,6 +836,17 @@ function db_add_primary_key($table, $fields) {
|
|||
*
|
||||
* @param $table
|
||||
* Name of the table to be altered.
|
||||
*
|
||||
* @return bool
|
||||
* TRUE if the primary key was successfully dropped, FALSE if there was no
|
||||
* primary key on this table to begin with.
|
||||
*
|
||||
* @deprecated as of Drupal 8.0.x, will be removed in Drupal 9.0.0. Instead, get
|
||||
* a database connection injected into your service from the container, get
|
||||
* its schema driver, and call dropPrimaryKey() on it. E.g.
|
||||
* $injected_database->schema()->dropPrimaryKey($table);
|
||||
*
|
||||
* @see \Drupal\Core\Database\Schema::dropPrimaryKey()
|
||||
*/
|
||||
function db_drop_primary_key($table) {
|
||||
return Database::getConnection()->schema()->dropPrimaryKey($table);
|
||||
|
@ -626,8 +859,15 @@ function db_drop_primary_key($table) {
|
|||
* The table to be altered.
|
||||
* @param $name
|
||||
* The name of the key.
|
||||
* @param $fields
|
||||
* @param array $fields
|
||||
* An array of field names.
|
||||
*
|
||||
* @deprecated as of Drupal 8.0.x, will be removed in Drupal 9.0.0. Instead, get
|
||||
* a database connection injected into your service from the container, get
|
||||
* its schema driver, and call addUniqueKey() on it. E.g.
|
||||
* $injected_database->schema()->addUniqueKey($table, $name, $fields);
|
||||
*
|
||||
* @see \Drupal\Core\Database\Schema::addUniqueKey()
|
||||
*/
|
||||
function db_add_unique_key($table, $name, $fields) {
|
||||
return Database::getConnection()->schema()->addUniqueKey($table, $name, $fields);
|
||||
|
@ -640,6 +880,17 @@ function db_add_unique_key($table, $name, $fields) {
|
|||
* The table to be altered.
|
||||
* @param $name
|
||||
* The name of the key.
|
||||
*
|
||||
* @return bool
|
||||
* TRUE if the key was successfully dropped, FALSE if there was no key by
|
||||
* that name to begin with.
|
||||
*
|
||||
* @deprecated as of Drupal 8.0.x, will be removed in Drupal 9.0.0. Instead, get
|
||||
* a database connection injected into your service from the container, get
|
||||
* its schema driver, and call dropUniqueKey() on it. E.g.
|
||||
* $injected_database->schema()->dropUniqueKey($table, $name);
|
||||
*
|
||||
* @see \Drupal\Core\Database\Schema::dropUniqueKey()
|
||||
*/
|
||||
function db_drop_unique_key($table, $name) {
|
||||
return Database::getConnection()->schema()->dropUniqueKey($table, $name);
|
||||
|
@ -652,8 +903,15 @@ function db_drop_unique_key($table, $name) {
|
|||
* The table to be altered.
|
||||
* @param $name
|
||||
* The name of the index.
|
||||
* @param $fields
|
||||
* @param array $fields
|
||||
* An array of field names.
|
||||
*
|
||||
* @deprecated as of Drupal 8.0.x, will be removed in Drupal 9.0.0. Instead, get
|
||||
* a database connection injected into your service from the container, get
|
||||
* its schema driver, and call addIndex() on it. E.g.
|
||||
* $injected_database->schema()->addIndex($table, $name, $fields);
|
||||
*
|
||||
* @see \Drupal\Core\Database\Schema::addIndex()
|
||||
*/
|
||||
function db_add_index($table, $name, $fields) {
|
||||
return Database::getConnection()->schema()->addIndex($table, $name, $fields);
|
||||
|
@ -666,6 +924,17 @@ function db_add_index($table, $name, $fields) {
|
|||
* The table to be altered.
|
||||
* @param $name
|
||||
* The name of the index.
|
||||
*
|
||||
* @return bool
|
||||
* TRUE if the index was successfully dropped, FALSE if there was no index
|
||||
* by that name to begin with.
|
||||
*
|
||||
* @deprecated as of Drupal 8.0.x, will be removed in Drupal 9.0.0. Instead, get
|
||||
* a database connection injected into your service from the container, get
|
||||
* its schema driver, and call dropIndex() on it. E.g.
|
||||
* $injected_database->schema()->dropIndex($table, $name);
|
||||
*
|
||||
* @see \Drupal\Core\Database\Schema::dropIndex()
|
||||
*/
|
||||
function db_drop_index($table, $name) {
|
||||
return Database::getConnection()->schema()->dropIndex($table, $name);
|
||||
|
@ -726,10 +995,17 @@ function db_drop_index($table, $name) {
|
|||
* change the name).
|
||||
* @param $spec
|
||||
* The field specification for the new field.
|
||||
* @param $keys_new
|
||||
* @param array $keys_new
|
||||
* (optional) Keys and indexes specification to be created on the table along
|
||||
* with changing the field. The format is the same as a table specification
|
||||
* but without the 'fields' element.
|
||||
*
|
||||
* @deprecated as of Drupal 8.0.x, will be removed in Drupal 9.0.0. Instead, get
|
||||
* a database connection injected into your service from the container, get
|
||||
* its schema driver, and call changeField() on it. E.g.
|
||||
* $injected_database->schema()->changeField($table, $field, $field_new, $spec, $keys_new);
|
||||
*
|
||||
* @see \Drupal\Core\Database\Schema::changeField()
|
||||
*/
|
||||
function db_change_field($table, $field, $field_new, $spec, $keys_new = array()) {
|
||||
return Database::getConnection()->schema()->changeField($table, $field, $field_new, $spec, $keys_new);
|
||||
|
|
|
@ -31,6 +31,11 @@ function entity_render_cache_clear() {
|
|||
* @return array
|
||||
* The bundle info for a specific entity type, or all entity types.
|
||||
*
|
||||
* @deprecated in Drupal 8.x-dev and will be removed before Drupal 9.0.0. Use
|
||||
* \Drupal\Core\Entity\EntityManagerInterface::getBundleInfo() for a single
|
||||
* bundle, or \Drupal\Core\Entity\EntityManagerInterface::getAllBundleInfo()
|
||||
* for all bundles.
|
||||
*
|
||||
* @see \Drupal\Core\Entity\EntityManagerInterface::getBundleInfo()
|
||||
* @see \Drupal\Core\Entity\EntityManagerInterface::getAllBundleInfo()
|
||||
*/
|
||||
|
@ -56,8 +61,18 @@ function entity_get_bundles($entity_type = NULL) {
|
|||
* @return \Drupal\Core\Entity\EntityInterface|null
|
||||
* The entity object, or NULL if there is no entity with the given ID.
|
||||
*
|
||||
* @see \Drupal\Core\Entity\EntityManagerInterface
|
||||
* @see \Drupal\Core\Entity\EntityStorageInterface
|
||||
* @deprecated in Drupal 8.0.x, will be removed before Drupal 9.0.0. Use
|
||||
* The method overriding Entity::load() for the entity type, e.g.
|
||||
* \Drupal\node\Entity\Node::load() if the entity type is known. If the
|
||||
* entity type is variable, use the entity manager service to load the entity
|
||||
* from the entity storage:
|
||||
* @code
|
||||
* \Drupal::entityManager()->getStorage($entity_type)->load($id)
|
||||
* @endcode
|
||||
*
|
||||
* @see \Drupal\Core\Entity\EntityInterface::load()
|
||||
* @see \Drupal\Core\Entity\EntityManagerInterface::getStorage()
|
||||
* @see \Drupal\Core\Entity\EntityStorageInterface::load()
|
||||
* @see \Drupal\Core\Entity\Sql\SqlContentEntityStorage
|
||||
* @see \Drupal\Core\Entity\Query\QueryInterface
|
||||
*/
|
||||
|
@ -81,8 +96,15 @@ function entity_load($entity_type, $id, $reset = FALSE) {
|
|||
* The entity object, or NULL if there is no entity with the given revision
|
||||
* id.
|
||||
*
|
||||
* @see \Drupal\Core\Entity\EntityManagerInterface
|
||||
* @see \Drupal\Core\Entity\EntityStorageInterface
|
||||
* @deprecated as of Drupal 8.0.x, will be removed before Drupal 9.0.0. Use
|
||||
* the entity storage's loadRevision() method to load a specific entity
|
||||
* revision:
|
||||
* @code
|
||||
* \Drupal::entityManager()->getStorage($entity_type)->loadRevision($revision_id);
|
||||
* @endcode
|
||||
*
|
||||
* @see \Drupal\Core\Entity\EntityManagerInterface::getStorage()
|
||||
* @see \Drupal\Core\Entity\EntityStorageInterface::loadRevision()
|
||||
* @see \Drupal\Core\Entity\Sql\SqlContentEntityStorage
|
||||
*/
|
||||
function entity_revision_load($entity_type, $revision_id) {
|
||||
|
@ -98,6 +120,16 @@ function entity_revision_load($entity_type, $revision_id) {
|
|||
* The entity type to load, e.g. node or user.
|
||||
* @param $revision_id
|
||||
* The revision ID to delete.
|
||||
*
|
||||
* @deprecated as of Drupal 8.0.x, will be removed before Drupal 9.0.0. Use
|
||||
* the entity storage's deleteRevision() method to delete a specific entity
|
||||
* revision:
|
||||
* @code
|
||||
* \Drupal::entityManager()->getStorage($entity_type)>deleteRevision($revision_id);
|
||||
* @endcode
|
||||
*
|
||||
* @see \Drupal\Core\Entity\EntityManagerInterface::getStorage()
|
||||
* @see \Drupal\Core\Entity\EntityStorageInterface::deleteRevision()
|
||||
*/
|
||||
function entity_revision_delete($entity_type, $revision_id) {
|
||||
\Drupal::entityManager()
|
||||
|
@ -134,8 +166,18 @@ function entity_revision_delete($entity_type, $revision_id) {
|
|||
* @return array
|
||||
* An array of entity objects indexed by their IDs.
|
||||
*
|
||||
* @see \Drupal\Core\Entity\EntityManagerInterface
|
||||
* @see \Drupal\Core\Entity\EntityStorageInterface
|
||||
* @deprecated in Drupal 8.0.x, will be removed before Drupal 9.0.0. Use
|
||||
* The method overriding Entity::loadMultiple() for the entity type, e.g.
|
||||
* \Drupal\node\Entity\Node::loadMultiple() if the entity type is known. If
|
||||
* the entity type is variable, use the entity manager service to load the
|
||||
* entity from the entity storage:
|
||||
* @code
|
||||
* \Drupal::entityManager()->getStorage($entity_type)->loadMultiple($id)
|
||||
* @endcode
|
||||
*
|
||||
* @see \Drupal\Core\Entity\EntityInterface::loadMultiple()
|
||||
* @see \Drupal\Core\Entity\EntityManagerInterface::getStorage()
|
||||
* @see \Drupal\Core\Entity\EntityStorageInterface::loadMultiple()
|
||||
* @see \Drupal\Core\Entity\Sql\SqlContentEntityStorage
|
||||
* @see \Drupal\Core\Entity\Query\QueryInterface
|
||||
*/
|
||||
|
@ -159,6 +201,16 @@ function entity_load_multiple($entity_type, array $ids = NULL, $reset = FALSE) {
|
|||
* @return array
|
||||
* An array of entity objects indexed by their IDs. Returns an empty array if
|
||||
* no matching entities are found.
|
||||
*
|
||||
* @deprecated as of Drupal 8.0.x, will be removed before Drupal 9.0.0. Use
|
||||
* the entity storage's loadByProperties() method to load an entity by their
|
||||
* property values:
|
||||
* @code
|
||||
* \Drupal::entityManager()->getStorage($entity_type)->loadByProperties($values);
|
||||
* @endcode
|
||||
*
|
||||
* @see \Drupal\Core\Entity\EntityManagerInterface::getStorage()
|
||||
* @see \Drupal\Core\Entity\EntityStorageInterface::loadByProperties()
|
||||
*/
|
||||
function entity_load_multiple_by_properties($entity_type, array $values) {
|
||||
return \Drupal::entityManager()
|
||||
|
@ -179,8 +231,17 @@ function entity_load_multiple_by_properties($entity_type, array $values) {
|
|||
* @param $id
|
||||
* The ID of the entity to load.
|
||||
*
|
||||
* @return
|
||||
* @return \Drupal\Core\Entity\EntityInterface|null
|
||||
* The unchanged entity, or FALSE if the entity cannot be loaded.
|
||||
*
|
||||
* @deprecated as of Drupal 8.0.x, will be removed before Drupal 9.0.0. Use
|
||||
* the entity storage's loadUnchanged() method to load an unchanged entity:
|
||||
* @code
|
||||
* \Drupal::entityManager()->getStorage($entity_type)->loadUnchanged($id).
|
||||
* @endcode
|
||||
*
|
||||
* @see \Drupal\Core\Entity\EntityManagerInterface::getStorage()
|
||||
* @see \Drupal\Core\Entity\EntityStorageInterface::loadUnchanged()
|
||||
*/
|
||||
function entity_load_unchanged($entity_type, $id) {
|
||||
return \Drupal::entityManager()
|
||||
|
@ -195,6 +256,18 @@ function entity_load_unchanged($entity_type, $id) {
|
|||
* The type of the entity.
|
||||
* @param array $ids
|
||||
* An array of entity IDs of the entities to delete.
|
||||
*
|
||||
* @deprecated as of Drupal 8.0.x, will be removed before Drupal 9.0.0. Use
|
||||
* the entity storage's delete() method to delete multiple entities:
|
||||
* @code
|
||||
* $storage_handler = \Drupal::entityManager()->getStorage($entity_type);
|
||||
* $entities = $storage_handler->loadMultiple($ids);
|
||||
* $storage_handler->delete($entities);
|
||||
* @endcode
|
||||
*
|
||||
* @see \Drupal\Core\Entity\EntityManagerInterface::getStorage()
|
||||
* @see \Drupal\Core\Entity\EntityStorageInterface::loadMultiple()
|
||||
* @see \Drupal\Core\Entity\EntityStorageInterface::delete()
|
||||
*/
|
||||
function entity_delete_multiple($entity_type, array $ids) {
|
||||
$controller = \Drupal::entityManager()->getStorage($entity_type);
|
||||
|
@ -214,10 +287,17 @@ function entity_delete_multiple($entity_type, array $ids) {
|
|||
* @return \Drupal\Core\Entity\EntityInterface
|
||||
* A new entity object.
|
||||
*
|
||||
* @deprecated in Drupal 8.x-dev, will be removed before Drupal 9.0.0. Use
|
||||
* the <EntityType>::create($values) method if the entity type is known or
|
||||
* \Drupal::entityManager()->getStorage($entity_type)->create($values) if the
|
||||
* entity type is variable.
|
||||
* @deprecated in Drupal 8.0.x, will be removed before Drupal 9.0.0. Use
|
||||
* The method overriding Entity::create() for the entity type, e.g.
|
||||
* \Drupal\node\Entity\Node::create() if the entity type is known. If the
|
||||
* entity type is variable, use the entity storage's create() method to
|
||||
* construct a new entity:
|
||||
* @code
|
||||
* \Drupal::entityManager()->getStorage($entity_type)->create($values)
|
||||
* @endcode
|
||||
*
|
||||
* @see \Drupal\Core\Entity\EntityManagerInterface::getStorage()
|
||||
* @see \Drupal\Core\Entity\EntityStorageInterface::create()
|
||||
*/
|
||||
function entity_create($entity_type, array $values = array()) {
|
||||
return \Drupal::entityManager()
|
||||
|
@ -228,9 +308,6 @@ function entity_create($entity_type, array $values = array()) {
|
|||
/**
|
||||
* Returns the label of an entity.
|
||||
*
|
||||
* This is a wrapper for Drupal\Core\Entity\EntityInterface::label(). This function
|
||||
* should only be used as a callback, e.g. for menu title callbacks.
|
||||
*
|
||||
* @param \Drupal\Core\Entity\EntityInterface $entity
|
||||
* The entity for which to generate the label.
|
||||
* @param $langcode
|
||||
|
@ -238,9 +315,15 @@ function entity_create($entity_type, array $values = array()) {
|
|||
* getting the label. If set to NULL, the entity's default language is
|
||||
* used.
|
||||
*
|
||||
* @return
|
||||
* @return string|null
|
||||
* The label of the entity, or NULL if there is no label defined.
|
||||
*
|
||||
* @deprecated as of Drupal 8.0.x, will be removed before Drupal 9.0.0. Use
|
||||
* the entity's label() method to get the label of the entity:
|
||||
* @code
|
||||
* $entity->label($langcode);
|
||||
* @endcode
|
||||
*
|
||||
* @see \Drupal\Core\Entity\EntityInterface::label()
|
||||
*/
|
||||
function entity_page_label(EntityInterface $entity, $langcode = NULL) {
|
||||
|
@ -263,6 +346,16 @@ function entity_page_label(EntityInterface $entity, $langcode = NULL) {
|
|||
*
|
||||
* @return array
|
||||
* A render array for the entity.
|
||||
*
|
||||
* @deprecated as of Drupal 8.0.x, will be removed before Drupal 9.0.0.
|
||||
* Use the entity view builder's view() method for creating a render array:
|
||||
* @code
|
||||
* $view_builder = \Drupal::entityManager()->getViewBuilder($entity->getEntityTypeId());
|
||||
* return $view_builder->view($entity, $view_mode, $langcode);
|
||||
* @endcode
|
||||
*
|
||||
* @see \Drupal\Core\Entity\EntityManagerInterface::getViewBuilder()
|
||||
* @see \Drupal\Core\Entity\EntityViewBuilderInterface::view()
|
||||
*/
|
||||
function entity_view(EntityInterface $entity, $view_mode, $langcode = NULL, $reset = FALSE) {
|
||||
$render_controller = \Drupal::entityManager()->getViewBuilder($entity->getEntityTypeId());
|
||||
|
@ -289,6 +382,17 @@ function entity_view(EntityInterface $entity, $view_mode, $langcode = NULL, $res
|
|||
* @return array
|
||||
* A render array for the entities, indexed by the same keys as the
|
||||
* entities array passed in $entities.
|
||||
*
|
||||
* @deprecated as of Drupal 8.0.x, will be removed before Drupal 9.0.0.
|
||||
* Use the entity view builder's viewMultiple() method for creating a render
|
||||
* array for the provided entities:
|
||||
* @code
|
||||
* $view_builder = \Drupal::entityManager()->getViewBuilder($entity->getEntityTypeId());
|
||||
* return $view_builder->viewMultiple($entities, $view_mode, $langcode);
|
||||
* @endcode
|
||||
*
|
||||
* @see \Drupal\Core\Entity\EntityManagerInterface::getViewBuilder()
|
||||
* @see \Drupal\Core\Entity\EntityViewBuilderInterface::viewMultiple()
|
||||
*/
|
||||
function entity_view_multiple(array $entities, $view_mode, $langcode = NULL, $reset = FALSE) {
|
||||
$render_controller = \Drupal::entityManager()->getViewBuilder(reset($entities)->getEntityTypeId());
|
||||
|
@ -336,6 +440,26 @@ function entity_view_multiple(array $entities, $view_mode, $langcode = NULL, $re
|
|||
*
|
||||
* @return \Drupal\Core\Entity\Display\EntityViewDisplayInterface
|
||||
* The entity view display associated to the view mode.
|
||||
*
|
||||
* @deprecated as of Drupal 8.0.x, will be removed before Drupal 9.0.0.
|
||||
* If the display is available in configuration use:
|
||||
* @code
|
||||
* \Drupal::entityManager()->getStorage('entity_view_display')->load($entity_type . '.' . $bundle . '.' . $view_mode);
|
||||
* @endcode
|
||||
* When the display is not available in configuration, you can create a new
|
||||
* EntityViewDisplay object using:
|
||||
* @code
|
||||
* $values = ('entity_view_display', array(
|
||||
* 'targetEntityType' => $entity_type,
|
||||
* 'bundle' => $bundle,
|
||||
* 'mode' => $view_mode,
|
||||
* 'status' => TRUE,
|
||||
* ));
|
||||
* \Drupal::entityManager()->getStorage('entity_view_display')->create($values);
|
||||
* @endcode
|
||||
*
|
||||
* @see \Drupal\Core\Entity\EntityStorageInterface::create()
|
||||
* @see \Drupal\Core\Entity\EntityStorageInterface::load()
|
||||
*/
|
||||
function entity_get_display($entity_type, $bundle, $view_mode) {
|
||||
// Try loading the display from configuration.
|
||||
|
@ -392,6 +516,26 @@ function entity_get_display($entity_type, $bundle, $view_mode) {
|
|||
*
|
||||
* @return \Drupal\Core\Entity\Display\EntityFormDisplayInterface
|
||||
* The entity form display associated to the given form mode.
|
||||
*
|
||||
* @deprecated as of Drupal 8.0.x, will be removed before Drupal 9.0.0.
|
||||
* If the entity form display is available in configuration use:
|
||||
* @code
|
||||
* \Drupal::entityManager()->getStorage('entity_form_display')->load($entity_type . '.' . $bundle . '.' . $form_mode);
|
||||
* @endcode
|
||||
* When the entity form display is not available in configuration, you can create a new
|
||||
* EntityFormDisplay object using:
|
||||
* @code
|
||||
* $values = ('entity_form_display', array(
|
||||
* 'targetEntityType' => $entity_type,
|
||||
* 'bundle' => $bundle,
|
||||
* 'mode' => $form_mode,
|
||||
* 'status' => TRUE,
|
||||
* ));
|
||||
* \Drupal::entityManager()->getStorage('entity_form_display')->create($values);
|
||||
* @endcode
|
||||
*
|
||||
* @see \Drupal\Core\Entity\EntityStorageInterface::create()
|
||||
* @see \Drupal\Core\Entity\EntityStorageInterface::load()
|
||||
*/
|
||||
function entity_get_form_display($entity_type, $bundle, $form_mode) {
|
||||
// Try loading the entity from configuration.
|
||||
|
|
|
@ -9,6 +9,7 @@ use Drupal\Component\Utility\SafeMarkup;
|
|||
use Drupal\Component\Utility\Xss;
|
||||
use Drupal\Core\Logger\RfcLogLevel;
|
||||
use Drupal\Core\Utility\Error;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
/**
|
||||
* Maps PHP error constants to watchdog severity levels.
|
||||
|
@ -117,21 +118,6 @@ function error_displayable($error = NULL) {
|
|||
*/
|
||||
function _drupal_log_error($error, $fatal = FALSE) {
|
||||
$is_installer = drupal_installation_attempted();
|
||||
// Initialize a maintenance theme if the bootstrap was not complete.
|
||||
// Do it early because drupal_set_message() triggers a
|
||||
// \Drupal\Core\Theme\ThemeManager::initTheme().
|
||||
if ($fatal && \Drupal::hasService('theme.manager')) {
|
||||
// The installer initializes a maintenance theme at the earliest possible
|
||||
// point in time already. Do not unset that.
|
||||
if (!$is_installer) {
|
||||
\Drupal::theme()->resetActiveTheme();
|
||||
}
|
||||
if (!defined('MAINTENANCE_MODE')) {
|
||||
define('MAINTENANCE_MODE', 'error');
|
||||
}
|
||||
// No-op if the active theme is set already.
|
||||
drupal_maintenance_theme();
|
||||
}
|
||||
|
||||
// Backtrace array is not a valid replacement value for t().
|
||||
$backtrace = $error['backtrace'];
|
||||
|
@ -152,22 +138,37 @@ function _drupal_log_error($error, $fatal = FALSE) {
|
|||
'line' => $error['%line'],
|
||||
),
|
||||
);
|
||||
// For non-fatal errors (e.g. PHP notices) _drupal_log_error can be called
|
||||
// multiple times per request. In that case the response is typically
|
||||
// generated outside of the error handler, e.g., in a controller. As a
|
||||
// result it is not possible to use a Response object here but instead the
|
||||
// headers need to be emitted directly.
|
||||
header('X-Drupal-Assertion-' . $number . ': ' . rawurlencode(serialize($assertion)));
|
||||
$number++;
|
||||
}
|
||||
|
||||
$response = new Response();
|
||||
|
||||
// Only call the logger if there is a logger factory available. This can occur
|
||||
// if there is an error while rebuilding the container or during the
|
||||
// installer.
|
||||
if (\Drupal::hasService('logger.factory')) {
|
||||
\Drupal::logger('php')->log($error['severity_level'], '%type: !message in %function (line %line of %file).', $error);
|
||||
try {
|
||||
\Drupal::logger('php')->log($error['severity_level'], '%type: !message in %function (line %line of %file).', $error);
|
||||
}
|
||||
catch (\Exception $e) {
|
||||
// We can't log, for example because the database connection is not
|
||||
// available. At least try to log to PHP error log.
|
||||
error_log(sprintf('Failed to log error: %type: !message in %function (line %line of %file).', $error['%type'], $error['%function'], $error['%line'], $error['%file']));
|
||||
}
|
||||
}
|
||||
|
||||
if (PHP_SAPI === 'cli') {
|
||||
if ($fatal) {
|
||||
// When called from CLI, simply output a plain text message.
|
||||
// Should not translate the string to avoid errors producing more errors.
|
||||
print html_entity_decode(strip_tags(format_string('%type: !message in %function (line %line of %file).', $error))). "\n";
|
||||
$response->setContent(html_entity_decode(strip_tags(format_string('%type: !message in %function (line %line of %file).', $error))). "\n");
|
||||
$response->send();
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
@ -177,7 +178,8 @@ function _drupal_log_error($error, $fatal = FALSE) {
|
|||
if (error_displayable($error)) {
|
||||
// When called from JavaScript, simply output the error message.
|
||||
// Should not translate the string to avoid errors producing more errors.
|
||||
print format_string('%type: !message in %function (line %line of %file).', $error);
|
||||
$response->setContent(format_string('%type: !message in %function (line %line of %file).', $error));
|
||||
$response->send();
|
||||
}
|
||||
exit;
|
||||
}
|
||||
|
@ -185,6 +187,8 @@ function _drupal_log_error($error, $fatal = FALSE) {
|
|||
else {
|
||||
// Display the message if the current error reporting level allows this type
|
||||
// of message to be displayed, and unconditionally in update.php.
|
||||
$message = '';
|
||||
$class = NULL;
|
||||
if (error_displayable($error)) {
|
||||
$class = 'error';
|
||||
|
||||
|
@ -219,6 +223,32 @@ function _drupal_log_error($error, $fatal = FALSE) {
|
|||
// Generate a backtrace containing only scalar argument values.
|
||||
$message .= '<pre class="backtrace">' . Error::formatBacktrace($backtrace) . '</pre>';
|
||||
}
|
||||
}
|
||||
|
||||
if ($fatal) {
|
||||
// We fallback to a maintenance page at this point, because the page generation
|
||||
// itself can generate errors.
|
||||
// Should not translate the string to avoid errors producing more errors.
|
||||
$message = 'The website encountered an unexpected error. Please try again later.' . '<br />' . $message;
|
||||
|
||||
if ($is_installer) {
|
||||
// install_display_output() prints the output and ends script execution.
|
||||
$output = array(
|
||||
'#title' => 'Error',
|
||||
'#markup' => $message,
|
||||
);
|
||||
install_display_output($output, $GLOBALS['install_state'], $response->headers->all());
|
||||
exit;
|
||||
}
|
||||
|
||||
$response->setContent($message);
|
||||
$response->setStatusCode(500, '500 Service unavailable (with message)');
|
||||
|
||||
$response->send();
|
||||
// An exception must halt script execution.
|
||||
exit;
|
||||
}
|
||||
else {
|
||||
if (\Drupal::hasService('session')) {
|
||||
// Message display is dependent on sessions being available.
|
||||
drupal_set_message(SafeMarkup::set($message), $class, TRUE);
|
||||
|
@ -227,29 +257,6 @@ function _drupal_log_error($error, $fatal = FALSE) {
|
|||
print $message;
|
||||
}
|
||||
}
|
||||
|
||||
if ($fatal) {
|
||||
// We fallback to a maintenance page at this point, because the page generation
|
||||
// itself can generate errors.
|
||||
// Should not translate the string to avoid errors producing more errors.
|
||||
$message = 'The website encountered an unexpected error. Please try again later.';
|
||||
if ($is_installer) {
|
||||
// install_display_output() prints the output and ends script execution.
|
||||
$output = array(
|
||||
'#title' => 'Error',
|
||||
'#markup' => $message,
|
||||
);
|
||||
install_display_output($output, $GLOBALS['install_state']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$bare_html_page_renderer = \Drupal::service('bare_html_page_renderer');
|
||||
$response = $bare_html_page_renderer->renderBarePage(['#markup' => $message], 'Error', 'maintenance_page');
|
||||
$response->setStatusCode(500, '500 Service unavailable (with message)');
|
||||
// An exception must halt script execution.
|
||||
$response->send();
|
||||
exit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -277,9 +284,16 @@ function _drupal_get_error_level() {
|
|||
return ERROR_REPORTING_DISPLAY_VERBOSE;
|
||||
}
|
||||
$error_level = NULL;
|
||||
if (\Drupal::hasService('config.factory')) {
|
||||
// Try to get the error level configuration from database. If this fails,
|
||||
// for example if the database connection is not there, try to read it from
|
||||
// settings.php.
|
||||
try {
|
||||
$error_level = \Drupal::config('system.logging')->get('error_level');
|
||||
}
|
||||
catch (\Exception $e) {
|
||||
$error_level = isset($GLOBALS['config']['system.logging']['error_level']) ? $GLOBALS['config']['system.logging']['error_level'] : ERROR_REPORTING_HIDE;
|
||||
}
|
||||
|
||||
// If there is no container or if it has no config.factory service, we are
|
||||
// possibly in an edge-case error situation while trying to serve a regular
|
||||
// request on a public site, so use the non-verbose default value.
|
||||
|
|
|
@ -89,49 +89,6 @@ const FILE_EXISTS_ERROR = 2;
|
|||
*/
|
||||
const FILE_STATUS_PERMANENT = 1;
|
||||
|
||||
/**
|
||||
* Provides Drupal stream wrapper registry.
|
||||
*
|
||||
* @param int $filter
|
||||
* (Optional) Filters out all types except those with an on bit for each on
|
||||
* bit in $filter. For example, if $filter is
|
||||
* StreamWrapperInterface::WRITE_VISIBLE, which is equal to
|
||||
* (StreamWrapperInterface::READ | StreamWrapperInterface::WRITE |
|
||||
* StreamWrapperInterface::VISIBLE), then only stream wrappers with all three
|
||||
* of these bits set are returned. Defaults to StreamWrapperInterface::ALL,
|
||||
* which returns all registered stream wrappers.
|
||||
*
|
||||
* @return array
|
||||
* An array keyed by scheme, with values containing an array of information
|
||||
* about the stream wrapper, as returned by hook_stream_wrappers(). If $filter
|
||||
* is omitted or set to StreamWrapperInterface::ALL, the entire Drupal stream
|
||||
* wrapper registry is returned. Otherwise only the stream wrappers whose
|
||||
* 'type' bitmask has an on bit for each bit specified in $filter are
|
||||
* returned.
|
||||
*
|
||||
* @deprecated in Drupal 8.x-dev, will be removed before Drupal 8.0.
|
||||
* Use \Drupal::service('stream_wrapper_manager')->getWrappers().
|
||||
*/
|
||||
function file_get_stream_wrappers($filter = StreamWrapperInterface::ALL) {
|
||||
return \Drupal::service('stream_wrapper_manager')->getWrappers($filter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the stream wrapper class name for a given scheme.
|
||||
*
|
||||
* @param string $scheme
|
||||
* Stream scheme.
|
||||
*
|
||||
* @return string|bool
|
||||
* Return string if a scheme has a registered handler, or FALSE.
|
||||
*
|
||||
* @deprecated in Drupal 8.x-dev, will be removed before Drupal 8.0.
|
||||
* Use \Drupal::service('stream_wrapper_manager')->getClass().
|
||||
*/
|
||||
function file_stream_wrapper_get_class($scheme) {
|
||||
return \Drupal::service('stream_wrapper_manager')->getClass($scheme);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the scheme of a URI (e.g. a stream).
|
||||
*
|
||||
|
@ -214,55 +171,6 @@ function file_stream_wrapper_uri_normalize($uri) {
|
|||
return $uri;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a reference to the stream wrapper class responsible for a given URI.
|
||||
*
|
||||
* The scheme determines the stream wrapper class that should be
|
||||
* used by consulting the stream wrapper registry.
|
||||
*
|
||||
* @param string $uri
|
||||
* A stream, referenced as "scheme://target".
|
||||
*
|
||||
* @return \Drupal\Core\StreamWrapper\StreamWrapperInterface|bool
|
||||
* Returns a new stream wrapper object appropriate for the given URI or FALSE
|
||||
* if no registered handler could be found. For example, a URI of
|
||||
* "private://example.txt" would return a new private stream wrapper object
|
||||
* (Drupal\Core\StreamWrapper\PrivateStream).
|
||||
*
|
||||
* * @deprecated in Drupal 8.x-dev, will be removed before Drupal 8.0.
|
||||
* Use \Drupal::service('stream_wrapper_manager')->getViaUri().
|
||||
*/
|
||||
function file_stream_wrapper_get_instance_by_uri($uri) {
|
||||
return \Drupal::service('stream_wrapper_manager')->getViaUri($uri);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a reference to the stream wrapper class responsible for a scheme.
|
||||
*
|
||||
* This helper method returns a stream instance using a scheme. That is, the
|
||||
* passed string does not contain a "://". For example, "public" is a scheme
|
||||
* but "public://" is a URI (stream). This is because the later contains both
|
||||
* a scheme and target despite target being empty.
|
||||
*
|
||||
* Note: the instance URI will be initialized to "scheme://" so that you can
|
||||
* make the customary method calls as if you had retrieved an instance by URI.
|
||||
*
|
||||
* @param string $scheme
|
||||
* If the stream was "public://target", "public" would be the scheme.
|
||||
*
|
||||
* @return \Drupal\Core\StreamWrapper\StreamWrapperInterface|bool
|
||||
* Returns a new stream wrapper object appropriate for the given $scheme.
|
||||
* For example, for the public scheme a stream wrapper object
|
||||
* (Drupal\Core\StreamWrapper\PublicStream).
|
||||
* FALSE is returned if no registered handler could be found.
|
||||
*
|
||||
* @deprecated in Drupal 8.x-dev, will be removed before Drupal 8.0.
|
||||
* Use \Drupal::service('stream_wrapper_manager')->getViaScheme().
|
||||
*/
|
||||
function file_stream_wrapper_get_instance_by_scheme($scheme) {
|
||||
return \Drupal::service('stream_wrapper_manager')->getViaScheme($scheme);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a web-accessible URL for a stream to an external or local file.
|
||||
*
|
||||
|
@ -331,7 +239,7 @@ function file_create_url($uri) {
|
|||
}
|
||||
else {
|
||||
// Attempt to return an external URL using the appropriate wrapper.
|
||||
if ($wrapper = file_stream_wrapper_get_instance_by_uri($uri)) {
|
||||
if ($wrapper = \Drupal::service('stream_wrapper_manager')->getViaUri($uri)) {
|
||||
return $wrapper->getExternalUrl();
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -43,7 +43,7 @@ function template_preprocess_select(&$variables) {
|
|||
}
|
||||
|
||||
/**
|
||||
* Converts an array of options into HTML, for use in select list form elements.
|
||||
* Converts an options form element into a structured array for output.
|
||||
*
|
||||
* This function calls itself recursively to obtain the values for each optgroup
|
||||
* within the list of options and when the function encounters an object with
|
||||
|
@ -78,13 +78,22 @@ function template_preprocess_select(&$variables) {
|
|||
* $element['#options'] above, or NULL. This parameter is only used internally
|
||||
* and is not intended to be passed in to the initial function call.
|
||||
*
|
||||
* @return string
|
||||
* An HTML string of options and optgroups for use in a select form element.
|
||||
* @return mixed[]
|
||||
* A structured, possibly nested, array of options and optgroups for use in a
|
||||
* select form element.
|
||||
* - label: A translated string whose value is the text of a single HTML
|
||||
* option element, or the label attribute for an optgroup.
|
||||
* - options: Optional, array of options for an optgroup.
|
||||
* - selected: A boolean that indicates whether the option is selected when
|
||||
* rendered.
|
||||
* - type: A string that defines the element type. The value can be 'option'
|
||||
* or 'optgroup'.
|
||||
* - value: A string that contains the value attribute for the option.
|
||||
*/
|
||||
function form_select_options($element, $choices = NULL) {
|
||||
if (!isset($choices)) {
|
||||
if (empty($element['#options'])) {
|
||||
return '';
|
||||
return [];
|
||||
}
|
||||
$choices = $element['#options'];
|
||||
}
|
||||
|
@ -94,29 +103,35 @@ function form_select_options($element, $choices = NULL) {
|
|||
$value_is_array = $value_valid && is_array($element['#value']);
|
||||
// Check if the element is multiple select and no value has been selected.
|
||||
$empty_value = (empty($element['#value']) && !empty($element['#multiple']));
|
||||
$options = '';
|
||||
$options = [];
|
||||
foreach ($choices as $key => $choice) {
|
||||
if (is_array($choice)) {
|
||||
$options .= '<optgroup label="' . SafeMarkup::checkPlain($key) . '">';
|
||||
$options .= form_select_options($element, $choice);
|
||||
$options .= '</optgroup>';
|
||||
$options[] = [
|
||||
'type' => 'optgroup',
|
||||
'label' => $key,
|
||||
'options' => form_select_options($element, $choice),
|
||||
];
|
||||
}
|
||||
elseif (is_object($choice) && isset($choice->option)) {
|
||||
$options .= form_select_options($element, $choice->option);
|
||||
$options = array_merge($options, form_select_options($element, $choice->option));
|
||||
}
|
||||
else {
|
||||
$option = [];
|
||||
$key = (string) $key;
|
||||
$empty_choice = $empty_value && $key == '_none';
|
||||
if ($value_valid && ((!$value_is_array && (string) $element['#value'] === $key || ($value_is_array && in_array($key, $element['#value']))) || $empty_choice)) {
|
||||
$selected = ' selected="selected"';
|
||||
$option['selected'] = TRUE;
|
||||
}
|
||||
else {
|
||||
$selected = '';
|
||||
$option['selected'] = FALSE;
|
||||
}
|
||||
$options .= '<option value="' . SafeMarkup::checkPlain($key) . '"' . $selected . '>' . SafeMarkup::checkPlain($choice) . '</option>';
|
||||
$option['type'] = 'option';
|
||||
$option['value'] = $key;
|
||||
$option['label'] = $choice;
|
||||
$options[] = $option;
|
||||
}
|
||||
}
|
||||
return SafeMarkup::set($options);
|
||||
return $options;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -810,7 +825,7 @@ function batch_process($redirect = NULL, Url $url = NULL, $redirect_callback = N
|
|||
$query_options['op'] = 'finished';
|
||||
$error_url->setOption('query', $query_options);
|
||||
|
||||
$batch['error_message'] = t('Please continue to <a href="@error_url">the error page</a>', array('@error_url' => $error_url->toString()));
|
||||
$batch['error_message'] = t('Please continue to <a href="@error_url">the error page</a>', array('@error_url' => $error_url->toString(TRUE)->getGeneratedUrl()));
|
||||
|
||||
// Clear the way for the redirection to the batch processing page, by
|
||||
// saving and unsetting the 'destination', if there is any.
|
||||
|
@ -840,7 +855,7 @@ function batch_process($redirect = NULL, Url $url = NULL, $redirect_callback = N
|
|||
$function($batch_url->toString(), ['query' => $query_options]);
|
||||
}
|
||||
else {
|
||||
return new RedirectResponse($batch_url->setAbsolute()->toString());
|
||||
return new RedirectResponse($batch_url->setAbsolute()->toString(TRUE)->getGeneratedUrl());
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -1350,7 +1350,7 @@ function install_download_translation(&$install_state) {
|
|||
* original name. If the path contains a filename as well, that one will be
|
||||
* used instead.
|
||||
*
|
||||
* @return boolean
|
||||
* @return bool
|
||||
* TRUE on success, FALSE on failure.
|
||||
*/
|
||||
function install_retrieve_file($uri, $destination) {
|
||||
|
@ -1364,8 +1364,8 @@ function install_retrieve_file($uri, $destination) {
|
|||
}
|
||||
|
||||
try {
|
||||
$request = \Drupal::httpClient()->get($uri, array('headers' => array('Accept' => 'text/plain')));
|
||||
$data = $request->getBody(TRUE);
|
||||
$response = \Drupal::httpClient()->get($uri, array('headers' => array('Accept' => 'text/plain')));
|
||||
$data = (string) $response->getBody();
|
||||
if (empty($data)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -1656,6 +1656,12 @@ function install_profile_themes(&$install_state) {
|
|||
* An array of information about the current installation state.
|
||||
*/
|
||||
function install_install_profile(&$install_state) {
|
||||
// Now that all modules are installed, make sure the entity storage and other
|
||||
// handlers are up to date with the current entity and field definitions. For
|
||||
// example, Path module adds a base field to nodes and taxonomy terms after
|
||||
// those modules are already installed.
|
||||
\Drupal::service('entity.definition_update_manager')->applyUpdates();
|
||||
|
||||
\Drupal::service('module_installer')->install(array(drupal_get_profile()), FALSE);
|
||||
// Install all available optional config. During installation the module order
|
||||
// is determined by dependencies. If there are no dependencies between modules
|
||||
|
|
|
@ -40,10 +40,6 @@ function template_preprocess_menu_local_task(&$variables) {
|
|||
$active = SafeMarkup::format('<span class="visually-hidden">@label</span>', array('@label' => t('(active tab)')));
|
||||
$link_text = t('@local-task-title@active', array('@local-task-title' => $link_text, '@active' => $active));
|
||||
}
|
||||
else {
|
||||
// @todo Remove this once https://www.drupal.org/node/2338081 is fixed.
|
||||
$link_text = SafeMarkup::checkPlain($link_text);
|
||||
}
|
||||
|
||||
$link['localized_options']['set_active_class'] = TRUE;
|
||||
|
||||
|
|
|
@ -176,6 +176,7 @@ function template_preprocess_pager(&$variables) {
|
|||
$element = $variables['pager']['#element'];
|
||||
$parameters = $variables['pager']['#parameters'];
|
||||
$quantity = $variables['pager']['#quantity'];
|
||||
$route_name = $variables['pager']['#route_name'];
|
||||
global $pager_page_array, $pager_total;
|
||||
|
||||
// Nothing to do if there is only one page.
|
||||
|
@ -218,7 +219,7 @@ function template_preprocess_pager(&$variables) {
|
|||
$options = array(
|
||||
'query' => pager_query_add_page($parameters, $element, 0),
|
||||
);
|
||||
$items['first']['href'] = \Drupal::url('<current>', [], $options);
|
||||
$items['first']['href'] = \Drupal::url($route_name, [], $options);
|
||||
if (isset($tags[0])) {
|
||||
$items['first']['text'] = $tags[0];
|
||||
}
|
||||
|
@ -227,7 +228,7 @@ function template_preprocess_pager(&$variables) {
|
|||
$options = array(
|
||||
'query' => pager_query_add_page($parameters, $element, $pager_page_array[$element] - 1),
|
||||
);
|
||||
$items['previous']['href'] = \Drupal::url('<current>', [], $options);
|
||||
$items['previous']['href'] = \Drupal::url($route_name, [], $options);
|
||||
if (isset($tags[1])) {
|
||||
$items['previous']['text'] = $tags[1];
|
||||
}
|
||||
|
@ -243,7 +244,7 @@ function template_preprocess_pager(&$variables) {
|
|||
$options = array(
|
||||
'query' => pager_query_add_page($parameters, $element, $i - 1),
|
||||
);
|
||||
$items['pages'][$i]['href'] = \Drupal::url('<current>', [], $options);
|
||||
$items['pages'][$i]['href'] = \Drupal::url($route_name, [], $options);
|
||||
if ($i == $pager_current) {
|
||||
$variables['current'] = $i;
|
||||
}
|
||||
|
@ -260,7 +261,7 @@ function template_preprocess_pager(&$variables) {
|
|||
$options = array(
|
||||
'query' => pager_query_add_page($parameters, $element, $pager_page_array[$element] + 1),
|
||||
);
|
||||
$items['next']['href'] = \Drupal::url('<current>', [], $options);
|
||||
$items['next']['href'] = \Drupal::url($route_name, [], $options);
|
||||
if (isset($tags[3])) {
|
||||
$items['next']['text'] = $tags[3];
|
||||
}
|
||||
|
@ -269,13 +270,18 @@ function template_preprocess_pager(&$variables) {
|
|||
$options = array(
|
||||
'query' => pager_query_add_page($parameters, $element, $pager_max - 1),
|
||||
);
|
||||
$items['last']['href'] = \Drupal::url('<current>', [], $options);
|
||||
$items['last']['href'] = \Drupal::url($route_name, [], $options);
|
||||
if (isset($tags[4])) {
|
||||
$items['last']['text'] = $tags[4];
|
||||
}
|
||||
}
|
||||
|
||||
$variables['items'] = $items;
|
||||
|
||||
// The rendered link needs to play well with any other query parameter
|
||||
// used on the page, like exposed filters, so for the cacheability all query
|
||||
// parameters matter.
|
||||
$variables['#cache']['contexts'][] = 'url.query_args';
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1066,30 +1066,6 @@ function template_preprocess_item_list(&$variables) {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares variables for feed icon templates.
|
||||
*
|
||||
* Default template: feed-icon.html.twig.
|
||||
*
|
||||
* @param array $variables
|
||||
* An associative array containing:
|
||||
* - url: An internal system path or a fully qualified external URL of the
|
||||
* feed.
|
||||
* - title: A descriptive title of the feed.
|
||||
*/
|
||||
function template_preprocess_feed_icon(&$variables) {
|
||||
$text = t('Subscribe to !feed-title', array('!feed-title' => $variables['title']));
|
||||
$variables['icon'] = array(
|
||||
'#theme' => 'image__feed_icon',
|
||||
'#uri' => 'core/misc/feed.png',
|
||||
'#width' => 16,
|
||||
'#height' => 16,
|
||||
'#alt' => $text,
|
||||
);
|
||||
// Stripping tags because that's what l() used to do.
|
||||
$variables['attributes']['title'] = strip_tags($text);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns HTML for an indentation div; used for drag and drop tables.
|
||||
*
|
||||
|
@ -1350,7 +1326,7 @@ function template_preprocess_page(&$variables) {
|
|||
$variables['language'] = $language_interface;
|
||||
$variables['logo'] = theme_get_setting('logo.url');
|
||||
$variables['site_name'] = (theme_get_setting('features.name') ? SafeMarkup::checkPlain($site_config->get('name')) : '');
|
||||
$variables['site_slogan'] = (theme_get_setting('features.slogan') ? Xss::filterAdmin($site_config->get('slogan')) : '');
|
||||
$variables['site_slogan']['#markup'] = (theme_get_setting('features.slogan') ? $site_config->get('slogan') : '');
|
||||
|
||||
// An exception might be thrown.
|
||||
try {
|
||||
|
@ -1462,7 +1438,6 @@ function template_preprocess_maintenance_page(&$variables) {
|
|||
template_preprocess_page($variables);
|
||||
|
||||
// @see system_page_attachments()
|
||||
$variables['#attached']['library'][] = 'core/normalize';
|
||||
$variables['#attached']['library'][] = 'system/maintenance';
|
||||
}
|
||||
|
||||
|
|
|
@ -224,14 +224,10 @@ function update_do_one($module, $number, $dependency_map, &$context) {
|
|||
/**
|
||||
* Performs entity definition updates, which can trigger schema updates.
|
||||
*
|
||||
* @param $module
|
||||
* The module whose update will be run.
|
||||
* @param $number
|
||||
* The update number to run.
|
||||
* @param $context
|
||||
* The batch context array.
|
||||
*/
|
||||
function update_entity_definitions($module, $number, &$context) {
|
||||
function update_entity_definitions(&$context) {
|
||||
try {
|
||||
\Drupal::service('entity.definition_update_manager')->applyUpdates();
|
||||
}
|
||||
|
@ -243,7 +239,7 @@ function update_entity_definitions($module, $number, &$context) {
|
|||
// \Drupal\Component\Utility\SafeMarkup::checkPlain() by
|
||||
// \Drupal\Core\Utility\Error::decodeException().
|
||||
$ret['#abort'] = array('success' => FALSE, 'query' => t('%type: !message in %function (line %line of %file).', $variables));
|
||||
$context['results'][$module][$number] = $ret;
|
||||
$context['results']['core']['update_entity_definitions'] = $ret;
|
||||
$context['results']['#abort'][] = 'update_entity_definitions';
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,13 +29,17 @@ function drupal_rebuild(ClassLoader $class_loader, Request $request) {
|
|||
restore_error_handler();
|
||||
restore_exception_handler();
|
||||
|
||||
// Force kernel to rebuild container.
|
||||
PhpStorageFactory::get('service_container')->deleteAll();
|
||||
// Force kernel to rebuild php cache.
|
||||
PhpStorageFactory::get('twig')->deleteAll();
|
||||
|
||||
// Bootstrap up to where caches exist and clear them.
|
||||
$kernel = new DrupalKernel('prod', $class_loader);
|
||||
$kernel->setSitePath(DrupalKernel::findSitePath($request));
|
||||
|
||||
// Invalidate the container.
|
||||
$kernel->invalidateContainer();
|
||||
|
||||
// Prepare a NULL request.
|
||||
$kernel->prepareLegacyRequest($request);
|
||||
|
||||
foreach (Cache::getBins() as $bin) {
|
||||
|
|
|
@ -21,8 +21,8 @@ define('MAINTENANCE_MODE', 'install');
|
|||
// The minimum version is specified explicitly, as DRUPAL_MINIMUM_PHP is not
|
||||
// yet available. It is defined in bootstrap.inc, but it is not possible to
|
||||
// load that file yet as it would cause a fatal error on older versions of PHP.
|
||||
if (version_compare(PHP_VERSION, '5.4.5') < 0) {
|
||||
print 'Your PHP installation is too old. Drupal requires at least PHP 5.4.5. See the <a href="https://www.drupal.org/requirements">system requirements</a> page for more information.';
|
||||
if (version_compare(PHP_VERSION, '5.5.9') < 0) {
|
||||
print 'Your PHP installation is too old. Drupal requires at least PHP 5.5.9. See the <a href="https://www.drupal.org/requirements">system requirements</a> page for more information.';
|
||||
exit;
|
||||
}
|
||||
|
||||
|
|
|
@ -81,7 +81,7 @@ class Drupal {
|
|||
/**
|
||||
* The current system version.
|
||||
*/
|
||||
const VERSION = '8.0.0-beta12';
|
||||
const VERSION = '8.0.0-beta14';
|
||||
|
||||
/**
|
||||
* Core API compatibility.
|
||||
|
@ -395,7 +395,7 @@ class Drupal {
|
|||
/**
|
||||
* Returns the default http client.
|
||||
*
|
||||
* @return \GuzzleHttp\ClientInterface
|
||||
* @return \GuzzleHttp\Client
|
||||
* A guzzle http client instance.
|
||||
*/
|
||||
public static function httpClient() {
|
||||
|
@ -504,22 +504,22 @@ class Drupal {
|
|||
* (optional) An associative array of parameter names and values.
|
||||
* @param array $options
|
||||
* (optional) An associative array of additional options.
|
||||
* @param bool $collect_cacheability_metadata
|
||||
* @param bool $collect_bubbleable_metadata
|
||||
* (optional) Defaults to FALSE. When TRUE, both the generated URL and its
|
||||
* associated cacheability metadata are returned.
|
||||
* associated bubbleable metadata are returned.
|
||||
*
|
||||
* @return string|\Drupal\Core\GeneratedUrl
|
||||
* A string containing a URL to the given path.
|
||||
* When $collect_cacheability_metadata is TRUE, a GeneratedUrl object is
|
||||
* returned, containing the generated URL plus cacheability metadata.
|
||||
* When $collect_bubbleable_metadata is TRUE, a GeneratedUrl object is
|
||||
* returned, containing the generated URL plus bubbleable metadata.
|
||||
*
|
||||
* @see \Drupal\Core\Routing\UrlGeneratorInterface::generateFromRoute()
|
||||
* @see \Drupal\Core\Url
|
||||
* @see \Drupal\Core\Url::fromRoute()
|
||||
* @see \Drupal\Core\Url::fromUri()
|
||||
*/
|
||||
public static function url($route_name, $route_parameters = array(), $options = array(), $collect_cacheability_metadata = FALSE) {
|
||||
return static::getContainer()->get('url_generator')->generateFromRoute($route_name, $route_parameters, $options, $collect_cacheability_metadata);
|
||||
public static function url($route_name, $route_parameters = array(), $options = array(), $collect_bubbleable_metadata = FALSE) {
|
||||
return static::getContainer()->get('url_generator')->generateFromRoute($route_name, $route_parameters, $options, $collect_bubbleable_metadata);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -542,20 +542,20 @@ class Drupal {
|
|||
* The link text for the anchor tag.
|
||||
* @param \Drupal\Core\Url $url
|
||||
* The URL object used for the link.
|
||||
* @param bool $collect_cacheability_metadata
|
||||
* @param bool $collect_bubbleable_metadata
|
||||
* (optional) Defaults to FALSE. When TRUE, both the generated URL and its
|
||||
* associated cacheability metadata are returned.
|
||||
* associated bubbleable metadata are returned.
|
||||
*
|
||||
* @return string|\Drupal\Core\GeneratedLink
|
||||
* An HTML string containing a link to the given route and parameters.
|
||||
* When $collect_cacheability_metadata is TRUE, a GeneratedLink object is
|
||||
* returned, containing the generated link plus cacheability metadata.
|
||||
* When $collect_bubbleable_metadata is TRUE, a GeneratedLink object is
|
||||
* returned, containing the generated link plus bubbleable metadata.
|
||||
*
|
||||
* @see \Drupal\Core\Utility\LinkGeneratorInterface::generate()
|
||||
* @see \Drupal\Core\Url
|
||||
*/
|
||||
public static function l($text, Url $url, $collect_cacheability_metadata = FALSE) {
|
||||
return static::getContainer()->get('link_generator')->generate($text, $url, $collect_cacheability_metadata);
|
||||
public static function l($text, Url $url, $collect_bubbleable_metadata = FALSE) {
|
||||
return static::getContainer()->get('link_generator')->generate($text, $url, $collect_bubbleable_metadata);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
409
core/lib/Drupal/Component/Assertion/Inspector.php
Normal file
409
core/lib/Drupal/Component/Assertion/Inspector.php
Normal file
|
@ -0,0 +1,409 @@
|
|||
<?php
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Component\Assertion\Inspector.
|
||||
*/
|
||||
|
||||
namespace Drupal\Component\Assertion;
|
||||
|
||||
use Traversable;
|
||||
|
||||
/**
|
||||
* Generic inspections for the assert() statement.
|
||||
*
|
||||
* This is a static function collection for inspecting variable contents. All
|
||||
* functions in this collection check a variable against an assertion about its
|
||||
* structure.
|
||||
*
|
||||
* Example call:
|
||||
* @code
|
||||
* assert('Drupal\\Component\\Assertion\\Inspector::assertAllStrings($array)');
|
||||
* @endcode
|
||||
*
|
||||
* @ingroup php_assert
|
||||
*/
|
||||
class Inspector {
|
||||
|
||||
/**
|
||||
* Asserts argument can be traversed with foreach.
|
||||
*
|
||||
* @param mixed $traversable
|
||||
* Variable to be examined.
|
||||
*
|
||||
* @return bool
|
||||
* TRUE if $traversable can be traversed with foreach.
|
||||
*/
|
||||
public static function assertTraversable($traversable) {
|
||||
return is_array($traversable) || $traversable instanceof Traversable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts callback returns TRUE for each member of a traversable.
|
||||
*
|
||||
* This is less memory intensive than using array_filter() to build a second
|
||||
* array and then comparing the arrays. Many of the other functions in this
|
||||
* collection alias this function passing a specific callback to make the
|
||||
* code more readable.
|
||||
*
|
||||
* @param callable $callable
|
||||
* Callback function.
|
||||
* @param mixed $traversable
|
||||
* Variable to be examined.
|
||||
*
|
||||
* @return bool
|
||||
* TRUE if $traversable can be traversed and $callable returns TRUE on
|
||||
* all members.
|
||||
*
|
||||
* @see http://php.net/manual/language.types.callable.php
|
||||
*/
|
||||
public static function assertAll(callable $callable, $traversable) {
|
||||
if (static::assertTraversable($traversable)) {
|
||||
foreach ($traversable as $member) {
|
||||
if (!$callable($member)) {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that all members are strings.
|
||||
*
|
||||
* @param mixed $traversable
|
||||
* Variable to be examined.
|
||||
*
|
||||
* @return bool
|
||||
* TRUE if $traversable can be traversed and all members are strings.
|
||||
*/
|
||||
public static function assertAllStrings($traversable) {
|
||||
return static::assertAll('is_string', $traversable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts all members are strings or objects with magic __toString() method.
|
||||
*
|
||||
* @param mixed $traversable
|
||||
* Variable to be examined.
|
||||
*
|
||||
* @return bool
|
||||
* TRUE if $traversable can be traversed and all members are strings or
|
||||
* objects with __toString().
|
||||
*/
|
||||
public static function assertAllStringable($traversable) {
|
||||
if (static::assertTraversable($traversable)) {
|
||||
foreach ($traversable as $member) {
|
||||
if (!(is_string($member) || (is_object($member) && method_exists($member, '__toString')))) {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that all members are arrays.
|
||||
*
|
||||
* @param mixed $traversable
|
||||
* Variable to be examined.
|
||||
*
|
||||
* @return bool
|
||||
* TRUE if $traversable can be traversed and all members are arrays.
|
||||
*/
|
||||
public static function assertAllArrays($traversable) {
|
||||
return static::assertAll('is_array', $traversable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the array is strict.
|
||||
*
|
||||
* What PHP calls arrays are more formally called maps in most other
|
||||
* programming languages. A map is a datatype that associates values to keys.
|
||||
* The term 'strict array' here refers to a 0-indexed array in the classic
|
||||
* sense found in programming languages other than PHP.
|
||||
*
|
||||
* @param mixed $array
|
||||
* Variable to be examined.
|
||||
*
|
||||
* @return bool
|
||||
* TRUE if $traversable is a 0-indexed array.
|
||||
*
|
||||
* @see http://php.net/manual/language.types.array.php
|
||||
*/
|
||||
public static function assertStrictArray($array) {
|
||||
if (!is_array($array)) {
|
||||
return FALSE;
|
||||
}
|
||||
$i = 0;
|
||||
|
||||
foreach (array_keys($array) as $key) {
|
||||
if ($i !== $key) {
|
||||
return FALSE;
|
||||
}
|
||||
$i++;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts all members are strict arrays.
|
||||
*
|
||||
* @param mixed $traversable
|
||||
* Variable to be examined.
|
||||
*
|
||||
* @return bool
|
||||
* TRUE if $traversable can be traversed and all members are strict arrays.
|
||||
*
|
||||
* @see ::assertStrictArray
|
||||
*/
|
||||
public static function assertAllStrictArrays($traversable) {
|
||||
return static::assertAll([__CLASS__, 'assertStrictArray'], $traversable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts all given keys exist in every member array.
|
||||
*
|
||||
* Drupal has several data structure arrays that require certain keys be set.
|
||||
* You can overload this function to specify a list of required keys. All
|
||||
* of the keys must be set for this method to return TRUE.
|
||||
*
|
||||
* As an example, this assertion tests for the keys of a theme registry.
|
||||
*
|
||||
* @code
|
||||
* assert('Drupal\\Component\\Assertion\\Inspector::assertAllHaveKey(
|
||||
* $arrayToTest, "type", "theme path", "function", "template", "variables", "render element", "preprocess functions")');
|
||||
* @endcode
|
||||
*
|
||||
* Note: If a method requires certain keys to be present it will usually be
|
||||
* specific about the data types for the values of those keys. Therefore it
|
||||
* will be best to write a specific test for it. Such tests are either bound
|
||||
* to the object that uses them, or are collected into one assertion set for
|
||||
* the package.
|
||||
*
|
||||
* @param mixed $traversable
|
||||
* Variable to be examined.
|
||||
* @param string ...
|
||||
* Keys to be searched for.
|
||||
*
|
||||
* @return bool
|
||||
* TRUE if $traversable can be traversed and all members have all keys.
|
||||
*/
|
||||
public static function assertAllHaveKey() {
|
||||
$args = func_get_args();
|
||||
$traversable = array_shift($args);
|
||||
|
||||
if (static::assertTraversable($traversable)) {
|
||||
foreach ($traversable as $member) {
|
||||
foreach ($args as $key) {
|
||||
if (!array_key_exists($key, $member)) {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that all members are integer values.
|
||||
*
|
||||
* @param mixed $traversable
|
||||
* Variable to be examined.
|
||||
*
|
||||
* @return bool
|
||||
* TRUE if $traversable can be traversed and all members are integers.
|
||||
*/
|
||||
public static function assertAllIntegers($traversable) {
|
||||
return static::assertAll('is_int', $traversable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that all members are float values.
|
||||
*
|
||||
* @param mixed $traversable
|
||||
* Variable to be examined.
|
||||
*
|
||||
* @return bool
|
||||
* TRUE if $traversable can be traversed and all members are floating point
|
||||
* numbers.
|
||||
*/
|
||||
public static function assertAllFloat($traversable) {
|
||||
return static::assertAll('is_float', $traversable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that all members are callable.
|
||||
*
|
||||
* @param mixed $traversable
|
||||
* Variable to be examined.
|
||||
*
|
||||
* @return bool
|
||||
* TRUE if $traversable can be traversed and all members are callable.
|
||||
*/
|
||||
public static function assertAllCallable($traversable) {
|
||||
return static::assertAll('is_callable', $traversable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that all members are not empty.
|
||||
*
|
||||
* @param mixed $traversable
|
||||
* Variable to be examined.
|
||||
*
|
||||
* @return bool
|
||||
* TRUE if $traversable can be traversed and all members not empty.
|
||||
*/
|
||||
public static function assertAllNotEmpty($traversable) {
|
||||
if (static::assertTraversable($traversable)) {
|
||||
foreach ($traversable as $member) {
|
||||
if (empty($member)) {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts all members are numeric data types or strings castable to such.
|
||||
*
|
||||
* @param mixed $traversable
|
||||
* Variable to be examined.
|
||||
*
|
||||
* @return bool
|
||||
* TRUE if $traversable can be traversed and all members are numeric.
|
||||
*/
|
||||
public static function assertAllNumeric($traversable) {
|
||||
return static::assertAll('is_numeric', $traversable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that all members are strings that contain the specified string.
|
||||
*
|
||||
* This runs faster than the regular expression equivalent.
|
||||
*
|
||||
* @param string $pattern
|
||||
* The needle to find.
|
||||
* @param mixed $traversable
|
||||
* Variable to examine.
|
||||
* @param bool $case_sensitive
|
||||
* TRUE to use strstr(), FALSE to use stristr() which is case insensitive.
|
||||
*
|
||||
* @return bool
|
||||
* TRUE if $traversable can be traversed and all members are strings
|
||||
* containing $pattern.
|
||||
*/
|
||||
public static function assertAllMatch($pattern, $traversable, $case_sensitive = FALSE) {
|
||||
if (static::assertTraversable($traversable)) {
|
||||
if ($case_sensitive) {
|
||||
foreach ($traversable as $member) {
|
||||
if (!(is_string($member) && strstr($member, $pattern))) {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
foreach ($traversable as $member) {
|
||||
if (!(is_string($member) && stristr($member, $pattern))) {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Asserts that all members are strings matching a regular expression.
|
||||
*
|
||||
* @param string $pattern
|
||||
* Regular expression string to find.
|
||||
* @param mixed $traversable
|
||||
* Variable to be examined.
|
||||
*
|
||||
* @return bool
|
||||
* TRUE if $traversable can be traversed and all members are strings
|
||||
* matching $pattern.
|
||||
*/
|
||||
public static function assertAllRegularExpressionMatch($pattern, $traversable) {
|
||||
if (static::assertTraversable($traversable)) {
|
||||
foreach ($traversable as $member) {
|
||||
if (!is_string($member)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!preg_match($pattern, $member)) {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that all members are objects.
|
||||
*
|
||||
* When testing if a collection is composed of objects those objects should
|
||||
* be given a common interface to implement and the test should be written to
|
||||
* search for just that interface. While this method will allow tests for
|
||||
* just object status or for multiple classes and interfaces this was done to
|
||||
* allow tests to be written for existing code without altering it. Only use
|
||||
* this method in that manner when testing code from third party vendors.
|
||||
*
|
||||
* Here are some examples:
|
||||
* @code
|
||||
* // Just test all are objects, like a cache.
|
||||
* assert('Drupal\\Component\\Assertion\\Inspector::assertAllObjects(
|
||||
* $collection');
|
||||
*
|
||||
* // Test if traversable objects (arrays won't pass this)
|
||||
* assert('Drupal\\Component\\Assertion\\Inspector::assertAllObjects(
|
||||
* $collection', \'\\Traversable\');
|
||||
*
|
||||
* // Test for the Foo class or Bar\None interface
|
||||
* assert('Drupal\\Component\\Assertion\\Inspector::assertAllObjects(
|
||||
* $collection', \'\\Foo\', \'\\Bar\\None\'');
|
||||
* @endcode
|
||||
*
|
||||
* @param mixed $traversable
|
||||
* Variable to be examined.
|
||||
* @param string ...
|
||||
* Classes and interfaces to test objects against.
|
||||
*
|
||||
* @return bool
|
||||
* TRUE if $traversable can be traversed and all members are objects with
|
||||
* at least one of the listed classes or interfaces.
|
||||
*/
|
||||
public static function assertAllObjects() {
|
||||
$args = func_get_args();
|
||||
$traversable = array_shift($args);
|
||||
|
||||
if (static::assertTraversable($traversable)) {
|
||||
foreach ($traversable as $member) {
|
||||
if (count($args) > 0) {
|
||||
foreach ($args as $instance) {
|
||||
if ($member instanceof $instance) {
|
||||
// We're continuing to the next member on the outer loop.
|
||||
// @see http://php.net/continue
|
||||
continue 2;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
elseif (!is_object($member)) {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
}
|
|
@ -508,7 +508,7 @@ class DateTimePlus {
|
|||
* @param array $array
|
||||
* An array of datetime values keyed by date part.
|
||||
*
|
||||
* @return boolean
|
||||
* @return bool
|
||||
* TRUE if the datetime parts contain valid values, otherwise FALSE.
|
||||
*/
|
||||
public static function checkArray($array) {
|
||||
|
|
339
core/lib/Drupal/Component/Gettext/LICENSE.txt
Normal file
339
core/lib/Drupal/Component/Gettext/LICENSE.txt
Normal file
|
@ -0,0 +1,339 @@
|
|||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Lesser General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License.
|
|
@ -147,7 +147,7 @@ class PoItem {
|
|||
/**
|
||||
* Get if the translation has plural values.
|
||||
*
|
||||
* @return boolean $plural
|
||||
* @return bool
|
||||
*/
|
||||
function isPlural() {
|
||||
return $this->_plural;
|
||||
|
|
12
core/lib/Drupal/Component/Gettext/README.txt
Normal file
12
core/lib/Drupal/Component/Gettext/README.txt
Normal file
|
@ -0,0 +1,12 @@
|
|||
The Drupal Gettext Component
|
||||
|
||||
Thanks for using this Drupal component.
|
||||
|
||||
You can participate in its development on Drupal.org, through our issue system:
|
||||
https://www.drupal.org/project/issues/drupal
|
||||
|
||||
You can get the full Drupal repo here:
|
||||
https://www.drupal.org/project/drupal/git-instructions
|
||||
|
||||
You can browse the full Drupal repo here:
|
||||
http://cgit.drupalcode.org/drupal
|
19
core/lib/Drupal/Component/Gettext/TESTING.txt
Normal file
19
core/lib/Drupal/Component/Gettext/TESTING.txt
Normal file
|
@ -0,0 +1,19 @@
|
|||
HOW-TO: Test this Drupal component
|
||||
|
||||
In order to test this component, you'll need to get the entire Drupal repo and
|
||||
run the tests there.
|
||||
|
||||
You'll find the tests under core/tests/Drupal/Tests/Component.
|
||||
|
||||
You can get the full Drupal repo here:
|
||||
https://www.drupal.org/project/drupal/git-instructions
|
||||
|
||||
You can find more information about running PHPUnit tests with Drupal here:
|
||||
https://www.drupal.org/node/2116263
|
||||
|
||||
Each component in the Drupal\Component namespace has its own annotated test
|
||||
group. You can use this group to run only the tests for this component. Like
|
||||
this:
|
||||
|
||||
$ cd ./core
|
||||
$ ./vendor/bin/phpunit --group Gettext
|
16
core/lib/Drupal/Component/Gettext/composer.json
Normal file
16
core/lib/Drupal/Component/Gettext/composer.json
Normal file
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"name": "drupal/core-gettext",
|
||||
"description": "PHP library for reading PO files.",
|
||||
"type": "library",
|
||||
"license": "GPL-2.0+",
|
||||
"support": {
|
||||
"issues": "https://www.drupal.org/project/issues/drupal",
|
||||
"irc": "irc://irc.freenode.net/drupal-contribute",
|
||||
"source": "https://www.drupal.org/project/drupal/git-instructions"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Drupal\\Component\\Gettext\\": ""
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Component\HttpFoundation\SecuredRedirectResponse.
|
||||
*/
|
||||
|
||||
namespace Drupal\Component\HttpFoundation;
|
||||
|
||||
use \Symfony\Component\HttpFoundation\RedirectResponse;
|
||||
|
||||
/**
|
||||
* Provides a common base class for safe redirects.
|
||||
*
|
||||
* In case you want to redirect to external URLs use
|
||||
* TrustedRedirectResponse.
|
||||
*
|
||||
* For local URLs we use LocalRedirectResponse which opts
|
||||
* out of external redirects.
|
||||
*/
|
||||
abstract class SecuredRedirectResponse extends RedirectResponse {
|
||||
|
||||
/**
|
||||
* Copies an existing redirect response into a safe one.
|
||||
*
|
||||
* The safe one cannot accidentally redirect to an external URL, unless
|
||||
* actively wanted (see TrustedRedirectResponse).
|
||||
*
|
||||
* @param \Symfony\Component\HttpFoundation\RedirectResponse $response
|
||||
* The original redirect.
|
||||
*
|
||||
* @return static
|
||||
*/
|
||||
public static function createFromRedirectResponse(RedirectResponse $response) {
|
||||
$safe_response = new static($response->getTargetUrl(), $response->getStatusCode(), $response->headers->allPreserveCase());
|
||||
$safe_response->setProtocolVersion($response->getProtocolVersion());
|
||||
$safe_response->setCharset($response->getCharset());
|
||||
return $safe_response;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setTargetUrl($url) {
|
||||
if (!$this->isSafe($url)) {
|
||||
throw new \InvalidArgumentException(sprintf('It is not safe to redirect to %s', $url));
|
||||
}
|
||||
return parent::setTargetUrl($url);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the URL is considered as safe to redirect to.
|
||||
*
|
||||
* @param string $url
|
||||
* The URL checked for safety.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
abstract protected function isSafe($url);
|
||||
|
||||
}
|
|
@ -224,7 +224,7 @@ EOF;
|
|||
* @param string $path
|
||||
* A string containing either a file or directory path.
|
||||
*
|
||||
* @return boolean
|
||||
* @return bool
|
||||
* TRUE for success or if path does not exist, FALSE in the event of an
|
||||
* error.
|
||||
*/
|
||||
|
|
|
@ -58,7 +58,8 @@ class MTimeProtectedFileStorage extends MTimeProtectedFastFileStorage {
|
|||
*
|
||||
* @param string $name
|
||||
* The virtual file name. Can be a relative path.
|
||||
* return string
|
||||
*
|
||||
* @return string|false
|
||||
* The full path where the file is if it is valid, FALSE otherwise.
|
||||
*/
|
||||
protected function checkFile($name) {
|
||||
|
|
|
@ -67,6 +67,13 @@ class Context implements ContextInterface {
|
|||
return $this->contextValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function hasContextValue() {
|
||||
return (bool) $this->contextValue || (bool) $this->getContextDefinition()->getDefaultValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
|
|
@ -30,6 +30,14 @@ interface ContextInterface {
|
|||
*/
|
||||
public function getContextValue();
|
||||
|
||||
/**
|
||||
* Returns whether the context has a value.
|
||||
*
|
||||
* @return bool
|
||||
* TRUE if the context has a value, FALSE otherwise.
|
||||
*/
|
||||
public function hasContextValue();
|
||||
|
||||
/**
|
||||
* Sets the definition that the context must conform to.
|
||||
*
|
||||
|
|
|
@ -22,7 +22,7 @@ abstract class ContextAwarePluginBase extends PluginBase implements ContextAware
|
|||
*
|
||||
* @var \Drupal\Component\Plugin\Context\ContextInterface[]
|
||||
*/
|
||||
protected $context;
|
||||
protected $context = [];
|
||||
|
||||
/**
|
||||
* Overrides \Drupal\Component\Plugin\PluginBase::__construct().
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
"homepage": "https://www.drupal.org/project/drupal",
|
||||
"license": "GPL-2.0+",
|
||||
"require": {
|
||||
"php": ">=5.4.2"
|
||||
"php": ">=5.5.9"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
|
|
|
@ -22,7 +22,30 @@ class ProxyBuilder {
|
|||
* The class name of the proxy.
|
||||
*/
|
||||
public static function buildProxyClassName($class_name) {
|
||||
return str_replace('\\', '_', $class_name) . '_Proxy';
|
||||
$match = [];
|
||||
preg_match('/([a-zA-Z0-9_]+\\\\[a-zA-Z0-9_]+)\\\\(.+)/', $class_name, $match);
|
||||
$root_namespace = $match[1];
|
||||
$rest_fqcn = $match[2];
|
||||
$proxy_class_name = $root_namespace . '\\ProxyClass\\' . $rest_fqcn;
|
||||
|
||||
return $proxy_class_name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the used proxy namespace from a given class name.
|
||||
*
|
||||
* @param string $class_name
|
||||
* The class name of the actual service.
|
||||
*
|
||||
* @return string
|
||||
* The namespace name of the proxy.
|
||||
*/
|
||||
public static function buildProxyNamespace($class_name) {
|
||||
$proxy_classname = static::buildProxyClassName($class_name);
|
||||
|
||||
preg_match('/(.+)\\\\[a-zA-Z0-9]+/', $proxy_classname, $match);
|
||||
$proxy_namespace = $match[1];
|
||||
return $proxy_namespace;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -30,23 +53,38 @@ class ProxyBuilder {
|
|||
*
|
||||
* @param string $class_name
|
||||
* The class name of the actual service.
|
||||
* @param string $proxy_class_name
|
||||
* (optional) The class name of the proxy service.
|
||||
*
|
||||
* @return string
|
||||
* The full string with namespace class and methods.
|
||||
*/
|
||||
public function build($class_name) {
|
||||
public function build($class_name, $proxy_class_name = '') {
|
||||
$reflection = new \ReflectionClass($class_name);
|
||||
|
||||
if ($proxy_class_name) {
|
||||
$proxy_class_reflection = new \ReflectionClass($proxy_class_name);
|
||||
$proxy_namespace = $proxy_class_reflection->getNamespaceName();
|
||||
}
|
||||
else {
|
||||
$proxy_class_name = $this->buildProxyClassName($class_name);
|
||||
$proxy_namespace = $this->buildProxyNamespace($class_name);
|
||||
$proxy_class_shortname = str_replace($proxy_namespace . '\\', '', $proxy_class_name);
|
||||
}
|
||||
|
||||
$output = '';
|
||||
$class_documentation = <<<'EOS'
|
||||
/**
|
||||
* Provides a proxy class for \{{ class_name }}.
|
||||
*
|
||||
* @see \Drupal\Component\ProxyBuilder
|
||||
*/
|
||||
|
||||
namespace {{ namespace }}{
|
||||
|
||||
/**
|
||||
* Provides a proxy class for \{{ class_name }}.
|
||||
*
|
||||
* @see \Drupal\Component\ProxyBuilder
|
||||
*/
|
||||
|
||||
EOS;
|
||||
$class_start = 'class {{ proxy_class_name }}';
|
||||
$class_start = ' class {{ proxy_class_shortname }}';
|
||||
|
||||
// For cases in which the implemented interface is a child of another
|
||||
// interface, getInterfaceNames() also returns the parent. This causes a
|
||||
|
@ -77,11 +115,15 @@ EOS;
|
|||
// The actual class;
|
||||
$properties = <<<'EOS'
|
||||
/**
|
||||
* The id of the original proxied service.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $serviceId;
|
||||
protected $drupalProxyOriginalServiceId;
|
||||
|
||||
/**
|
||||
* The real proxied service, after it was lazy loaded.
|
||||
*
|
||||
* @var \{{ class_name }}
|
||||
*/
|
||||
protected $service;
|
||||
|
@ -123,13 +165,14 @@ EOS;
|
|||
if ($value === '') {
|
||||
return $value;
|
||||
}
|
||||
return " $value";
|
||||
return " $value";
|
||||
}, explode("\n", $output)));
|
||||
|
||||
$final_output = $class_documentation . $class_start . "\n{\n\n" . $output . "\n}\n";
|
||||
$final_output = $class_documentation . $class_start . "\n {\n\n" . $output . "\n }\n\n}\n";
|
||||
|
||||
$final_output = str_replace('{{ class_name }}', $class_name, $final_output);
|
||||
$final_output = str_replace('{{ proxy_class_name }}', $this->buildProxyClassName($class_name), $final_output);
|
||||
$final_output = str_replace('{{ namespace }}', $proxy_namespace ? $proxy_namespace . ' ' : '', $final_output);
|
||||
$final_output = str_replace('{{ proxy_class_shortname }}', $proxy_class_shortname, $final_output);
|
||||
|
||||
return $final_output;
|
||||
}
|
||||
|
@ -141,11 +184,16 @@ EOS;
|
|||
*/
|
||||
protected function buildLazyLoadItselfMethod() {
|
||||
$output = <<<'EOS'
|
||||
/**
|
||||
* Lazy loads the real service from the container.
|
||||
*
|
||||
* @return object
|
||||
* Returns the constructed real service.
|
||||
*/
|
||||
protected function lazyLoadItself()
|
||||
{
|
||||
if (!isset($this->service)) {
|
||||
$method_name = 'get' . Container::camelize($this->serviceId) . 'Service';
|
||||
$this->service = $this->container->$method_name(false);
|
||||
$this->service = $this->container->get($this->drupalProxyOriginalServiceId);
|
||||
}
|
||||
|
||||
return $this->service;
|
||||
|
@ -177,11 +225,19 @@ EOS;
|
|||
if ($reflection_method->returnsReference()) {
|
||||
$reference = '&';
|
||||
}
|
||||
|
||||
$signature_line = <<<'EOS'
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
||||
EOS;
|
||||
|
||||
if ($reflection_method->isStatic()) {
|
||||
$signature_line = 'public static function ' . $reference . $function_name . '(';
|
||||
$signature_line .= 'public static function ' . $reference . $function_name . '(';
|
||||
}
|
||||
else {
|
||||
$signature_line = 'public function ' . $reference . $function_name . '(';
|
||||
$signature_line .= 'public function ' . $reference . $function_name . '(';
|
||||
}
|
||||
|
||||
$signature_line .= implode(', ', $parameters);
|
||||
|
@ -269,10 +325,18 @@ EOS;
|
|||
*/
|
||||
protected function buildConstructorMethod() {
|
||||
$output = <<<'EOS'
|
||||
public function __construct(\Symfony\Component\DependencyInjection\ContainerInterface $container, $serviceId)
|
||||
/**
|
||||
* Constructs a ProxyClass Drupal proxy object.
|
||||
*
|
||||
* @param \Symfony\Component\DependencyInjection\ContainerInterface $container
|
||||
* The container.
|
||||
* @param string $drupal_proxy_original_service_id
|
||||
* The service ID of the original service.
|
||||
*/
|
||||
public function __construct(\Symfony\Component\DependencyInjection\ContainerInterface $container, $drupal_proxy_original_service_id)
|
||||
{
|
||||
$this->container = $container;
|
||||
$this->serviceId = $serviceId;
|
||||
$this->drupalProxyOriginalServiceId = $drupal_proxy_original_service_id;
|
||||
}
|
||||
|
||||
EOS;
|
||||
|
|
|
@ -1,78 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Component\ProxyBuilder\ProxyDumper.
|
||||
*/
|
||||
|
||||
namespace Drupal\Component\ProxyBuilder;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Definition;
|
||||
use Symfony\Component\DependencyInjection\LazyProxy\PhpDumper\DumperInterface;
|
||||
|
||||
/**
|
||||
* Dumps the proxy service into the dumped PHP container file.
|
||||
*/
|
||||
class ProxyDumper implements DumperInterface {
|
||||
|
||||
/**
|
||||
* Keeps track of already existing proxy classes.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $buildClasses = [];
|
||||
|
||||
/**
|
||||
* The proxy builder.
|
||||
*
|
||||
* @var \Drupal\Component\ProxyBuilder\ProxyBuilder
|
||||
*/
|
||||
protected $builder;
|
||||
|
||||
public function __construct(ProxyBuilder $builder) {
|
||||
$this->builder = $builder;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function isProxyCandidate(Definition $definition) {
|
||||
return $definition->isLazy() && ($class = $definition->getClass()) && class_exists($class);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getProxyFactoryCode(Definition $definition, $id) {
|
||||
// Note: the specific get method is called initially with $lazyLoad=TRUE;
|
||||
// When you want to retrieve the actual service, the code generated in
|
||||
// ProxyBuilder calls the method with lazy loading disabled.
|
||||
$output = <<<'EOS'
|
||||
if ($lazyLoad) {
|
||||
return $this->services['{{ id }}'] = new {{ class_name }}($this, '{{ id }}');
|
||||
}
|
||||
|
||||
EOS;
|
||||
$output = str_replace('{{ id }}', $id, $output);
|
||||
$output = str_replace('{{ class_name }}', $this->builder->buildProxyClassName($definition->getClass()), $output);
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getProxyCode(Definition $definition) {
|
||||
// Maybe the same class is used in different services, which are both marked
|
||||
// as lazy (just think about 2 database connections).
|
||||
// In those cases we should not generate proxy code the second time.
|
||||
if (!isset($this->buildClasses[$definition->getClass()])) {
|
||||
$this->buildClasses[$definition->getClass()] = TRUE;
|
||||
return $this->builder->build($definition->getClass());
|
||||
}
|
||||
else {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -5,7 +5,7 @@
|
|||
"homepage": "https://www.drupal.org/project/drupal",
|
||||
"license": "GPL-2.0+",
|
||||
"require": {
|
||||
"php": ">=5.4.2",
|
||||
"php": ">=5.5.9",
|
||||
"symfony/dependency-injection": "~2.6"
|
||||
},
|
||||
"autoload": {
|
||||
|
|
|
@ -106,7 +106,7 @@ class Crypt {
|
|||
|
||||
$hmac = base64_encode(hash_hmac('sha256', $data, $key, TRUE));
|
||||
// Modify the hmac so it's safe to use in URLs.
|
||||
return strtr($hmac, array('+' => '-', '/' => '_', '=' => ''));
|
||||
return str_replace(['+', '/', '='], ['-', '_', ''], $hmac);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -122,7 +122,7 @@ class Crypt {
|
|||
public static function hashBase64($data) {
|
||||
$hash = base64_encode(hash('sha256', $data, TRUE));
|
||||
// Modify the hash so it's safe to use in URLs.
|
||||
return strtr($hash, array('+' => '-', '/' => '_', '=' => ''));
|
||||
return str_replace(['+', '/', '='], ['-', '_', ''], $hash);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -137,7 +137,7 @@ class Crypt {
|
|||
* @see \Drupal\Component\Utility\Crypt::randomBytes()
|
||||
*/
|
||||
public static function randomBytesBase64($count = 32) {
|
||||
return strtr(base64_encode(static::randomBytes($count)), array('+' => '-', '/' => '_', '=' => ''));
|
||||
return str_replace(['+', '/', '='], ['-', '_', ''], base64_encode(static::randomBytes($count)));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -187,7 +187,7 @@ class Html {
|
|||
* @see self::getUniqueId()
|
||||
*/
|
||||
public static function getId($id) {
|
||||
$id = strtr(Unicode::strtolower($id), array(' ' => '-', '_' => '-', '[' => '-', ']' => ''));
|
||||
$id = str_replace([' ', '_', '[', ']'], ['-', '-', '-', ''], Unicode::strtolower($id));
|
||||
|
||||
// As defined in http://www.w3.org/TR/html4/types.html#type-name, HTML IDs can
|
||||
// only contain letters, digits ([0-9]), hyphens ("-"), underscores ("_"),
|
||||
|
|
|
@ -15,9 +15,9 @@ namespace Drupal\Component\Utility;
|
|||
* provides a store for known safe strings and methods to manage them
|
||||
* throughout the page request.
|
||||
*
|
||||
* Strings sanitized by self::checkPlain() or Xss::filter() are automatically
|
||||
* marked safe, as are markup strings created from render arrays via
|
||||
* drupal_render().
|
||||
* Strings sanitized by self::checkPlain() and self::escape() or
|
||||
* self::xssFilter() are automatically marked safe, as are markup strings
|
||||
* created from @link theme_render render arrays @endlink via drupal_render().
|
||||
*
|
||||
* This class should be limited to internal use only. Module developers should
|
||||
* instead use the appropriate
|
||||
|
@ -141,17 +141,79 @@ class SafeMarkup {
|
|||
/**
|
||||
* Applies a very permissive XSS/HTML filter for admin-only use.
|
||||
*
|
||||
* @param string $string
|
||||
* A string.
|
||||
* Note: This method only filters if $string is not marked safe already.
|
||||
*
|
||||
* @return string
|
||||
* The escaped string. If $string was already set as safe with
|
||||
* self::set(), it won't be escaped again.
|
||||
* @deprecated as of Drupal 8.0.x, will be removed before Drupal 8.0.0. If the
|
||||
* string used as part of a @link theme_render render array @endlink use
|
||||
* #markup to allow the render system to filter automatically. If the result
|
||||
* is not being used directly in the rendering system (for example, when its
|
||||
* result is being combined with other strings before rendering), use
|
||||
* Xss::filterAdmin(). Otherwise, use SafeMarkup::xssFilter() and the tag
|
||||
* list provided by Xss::getAdminTagList() instead. In the rare instance
|
||||
* that the caller does not want to filter strings that are marked safe
|
||||
* already, it needs to check SafeMarkup::isSafe() itself.
|
||||
*
|
||||
* @see \Drupal\Component\Utility\SafeMarkup::xssFilter()
|
||||
* @see \Drupal\Component\Utility\SafeMarkup::isSafe()
|
||||
* @see \Drupal\Component\Utility\Xss::filterAdmin()
|
||||
* @see \Drupal\Component\Utility\Xss::getAdminTagList()
|
||||
*/
|
||||
public static function checkAdminXss($string) {
|
||||
return static::isSafe($string) ? $string : Xss::filterAdmin($string);
|
||||
return static::isSafe($string) ? $string : static::xssFilter($string, Xss::getAdminTagList());
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters HTML for XSS vulnerabilities and marks the result as safe.
|
||||
*
|
||||
* Calling this method unnecessarily will result in bloating the safe string
|
||||
* list and increases the chance of unintended side effects.
|
||||
*
|
||||
* If Twig receives a value that is not marked as safe then it will
|
||||
* automatically encode special characters in a plain-text string for display
|
||||
* as HTML. Therefore, SafeMarkup::xssFilter() should only be used when the
|
||||
* string might contain HTML that needs to be rendered properly by the
|
||||
* browser.
|
||||
*
|
||||
* If you need to filter for admin use, like Xss::filterAdmin(), then:
|
||||
* - If the string is used as part of a @link theme_render render array @endlink,
|
||||
* use #markup to allow the render system to filter by the admin tag list
|
||||
* automatically.
|
||||
* - Otherwise, use the SafeMarkup::xssFilter() with tag list provided by
|
||||
* Xss::getAdminTagList() instead.
|
||||
*
|
||||
* This method should only be used instead of Xss::filter() when the result is
|
||||
* being added to a render array that is constructed before rendering begins.
|
||||
*
|
||||
* In the rare instance that the caller does not want to filter strings that
|
||||
* are marked safe already, it needs to check SafeMarkup::isSafe() itself.
|
||||
*
|
||||
* @param $string
|
||||
* The string with raw HTML in it. It will be stripped of everything that
|
||||
* can cause an XSS attack. The string provided will always be escaped
|
||||
* regardless of whether the string is already marked as safe.
|
||||
* @param array $html_tags
|
||||
* (optional) An array of HTML tags. If omitted, it uses the default tag
|
||||
* list defined by \Drupal\Component\Utility\Xss::filter().
|
||||
*
|
||||
* @return string
|
||||
* An XSS-safe version of $string, or an empty string if $string is not
|
||||
* valid UTF-8. The string is marked as safe.
|
||||
*
|
||||
* @ingroup sanitization
|
||||
*
|
||||
* @see \Drupal\Component\Utility\Xss::filter()
|
||||
* @see \Drupal\Component\Utility\Xss::filterAdmin()
|
||||
* @see \Drupal\Component\Utility\Xss::getAdminTagList()
|
||||
* @see \Drupal\Component\Utility\SafeMarkup::isSafe()
|
||||
*/
|
||||
public static function xssFilter($string, $html_tags = NULL) {
|
||||
if (is_null($html_tags)) {
|
||||
$string = Xss::filter($string);
|
||||
}
|
||||
else {
|
||||
$string = Xss::filter($string, $html_tags);
|
||||
}
|
||||
return static::set($string);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -244,7 +244,7 @@ class UrlHelper {
|
|||
$base_parts = parse_url($base_url);
|
||||
|
||||
if (empty($base_parts['host']) || empty($url_parts['host'])) {
|
||||
throw new \InvalidArgumentException(SafeMarkup::format('A path was passed when a fully qualified domain was expected.'));
|
||||
throw new \InvalidArgumentException('A path was passed when a fully qualified domain was expected.');
|
||||
}
|
||||
|
||||
if (!isset($url_parts['path']) || !isset($base_parts['path'])) {
|
||||
|
|
|
@ -29,14 +29,19 @@ class Xss {
|
|||
* Based on kses by Ulf Harnhammar, see http://sourceforge.net/projects/kses.
|
||||
* For examples of various XSS attacks, see: http://ha.ckers.org/xss.html.
|
||||
*
|
||||
* This code does five things:
|
||||
* This method is preferred to
|
||||
* \Drupal\Component\Utility\SafeMarkup::xssFilter() when the result is not
|
||||
* being used directly in the rendering system (for example, when its result
|
||||
* is being combined with other strings before rendering). This avoids
|
||||
* bloating the safe string list with partial strings if the whole result will
|
||||
* be marked safe.
|
||||
*
|
||||
* This code does four things:
|
||||
* - Removes characters and constructs that can trick browsers.
|
||||
* - Makes sure all HTML entities are well-formed.
|
||||
* - Makes sure all HTML tags and attributes are well-formed.
|
||||
* - Makes sure no HTML tags contain URLs with a disallowed protocol (e.g.
|
||||
* javascript:).
|
||||
* - Marks the sanitized, XSS-safe version of $string as safe markup for
|
||||
* rendering.
|
||||
*
|
||||
* @param $string
|
||||
* The string with raw HTML in it. It will be stripped of everything that
|
||||
|
@ -49,7 +54,7 @@ class Xss {
|
|||
* valid UTF-8.
|
||||
*
|
||||
* @see \Drupal\Component\Utility\Unicode::validateUtf8()
|
||||
* @see \Drupal\Component\Utility\SafeMarkup
|
||||
* @see \Drupal\Component\Utility\SafeMarkup::xssFilter()
|
||||
*
|
||||
* @ingroup sanitization
|
||||
*/
|
||||
|
@ -83,7 +88,7 @@ class Xss {
|
|||
// for output. All other known XSS vectors have been filtered out by this
|
||||
// point and any HTML tags remaining will have been deliberately allowed, so
|
||||
// it is acceptable to call SafeMarkup::set() on the resultant string.
|
||||
return SafeMarkup::set(preg_replace_callback('%
|
||||
return preg_replace_callback('%
|
||||
(
|
||||
<(?=[^a-zA-Z!/]) # a lone <
|
||||
| # or
|
||||
|
@ -92,7 +97,7 @@ class Xss {
|
|||
<[^>]*(>|$) # a string that starts with a <, up until the > or the end of the string
|
||||
| # or
|
||||
> # just a >
|
||||
)%x', $splitter, $string));
|
||||
)%x', $splitter, $string);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -103,6 +108,13 @@ class Xss {
|
|||
* is desired (so \Drupal\Component\Utility\SafeMarkup::checkPlain() is
|
||||
* not acceptable).
|
||||
*
|
||||
* This method is preferred to
|
||||
* \Drupal\Component\Utility\SafeMarkup::xssFilter() when the result is
|
||||
* not being used directly in the rendering system (for example, when its
|
||||
* result is being combined with other strings before rendering). This avoids
|
||||
* bloating the safe string list with partial strings if the whole result will
|
||||
* be marked safe.
|
||||
*
|
||||
* Allows all tags that can be used inside an HTML body, save
|
||||
* for scripts and styles.
|
||||
*
|
||||
|
@ -111,6 +123,12 @@ class Xss {
|
|||
*
|
||||
* @return string
|
||||
* The filtered string.
|
||||
*
|
||||
* @ingroup sanitization
|
||||
*
|
||||
* @see \Drupal\Component\Utility\SafeMarkup::xssFilter()
|
||||
* @see \Drupal\Component\Utility\Xss::getAdminTagList()
|
||||
*
|
||||
*/
|
||||
public static function filterAdmin($string) {
|
||||
return static::filter($string, static::$adminTags);
|
||||
|
@ -319,4 +337,14 @@ class Xss {
|
|||
return !isset($html_tags[strtolower($elem)]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the list of html tags allowed by Xss::filterAdmin().
|
||||
*
|
||||
* @return array
|
||||
* The list of html tags allowed by filterAdmin().
|
||||
*/
|
||||
public static function getAdminTagList() {
|
||||
return static::$adminTags;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
"homepage": "https://www.drupal.org/project/drupal",
|
||||
"license": "GPL-2.0+",
|
||||
"require": {
|
||||
"php": ">=5.3.10"
|
||||
"php": ">=5.5.9"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
|
|
|
@ -25,6 +25,9 @@ use Drupal\Core\Session\AccountInterface;
|
|||
*
|
||||
* When using ::orIf() and ::andIf(), cacheability metadata will be merged
|
||||
* accordingly as well.
|
||||
*
|
||||
* @todo Use RefinableCacheableDependencyInterface and the corresponding trait in
|
||||
* https://www.drupal.org/node/2526326.
|
||||
*/
|
||||
abstract class AccessResult implements AccessResultInterface, CacheableDependencyInterface {
|
||||
|
||||
|
@ -316,10 +319,12 @@ abstract class AccessResult implements AccessResultInterface, CacheableDependenc
|
|||
* The entity whose cache tag to set on the access result.
|
||||
*
|
||||
* @return $this
|
||||
*
|
||||
* @deprecated in Drupal 8.0.x-dev, will be removed before Drupal 9.0.0. Use
|
||||
* ::addCacheableDependency() instead.
|
||||
*/
|
||||
public function cacheUntilEntityChanges(EntityInterface $entity) {
|
||||
$this->addCacheTags($entity->getCacheTags());
|
||||
return $this;
|
||||
return $this->addCacheableDependency($entity);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -329,9 +334,33 @@ abstract class AccessResult implements AccessResultInterface, CacheableDependenc
|
|||
* The configuration object whose cache tag to set on the access result.
|
||||
*
|
||||
* @return $this
|
||||
*
|
||||
* @deprecated in Drupal 8.0.x-dev, will be removed before Drupal 9.0.0. Use
|
||||
* ::addCacheableDependency() instead.
|
||||
*/
|
||||
public function cacheUntilConfigurationChanges(ConfigBase $configuration) {
|
||||
$this->addCacheTags($configuration->getCacheTags());
|
||||
return $this->addCacheableDependency($configuration);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a dependency on an object: merges its cacheability metadata.
|
||||
*
|
||||
* @param \Drupal\Core\Cache\CacheableDependencyInterface|object $other_object
|
||||
* The dependency. If the object implements CacheableDependencyInterface,
|
||||
* then its cacheability metadata will be used. Otherwise, the passed in
|
||||
* object must be assumed to be uncacheable, so max-age 0 is set.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function addCacheableDependency($other_object) {
|
||||
if ($other_object instanceof CacheableDependencyInterface) {
|
||||
$this->contexts = Cache::mergeContexts($this->contexts, $other_object->getCacheContexts());
|
||||
$this->tags = Cache::mergeTags($this->tags, $other_object->getCacheTags());
|
||||
$this->maxAge = Cache::mergeMaxAges($this->maxAge, $other_object->getCacheMaxAge());
|
||||
}
|
||||
else {
|
||||
$this->maxAge = 0;
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
namespace Drupal\Core\Access;
|
||||
|
||||
use Drupal\Core\Cache\CacheableMetadata;
|
||||
use Drupal\Core\Render\BubbleableMetadata;
|
||||
use Drupal\Core\RouteProcessor\OutboundRouteProcessorInterface;
|
||||
use Symfony\Component\Routing\Route;
|
||||
|
||||
|
@ -36,7 +36,7 @@ class RouteProcessorCsrf implements OutboundRouteProcessorInterface {
|
|||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function processOutbound($route_name, Route $route, array &$parameters, CacheableMetadata $cacheable_metadata = NULL) {
|
||||
public function processOutbound($route_name, Route $route, array &$parameters, BubbleableMetadata $bubbleable_metadata = NULL) {
|
||||
if ($route->hasRequirement('_csrf_token')) {
|
||||
$path = ltrim($route->getPath(), '/');
|
||||
// Replace the path parameters with values from the parameters array.
|
||||
|
@ -45,13 +45,44 @@ class RouteProcessorCsrf implements OutboundRouteProcessorInterface {
|
|||
}
|
||||
// Adding this to the parameters means it will get merged into the query
|
||||
// string when the route is compiled.
|
||||
$parameters['token'] = $this->csrfToken->get($path);
|
||||
if ($cacheable_metadata) {
|
||||
// Tokens are per user and per session, so not cacheable.
|
||||
// @todo Improve in https://www.drupal.org/node/2351015.
|
||||
$cacheable_metadata->setCacheMaxAge(0);
|
||||
if (!$bubbleable_metadata) {
|
||||
$parameters['token'] = $this->csrfToken->get($path);
|
||||
}
|
||||
else {
|
||||
// Generate a placeholder and a render array to replace it.
|
||||
$placeholder = hash('sha1', $path);
|
||||
$placeholder_render_array = [
|
||||
'#lazy_builder' => ['route_processor_csrf:renderPlaceholderCsrfToken', [$path]],
|
||||
];
|
||||
|
||||
// Instead of setting an actual CSRF token as the query string, we set
|
||||
// the placeholder, which will be replaced at the very last moment. This
|
||||
// ensures links with CSRF tokens don't break cacheability.
|
||||
$parameters['token'] = $placeholder;
|
||||
$bubbleable_metadata->addAttachments(['placeholders' => [$placeholder => $placeholder_render_array]]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* #lazy_builder callback; gets a CSRF token for the given path.
|
||||
*
|
||||
* @param string $path
|
||||
* The path to get a CSRF token for.
|
||||
*
|
||||
* @return array
|
||||
* A renderable array representing the CSRF token.
|
||||
*/
|
||||
public function renderPlaceholderCsrfToken($path) {
|
||||
return [
|
||||
'#markup' => $this->csrfToken->get($path),
|
||||
// Tokens are per session.
|
||||
'#cache' => [
|
||||
'contexts' => [
|
||||
'session',
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -164,15 +164,15 @@ class AjaxResponseAttachmentsProcessor implements AttachmentsResponseProcessorIn
|
|||
$resource_commands = array();
|
||||
if ($css_assets) {
|
||||
$css_render_array = $this->cssCollectionRenderer->render($css_assets);
|
||||
$resource_commands[] = new AddCssCommand($this->renderer->renderPlain($css_render_array));
|
||||
$resource_commands[] = new AddCssCommand((string) $this->renderer->renderPlain($css_render_array));
|
||||
}
|
||||
if ($js_assets_header) {
|
||||
$js_header_render_array = $this->jsCollectionRenderer->render($js_assets_header);
|
||||
$resource_commands[] = new PrependCommand('head', $this->renderer->renderPlain($js_header_render_array));
|
||||
$resource_commands[] = new PrependCommand('head', (string) $this->renderer->renderPlain($js_header_render_array));
|
||||
}
|
||||
if ($js_assets_footer) {
|
||||
$js_footer_render_array = $this->jsCollectionRenderer->render($js_assets_footer);
|
||||
$resource_commands[] = new AppendCommand('body', $this->renderer->renderPlain($js_footer_render_array));
|
||||
$resource_commands[] = new AppendCommand('body', (string) $this->renderer->renderPlain($js_footer_render_array));
|
||||
}
|
||||
foreach (array_reverse($resource_commands) as $resource_command) {
|
||||
$response->addCommand($resource_command, TRUE);
|
||||
|
|
|
@ -37,10 +37,10 @@ trait CommandWithAttachedAssetsTrait {
|
|||
if (is_array($this->content)) {
|
||||
$html = \Drupal::service('renderer')->renderRoot($this->content);
|
||||
$this->attachedAssets = AttachedAssets::createFromRenderArray($this->content);
|
||||
return $html;
|
||||
return (string) $html;
|
||||
}
|
||||
else {
|
||||
return $this->content;
|
||||
return (string) $this->content;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,89 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Core\Authentication\AuthenticationCollector.
|
||||
*/
|
||||
|
||||
namespace Drupal\Core\Authentication;
|
||||
|
||||
/**
|
||||
* A collector class for authentication providers.
|
||||
*/
|
||||
class AuthenticationCollector implements AuthenticationCollectorInterface {
|
||||
|
||||
/**
|
||||
* Array of all registered authentication providers, keyed by ID.
|
||||
*
|
||||
* @var \Drupal\Core\Authentication\AuthenticationProviderInterface[]
|
||||
*/
|
||||
protected $providers;
|
||||
|
||||
/**
|
||||
* Array of all providers and their priority.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $providerOrders = [];
|
||||
|
||||
/**
|
||||
* Sorted list of registered providers.
|
||||
*
|
||||
* @var \Drupal\Core\Authentication\AuthenticationProviderInterface[]
|
||||
*/
|
||||
protected $sortedProviders;
|
||||
|
||||
/**
|
||||
* List of providers which are allowed on routes with no _auth option.
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
protected $globalProviders;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function addProvider(AuthenticationProviderInterface $provider, $provider_id, $priority = 0, $global = FALSE) {
|
||||
$this->providers[$provider_id] = $provider;
|
||||
$this->providerOrders[$priority][$provider_id] = $provider;
|
||||
// Force the providers to be re-sorted.
|
||||
$this->sortedProviders = NULL;
|
||||
|
||||
if ($global) {
|
||||
$this->globalProviders[$provider_id] = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function isGlobal($provider_id) {
|
||||
return isset($this->globalProviders[$provider_id]);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getProvider($provider_id) {
|
||||
return isset($this->providers[$provider_id]) ? $this->providers[$provider_id] : NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getSortedProviders() {
|
||||
if (!isset($this->sortedProviders)) {
|
||||
// Sort the providers according to priority.
|
||||
krsort($this->providerOrders);
|
||||
|
||||
// Merge nested providers from $this->providers into $this->sortedProviders.
|
||||
$this->sortedProviders = [];
|
||||
foreach ($this->providerOrders as $providers) {
|
||||
$this->sortedProviders = array_merge($this->sortedProviders, $providers);
|
||||
}
|
||||
}
|
||||
|
||||
return $this->sortedProviders;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Core\Authentication\AuthenticationCollectorInterface.
|
||||
*/
|
||||
|
||||
namespace Drupal\Core\Authentication;
|
||||
|
||||
/**
|
||||
* Interface for collectors of registered authentication providers.
|
||||
*/
|
||||
interface AuthenticationCollectorInterface {
|
||||
|
||||
/**
|
||||
* Adds a provider to the array of registered providers.
|
||||
*
|
||||
* @param \Drupal\Core\Authentication\AuthenticationProviderInterface $provider
|
||||
* The provider object.
|
||||
* @param string $provider_id
|
||||
* Identifier of the provider.
|
||||
* @param int $priority
|
||||
* (optional) The provider's priority.
|
||||
* @param bool $global
|
||||
* (optional) TRUE if the provider is to be applied globally on all routes.
|
||||
* Defaults to FALSE.
|
||||
*/
|
||||
public function addProvider(AuthenticationProviderInterface $provider, $provider_id, $priority = 0, $global = FALSE);
|
||||
|
||||
/**
|
||||
* Returns whether a provider is considered global.
|
||||
*
|
||||
* @param string $provider_id
|
||||
* The provider ID.
|
||||
*
|
||||
* @return bool
|
||||
* TRUE if the provider is global, FALSE otherwise.
|
||||
*
|
||||
* @see \Drupal\Core\Authentication\AuthenticationCollectorInterface::addProvider
|
||||
*/
|
||||
public function isGlobal($provider_id);
|
||||
|
||||
/**
|
||||
* Returns an authentication provider.
|
||||
*
|
||||
* @param string $provider_id
|
||||
* The provider ID.
|
||||
*
|
||||
* @return \Drupal\Core\Authentication\AuthenticationProviderInterface|NULL
|
||||
* The authentication provider which matches the ID.
|
||||
*/
|
||||
public function getProvider($provider_id);
|
||||
|
||||
/**
|
||||
* Returns the sorted array of authentication providers.
|
||||
*
|
||||
* @return \Drupal\Core\Authentication\AuthenticationProviderInterface[]
|
||||
* An array of authentication provider objects.
|
||||
*/
|
||||
public function getSortedProviders();
|
||||
|
||||
}
|
|
@ -20,69 +20,23 @@ use Symfony\Component\HttpFoundation\Request;
|
|||
*
|
||||
* If no provider set an active user then the user is set to anonymous.
|
||||
*/
|
||||
class AuthenticationManager implements AuthenticationProviderInterface, AuthenticationProviderFilterInterface, AuthenticationProviderChallengeInterface, AuthenticationManagerInterface {
|
||||
class AuthenticationManager implements AuthenticationProviderInterface, AuthenticationProviderFilterInterface, AuthenticationProviderChallengeInterface {
|
||||
|
||||
/**
|
||||
* Array of all registered authentication providers, keyed by ID.
|
||||
* The authentication provider collector.
|
||||
*
|
||||
* @var \Drupal\Core\Authentication\AuthenticationProviderInterface[]
|
||||
* @var \Drupal\Core\Authentication\AuthenticationCollectorInterface
|
||||
*/
|
||||
protected $providers;
|
||||
protected $authCollector;
|
||||
|
||||
/**
|
||||
* Array of all providers and their priority.
|
||||
* Creates a new authentication manager instance.
|
||||
*
|
||||
* @var array
|
||||
* @param \Drupal\Core\Authentication\AuthenticationCollectorInterface $auth_collector
|
||||
* The authentication provider collector.
|
||||
*/
|
||||
protected $providerOrders = array();
|
||||
|
||||
/**
|
||||
* Sorted list of registered providers.
|
||||
*
|
||||
* @var \Drupal\Core\Authentication\AuthenticationProviderInterface[]
|
||||
*/
|
||||
protected $sortedProviders;
|
||||
|
||||
/**
|
||||
* List of providers which implement the filter interface.
|
||||
*
|
||||
* @var \Drupal\Core\Authentication\AuthenticationProviderFilterInterface[]
|
||||
*/
|
||||
protected $filters;
|
||||
|
||||
/**
|
||||
* List of providers which implement the challenge interface.
|
||||
*
|
||||
* @var \Drupal\Core\Authentication\AuthenticationProviderChallengeInterface[]
|
||||
*/
|
||||
protected $challengers;
|
||||
|
||||
/**
|
||||
* List of providers which are allowed on routes with no _auth option.
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
protected $globalProviders;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function addProvider(AuthenticationProviderInterface $provider, $provider_id, $priority = 0, $global = FALSE) {
|
||||
$this->providers[$provider_id] = $provider;
|
||||
$this->providerOrders[$priority][$provider_id] = $provider;
|
||||
// Force the builders to be re-sorted.
|
||||
$this->sortedProviders = NULL;
|
||||
|
||||
if ($provider instanceof AuthenticationProviderFilterInterface) {
|
||||
$this->filters[$provider_id] = $provider;
|
||||
}
|
||||
if ($provider instanceof AuthenticationProviderChallengeInterface) {
|
||||
$this->challengers[$provider_id] = $provider;
|
||||
}
|
||||
|
||||
if ($global) {
|
||||
$this->globalProviders[$provider_id] = TRUE;
|
||||
}
|
||||
public function __construct(AuthenticationCollectorInterface $auth_collector) {
|
||||
$this->authCollector = $auth_collector;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -97,7 +51,13 @@ class AuthenticationManager implements AuthenticationProviderInterface, Authenti
|
|||
*/
|
||||
public function authenticate(Request $request) {
|
||||
$provider_id = $this->getProvider($request);
|
||||
return $this->providers[$provider_id]->authenticate($request);
|
||||
$provider = $this->authCollector->getProvider($provider_id);
|
||||
|
||||
if ($provider) {
|
||||
return $provider->authenticate($request);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -110,7 +70,7 @@ class AuthenticationManager implements AuthenticationProviderInterface, Authenti
|
|||
$result = $this->applyFilter($request, $authenticated, $this->getProvider($request));
|
||||
}
|
||||
else {
|
||||
foreach ($this->getSortedProviders() as $provider_id => $provider) {
|
||||
foreach ($this->authCollector->getSortedProviders() as $provider_id => $provider) {
|
||||
if ($this->applyFilter($request, $authenticated, $provider_id)) {
|
||||
$result = TRUE;
|
||||
break;
|
||||
|
@ -126,8 +86,10 @@ class AuthenticationManager implements AuthenticationProviderInterface, Authenti
|
|||
*/
|
||||
public function challengeException(Request $request, \Exception $previous) {
|
||||
$provider_id = $this->getChallenger($request);
|
||||
|
||||
if ($provider_id) {
|
||||
return $this->challengers[$provider_id]->challengeException($request, $previous);
|
||||
$provider = $this->authCollector->getProvider($provider_id);
|
||||
return $provider->challengeException($request, $previous);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -142,7 +104,7 @@ class AuthenticationManager implements AuthenticationProviderInterface, Authenti
|
|||
* If no application detects appropriate credentials, then NULL is returned.
|
||||
*/
|
||||
protected function getProvider(Request $request) {
|
||||
foreach ($this->getSortedProviders() as $provider_id => $provider) {
|
||||
foreach ($this->authCollector->getSortedProviders() as $provider_id => $provider) {
|
||||
if ($provider->applies($request)) {
|
||||
return $provider_id;
|
||||
}
|
||||
|
@ -150,21 +112,19 @@ class AuthenticationManager implements AuthenticationProviderInterface, Authenti
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns the id of the challenge provider for a request.
|
||||
* Returns the ID of the challenge provider for a request.
|
||||
*
|
||||
* @param \Symfony\Component\HttpFoundation\Request $request
|
||||
* The incoming request.
|
||||
*
|
||||
* @return string|NULL
|
||||
* The id of the first authentication provider which applies to the request.
|
||||
* The ID of the first authentication provider which applies to the request.
|
||||
* If no application detects appropriate credentials, then NULL is returned.
|
||||
*/
|
||||
protected function getChallenger(Request $request) {
|
||||
if (!empty($this->challengers)) {
|
||||
foreach ($this->getSortedProviders($request, FALSE) as $provider_id => $provider) {
|
||||
if (isset($this->challengers[$provider_id]) && !$provider->applies($request) && $this->applyFilter($request, FALSE, $provider_id)) {
|
||||
return $provider_id;
|
||||
}
|
||||
foreach ($this->authCollector->getSortedProviders() as $provider_id => $provider) {
|
||||
if (($provider instanceof AuthenticationProviderChallengeInterface) && !$provider->applies($request) && $this->applyFilter($request, FALSE, $provider_id)) {
|
||||
return $provider_id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -186,8 +146,10 @@ class AuthenticationManager implements AuthenticationProviderInterface, Authenti
|
|||
* TRUE if provider is allowed, FALSE otherwise.
|
||||
*/
|
||||
protected function applyFilter(Request $request, $authenticated, $provider_id) {
|
||||
if (isset($this->filters[$provider_id])) {
|
||||
$result = $this->filters[$provider_id]->appliesToRoutedRequest($request, $authenticated);
|
||||
$provider = $this->authCollector->getProvider($provider_id);
|
||||
|
||||
if ($provider && ($provider instanceof AuthenticationProviderFilterInterface)) {
|
||||
$result = $provider->appliesToRoutedRequest($request, $authenticated);
|
||||
}
|
||||
else {
|
||||
$result = $this->defaultFilter($request, $provider_id);
|
||||
|
@ -222,27 +184,8 @@ class AuthenticationManager implements AuthenticationProviderInterface, Authenti
|
|||
return in_array($provider_id, $route->getOption('_auth'));
|
||||
}
|
||||
else {
|
||||
return isset($this->globalProviders[$provider_id]);
|
||||
return $this->authCollector->isGlobal($provider_id);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the sorted array of authentication providers.
|
||||
*
|
||||
* @return \Drupal\Core\Authentication\AuthenticationProviderInterface[]
|
||||
* An array of authentication provider objects.
|
||||
*/
|
||||
protected function getSortedProviders() {
|
||||
if (!isset($this->sortedProviders)) {
|
||||
// Sort the builders according to priority.
|
||||
krsort($this->providerOrders);
|
||||
// Merge nested providers from $this->providers into $this->sortedProviders.
|
||||
$this->sortedProviders = array();
|
||||
foreach ($this->providerOrders as $providers) {
|
||||
$this->sortedProviders = array_merge($this->sortedProviders, $providers);
|
||||
}
|
||||
}
|
||||
return $this->sortedProviders;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,30 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Core\Authentication\AuthenticationManagerInterface.
|
||||
*/
|
||||
|
||||
namespace Drupal\Core\Authentication;
|
||||
|
||||
/**
|
||||
* Defines an interface for authentication managers.
|
||||
*/
|
||||
interface AuthenticationManagerInterface {
|
||||
|
||||
/**
|
||||
* Adds a provider to the array of registered providers.
|
||||
*
|
||||
* @param \Drupal\Core\Authentication\AuthenticationProviderInterface $provider
|
||||
* The provider object.
|
||||
* @param string $provider_id
|
||||
* Identifier of the provider.
|
||||
* @param int $priority
|
||||
* (optional) The provider's priority.
|
||||
* @param bool $global
|
||||
* (optional) TRUE if the provider is to be applied globally on all routes.
|
||||
* Defaults to FALSE.
|
||||
*/
|
||||
public function addProvider(AuthenticationProviderInterface $provider, $provider_id, $priority = 0, $global = FALSE);
|
||||
|
||||
}
|
|
@ -10,6 +10,7 @@ namespace Drupal\Core\Block;
|
|||
use Drupal\block\BlockInterface;
|
||||
use Drupal\Component\Utility\SafeMarkup;
|
||||
use Drupal\Core\Access\AccessResult;
|
||||
use Drupal\Core\Cache\CacheableDependencyInterface;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\Core\Plugin\ContextAwarePluginBase;
|
||||
use Drupal\Component\Utility\Unicode;
|
||||
|
@ -265,18 +266,23 @@ abstract class BlockBase extends ContextAwarePluginBase implements BlockPluginIn
|
|||
// \Drupal\system\MachineNameController::transliterate(), so it might make
|
||||
// sense to provide a common service for the two.
|
||||
$transliterated = $this->transliteration()->transliterate($admin_label, LanguageInterface::LANGCODE_DEFAULT, '_');
|
||||
|
||||
$replace_pattern = '[^a-z0-9_.]+';
|
||||
|
||||
$transliterated = Unicode::strtolower($transliterated);
|
||||
|
||||
if (isset($replace_pattern)) {
|
||||
$transliterated = preg_replace('@' . $replace_pattern . '@', '', $transliterated);
|
||||
}
|
||||
$transliterated = preg_replace('@[^a-z0-9_.]+@', '', $transliterated);
|
||||
|
||||
return $transliterated;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCacheMaxAge() {
|
||||
$max_age = parent::getCacheMaxAge();
|
||||
// @todo Configurability of this will be removed in
|
||||
// https://www.drupal.org/node/2458763.
|
||||
return Cache::mergeMaxAges($max_age, (int) $this->configuration['cache']['max_age']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps the transliteration service.
|
||||
*
|
||||
|
@ -299,25 +305,4 @@ abstract class BlockBase extends ContextAwarePluginBase implements BlockPluginIn
|
|||
$this->transliteration = $transliteration;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCacheContexts() {
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCacheTags() {
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCacheMaxAge() {
|
||||
return (int)$this->configuration['cache']['max_age'];
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
|
||||
namespace Drupal\Core\Breadcrumb;
|
||||
|
||||
use Drupal\Component\Utility\SafeMarkup;
|
||||
use Drupal\Core\Extension\ModuleHandlerInterface;
|
||||
use Drupal\Core\Routing\RouteMatchInterface;
|
||||
|
||||
|
@ -95,7 +94,7 @@ class BreadcrumbManager implements ChainBreadcrumbBuilderInterface {
|
|||
break;
|
||||
}
|
||||
else {
|
||||
throw new \UnexpectedValueException(SafeMarkup::format('Invalid breadcrumb returned by !class::build().', array('!class' => get_class($builder))));
|
||||
throw new \UnexpectedValueException('Invalid breadcrumb returned by ' . get_class($builder) . '::build().');
|
||||
}
|
||||
}
|
||||
// Allow modules to alter the breadcrumb.
|
||||
|
|
|
@ -24,19 +24,16 @@ class Cache {
|
|||
/**
|
||||
* Merges arrays of cache contexts and removes duplicates.
|
||||
*
|
||||
* @param string[] …
|
||||
* Arrays of cache contexts to merge.
|
||||
* @param array $a
|
||||
* Cache contexts array to merge.
|
||||
* @param array $b
|
||||
* Cache contexts array to merge.
|
||||
*
|
||||
* @return string[]
|
||||
* The merged array of cache contexts.
|
||||
*/
|
||||
public static function mergeContexts() {
|
||||
$cache_context_arrays = func_get_args();
|
||||
$cache_contexts = [];
|
||||
foreach ($cache_context_arrays as $contexts) {
|
||||
$cache_contexts = array_merge($cache_contexts, $contexts);
|
||||
}
|
||||
$cache_contexts = array_unique($cache_contexts);
|
||||
public static function mergeContexts(array $a = [], array $b = []) {
|
||||
$cache_contexts = array_unique(array_merge($a, $b));
|
||||
\Drupal::service('cache_contexts_manager')->validateTokens($cache_contexts);
|
||||
sort($cache_contexts);
|
||||
return $cache_contexts;
|
||||
|
@ -53,19 +50,16 @@ class Cache {
|
|||
* allows items to be invalidated based on all tags attached to the content
|
||||
* they're constituted from.
|
||||
*
|
||||
* @param string[] …
|
||||
* Arrays of cache tags to merge.
|
||||
* @param array $a
|
||||
* Cache tags array to merge.
|
||||
* @param array $b
|
||||
* Cache tags array to merge.
|
||||
*
|
||||
* @return string[]
|
||||
* The merged array of cache tags.
|
||||
*/
|
||||
public static function mergeTags() {
|
||||
$cache_tag_arrays = func_get_args();
|
||||
$cache_tags = [];
|
||||
foreach ($cache_tag_arrays as $tags) {
|
||||
$cache_tags = array_merge($cache_tags, $tags);
|
||||
}
|
||||
$cache_tags = array_unique($cache_tags);
|
||||
public static function mergeTags(array $a = [], array $b = []) {
|
||||
$cache_tags = array_unique(array_merge($a, $b));
|
||||
static::validateTags($cache_tags);
|
||||
sort($cache_tags);
|
||||
return $cache_tags;
|
||||
|
@ -76,29 +70,25 @@ class Cache {
|
|||
*
|
||||
* Ensures infinite max-age (Cache::PERMANENT) is taken into account.
|
||||
*
|
||||
* @param int …
|
||||
* Max-age values.
|
||||
* @param int $a
|
||||
* Max age value to merge.
|
||||
* @param int $b
|
||||
* Max age value to merge.
|
||||
*
|
||||
* @return int
|
||||
* The minimum max-age value.
|
||||
*/
|
||||
public static function mergeMaxAges() {
|
||||
$max_ages = func_get_args();
|
||||
|
||||
// Filter out all max-age values set to cache permanently.
|
||||
if (in_array(Cache::PERMANENT, $max_ages)) {
|
||||
$max_ages = array_filter($max_ages, function ($max_age) {
|
||||
return $max_age !== Cache::PERMANENT;
|
||||
});
|
||||
|
||||
// If nothing is left, then all max-age values were set to cache
|
||||
// permanently, and then that is the result.
|
||||
if (empty($max_ages)) {
|
||||
return Cache::PERMANENT;
|
||||
}
|
||||
public static function mergeMaxAges($a = Cache::PERMANENT, $b = Cache::PERMANENT) {
|
||||
// If one of the values is Cache::PERMANENT, return the other value.
|
||||
if ($a === Cache::PERMANENT){
|
||||
return $b;
|
||||
}
|
||||
if ($b === Cache::PERMANENT){
|
||||
return $a;
|
||||
}
|
||||
|
||||
return min($max_ages);
|
||||
// If none or the values are Cache::PERMANENT, return the minimum value.
|
||||
return min($a, $b);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -10,6 +10,9 @@ namespace Drupal\Core\Cache;
|
|||
* Defines a generic class for passing cacheability metadata.
|
||||
*
|
||||
* @ingroup cache
|
||||
*
|
||||
* @todo Use RefinableCacheableDependencyInterface and the corresponding trait in
|
||||
* https://www.drupal.org/node/2526326.
|
||||
*/
|
||||
class CacheableMetadata implements CacheableDependencyInterface {
|
||||
|
||||
|
@ -129,6 +132,35 @@ class CacheableMetadata implements CacheableDependencyInterface {
|
|||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a dependency on an object: merges its cacheability metadata.
|
||||
*
|
||||
* @param \Drupal\Core\Cache\CacheableDependencyInterface|mixed $other_object
|
||||
* The dependency. If the object implements CacheableDependencyInterface,
|
||||
* then its cacheability metadata will be used. Otherwise, the passed in
|
||||
* object must be assumed to be uncacheable, so max-age 0 is set.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function addCacheableDependency($other_object) {
|
||||
if ($other_object instanceof CacheableDependencyInterface) {
|
||||
$this->addCacheTags($other_object->getCacheTags());
|
||||
$this->addCacheContexts($other_object->getCacheContexts());
|
||||
if ($this->maxAge === Cache::PERMANENT) {
|
||||
$this->maxAge = $other_object->getCacheMaxAge();
|
||||
}
|
||||
elseif (($max_age = $other_object->getCacheMaxAge()) && $max_age !== Cache::PERMANENT) {
|
||||
$this->maxAge = Cache::mergeMaxAges($this->maxAge, $max_age);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Not a cacheable dependency, this can not be cached.
|
||||
$this->maxAge = 0;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Merges the values of another CacheableMetadata object with this one.
|
||||
*
|
||||
|
@ -139,7 +171,7 @@ class CacheableMetadata implements CacheableDependencyInterface {
|
|||
* A new CacheableMetadata object, with the merged data.
|
||||
*/
|
||||
public function merge(CacheableMetadata $other) {
|
||||
$result = new static();
|
||||
$result = clone $this;
|
||||
|
||||
// This is called many times per request, so avoid merging unless absolutely
|
||||
// necessary.
|
||||
|
|
|
@ -7,18 +7,21 @@
|
|||
|
||||
namespace Drupal\Core\Cache\Context;
|
||||
|
||||
use Drupal\Core\Cache\CacheableMetadata;
|
||||
use Drupal\Core\Session\AccountInterface;
|
||||
use Drupal\Core\Session\PermissionsHashGeneratorInterface;
|
||||
|
||||
/**
|
||||
* Defines the AccountPermissionsCacheContext service, for "per permission" caching.
|
||||
*
|
||||
* Cache context ID: 'user.permissions'.
|
||||
*/
|
||||
class AccountPermissionsCacheContext extends UserCacheContext {
|
||||
class AccountPermissionsCacheContext extends UserCacheContextBase implements CacheContextInterface {
|
||||
|
||||
/**
|
||||
* The permissions hash generator.
|
||||
*
|
||||
* @var \Drupal\user\PermissionsHashInterface
|
||||
* @var \Drupal\Core\Session\PermissionsHashGeneratorInterface
|
||||
*/
|
||||
protected $permissionsHashGenerator;
|
||||
|
||||
|
@ -27,7 +30,7 @@ class AccountPermissionsCacheContext extends UserCacheContext {
|
|||
*
|
||||
* @param \Drupal\Core\Session\AccountInterface $user
|
||||
* The current user.
|
||||
* @param \Drupal\user\PermissionsHashInterface $permissions_hash_generator
|
||||
* @param \Drupal\Core\Session\PermissionsHashGeneratorInterface $permissions_hash_generator
|
||||
* The permissions hash generator.
|
||||
*/
|
||||
public function __construct(AccountInterface $user, PermissionsHashGeneratorInterface $permissions_hash_generator) {
|
||||
|
@ -46,7 +49,24 @@ class AccountPermissionsCacheContext extends UserCacheContext {
|
|||
* {@inheritdoc}
|
||||
*/
|
||||
public function getContext() {
|
||||
return 'ph.' . $this->permissionsHashGenerator->generate($this->user);
|
||||
return $this->permissionsHashGenerator->generate($this->user);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCacheableMetadata() {
|
||||
$cacheable_metadata = new CacheableMetadata();
|
||||
|
||||
// The permissions hash changes when:
|
||||
// - a user is updated to have different roles;
|
||||
$tags = ['user:' . $this->user->id()];
|
||||
// - a role is updated to have different permissions.
|
||||
foreach ($this->user->getRoles() as $rid) {
|
||||
$tags[] = "config:user.role.$rid";
|
||||
}
|
||||
|
||||
return $cacheable_metadata->setCacheTags($tags);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -31,4 +31,21 @@ interface CacheContextInterface {
|
|||
*/
|
||||
public function getContext();
|
||||
|
||||
/**
|
||||
* Gets the cacheability metadata for the context.
|
||||
*
|
||||
* There are three valid cases for the returned CacheableMetadata object:
|
||||
* - An empty object means this can be optimized away safely.
|
||||
* - A max-age of 0 means that this context can never be optimized away. It
|
||||
* will never bubble up and cache tags will not be used.
|
||||
* - Any non-zero max-age and cache tags will bubble up into the cache item
|
||||
* if this is optimized away to allow for invalidation if the context
|
||||
* value changes.
|
||||
*
|
||||
*
|
||||
* @return \Drupal\Core\Cache\CacheableMetadata
|
||||
* A cacheable metadata object.
|
||||
*/
|
||||
public function getCacheableMetadata();
|
||||
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
namespace Drupal\Core\Cache\Context;
|
||||
|
||||
use Drupal\Component\Utility\SafeMarkup;
|
||||
use Drupal\Core\Cache\CacheableMetadata;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
|
@ -99,23 +99,35 @@ class CacheContextsManager {
|
|||
* @param string[] $context_tokens
|
||||
* An array of cache context tokens.
|
||||
*
|
||||
* @return string[]
|
||||
* The array of corresponding cache keys.
|
||||
* @return \Drupal\Core\Cache\Context\ContextCacheKeys
|
||||
* The ContextCacheKeys object containing the converted cache keys and
|
||||
* cacheability metadata.
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
* @throws \LogicException
|
||||
* Thrown if any of the context tokens or parameters are not valid.
|
||||
*/
|
||||
public function convertTokensToKeys(array $context_tokens) {
|
||||
$context_tokens = $this->optimizeTokens($context_tokens);
|
||||
sort($context_tokens);
|
||||
$keys = [];
|
||||
foreach (static::parseTokens($context_tokens) as $context) {
|
||||
list($context_id, $parameter) = $context;
|
||||
if (!in_array($context_id, $this->contexts)) {
|
||||
throw new \InvalidArgumentException(SafeMarkup::format('"@context" is not a valid cache context ID.', ['@context' => $context_id]));
|
||||
}
|
||||
$keys[] = $this->getService($context_id)->getContext($parameter);
|
||||
$this->validateTokens($context_tokens);
|
||||
$cacheable_metadata = new CacheableMetadata();
|
||||
$optimized_tokens = $this->optimizeTokens($context_tokens);
|
||||
// Iterate over cache contexts that have been optimized away and get their
|
||||
// cacheability metadata.
|
||||
foreach (static::parseTokens(array_diff($context_tokens, $optimized_tokens)) as $context_token) {
|
||||
list($context_id, $parameter) = $context_token;
|
||||
$context = $this->getService($context_id);
|
||||
$cacheable_metadata = $cacheable_metadata->merge($context->getCacheableMetadata($parameter));
|
||||
}
|
||||
return $keys;
|
||||
|
||||
sort($optimized_tokens);
|
||||
$keys = [];
|
||||
foreach (array_combine($optimized_tokens, static::parseTokens($optimized_tokens)) as $context_token => $context) {
|
||||
list($context_id, $parameter) = $context;
|
||||
$keys[] = '[' . $context_token . ']=' . $this->getService($context_id)->getContext($parameter);
|
||||
}
|
||||
|
||||
// Create the returned object and merge in the cacheability metadata.
|
||||
$context_cache_keys = new ContextCacheKeys($keys);
|
||||
return $context_cache_keys->merge($cacheable_metadata);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -129,6 +141,9 @@ class CacheContextsManager {
|
|||
* possible of a set of cache context tokens, that still captures the entire
|
||||
* universe of variations.
|
||||
*
|
||||
* If a cache context is being optimized away, it is able to set cacheable
|
||||
* metadata for itself which will be bubbled up.
|
||||
*
|
||||
* E.g. when caching per user ('user'), also caching per role ('user.roles')
|
||||
* is meaningless because "per role" is implied by "per user".
|
||||
*
|
||||
|
@ -150,6 +165,14 @@ class CacheContextsManager {
|
|||
public function optimizeTokens(array $context_tokens) {
|
||||
$optimized_content_tokens = [];
|
||||
foreach ($context_tokens as $context_token) {
|
||||
|
||||
// Extract the parameter if available.
|
||||
$parameter = NULL;
|
||||
$context_id = $context_token;
|
||||
if (strpos($context_token, ':') !== FALSE) {
|
||||
list($context_id, $parameter) = explode(':', $context_token);
|
||||
}
|
||||
|
||||
// Context tokens without:
|
||||
// - a period means they don't have a parent
|
||||
// - a colon means they're not a specific value of a cache context
|
||||
|
@ -157,6 +180,11 @@ class CacheContextsManager {
|
|||
if (strpos($context_token, '.') === FALSE && strpos($context_token, ':') === FALSE) {
|
||||
$optimized_content_tokens[] = $context_token;
|
||||
}
|
||||
// Check cacheability. If the context defines a max-age of 0, then it
|
||||
// can not be optimized away. Pass the parameter along if we have one.
|
||||
elseif ($this->getService($context_id)->getCacheableMetadata($parameter)->getCacheMaxAge() === 0) {
|
||||
$optimized_content_tokens[] = $context_token;
|
||||
}
|
||||
// The context token has a period or a colon. Iterate over all ancestor
|
||||
// cache contexts. If one exists, omit the context token.
|
||||
else {
|
||||
|
|
|
@ -34,7 +34,32 @@ interface CalculatedCacheContextInterface {
|
|||
* @return string
|
||||
* The string representation of the cache context. When $parameter is NULL,
|
||||
* a value representing all possible parameters must be generated.
|
||||
*
|
||||
* @throws \LogicException
|
||||
* Thrown if the passed in parameter is invalid.
|
||||
*/
|
||||
public function getContext($parameter = NULL);
|
||||
|
||||
/**
|
||||
* Gets the cacheability metadata for the context based on the parameter value.
|
||||
*
|
||||
* There are three valid cases for the returned CacheableMetadata object:
|
||||
* - An empty object means this can be optimized away safely.
|
||||
* - A max-age of 0 means that this context can never be optimized away. It
|
||||
* will never bubble up and cache tags will not be used.
|
||||
* - Any non-zero max-age and cache tags will bubble up into the cache item
|
||||
* if this is optimized away to allow for invalidation if the context
|
||||
* value changes.
|
||||
*
|
||||
* @param string|null $parameter
|
||||
* The parameter, or NULL to indicate all possible parameter values.
|
||||
*
|
||||
* @return \Drupal\Core\Cache\CacheableMetadata
|
||||
* A cacheable metadata object.
|
||||
*
|
||||
* @throws \LogicException
|
||||
* Thrown if the passed in parameter is invalid.
|
||||
*/
|
||||
public function getCacheableMetadata($parameter = NULL);
|
||||
|
||||
}
|
||||
|
|
44
core/lib/Drupal/Core/Cache/Context/ContextCacheKeys.php
Normal file
44
core/lib/Drupal/Core/Cache/Context/ContextCacheKeys.php
Normal file
|
@ -0,0 +1,44 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Core\Cache\Context\ContextCacheKeys.
|
||||
*/
|
||||
|
||||
namespace Drupal\Core\Cache\Context;
|
||||
|
||||
use Drupal\Core\Cache\CacheableMetadata;
|
||||
|
||||
/**
|
||||
* A value object to store generated cache keys with its cacheability metadata.
|
||||
*/
|
||||
class ContextCacheKeys extends CacheableMetadata {
|
||||
|
||||
/**
|
||||
* The generated cache keys.
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
protected $keys;
|
||||
|
||||
/**
|
||||
* Constructs a ContextCacheKeys object.
|
||||
*
|
||||
* @param string[] $keys
|
||||
* The cache context keys.
|
||||
*/
|
||||
public function __construct(array $keys) {
|
||||
$this->keys = $keys;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the generated cache keys.
|
||||
*
|
||||
* @return string[]
|
||||
* The cache keys.
|
||||
*/
|
||||
public function getKeys() {
|
||||
return $this->keys;
|
||||
}
|
||||
|
||||
}
|
|
@ -7,8 +7,14 @@
|
|||
|
||||
namespace Drupal\Core\Cache\Context;
|
||||
|
||||
use Drupal\Core\Cache\CacheableMetadata;
|
||||
|
||||
/**
|
||||
* Defines the CookiesCacheContext service, for "per cookie" caching.
|
||||
*
|
||||
* Cache context ID: 'cookies' (to vary by all cookies).
|
||||
* Calculated cache context ID: 'cookies:%name', e.g. 'cookies:device_type' (to
|
||||
* vary by the 'device_type' cookie).
|
||||
*/
|
||||
class CookiesCacheContext extends RequestStackCacheContextBase implements CalculatedCacheContextInterface {
|
||||
|
||||
|
@ -31,4 +37,11 @@ class CookiesCacheContext extends RequestStackCacheContextBase implements Calcul
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCacheableMetadata($cookie = NULL) {
|
||||
return new CacheableMetadata();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -7,8 +7,14 @@
|
|||
|
||||
namespace Drupal\Core\Cache\Context;
|
||||
|
||||
use Drupal\Core\Cache\CacheableMetadata;
|
||||
|
||||
/**
|
||||
* Defines the HeadersCacheContext service, for "per header" caching.
|
||||
*
|
||||
* Cache context ID: 'headers' (to vary by all headers).
|
||||
* Calculated cache context ID: 'headers:%name', e.g. 'headers:X-Something' (to
|
||||
* vary by the 'X-Something' header).
|
||||
*/
|
||||
class HeadersCacheContext extends RequestStackCacheContextBase implements CalculatedCacheContextInterface {
|
||||
|
||||
|
@ -31,4 +37,11 @@ class HeadersCacheContext extends RequestStackCacheContextBase implements Calcul
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCacheableMetadata($header = NULL) {
|
||||
return new CacheableMetadata();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -7,10 +7,14 @@
|
|||
|
||||
namespace Drupal\Core\Cache\Context;
|
||||
|
||||
use Drupal\Core\Cache\CacheableMetadata;
|
||||
|
||||
/**
|
||||
* Defines the IpCacheContext service, for "per IP address" caching.
|
||||
*
|
||||
* Cache context ID: 'ip'.
|
||||
*/
|
||||
class IpCacheContext extends RequestStackCacheContextBase {
|
||||
class IpCacheContext extends RequestStackCacheContextBase implements CacheContextInterface {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
|
@ -26,4 +30,11 @@ class IpCacheContext extends RequestStackCacheContextBase {
|
|||
return $this->requestStack->getCurrentRequest()->getClientIp();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCacheableMetadata() {
|
||||
return new CacheableMetadata();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -7,10 +7,14 @@
|
|||
|
||||
namespace Drupal\Core\Cache\Context;
|
||||
|
||||
use Drupal\Core\Cache\CacheableMetadata;
|
||||
|
||||
/**
|
||||
* Defines the IsSuperUserCacheContext service, for "super user or not" caching.
|
||||
*
|
||||
* Cache context ID: 'user.is_super_user'.
|
||||
*/
|
||||
class IsSuperUserCacheContext extends UserCacheContext {
|
||||
class IsSuperUserCacheContext extends UserCacheContextBase implements CacheContextInterface {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
|
@ -26,4 +30,11 @@ class IsSuperUserCacheContext extends UserCacheContext {
|
|||
return ((int) $this->user->id()) === 1 ? '1' : '0';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCacheableMetadata() {
|
||||
return new CacheableMetadata();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
namespace Drupal\Core\Cache\Context;
|
||||
|
||||
use Drupal\Core\Cache\CacheableMetadata;
|
||||
use Drupal\Core\Language\LanguageManagerInterface;
|
||||
|
||||
/**
|
||||
|
@ -74,4 +75,11 @@ class LanguagesCacheContext implements CalculatedCacheContextInterface {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCacheableMetadata($type = NULL) {
|
||||
return new CacheableMetadata();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -7,12 +7,13 @@
|
|||
|
||||
namespace Drupal\Core\Cache\Context;
|
||||
|
||||
use Drupal\Core\Cache\CacheableMetadata;
|
||||
use Symfony\Component\DependencyInjection\ContainerAware;
|
||||
|
||||
/**
|
||||
* Defines the MenuActiveTrailsCacheContext service.
|
||||
*
|
||||
* This class is container-aware to avoid initializing the 'menu.active_trail'
|
||||
* This class is container-aware to avoid initializing the 'menu.active_trails'
|
||||
* service (and its dependencies) when it is not necessary.
|
||||
*/
|
||||
class MenuActiveTrailsCacheContext extends ContainerAware implements CalculatedCacheContextInterface {
|
||||
|
@ -28,9 +29,24 @@ class MenuActiveTrailsCacheContext extends ContainerAware implements CalculatedC
|
|||
* {@inheritdoc}
|
||||
*/
|
||||
public function getContext($menu_name = NULL) {
|
||||
if (!$menu_name) {
|
||||
throw new \LogicException('No menu name provided for menu.active_trails cache context.');
|
||||
}
|
||||
|
||||
$active_trail = $this->container->get('menu.active_trail')
|
||||
->getActiveTrailIds($menu_name);
|
||||
return 'menu_trail.' . $menu_name . '|' . implode('|', $active_trail);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCacheableMetadata($menu_name = NULL) {
|
||||
if (!$menu_name) {
|
||||
throw new \LogicException('No menu name provided for menu.active_trails cache context.');
|
||||
}
|
||||
$cacheable_metadata = new CacheableMetadata();
|
||||
return $cacheable_metadata->setCacheTags(["config:system.menu.$menu_name"]);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -7,8 +7,14 @@
|
|||
|
||||
namespace Drupal\Core\Cache\Context;
|
||||
|
||||
use Drupal\Core\Cache\CacheableMetadata;
|
||||
|
||||
/**
|
||||
* Defines a cache context for "per page in a pager" caching.
|
||||
*
|
||||
* Cache context ID: 'url.query_args.pagers' (to vary by all pagers).
|
||||
* Calculated cache context ID: 'url.query_args.pagers:%pager_id', e.g.
|
||||
* 'url.query_args.pagers:1' (to vary by the pager with ID 1).
|
||||
*/
|
||||
class PagersCacheContext extends RequestStackCacheContextBase implements CalculatedCacheContextInterface {
|
||||
|
||||
|
@ -28,10 +34,17 @@ class PagersCacheContext extends RequestStackCacheContextBase implements Calcula
|
|||
// The value of the 'page' query argument contains the information that
|
||||
// controls *all* pagers.
|
||||
if ($pager_id === NULL) {
|
||||
return 'pager' . $this->requestStack->getCurrentRequest()->query->get('page', '');
|
||||
return $this->requestStack->getCurrentRequest()->query->get('page', '');
|
||||
}
|
||||
|
||||
return 'pager.' . $pager_id . '.' . pager_find_page($pager_id);
|
||||
return $pager_id . '.' . pager_find_page($pager_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCacheableMetadata($pager_id = NULL) {
|
||||
return new CacheableMetadata();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -7,12 +7,14 @@
|
|||
|
||||
namespace Drupal\Core\Cache\Context;
|
||||
|
||||
use Drupal\Core\Cache\CacheableMetadata;
|
||||
|
||||
/**
|
||||
* Defines the QueryArgsCacheContext service, for "per query args" caching.
|
||||
*
|
||||
* A "host" is defined as the combination of URI scheme, domain name and port.
|
||||
*
|
||||
* @see Symfony\Component\HttpFoundation::getSchemeAndHttpHost()
|
||||
* Cache context ID: 'url.query_args' (to vary by all query arguments).
|
||||
* Calculated cache context ID: 'url.query_args:%key', e.g.'url.query_args:foo'
|
||||
* (to vary by the 'foo' query argument).
|
||||
*/
|
||||
class QueryArgsCacheContext extends RequestStackCacheContextBase implements CalculatedCacheContextInterface {
|
||||
|
||||
|
@ -35,4 +37,11 @@ class QueryArgsCacheContext extends RequestStackCacheContextBase implements Calc
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCacheableMetadata($query_arg = NULL) {
|
||||
return new CacheableMetadata();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -7,8 +7,12 @@
|
|||
|
||||
namespace Drupal\Core\Cache\Context;
|
||||
|
||||
use Drupal\Core\Cache\CacheableMetadata;
|
||||
|
||||
/**
|
||||
* Defines the RequestFormatCacheContext service, for "per format" caching.
|
||||
*
|
||||
* Cache context ID: 'request_format'.
|
||||
*/
|
||||
class RequestFormatCacheContext extends RequestStackCacheContextBase {
|
||||
|
||||
|
@ -26,4 +30,11 @@ class RequestFormatCacheContext extends RequestStackCacheContextBase {
|
|||
return $this->requestStack->getCurrentRequest()->getRequestFormat();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCacheableMetadata() {
|
||||
return new CacheableMetadata();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -11,8 +11,12 @@ use Symfony\Component\HttpFoundation\RequestStack;
|
|||
|
||||
/**
|
||||
* Defines a base class for cache contexts depending only on the request stack.
|
||||
*
|
||||
* Subclasses need to implement either
|
||||
* \Drupal\Core\Cache\Context\CacheContextInterface or
|
||||
* \Drupal\Core\Cache\Context\CalculatedCacheContextInterface.
|
||||
*/
|
||||
abstract class RequestStackCacheContextBase implements CacheContextInterface {
|
||||
abstract class RequestStackCacheContextBase {
|
||||
|
||||
/**
|
||||
* The request stack.
|
||||
|
|
|
@ -7,10 +7,13 @@
|
|||
|
||||
namespace Drupal\Core\Cache\Context;
|
||||
|
||||
use Drupal\Core\Cache\CacheableMetadata;
|
||||
use Drupal\Core\Routing\RouteMatchInterface;
|
||||
|
||||
/**
|
||||
* Defines the RouteCacheContext service, for "per route" caching.
|
||||
*
|
||||
* Cache context ID: 'route'.
|
||||
*/
|
||||
class RouteCacheContext implements CacheContextInterface {
|
||||
|
||||
|
@ -45,4 +48,11 @@ class RouteCacheContext implements CacheContextInterface {
|
|||
return $this->routeMatch->getRouteName() . hash('sha256', serialize($this->routeMatch->getRawParameters()->all()));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCacheableMetadata() {
|
||||
return new CacheableMetadata();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -9,6 +9,8 @@ namespace Drupal\Core\Cache\Context;
|
|||
|
||||
/**
|
||||
* Defines the RouteCacheContext service, for "per route name" caching.
|
||||
*
|
||||
* Cache context ID: 'route.name'.
|
||||
*/
|
||||
class RouteNameCacheContext extends RouteCacheContext {
|
||||
|
||||
|
|
31
core/lib/Drupal/Core/Cache/Context/SessionCacheContext.php
Normal file
31
core/lib/Drupal/Core/Cache/Context/SessionCacheContext.php
Normal file
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Core\Cache\Context\SessionCacheContext.
|
||||
*/
|
||||
|
||||
namespace Drupal\Core\Cache\Context;
|
||||
|
||||
/**
|
||||
* Defines the SessionCacheContext service, for "per session" caching.
|
||||
*
|
||||
* Cache context ID: 'session'.
|
||||
*/
|
||||
class SessionCacheContext extends RequestStackCacheContextBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function getLabel() {
|
||||
return t('Session');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getContext() {
|
||||
return $this->requestStack->getCurrentRequest()->getSession()->getId();
|
||||
}
|
||||
|
||||
}
|
|
@ -7,9 +7,13 @@
|
|||
|
||||
namespace Drupal\Core\Cache\Context;
|
||||
|
||||
use Drupal\Core\Cache\CacheableMetadata;
|
||||
|
||||
/**
|
||||
* Defines the SiteCacheContext service, for "per site" caching.
|
||||
*
|
||||
* Cache context ID: 'site'.
|
||||
*
|
||||
* A "site" is defined as the combination of URI scheme, domain name, port and
|
||||
* base path. It allows for varying between the *same* site being accessed via
|
||||
* different entry points. (Different sites in a multisite setup have separate
|
||||
|
@ -18,7 +22,7 @@ namespace Drupal\Core\Cache\Context;
|
|||
* @see \Symfony\Component\HttpFoundation\Request::getSchemeAndHttpHost()
|
||||
* @see \Symfony\Component\HttpFoundation\Request::getBaseUrl()
|
||||
*/
|
||||
class SiteCacheContext extends RequestStackCacheContextBase {
|
||||
class SiteCacheContext extends RequestStackCacheContextBase implements CacheContextInterface {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
|
@ -35,4 +39,11 @@ class SiteCacheContext extends RequestStackCacheContextBase {
|
|||
return $request->getSchemeAndHttpHost() . $request->getBaseUrl();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCacheableMetadata() {
|
||||
return new CacheableMetadata();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -7,11 +7,13 @@
|
|||
|
||||
namespace Drupal\Core\Cache\Context;
|
||||
|
||||
use Drupal\Core\Routing\RouteMatchInterface;
|
||||
use Drupal\Core\Cache\CacheableMetadata;
|
||||
use Drupal\Core\Theme\ThemeManagerInterface;
|
||||
|
||||
/**
|
||||
* Defines the ThemeCacheContext service, for "per theme" caching.
|
||||
*
|
||||
* Cache context ID: 'theme'.
|
||||
*/
|
||||
class ThemeCacheContext implements CacheContextInterface {
|
||||
|
||||
|
@ -46,4 +48,11 @@ class ThemeCacheContext implements CacheContextInterface {
|
|||
return $this->themeManager->getActiveTheme()->getName() ?: 'stark';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCacheableMetadata() {
|
||||
return new CacheableMetadata();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -7,9 +7,13 @@
|
|||
|
||||
namespace Drupal\Core\Cache\Context;
|
||||
|
||||
use Drupal\Core\Cache\CacheableMetadata;
|
||||
|
||||
/**
|
||||
* Defines the TimeZoneCacheContext service, for "per time zone" caching.
|
||||
*
|
||||
* Cache context ID: 'timezone'.
|
||||
*
|
||||
* @see \Drupal\Core\Session\AccountProxy::setAccount()
|
||||
*/
|
||||
class TimeZoneCacheContext implements CacheContextInterface {
|
||||
|
@ -30,4 +34,11 @@ class TimeZoneCacheContext implements CacheContextInterface {
|
|||
return date_default_timezone_get();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCacheableMetadata() {
|
||||
return new CacheableMetadata();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -7,10 +7,14 @@
|
|||
|
||||
namespace Drupal\Core\Cache\Context;
|
||||
|
||||
use Drupal\Core\Cache\CacheableMetadata;
|
||||
|
||||
/**
|
||||
* Defines the UrlCacheContext service, for "per page" caching.
|
||||
*
|
||||
* Cache context ID: 'url'.
|
||||
*/
|
||||
class UrlCacheContext extends RequestStackCacheContextBase {
|
||||
class UrlCacheContext extends RequestStackCacheContextBase implements CacheContextInterface {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
|
@ -26,4 +30,11 @@ class UrlCacheContext extends RequestStackCacheContextBase {
|
|||
return $this->requestStack->getCurrentRequest()->getUri();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCacheableMetadata() {
|
||||
return new CacheableMetadata();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -7,22 +7,14 @@
|
|||
|
||||
namespace Drupal\Core\Cache\Context;
|
||||
|
||||
use Drupal\Core\Session\AccountInterface;
|
||||
use Drupal\Core\Cache\CacheableMetadata;
|
||||
|
||||
/**
|
||||
* Defines the UserCacheContext service, for "per user" caching.
|
||||
*
|
||||
* Cache context ID: 'user'.
|
||||
*/
|
||||
class UserCacheContext implements CacheContextInterface {
|
||||
|
||||
/**
|
||||
* Constructs a new UserCacheContext service.
|
||||
*
|
||||
* @param \Drupal\Core\Session\AccountInterface $user
|
||||
* The current user.
|
||||
*/
|
||||
public function __construct(AccountInterface $user) {
|
||||
$this->user = $user;
|
||||
}
|
||||
class UserCacheContext extends UserCacheContextBase implements CacheContextInterface {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
|
@ -35,7 +27,14 @@ class UserCacheContext implements CacheContextInterface {
|
|||
* {@inheritdoc}
|
||||
*/
|
||||
public function getContext() {
|
||||
return "u." . $this->user->id();
|
||||
return $this->user->id();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCacheableMetadata() {
|
||||
return new CacheableMetadata();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
38
core/lib/Drupal/Core/Cache/Context/UserCacheContextBase.php
Normal file
38
core/lib/Drupal/Core/Cache/Context/UserCacheContextBase.php
Normal file
|
@ -0,0 +1,38 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Core\Cache\Context\UserCacheContextBase.
|
||||
*/
|
||||
|
||||
namespace Drupal\Core\Cache\Context;
|
||||
|
||||
use Drupal\Core\Session\AccountInterface;
|
||||
|
||||
/**
|
||||
* Base class for user-based cache contexts.
|
||||
*
|
||||
* Subclasses need to implement either
|
||||
* \Drupal\Core\Cache\Context\CacheContextInterface or
|
||||
* \Drupal\Core\Cache\Context\CalculatedCacheContextInterface.
|
||||
*/
|
||||
abstract class UserCacheContextBase {
|
||||
|
||||
/**
|
||||
* The account object.
|
||||
*
|
||||
* @var \Drupal\Core\Session\AccountInterface
|
||||
*/
|
||||
protected $user;
|
||||
|
||||
/**
|
||||
* Constructs a new UserCacheContextBase class.
|
||||
*
|
||||
* @param \Drupal\Core\Session\AccountInterface $user
|
||||
* The current user.
|
||||
*/
|
||||
public function __construct(AccountInterface $user) {
|
||||
$this->user = $user;
|
||||
}
|
||||
|
||||
}
|
|
@ -7,13 +7,19 @@
|
|||
|
||||
namespace Drupal\Core\Cache\Context;
|
||||
|
||||
use Drupal\Core\Cache\CacheableMetadata;
|
||||
|
||||
/**
|
||||
* Defines the UserRolesCacheContext service, for "per role" caching.
|
||||
*
|
||||
* Only use this cache context when checking explicitly for certain roles. Use
|
||||
* user.permissions for anything that checks permissions.
|
||||
*
|
||||
* Cache context ID: 'user.roles' (to vary by all roles of the current user).
|
||||
* Calculated cache context ID: 'user.roles:%role', e.g. 'user.roles:anonymous'
|
||||
* (to vary by the presence/absence of a specific role).
|
||||
*/
|
||||
class UserRolesCacheContext extends UserCacheContext implements CalculatedCacheContextInterface{
|
||||
class UserRolesCacheContext extends UserCacheContextBase implements CalculatedCacheContextInterface {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
|
@ -34,11 +40,18 @@ class UserRolesCacheContext extends UserCacheContext implements CalculatedCacheC
|
|||
return 'is-super-user';
|
||||
}
|
||||
if ($role === NULL) {
|
||||
return 'r.' . implode(',', $this->user->getRoles());
|
||||
return implode(',', $this->user->getRoles());
|
||||
}
|
||||
else {
|
||||
return 'r.' . $role . '.' . (in_array($role, $this->user->getRoles()) ? '0' : '1');
|
||||
return (in_array($role, $this->user->getRoles()) ? '0' : '1');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCacheableMetadata($role = NULL) {
|
||||
return (new CacheableMetadata())->setCacheTags(['user:' . $this->user->id()]);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
<?php
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Core\Cache\RefinableCacheableDependencyInterface.
|
||||
*/
|
||||
|
||||
namespace Drupal\Core\Cache;
|
||||
|
||||
/**
|
||||
* Allows to add cacheability metadata to an object for the current runtime.
|
||||
*
|
||||
* This must be used when changing an object in a way that affects its
|
||||
* cacheability. For example, when changing the active translation of an entity
|
||||
* based on the current content language then a cache context for that must be
|
||||
* added.
|
||||
*/
|
||||
interface RefinableCacheableDependencyInterface extends CacheableDependencyInterface {
|
||||
|
||||
/**
|
||||
* Adds cache contexts.
|
||||
*
|
||||
* @param string[] $cache_contexts
|
||||
* The cache contexts to be added.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function addCacheContexts(array $cache_contexts);
|
||||
|
||||
/**
|
||||
* Adds cache tags.
|
||||
*
|
||||
* @param string[] $cache_tags
|
||||
* The cache tags to be added.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function addCacheTags(array $cache_tags);
|
||||
|
||||
/**
|
||||
* Merges the maximum age (in seconds) with the existing maximum age.
|
||||
*
|
||||
* The max age will be set to the given value if it is lower than the existing
|
||||
* value.
|
||||
*
|
||||
* @param int $max_age
|
||||
* The max age to associate.
|
||||
*
|
||||
* @return $this
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
* Thrown if a non-integer value is supplied.
|
||||
*/
|
||||
public function mergeCacheMaxAge($max_age);
|
||||
|
||||
/**
|
||||
* Adds a dependency on an object: merges its cacheability metadata.
|
||||
*
|
||||
* @param \Drupal\Core\Cache\CacheableDependencyInterface|object $other_object
|
||||
* The dependency. If the object implements CacheableDependencyInterface,
|
||||
* then its cacheability metadata will be used. Otherwise, the passed in
|
||||
* object must be assumed to be uncacheable, so max-age 0 is set.
|
||||
*
|
||||
* @return $this
|
||||
*
|
||||
* @see \Drupal\Core\Cache\CacheableMetadata::createFromObject()
|
||||
*/
|
||||
public function addCacheableDependency($other_object);
|
||||
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Core\Cache\RefinableCacheableDependencyTrait.
|
||||
*/
|
||||
|
||||
namespace Drupal\Core\Cache;
|
||||
|
||||
/**
|
||||
* Trait for \Drupal\Core\Cache\RefinableCacheableDependencyInterface.
|
||||
*/
|
||||
trait RefinableCacheableDependencyTrait {
|
||||
|
||||
/**
|
||||
* Cache contexts.
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
protected $cacheContexts = [];
|
||||
|
||||
/**
|
||||
* Cache tags.
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
protected $cacheTags = [];
|
||||
|
||||
/**
|
||||
* Cache max-age.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $cacheMaxAge = Cache::PERMANENT;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function addCacheableDependency($other_object) {
|
||||
if ($other_object instanceof CacheableDependencyInterface) {
|
||||
$this->addCacheContexts($other_object->getCacheContexts());
|
||||
$this->addCacheTags($other_object->getCacheTags());
|
||||
$this->mergeCacheMaxAge($other_object->getCacheMaxAge());
|
||||
}
|
||||
else {
|
||||
// Not a cacheable dependency, this can not be cached.
|
||||
$this->maxAge = 0;
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function addCacheContexts(array $cache_contexts) {
|
||||
$this->cacheContexts = Cache::mergeContexts($this->cacheContexts, $cache_contexts);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function addCacheTags(array $cache_tags) {
|
||||
$this->cacheTags = Cache::mergeTags($this->cacheTags, $cache_tags);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function mergeCacheMaxAge($max_age) {
|
||||
$this->cacheMaxAge = Cache::mergeMaxAges($this->cacheMaxAge, $max_age);
|
||||
return $this;
|
||||
}
|
||||
|
||||
}
|
|
@ -220,6 +220,9 @@ class DbDumpCommand extends Command {
|
|||
// Set primary key, unique keys, and indexes.
|
||||
$this->getTableIndexes($table, $definition);
|
||||
|
||||
// Set table collation.
|
||||
$this->getTableCollation($table, $definition);
|
||||
|
||||
return $definition;
|
||||
}
|
||||
|
||||
|
@ -235,7 +238,6 @@ class DbDumpCommand extends Command {
|
|||
// Note, this query doesn't support ordering, so that is worked around
|
||||
// below by keying the array on Seq_in_index.
|
||||
$query = $this->connection->query("SHOW INDEX FROM {" . $table . "}");
|
||||
$indexes = [];
|
||||
while (($row = $query->fetchAssoc()) !== FALSE) {
|
||||
$index_name = $row['Key_name'];
|
||||
$column = $row['Column_name'];
|
||||
|
@ -259,6 +261,22 @@ class DbDumpCommand extends Command {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the table collation.
|
||||
*
|
||||
* @param string $table
|
||||
* The table to find indexes for.
|
||||
* @param array &$definition
|
||||
* The schema definition to modify.
|
||||
*/
|
||||
protected function getTableCollation($table, &$definition) {
|
||||
$query = $this->connection->query("SHOW TABLE STATUS LIKE '{" . $table . "}'");
|
||||
$data = $query->fetchAssoc();
|
||||
|
||||
// Set `mysql_character_set`. This will be ignored by other backends.
|
||||
$definition['mysql_character_set'] = str_replace('_general_ci', '', $data['Collation']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all data from a given table.
|
||||
*
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Core\Command\GenerateProxyClassApplication.
|
||||
*/
|
||||
|
||||
namespace Drupal\Core\Command;
|
||||
|
||||
use Drupal\Component\ProxyBuilder\ProxyBuilder;
|
||||
use Symfony\Component\Console\Application;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
|
||||
/**
|
||||
* Provides a console command to generate proxy classes.
|
||||
*/
|
||||
class GenerateProxyClassApplication extends Application {
|
||||
|
||||
/**
|
||||
* The proxy builder.
|
||||
*
|
||||
* @var \Drupal\Component\ProxyBuilder\ProxyBuilder
|
||||
*/
|
||||
protected $proxyBuilder;
|
||||
|
||||
/**
|
||||
* Constructs a new GenerateProxyClassApplication instance.
|
||||
*
|
||||
* @param \Drupal\Component\ProxyBuilder\ProxyBuilder $proxy_builder
|
||||
* The proxy builder.
|
||||
*/
|
||||
public function __construct(ProxyBuilder $proxy_builder) {
|
||||
$this->proxyBuilder = $proxy_builder;
|
||||
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getCommandName(InputInterface $input) {
|
||||
return 'generate-proxy-class';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getDefaultCommands() {
|
||||
// Even though this is a single command, keep the HelpCommand (--help).
|
||||
$default_commands = parent::getDefaultCommands();
|
||||
$default_commands[] = new GenerateProxyClassCommand($this->proxyBuilder);
|
||||
return $default_commands;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* Overridden so the application doesn't expect the command name as the first
|
||||
* argument.
|
||||
*/
|
||||
public function getDefinition() {
|
||||
$definition = parent::getDefinition();
|
||||
// Clears the normal first argument (the command name).
|
||||
$definition->setArguments();
|
||||
return $definition;
|
||||
}
|
||||
|
||||
}
|
97
core/lib/Drupal/Core/Command/GenerateProxyClassCommand.php
Normal file
97
core/lib/Drupal/Core/Command/GenerateProxyClassCommand.php
Normal file
|
@ -0,0 +1,97 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Core\Command\GenerateProxyClassCommand.
|
||||
*/
|
||||
|
||||
namespace Drupal\Core\Command;
|
||||
|
||||
use Drupal\Component\ProxyBuilder\ProxyBuilder;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
/**
|
||||
* Provides a console command to generate proxy classes.
|
||||
*/
|
||||
class GenerateProxyClassCommand extends Command {
|
||||
|
||||
/**
|
||||
* The proxy builder.
|
||||
*
|
||||
* @var \Drupal\Component\ProxyBuilder\ProxyBuilder
|
||||
*/
|
||||
protected $proxyBuilder;
|
||||
|
||||
/**
|
||||
* Constructs a new GenerateProxyClassCommand instance.
|
||||
*
|
||||
* @param \Drupal\Component\ProxyBuilder\ProxyBuilder $proxy_builder
|
||||
* The proxy builder.
|
||||
*/
|
||||
public function __construct(ProxyBuilder $proxy_builder) {
|
||||
parent::__construct();
|
||||
|
||||
$this->proxyBuilder = $proxy_builder;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function configure() {
|
||||
$this->setName('generate-proxy-class')
|
||||
->setDefinition([
|
||||
new InputArgument('class_name', InputArgument::REQUIRED, 'The class to be proxied'),
|
||||
new InputArgument('namespace_root_path', InputArgument::REQUIRED, 'The filepath to the root of the namespace.'),
|
||||
])
|
||||
->setDescription('Dumps a generated proxy class into its appropriate namespace.')
|
||||
->addUsage('\'Drupal\Core\Batch\BatchStorage\' "core/lib/Drupal/Core"')
|
||||
->addUsage('\'Drupal\block\BlockRepository\' "core/modules/block/src"')
|
||||
->addUsage('\'Drupal\mymodule\MyClass\' "modules/contrib/mymodule/src"');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function execute(InputInterface $input, OutputInterface $output) {
|
||||
$class_name = ltrim($input->getArgument('class_name'), '\\');
|
||||
$namespace_root = $input->getArgument('namespace_root_path');
|
||||
|
||||
$match = [];
|
||||
preg_match('/([a-zA-Z0-9_]+\\\\[a-zA-Z0-9_]+)\\\\(.+)/', $class_name, $match);
|
||||
|
||||
if ($match) {
|
||||
$root_namespace = $match[1];
|
||||
$rest_fqcn = $match[2];
|
||||
|
||||
$proxy_filename = $namespace_root . '/ProxyClass/' . str_replace('\\', '/', $rest_fqcn) . '.php';
|
||||
$proxy_class_name = $root_namespace . '\\ProxyClass\\' . $rest_fqcn;
|
||||
|
||||
$proxy_class_string = $this->proxyBuilder->build($class_name);
|
||||
|
||||
$file_string = <<<EOF
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \{{ proxy_class_name }}.
|
||||
*/
|
||||
|
||||
/**
|
||||
* This file was generated via php core/scripts/generate-proxy-class.php '$class_name' "$namespace_root".
|
||||
*/
|
||||
{{ proxy_class_string }}
|
||||
EOF;
|
||||
$file_string = str_replace(['{{ proxy_class_name }}', '{{ proxy_class_string }}'], [$proxy_class_name, $proxy_class_string], $file_string);
|
||||
|
||||
mkdir(dirname($proxy_filename), 0775, TRUE);
|
||||
file_put_contents($proxy_filename, $file_string);
|
||||
|
||||
$output->writeln(sprintf('Proxy of class %s written to %s', $class_name, $proxy_filename));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -9,6 +9,7 @@ namespace Drupal\Core\Condition;
|
|||
|
||||
use Drupal\Component\Plugin\ConfigurablePluginInterface;
|
||||
use Drupal\Component\Plugin\PluginInspectionInterface;
|
||||
use Drupal\Core\Cache\CacheableDependencyInterface;
|
||||
use Drupal\Core\Executable\ExecutableInterface;
|
||||
use Drupal\Core\Executable\ExecutableManagerInterface;
|
||||
use Drupal\Core\Plugin\PluginFormInterface;
|
||||
|
@ -46,12 +47,12 @@ use Drupal\Core\Plugin\PluginFormInterface;
|
|||
*
|
||||
* @ingroup plugin_api
|
||||
*/
|
||||
interface ConditionInterface extends ExecutableInterface, PluginFormInterface, ConfigurablePluginInterface, PluginInspectionInterface {
|
||||
interface ConditionInterface extends ExecutableInterface, PluginFormInterface, ConfigurablePluginInterface, PluginInspectionInterface, CacheableDependencyInterface {
|
||||
|
||||
/**
|
||||
* Determines whether condition result will be negated.
|
||||
*
|
||||
* @return boolean
|
||||
* @return bool
|
||||
* Whether the condition result will be negated.
|
||||
*/
|
||||
public function isNegated();
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
|
||||
namespace Drupal\Core\Condition;
|
||||
|
||||
use Drupal\Core\Cache\Cache;
|
||||
use Drupal\Core\Cache\CacheableDependencyInterface;
|
||||
use Drupal\Core\Executable\ExecutableManagerInterface;
|
||||
use Drupal\Core\Executable\ExecutablePluginBase;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
|
|
|
@ -8,9 +8,9 @@
|
|||
namespace Drupal\Core\Config;
|
||||
|
||||
use Drupal\Component\Utility\NestedArray;
|
||||
use Drupal\Component\Utility\SafeMarkup;
|
||||
use Drupal\Core\Cache\Cache;
|
||||
use Drupal\Core\Cache\CacheableDependencyInterface;
|
||||
use Drupal\Core\Cache\RefinableCacheableDependencyInterface;
|
||||
use Drupal\Core\Cache\RefinableCacheableDependencyTrait;
|
||||
use \Drupal\Core\DependencyInjection\DependencySerializationTrait;
|
||||
|
||||
/**
|
||||
|
@ -28,8 +28,9 @@ use \Drupal\Core\DependencyInjection\DependencySerializationTrait;
|
|||
* @see \Drupal\Core\Config\Config
|
||||
* @see \Drupal\Core\Theme\ThemeSettings
|
||||
*/
|
||||
abstract class ConfigBase implements CacheableDependencyInterface {
|
||||
abstract class ConfigBase implements RefinableCacheableDependencyInterface {
|
||||
use DependencySerializationTrait;
|
||||
use RefinableCacheableDependencyTrait;
|
||||
|
||||
/**
|
||||
* The name of the configuration object.
|
||||
|
@ -97,24 +98,17 @@ abstract class ConfigBase implements CacheableDependencyInterface {
|
|||
public static function validateName($name) {
|
||||
// The name must be namespaced by owner.
|
||||
if (strpos($name, '.') === FALSE) {
|
||||
throw new ConfigNameException(SafeMarkup::format('Missing namespace in Config object name @name.', array(
|
||||
'@name' => $name,
|
||||
)));
|
||||
throw new ConfigNameException("Missing namespace in Config object name $name.");
|
||||
}
|
||||
// The name must be shorter than Config::MAX_NAME_LENGTH characters.
|
||||
if (strlen($name) > self::MAX_NAME_LENGTH) {
|
||||
throw new ConfigNameException(SafeMarkup::format('Config object name @name exceeds maximum allowed length of @length characters.', array(
|
||||
'@name' => $name,
|
||||
'@length' => self::MAX_NAME_LENGTH,
|
||||
)));
|
||||
throw new ConfigNameException("Config object name $name exceeds maximum allowed length of " . static::MAX_NAME_LENGTH . " characters.");
|
||||
}
|
||||
|
||||
// The name must not contain any of the following characters:
|
||||
// : ? * < > " ' / \
|
||||
if (preg_match('/[:?*<>"\'\/\\\\]/', $name)) {
|
||||
throw new ConfigNameException(SafeMarkup::format('Invalid character in Config object name @name.', array(
|
||||
'@name' => $name,
|
||||
)));
|
||||
throw new ConfigNameException("Invalid character in Config object name $name.");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -222,7 +216,7 @@ abstract class ConfigBase implements CacheableDependencyInterface {
|
|||
protected function validateKeys(array $data) {
|
||||
foreach ($data as $key => $value) {
|
||||
if (strpos($key, '.') !== FALSE) {
|
||||
throw new ConfigValueException(SafeMarkup::format('@key key contains a dot which is not supported.', array('@key' => $key)));
|
||||
throw new ConfigValueException("$key key contains a dot which is not supported.");
|
||||
}
|
||||
if (is_array($value)) {
|
||||
$this->validateKeys($value);
|
||||
|
@ -269,21 +263,21 @@ abstract class ConfigBase implements CacheableDependencyInterface {
|
|||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCacheContexts() {
|
||||
return [];
|
||||
return $this->cacheContexts;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCacheTags() {
|
||||
return ['config:' . $this->name];
|
||||
return Cache::mergeTags(['config:' . $this->name], $this->cacheTags);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCacheMaxAge() {
|
||||
return Cache::PERMANENT;
|
||||
return $this->cacheMaxAge;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -21,11 +21,16 @@ final class ConfigEvents {
|
|||
* object is saved. The event listener method receives a
|
||||
* \Drupal\Core\Config\ConfigCrudEvent instance.
|
||||
*
|
||||
* See hook_update_N() documentation for safe configuration API usage and
|
||||
* restrictions as this event will be fired when configuration is saved by
|
||||
* hook_update_N().
|
||||
*
|
||||
* @Event
|
||||
*
|
||||
* @see \Drupal\Core\Config\ConfigCrudEvent
|
||||
* @see \Drupal\Core\Config\Config::save()
|
||||
* @see \Drupal\Core\Config\ConfigFactory::onConfigSave()
|
||||
* @see hook_update_N()
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
|
@ -38,11 +43,16 @@ final class ConfigEvents {
|
|||
* object is deleted. The event listener method receives a
|
||||
* \Drupal\Core\Config\ConfigCrudEvent instance.
|
||||
*
|
||||
* See hook_update_N() documentation for safe configuration API usage and
|
||||
* restrictions as this event will be fired when configuration is deleted by
|
||||
* hook_update_N().
|
||||
*
|
||||
* @Event
|
||||
*
|
||||
* @see \Drupal\Core\Config\ConfigCrudEvent
|
||||
* @see \Drupal\Core\Config\Config::delete()
|
||||
* @see \Drupal\Core\Config\ConfigFactory::onConfigDelete()
|
||||
* @see hook_update_N()
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
|
@ -55,10 +65,15 @@ final class ConfigEvents {
|
|||
* object's name is changed. The event listener method receives a
|
||||
* \Drupal\Core\Config\ConfigRenameEvent instance.
|
||||
*
|
||||
* See hook_update_N() documentation for safe configuration API usage and
|
||||
* restrictions as this event will be fired when configuration is renamed by
|
||||
* hook_update_N().
|
||||
*
|
||||
* @Event
|
||||
*
|
||||
* @see \Drupal\Core\Config\ConfigRenameEvent
|
||||
* @see \Drupal\Core\Config\ConfigFactoryInterface::rename().
|
||||
* @see \Drupal\Core\Config\ConfigFactoryInterface::rename()
|
||||
* @see hook_update_N()
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
|
|
|
@ -126,6 +126,9 @@ class ConfigFactory implements ConfigFactoryInterface, EventSubscriberInterface
|
|||
$this->cache[$cache_key]->setSettingsOverride($GLOBALS['config'][$name]);
|
||||
}
|
||||
}
|
||||
|
||||
$this->propagateConfigOverrideCacheability($cache_key, $name);
|
||||
|
||||
return $this->cache[$cache_key];
|
||||
}
|
||||
}
|
||||
|
@ -183,6 +186,9 @@ class ConfigFactory implements ConfigFactoryInterface, EventSubscriberInterface
|
|||
$this->cache[$cache_key]->setSettingsOverride($GLOBALS['config'][$name]);
|
||||
}
|
||||
}
|
||||
|
||||
$this->propagateConfigOverrideCacheability($cache_key, $name);
|
||||
|
||||
$list[$name] = $this->cache[$cache_key];
|
||||
}
|
||||
}
|
||||
|
@ -209,6 +215,20 @@ class ConfigFactory implements ConfigFactoryInterface, EventSubscriberInterface
|
|||
return $overrides;
|
||||
}
|
||||
|
||||
/**
|
||||
* Propagates cacheability of config overrides to cached config objects.
|
||||
*
|
||||
* @param string $cache_key
|
||||
* The key of the cached config object to update.
|
||||
* @param string $name
|
||||
* The name of the configuration object to construct.
|
||||
*/
|
||||
protected function propagateConfigOverrideCacheability($cache_key, $name) {
|
||||
foreach ($this->configFactoryOverrides as $override) {
|
||||
$this->cache[$cache_key]->addCacheableDependency($override->getCacheableMetadata($name));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Reference in a new issue