/core/core.api.php
PHP | 2598 lines | 112 code | 48 blank | 2438 comment | 12 complexity | 88133ae60fabbe9b0ec54849ee5e40f2 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1
Large files files are truncated, but you can click here to view the full file
- <?php
- /**
- * @file
- * Documentation landing page and topics, plus core library hooks.
- */
- /**
- * @mainpage
- * Welcome to the Drupal API Documentation!
- *
- * This site is an API reference for Drupal, generated from comments embedded
- * in the source code. More in-depth documentation can be found at
- * https://www.drupal.org/developing/api.
- *
- * Here are some topics to help you get started developing with Drupal.
- *
- * @section essentials Essential background concepts
- *
- * - @link oo_conventions Object-oriented conventions used in Drupal @endlink
- * - @link extending Extending and altering Drupal @endlink
- * - @link best_practices Security and best practices @endlink
- * - @link info_types Types of information in Drupal @endlink
- *
- * @section interface User interface
- *
- * - @link menu Menu entries, local tasks, and other links @endlink
- * - @link routing Routing API and page controllers @endlink
- * - @link form_api Forms @endlink
- * - @link block_api Blocks @endlink
- * - @link ajax Ajax @endlink
- *
- * @section store_retrieve Storing and retrieving data
- *
- * - @link entity_api Entities @endlink
- * - @link field Fields @endlink
- * - @link config_api Configuration API @endlink
- * - @link state_api State API @endlink
- * - @link views_overview Views @endlink
- * - @link database Database abstraction layer @endlink
- *
- * @section other_essentials Other essential APIs
- *
- * - @link plugin_api Plugins @endlink
- * - @link container Services and the Dependency Injection Container @endlink
- * - @link events Events @endlink
- * - @link i18n Internationalization @endlink
- * - @link cache Caching @endlink
- * - @link utility Utility classes and functions @endlink
- * - @link user_api User accounts, permissions, and roles @endlink
- * - @link theme_render Render API @endlink
- * - @link themeable Theme system @endlink
- * - @link update_api Update API @endlink
- * - @link migration Migration @endlink
- *
- * @section additional Additional topics
- *
- * - @link batch Batch API @endlink
- * - @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
- *
- * - @link https://api.drupal.org/api/drupal/groups/8 All topics @endlink
- * - @link https://www.drupal.org/project/examples Examples project (sample modules) @endlink
- * - @link https://www.drupal.org/list-changes API change notices @endlink
- * - @link https://www.drupal.org/developing/api/8 Drupal 8 API longer references @endlink
- */
- /**
- * @defgroup third_party REST and Application Integration
- * @{
- * Integrating third-party applications using REST and related operations.
- *
- * @section sec_overview Overview of web services
- * Web services make it possible for applications and web sites to read and
- * update information from other web sites. There are several standard
- * techniques for providing web services, including:
- * - SOAP: http://wikipedia.org/wiki/SOAP
- * - XML-RPC: http://wikipedia.org/wiki/XML-RPC
- * - REST: http://wikipedia.org/wiki/Representational_state_transfer
- * Drupal sites can both provide web services and integrate third-party web
- * services.
- *
- * @section sec_rest_overview Overview of REST
- * The REST technique uses basic HTTP requests to obtain and update data, where
- * each web service defines a specific API (HTTP GET and/or POST parameters and
- * returned response) for its HTTP requests. REST requests are separated into
- * several types, known as methods, including:
- * - GET: Requests to obtain data.
- * - POST: Requests to update or create data.
- * - PUT: Requests to update or create data (limited support, currently unused
- * by entity resources).
- * - PATCH: Requests to update a subset of data, such as one field.
- * - DELETE: Requests to delete data.
- * The Drupal Core REST module provides support for GET, POST, PATCH, and DELETE
- * quests on entities, GET requests on the database log from the Database
- * Logging module, and a plugin framework for providing REST support for other
- * data and other methods.
- *
- * REST requests can be authenticated. The Drupal Core Basic Auth module
- * provides authentication using the HTTP Basic protocol; the contributed module
- * OAuth (https://www.drupal.org/project/oauth) implements the OAuth
- * authentication protocol. You can also use cookie-based authentication, which
- * would require users to be logged into the Drupal site while using the
- * application on the third-party site that is using the REST service.
- *
- * @section sec_rest Enabling REST for entities and the log
- * Here are the steps to take to use the REST operations provided by Drupal
- * Core:
- * - Enable the REST module, plus Basic Auth (or another authentication method)
- * and HAL.
- * - Node entity support is configured by default. If you would like to support
- * other types of entities, you can copy
- * core/modules/rest/config/install/rest.settings.yml to your sync
- * configuration directory, appropriately modified for other entity types,
- * and import it. Support for GET on the log from the Database Logging module
- * can also be enabled in this way; in this case, the 'entity:node' line
- * in the configuration would be replaced by the appropriate plugin ID,
- * 'dblog'.
- * - Set up permissions to allow the desired REST operations for a role, and set
- * up one or more user accounts to perform the operations.
- * - To perform a REST operation, send a request to either the canonical URL
- * for an entity (such as node/12345 for a node), or if the entity does not
- * have a canonical URL, a URL like entity/(type)/(ID). The URL for a log
- * entry is dblog/(ID). The request must have the following properties:
- * - The request method must be set to the REST method you are using (POST,
- * GET, PATCH, etc.).
- * - The content type for the data you send, or the accept type for the
- * data you are receiving, must be set to 'application/hal+json'.
- * - If you are sending data, it must be JSON-encoded.
- * - You'll also need to make sure the authentication information is sent
- * with the request, unless you have allowed access to anonymous users.
- *
- * For more detailed information on setting up REST, see
- * https://www.drupal.org/documentation/modules/rest.
- *
- * @section sec_plugins Defining new REST plugins
- * The REST framework in the REST module has support built in for entities, but
- * it is also an extensible plugin-based system. REST plugins implement
- * interface \Drupal\rest\Plugin\ResourceInterface, and generally extend base
- * class \Drupal\rest\Plugin\ResourceBase. They are annotated with
- * \Drupal\rest\Annotation\RestResource annotation, and must be in plugin
- * namespace subdirectory Plugin\rest\resource. For more information on how to
- * create plugins, see the @link plugin_api Plugin API topic. @endlink
- *
- * If you create a new REST plugin, you will also need to enable it by
- * providing default configuration or configuration import, as outlined in
- * @ref sec_rest above.
- *
- * @section sec_integrate Integrating data from other sites into Drupal
- * If you want to integrate data from other web sites into Drupal, here are
- * some notes:
- * - There are contributed modules available for integrating many third-party
- * sites into Drupal. Search on https://www.drupal.org/project/project_module
- * - If there is not an existing module, you will need to find documentation on
- * the specific web services API for the site you are trying to integrate.
- * - There are several classes and functions that are useful for interacting
- * with web services:
- * - You should make requests using the 'http_client' service, which
- * implements \GuzzleHttp\ClientInterface. See the
- * @link container Services topic @endlink for more information on
- * services. If you cannot use dependency injection to retrieve this
- * service, the \Drupal::httpClient() method is available. A good example
- * of how to use this service can be found in
- * \Drupal\aggregator\Plugin\aggregator\fetcher\DefaultFetcher
- * - \Drupal\Component\Serialization\Json (JSON encoding and decoding).
- * - PHP has functions and classes for parsing XML; see
- * http://php.net/manual/refs.xml.php
- * @}
- */
- /**
- * @defgroup state_api State API
- * @{
- * Information about the State API.
- *
- * The State API is one of several methods in Drupal for storing information.
- * See the @link info_types Information types topic @endlink for an
- * overview of the different types of information.
- *
- * The basic entry point into the State API is \Drupal::state(), which returns
- * an object of class \Drupal\Core\State\StateInterface. This class has
- * methods for storing and retrieving state information; each piece of state
- * information is associated with a string-valued key. Example:
- * @code
- * // Get the state class.
- * $state = \Drupal::state();
- * // Find out when cron was last run; the key is 'system.cron_last'.
- * $time = $state->get('system.cron_last');
- * // Set the cron run time to the current request time.
- * $state->set('system.cron_last', REQUEST_TIME);
- * @endcode
- *
- * For more on the State API, see https://www.drupal.org/developing/api/8/state
- * @}
- */
- /**
- * @defgroup config_api Configuration API
- * @{
- * Information about the Configuration API.
- *
- * The Configuration API is one of several methods in Drupal for storing
- * information. See the @link info_types Information types topic @endlink for
- * an overview of the different types of information. The sections below have
- * more information about the configuration API; see
- * https://www.drupal.org/developing/api/8/configuration for more details.
- *
- * @section sec_storage Configuration storage
- * In Drupal, there is a concept of the "active" configuration, which is the
- * configuration that is currently in use for a site. The storage used for the
- * active configuration is configurable: it could be in the database, in files
- * in a particular directory, or in other storage backends; the default storage
- * is in the database. Module developers must use the configuration API to
- * access the active configuration, rather than being concerned about the
- * details of where and how it is stored.
- *
- * Configuration is divided into individual objects, each of which has a
- * unique name or key. Some modules will have only one configuration object,
- * typically called 'mymodule.settings'; some modules will have many. Within
- * a configuration object, configuration settings have data types (integer,
- * string, Boolean, etc.) and settings can also exist in a nested hierarchy,
- * known as a "mapping".
- *
- * Configuration can also be overridden on a global, per-language, or
- * per-module basis. See https://www.drupal.org/node/1928898 for more
- * information.
- *
- * @section sec_yaml Configuration YAML files
- * Whether or not configuration files are being used for the active
- * configuration storage on a particular site, configuration files are always
- * used for:
- * - Defining the default configuration for an extension (module, theme, or
- * profile), which is imported to the active storage when the extension is
- * enabled. These configuration items are located in the config/install
- * sub-directory of the extension. Note that changes to this configuration
- * after a module or theme is already enabled have no effect; to make a
- * configuration change after a module or theme is enabled, you would need to
- * uninstall/reinstall or use a hook_update_N() function.
- * - Defining optional configuration for a module or theme. Optional
- * configuration items are located in the config/optional sub-directory of the
- * extension. These configuration items have dependencies that are not
- * explicit dependencies of the extension, so they are only installed if all
- * dependencies are met. For example, in the scenario that module A defines a
- * dependency which requires module B, but module A is installed first and
- * module B some time later, then module A's config/optional directory will be
- * scanned at that time for newly met dependencies, and the configuration will
- * be installed then. If module B is never installed, the configuration item
- * will not be installed either.
- * - Exporting and importing configuration.
- *
- * The file storage format for configuration information in Drupal is
- * @link http://wikipedia.org/wiki/YAML YAML files. @endlink Configuration is
- * divided into files, each containing one configuration object. The file name
- * for a configuration object is equal to the unique name of the configuration,
- * with a '.yml' extension. The default configuration files for each module are
- * placed in the config/install directory under the top-level module directory,
- * so look there in most Core modules for examples.
- *
- * @section sec_schema Configuration schema and translation
- * Each configuration file has a specific structure, which is expressed as a
- * YAML-based configuration schema. The configuration schema details the
- * structure of the configuration, its data types, and which of its values need
- * to be translatable. Each module needs to define its configuration schema in
- * files in the config/schema directory under the top-level module directory, so
- * look there in most Core modules for examples.
- *
- * Configuration can be internationalized; see the
- * @link i18n Internationalization topic @endlink for more information. Data
- * types label, text, and date_format in configuration schema are translatable;
- * string is non-translatable text (the 'translatable' property on a schema
- * data type definition indicates that it is translatable).
- *
- * @section sec_simple Simple configuration
- * The simple configuration API should be used for information that will always
- * have exactly one copy or version. For instance, if your module has a
- * setting that is either on or off, then this is only defined once, and it
- * would be a Boolean-valued simple configuration setting.
- *
- * The first task in using the simple configuration API is to define the
- * configuration file structure, file name, and schema of your settings (see
- * @ref sec_yaml above). Once you have done that, you can retrieve the active
- * configuration object that corresponds to configuration file mymodule.foo.yml
- * with a call to:
- * @code
- * $config = \Drupal::config('mymodule.foo');
- * @endcode
- *
- * This will be an object of class \Drupal\Core\Config\Config, which has methods
- * for getting configuration information. For instance, if your YAML file
- * structure looks like this:
- * @code
- * enabled: '0'
- * bar:
- * baz: 'string1'
- * boo: 34
- * @endcode
- * you can make calls such as:
- * @code
- * // Get a single value.
- * $enabled = $config->get('enabled');
- * // Get an associative array.
- * $bar = $config->get('bar');
- * // Get one element of the array.
- * $bar_baz = $config->get('bar.baz');
- * @endcode
- *
- * The Config object that was obtained and used in the previous examples does
- * not allow you to change configuration. If you want to change configuration,
- * you will instead need to get the Config object by making a call to
- * getEditable() on the config factory:
- * @code
- * $config =\Drupal::service('config.factory')->getEditable('mymodule.foo');
- * @endcode
- *
- * Individual configuration values can be changed or added using the set()
- * method and saved using the save() method:
- * @code
- * // Set a scalar value.
- * $config->set('enabled', 1);
- * // Save the configuration.
- * $config->save();
- * @endcode
- *
- * Configuration values can also be unset using the clear() method, which is
- * also chainable:
- * @code
- * $config->clear('bar.boo')->save();
- * $config_data = $config->get('bar');
- * @endcode
- * In this example $config_data would return an array with one key - 'baz' -
- * because 'boo' was unset.
- *
- * @section sec_entity Configuration entities
- * In contrast to the simple configuration settings described in the previous
- * section, if your module allows users to create zero or more items (where
- * "items" are things like content type definitions, view definitions, and the
- * like), then you need to define a configuration entity type to store your
- * configuration. Creating an entity type, loading entities, and querying them
- * are outlined in the @link entity_api Entity API topic. @endlink Here are a
- * few additional steps and notes specific to configuration entities:
- * - For examples, look for classes that implement
- * \Drupal\Core\Config\Entity\ConfigEntityInterface -- one good example is
- * the \Drupal\user\Entity\Role entity type.
- * - In the entity type annotation, you will need to define a 'config_prefix'
- * string. When Drupal stores a configuration item, it will be given a name
- * composed of your module name, your chosen config prefix, and the ID of
- * the individual item, separated by '.'. For example, in the Role entity,
- * the config prefix is 'role', so one configuration item might be named
- * user.role.anonymous, with configuration file user.role.anonymous.yml.
- * - You will need to define the schema for your configuration in your
- * modulename.schema.yml file, with an entry for 'modulename.config_prefix.*'.
- * For example, for the Role entity, the file user.schema.yml has an entry
- * user.role.*; see @ref sec_yaml above for more information.
- * - Your module can provide default/optional configuration entities in YAML
- * files; see @ref sec_yaml above for more information.
- * - Some configuration entities have dependencies on other configuration
- * entities, and module developers need to consider this so that configuration
- * can be imported, uninstalled, and synchronized in the right order. For
- * example, a field display configuration entity would need to depend on
- * field configuration, which depends on field and bundle configuration.
- * Configuration entity classes expose dependencies by overriding the
- * \Drupal\Core\Config\Entity\ConfigEntityInterface::calculateDependencies()
- * method.
- * - On routes for paths starting with '/admin' or otherwise designated as
- * administration paths (such as node editing when it is set as an admin
- * operation), if they have configuration entity placeholders, configuration
- * entities are normally loaded in their original language, without
- * translations or other overrides. This is usually desirable, because most
- * admin paths are for editing configuration, and you need that to be in the
- * source language and to lack possibly dynamic overrides. If for some reason
- * you need to have your configuration entity loaded in the currently-selected
- * language on an admin path (for instance, if you go to
- * example.com/es/admin/your_path and you need the entity to be in Spanish),
- * then you can add a 'with_config_overrides' parameter option to your route.
- * The same applies if you need to load the entity with overrides (or
- * translated) on an admin path like '/node/add/article' (when configured to
- * be an admin path). Here's an example using the configurable_language config
- * entity:
- * @code
- * mymodule.myroute:
- * path: '/admin/mypath/{configurable_language}'
- * defaults:
- * _controller: '\Drupal\mymodule\MyController::myMethod'
- * options:
- * parameters:
- * configurable_language:
- * type: entity:configurable_language
- * with_config_overrides: TRUE
- * @endcode
- * With the route defined this way, the $configurable_language parameter to
- * your controller method will come in translated to the current language.
- * Without the parameter options section, it would be in the original
- * language, untranslated.
- *
- * @see i18n
- *
- * @}
- */
- /**
- * @defgroup cache Cache API
- * @{
- * Information about the Drupal Cache API
- *
- * @section basics Basics
- *
- * Note: If not specified, all of the methods mentioned here belong to
- * \Drupal\Core\Cache\CacheBackendInterface.
- *
- * The Cache API is used to store data that takes a long time to compute.
- * Caching can either be permanent or valid only for a certain time span, and
- * the cache can contain any type of data.
- *
- * To use the Cache API:
- * - Request a cache object through \Drupal::cache() or by injecting a cache
- * service.
- * - Define a Cache ID (cid) value for your data. A cid is a string, which must
- * contain enough information to uniquely identify the data. For example, if
- * your data contains translated strings, then your cid value must include the
- * interface text language selected for page.
- * - Call the get() method to attempt a cache read, to see if the cache already
- * contains your data.
- * - If your data is not already in the cache, compute it and add it to the
- * cache using the set() method. The third argument of set() can be used to
- * control the lifetime of your cache item.
- *
- * Example:
- * @code
- * $cid = 'mymodule_example:' . \Drupal::languageManager()->getCurrentLanguage()->getId();
- *
- * $data = NULL;
- * if ($cache = \Drupal::cache()->get($cid)) {
- * $data = $cache->data;
- * }
- * else {
- * $data = my_module_complicated_calculation();
- * \Drupal::cache()->set($cid, $data);
- * }
- * @endcode
- *
- * Note the use of $data and $cache->data in the above example. Calls to
- * \Drupal::cache()->get() return a record that contains the information stored
- * by \Drupal::cache()->set() in the data property as well as additional meta
- * information about the cached data. In order to make use of the cached data
- * you can access it via $cache->data.
- *
- * @section bins Cache bins
- *
- * Cache storage is separated into "bins", each containing various cache items.
- * Each bin can be configured separately; see @ref configuration.
- *
- * When you request a cache object, you can specify the bin name in your call to
- * \Drupal::cache(). Alternatively, you can request a bin by getting service
- * "cache.nameofbin" from the container. The default bin is called "default", with
- * service name "cache.default", it is used to store common and frequently used
- * caches.
- *
- * Other common cache bins are the following:
- * - bootstrap: Data needed from the beginning to the end of most requests,
- * that has a very strict limit on variations and is invalidated rarely.
- * - render: Contains cached HTML strings like cached pages and blocks, can
- * grow to large size.
- * - data: Contains data that can vary by path or similar context.
- * - discovery: Contains cached discovery data for things such as plugins,
- * views_data, or YAML discovered data such as library info.
- *
- * A module can define a cache bin by defining a service in its
- * modulename.services.yml file as follows (substituting the desired name for
- * "nameofbin"):
- * @code
- * cache.nameofbin:
- * class: Drupal\Core\Cache\CacheBackendInterface
- * tags:
- * - { name: cache.bin }
- * factory: cache_factory:get
- * arguments: [nameofbin]
- * @endcode
- * See the @link container Services topic @endlink for more on defining
- * services.
- *
- * @section delete Deletion
- *
- * There are two ways to remove an item from the cache:
- * - Deletion (using delete(), deleteMultiple() or deleteAll()) permanently
- * removes the item from the cache.
- * - Invalidation (using invalidate(), invalidateMultiple() or invalidateAll())
- * is a "soft" delete that only marks items as "invalid", meaning "not fresh"
- * or "not fresh enough". Invalid items are not usually returned from the
- * cache, so in most ways they behave as if they have been deleted. However,
- * it is possible to retrieve invalid items, if they have not yet been
- * permanently removed by the garbage collector, by passing TRUE as the second
- * argument for get($cid, $allow_invalid).
- *
- * Use deletion if a cache item is no longer useful; for instance, if the item
- * contains references to data that has been deleted. Use invalidation if the
- * cached item may still be useful to some callers until it has been updated
- * with fresh data. The fact that it was fresh a short while ago may often be
- * sufficient.
- *
- * Invalidation is particularly useful to protect against stampedes. Rather than
- * having multiple concurrent requests updating the same cache item when it
- * expires or is deleted, there can be one request updating the cache, while the
- * other requests can proceed using the stale value. As soon as the cache item
- * has been updated, all future requests will use the updated value.
- *
- * @section tags Cache Tags
- *
- * The fourth argument of the set() method can be used to specify cache tags,
- * which are used to identify which data is included in each cache item. A cache
- * item can have multiple cache tags (an array of cache tags), and each cache
- * tag is a string. The convention is to generate cache tags of the form
- * [prefix]:[suffix]. Usually, you'll want to associate the cache tags of
- * entities, or entity listings. You won't have to manually construct cache tags
- * for them — just get their cache tags via
- * \Drupal\Core\Cache\CacheableDependencyInterface::getCacheTags() and
- * \Drupal\Core\Entity\EntityTypeInterface::getListCacheTags().
- * Data that has been tagged can be invalidated as a group: no matter the Cache
- * ID (cid) of the cache item, no matter in which cache bin a cache item lives;
- * as long as it is tagged with a certain cache tag, it will be invalidated.
- *
- * Because of that, cache tags are a solution to the cache invalidation problem:
- * - For caching to be effective, each cache item must only be invalidated when
- * absolutely necessary. (i.e. maximizing the cache hit ratio.)
- * - For caching to be correct, each cache item that depends on a certain thing
- * must be invalidated whenever that certain thing is modified.
- *
- * A typical scenario: a user has modified a node that appears in two views,
- * three blocks and on twelve pages. Without cache tags, we couldn't possibly
- * know which cache items to invalidate, so we'd have to invalidate everything:
- * we had to sacrifice effectiveness to achieve correctness. With cache tags, we
- * can have both.
- *
- * Example:
- * @code
- * // A cache item with nodes, users, and some custom module data.
- * $tags = array(
- * 'my_custom_tag',
- * 'node:1',
- * 'node:3',
- * 'user:7',
- * );
- * \Drupal::cache()->set($cid, $data, CacheBackendInterface::CACHE_PERMANENT, $tags);
- *
- * // Invalidate all cache items with certain tags.
- * \Drupal\Core\Cache\Cache::invalidateTags(array('user:1'));
- * @endcode
- *
- * Drupal is a content management system, so naturally you want changes to your
- * content to be reflected everywhere, immediately. That's why we made sure that
- * every entity type in Drupal 8 automatically has support for cache tags: when
- * you save an entity, you can be sure that the cache items that have the
- * corresponding cache tags will be invalidated.
- * This also is the case when you define your own entity types: you'll get the
- * exact same cache tag invalidation as any of the built-in entity types, with
- * the ability to override any of the default behavior if needed.
- * See \Drupal\Core\Cache\CacheableDependencyInterface::getCacheTags(),
- * \Drupal\Core\Entity\EntityTypeInterface::getListCacheTags(),
- * \Drupal\Core\Entity\Entity::invalidateTagsOnSave() and
- * \Drupal\Core\Entity\Entity::invalidateTagsOnDelete().
- *
- * @section context Cache contexts
- *
- * Some computed data depends on contextual data, such as the user roles of the
- * logged-in user who is viewing a page, the language the page is being rendered
- * in, the theme being used, etc. When caching the output of such a calculation,
- * you must cache each variation separately, along with information about which
- * variation of the contextual data was used in the calculation. The next time
- * the computed data is needed, if the context matches that for an existing
- * cached data set, the cached data can be reused; if no context matches, a new
- * data set can be calculated and cached for later use.
- *
- * Cache contexts are services tagged with 'cache.context', whose classes
- * implement \Drupal\Core\Cache\Context\CacheContextInterface. See
- * https://www.drupal.org/developing/api/8/cache/contexts for more information
- * on cache contexts, including a list of the contexts that exist in Drupal
- * core, and information on how to define your own contexts. See the
- * @link container Services and the Dependency Injection Container @endlink
- * topic for more information about services.
- *
- * Typically, the cache context is specified as part of the #cache property
- * of a render array; see the Caching section of the
- * @link theme_render Render API overview topic @endlink for details.
- *
- * @section configuration Configuration
- *
- * By default cached data is stored in the database. This can be configured
- * though so that all cached data, or that of an individual cache bin, uses a
- * different cache backend, such as APCu or Memcache, for storage.
- *
- * In a settings.php file, you can override the service used for a particular
- * cache bin. For example, if your service implementation of
- * \Drupal\Core\Cache\CacheBackendInterface was called cache.custom, the
- * following line would make Drupal use it for the 'cache_render' bin:
- * @code
- * $settings['cache']['bins']['render'] = 'cache.custom';
- * @endcode
- *
- * Additionally, you can register your cache implementation to be used by
- * default for all cache bins with:
- * @code
- * $settings['cache']['default'] = 'cache.custom';
- * @endcode
- *
- * For cache bins that are stored in the database, the number of rows is limited
- * to 5000 by default. This can be changed for all database cache bins. For
- * example, to instead limit the number of rows to 50000:
- * @code
- * $settings['database_cache_max_rows']['default'] = 50000;
- * @endcode
- *
- * Or per bin (in this example we allow infinite entries):
- * @code
- * $settings['database_cache_max_rows']['bins']['dynamic_page_cache'] = -1;
- * @endcode
- *
- * For monitoring reasons it might be useful to figure out the amount of data
- * stored in tables. The following SQL snippet can be used for that:
- * @code
- * SELECT table_name AS `Table`, table_rows AS 'Num. of Rows',
- * ROUND(((data_length + index_length) / 1024 / 1024), 2) `Size in MB` FROM
- * information_schema.TABLES WHERE table_schema = '***DATABASE_NAME***' AND
- * table_name LIKE 'cache_%' ORDER BY (data_length + index_length) DESC
- * LIMIT 10;
- * @endcode
- *
- * @see \Drupal\Core\Cache\DatabaseBackend
- *
- * Finally, you can chain multiple cache backends together, see
- * \Drupal\Core\Cache\ChainedFastBackend and \Drupal\Core\Cache\BackendChain.
- *
- * @see https://www.drupal.org/node/1884796
- * @}
- */
- /**
- * @defgroup user_api User accounts, permissions, and roles
- * @{
- * API for user accounts, access checking, roles, and permissions.
- *
- * @section sec_overview Overview and terminology
- * Drupal's permission system is based on the concepts of accounts, roles,
- * and permissions.
- *
- * Users (site visitors) have accounts, which include a user name, an email
- * address, a password (or some other means of authentication), and possibly
- * other fields (if defined on the site). Anonymous users have an implicit
- * account that does not have a real user name or any account information.
- *
- * Each user account is assigned one or more roles. The anonymous user account
- * automatically has the anonymous user role; real user accounts
- * automatically have the authenticated user role, plus any roles defined on
- * the site that they have been assigned.
- *
- * Each role, including the special anonymous and authenticated user roles, is
- * granted one or more named permissions, which allow them to perform certain
- * tasks or view certain content on the site. It is possible to designate a
- * role to be the "administrator" role; if this is set up, this role is
- * automatically granted all available permissions whenever a module is
- * enabled that defines permissions.
- *
- * All code in Drupal that allows users to perform tasks or view content must
- * check that the current user has the correct permission before allowing the
- * action. In the standard case, access checking consists of answering the
- * question "Does the current user have permission 'foo'?", and allowing or
- * denying access based on the answer. Note that access checking should nearly
- * always be done at the permission level, not by checking for a particular role
- * or user ID, so that site administrators can set up user accounts and roles
- * appropriately for their particular sites.
- *
- * @section sec_define Defining permissions
- * Modules define permissions via a $module.permissions.yml file. See
- * \Drupal\user\PermissionHandler for documentation of permissions.yml files.
- *
- * @section sec_access Access permission checking
- * Depending on the situation, there are several methods for ensuring that
- * access checks are done properly in Drupal:
- * - Routes: When you register a route, include a 'requirements' section that
- * either gives the machine name of the permission that is needed to visit the
- * URL of the route, or tells Drupal to use an access check method or service
- * to check access. See the @link menu Routing topic @endlink for more
- * information.
- * - Entities: Access for various entity operations is designated either with
- * simple permissions or access control handler classes in the entity
- * annotation. See the @link entity_api Entity API topic @endlink for more
- * information.
- * - Other code: There is a 'current_user' service, which can be injected into
- * classes to provide access to the current user account (see the
- * @link container Services and Dependency Injection topic @endlink for more
- * information on dependency injection). In code that cannot use dependency
- * injection, you can access this service and retrieve the current user
- * account object by calling \Drupal::currentUser(). Once you have a user
- * object for the current user (implementing \Drupal\user\UserInterface), you
- * can call inherited method
- * \Drupal\Core\Session\AccountInterface::hasPermission() to check
- * permissions, or pass this object into other functions/methods.
- * - Forms: Each element of a form array can have a Boolean '#access' property,
- * which determines whether that element is visible and/or usable. This is a
- * common need in forms, so the current user service (described above) is
- * injected into the form base class as method
- * \Drupal\Core\Form\FormBase::currentUser().
- *
- * @section sec_entities User and role objects
- * User objects in Drupal are entity items, implementing
- * \Drupal\user\UserInterface. Role objects in Drupal are also entity items,
- * implementing \Drupal\user\RoleInterface. See the
- * @link entity_api Entity API topic @endlink for more information about
- * entities in general (including how to load, create, modify, and query them).
- *
- * Roles often need to be manipulated in automated test code, such as to add
- * permissions to them. Here's an example:
- * @code
- * $role = \Drupal\user\Entity\Role::load('authenticated');
- * $role->grantPermission('access comments');
- * $role->save();
- * @endcode
- *
- * Other important interfaces:
- * - \Drupal\Core\Session\AccountInterface: The part of UserInterface that
- * deals with access checking. In writing code that checks access, your
- * method parameters should use this interface, not UserInterface.
- * - \Drupal\Core\Session\AccountProxyInterface: The interface for the
- * current_user service (described above).
- * @}
- */
- /**
- * @defgroup container Services and Dependency Injection Container
- * @{
- * Overview of the Dependency Injection Container and Services.
- *
- * @section sec_overview Overview of container, injection, and services
- * The Services and Dependency Injection Container concepts have been adopted by
- * Drupal from the @link http://symfony.com/ Symfony framework. @endlink A
- * "service" (such as accessing the database, sending email, or translating user
- * interface text) is defined (given a name and an interface or at least a
- * class that defines the methods that may be called), and a default class is
- * designated to provide the service. These two steps must be done together, and
- * can be done by Drupal Core or a module. Other modules can then define
- * alternative classes to provide the same services, overriding the default
- * classes. Classes and functions that need to use the service should always
- * instantiate the class via the dependency injection container (also known
- * simply as the "container"), rather than instantiating a particular service
- * provider class directly, so that they get the correct class (default or
- * overridden).
- *
- * See https://www.drupal.org/node/2133171 for more detailed information on
- * services and the dependency injection container.
- *
- * @section sec_discover Discovering existing services
- * Drupal core defines many core services in the core.services.yml file (in the
- * top-level core directory). Some Drupal Core modules and contributed modules
- * also define services in modulename.services.yml files. API reference sites
- * (such as https://api.drupal.org) generate lists of all existing services from
- * these files. Look for the Services link in the API Navigation block.
- * Alternatively you can look through the individual files manually.
- *
- * A typical service definition in a *.services.yml file looks like this:
- * @code
- * path_alias.manager:
- * class: Drupal\path_alias\AliasManager
- * arguments: ['@path_alias.repository', '@path_alias.whitelist', '@language_manager']
- * @endcode
- * Some services use other services as factories; a typical service definition
- * is:
- * @code
- * cache.entity:
- * class: Drupal\Core\Cache\CacheBackendInterface
- * tags:
- * - { name: cache.bin }
- * factory: cache_factory:get
- * arguments: [entity]
- * @endcode
- *
- * The first line of a service definition gives the unique machine name of the
- * service. This is often prefixed by the module name if provided by a module;
- * however, by convention some service names are prefixed by a group name
- * instead, such as cache.* for cache bins and plugin.manager.* for plugin
- * managers.
- *
- * The class line either gives the default class that provides the service, or
- * if the service uses a factory class, the interface for the service. If the
- * class depends on other services, the arguments line lists the machine
- * names of the dependencies (preceded by '@'); objects for each of these
- * services are instantiated from the container and passed to the class
- * constructor when the service class is instantiated. Other arguments can also
- * be passed in; see the section at https://www.drupal.org/node/2133171 for more
- * detailed information.
- *
- * Services using factories can be defined as shown in the above example, if the
- * factory is itself a service. The factory can also be a class; details of how
- * to use service factories can be found in the section at
- * https://www.drupal.org/node/2133171.
- *
- * @section sec_container Accessing a service through the container
- * As noted above, if you need to use a service in your code, you should always
- * instantiate the service class via a call to the container, using the machine
- * name of the service, so that the default class can be overridden. There are
- * several ways to make sure this happens:
- * - For service-providing classes, see other sections of this documentation
- * describing how to pass services as arguments to the constructor.
- * - Plugin classes, controllers, and similar classes have create() or
- * createInstance() methods that are used to create an instance of the class.
- * These methods come from different interfaces, and have different
- * arguments, but they all include an argument $container of type
- * \Symfony\Component\DependencyInjection\ContainerInterface.
- * If you are defining one of these classes, in the create() or
- * createInstance() method, call $container->get('myservice.name') to
- * instantiate a service. The results of these calls are generally passed to
- * the class constructor and saved as member variables in the class.
- * - For functions and class methods that do not have access to either of
- * the above methods of dependency injection, you can use service location to
- * access services, via a call to the global \Drupal class. This class has
- * special methods for accessing commonly-used services, or you can call a
- * generic method to access any service. Examples:
- * @code
- * // Retrieve the entity.manager service object (special method exists).
- * $manager = \Drupal::entityManager();
- * // Retrieve the service object for machine name 'foo.bar'.
- * $foobar = \Drupal::service('foo.bar');
- * @endcode
- *
- * As a note, you should always use dependency injection (via service arguments
- * or create()/createInstance() methods) if possible to instantiate services,
- * rather than service location (via the \Drupal class), because:
- * - Dependency injection facilitates writing unit tests, since the container
- * argument can be mocked and the create() method can be bypassed by using
- * the class constructor. If you use the \Drupal class, unit tests are much
- * harder to write and your code has more dependencies.
- * - Having the service interfaces on the class constructor and member variables
- * is useful for IDE auto-complete and self-documentation.
- *
- * @section sec_define Defining a service
- * If your module needs to define a new service, here are the steps:
- * - Choose a unique machine name for your service. Typically, this should
- * start with your module name. Example: mymodule.myservice.
- * - Create a PHP interface to define what your service does.
- * - Create a default class implementing your interface that provides your
- * service. If your class needs to use existing services (such as database
- * access), be sure to make these services arguments to your class
- * constructor, and save them in member variables. Also, if the needed
- * services are provided by other modules and not Drupal Core, you'll want
- * these modules to be dependencies of your module.
- * - Add an entry to a modulename.services.yml file for the service. See
- * @ref sec_discover above, or existing *.services.yml files in Core, for the
- * syntax; it will start with your machine name, refer to your default class,
- * and list the services that need to be passed into your constructor.
- *
- * Services can also be defined dynamically, as in the
- * \Drupal\Core\CoreServiceProvider class, but this is less common for modules.
- *
- * @section sec_tags Service tags
- * Some services have tags, which are defined in the service definition. See
- * @link service_tag Service Tags @endlink for usage.
- *
- * @section sec_injection Overriding the default service class
- * Modules can override the default classes used for services. Here are the
- * steps:
- * - Define a class in the top-level namespace for your module
- * (Drupal\my_module), whose name is the camel-case version of your module's
- * machine name followed by "ServiceProvider" (for example, if your module
- * machine name is my_module, the class must be named
- * MyModuleServiceProvider).
- * - The class needs to implement
- * \Drupal\Core\DependencyInjection\ServiceModifierInterface, which is
- * typically done by extending
- * \Drupal\Core\DependencyInjection\ServiceProviderBase.
- * - The class needs to contain one method: alter(). This method does the
- * actual work of telling Drupal to use your class instead of the default.
- * Here's an example:
- * @code
- * public function alter(ContainerBuilder $container) {
- * // Override the language_manager class with a new class.
- * $definition = $container->getDefinition('language_manager');
- * $definition->setClass('Drupal\my_module\MyLanguageManager');
- * }
- * @endcode
- * Note that $container here is an instance of
- * \Drupal\Core\DependencyInjection\ContainerBuilder.
- *
- * @see https://www.drupal.org/node/2133171
- * @see core.services.yml
- * @see \Drupal
- * @see \Symfony\Component\DependencyInjection\ContainerInterface
- * @see plugin_api
- * @see menu
- * @}
- */
- /**
- * @defgroup listing_page_service Page header for Services page
- * @{
- * Introduction to services
- *
- * A "service" (such as accessing the database, sending email, or translating
- * user interface text) can be defined by a module or Drupal core. Defining a
- * service means giving it a name and designating a default class to provide the
- * service; ideally, there should also be an interface that defines the methods
- * that may be called. Services are collected into the Dependency Injection
- * Container, and can be overridden to use different classes or different
- * instantiation by modules. See the
- * @link container Services and Dependency Injection Container topic @endlink
- * for details.
- *
- * Some services have tags, which are defined in the service definition. Tags
- * are used to define a group of related services, or to specify some aspect of
- * how the service behaves. See the
- * @link service_tag Service Tags topic @endlink for more information.
- *
- * @see container
- * @see service_tag
- *
- * @}
- */
- /**
- * @defgroup typed_data Typed Data API
- * @{
- * API for describing data based on a set of available data types.
- *
- * PHP has data types, such as int, string, float, array, etc., and it is an
- * object-oriented language that lets you define classes and interfaces.
- * However, in some cases, it is useful to be able to define an abstract
- * type (as in an interface, free of implementation details), that still has
- * properties (which an interface cannot) as well as meta-data. The Typed Data
- * API provides this abstraction.
- *
- * @section sec_overview Overview
- * Each data type in the Typed Data API is a plugin class (annotation class
- * example: \Drupal\Core\TypedData\Annotation\DataType); these plugins are
- * managed by the typed_data_manager service (by default
- * \Drupal\Core\TypedData\TypedDataManager). Each data object encapsulates a
- * single piece of data, provides access to the metadata, and provides
- * validation capability. Also, the typed data plugins have a shorthand
- * for easily accessing data values, described in @ref sec_tree.
- *
- * The metadata of a data object is defined by an object based on a class called
- * the definition class (see \Drupal\Core\TypedData\DataDefinitionInterface).
- * The class used can vary by data type and can be specified in the data type's
- * plugin definition, while the default is set in the $definition_class property
- * of the annotation class. The default class is
- * \Drupal\Core\TypedData\DataDefinition. For data types provided by a plugin
- * deriver, the plugin deriver can set the definition_class property too.
- * The metadata object provides information about the data, such as the data
- * type, whether it is translatable, the names of its properties (for complex
- * types), and who can access it.
- *
- * See https://www.drupal.org/node/1794140 for more information about the Typed
- * Data API.
- *
- * @section sec_varieties Varieties of typed data
- * There are three kinds of typed data: primitive, complex, and list.
- *
- * @subsection sub_primitive Primitive data types
- * Primitive data types wrap PHP data types and also serve as building blocks
- * for complex and list typed data. Each primitive data type has an interface
- * that extends \Drupal\Core\TypedData\PrimitiveInterface, with getValue()
- * and setValue() methods for accessing the data value, and a default plugin
- * implementation. Here's a list:
- * - \Drupal\Core\TypedData\Type\IntegerInterface: Plugin ID integer,
- * corresponds to PHP type int.
- * - \Drupal\Core\TypedData\Type\StringInterface: Plugin ID string,
- * corresponds to PHP type string.
- * - \Drupal\Core\TypedData\Type\FloatInterface: Plugin ID float,
- * corresponds to PHP type float.
- * - \Drupal\Core\TypedData\Type\BooleanInterface: Plugin ID bool,
- * corresponds to PHP type bool.
- * - \Drupal\Core\TypedData\Type\BinaryInterface: Plugin ID binary,
- * corresponds to a PHP file resource.
- * - \Drupal\Core\TypedData\Type\UriInterface: Plugin ID uri.
- *
- * @subsection sec_complex Complex data
- * Complex data types, with interface
- * \Drupal\Core\TypedData\ComplexDataInterface, represent data with named
- * properties; the properties can be accessed with get() and set() methods.
- * The value of each property is itself a typed data object, which can be
- * primitive, complex, or list data.
- *
- * The base type for most complex data is the
- * \Drupal\Core\TypedData\Plugin\DataType\Map class, which represents an
- * associative array. Map provides its own definition class in the annotation,
- * \Drupal\Core\TypedData\MapDataDefinition, and most complex data classes
- * extend this class. The getValue() and setValue() methods on the Map class
- * enforce the data definition and its property structure.
- *
- * The Drupal Field API uses complex typed data for its field items, with
- * definition class \Drupal\Core\Field\TypedData\FieldItemDataDefinition.
- *
- * @section sec_list Lists
- * List data types, with interface \Drupal\Core\TypedData\ListInterface,
- * represent data that is an ordered list of typed data, all of the same type.
- * More precisely, the plugins in the list must have the same base plugin ID;
- * however, some types (for example field items and entities) are provided by
- * plugin derivatives and the sub IDs can be different.
- *
- * @section sec_tree Tree handling
- * Typed data allows you to use shorthand to get data values nested in the
- * implicit tree structure of the data. For example, to get the value from
- * an entity field item, the Entity Field API allows you to call:
- * @code
- * $value = $entity->fieldName->propertyName;
- * @endcode
- * T…
Large files files are truncated, but you can click here to view the full file