Skip to content
Snippets Groups Projects
core.api.php 122 KiB
Newer Older
 * 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
 * This is really shorthand for:
 * @code
 * $field_item_list = $entity->get('fieldName');
 * $field_item = $field_item_list->get(0);
 * $property = $field_item->get('propertyName');
 * $value = $property->getValue();
 * @endcode
 * Some notes:
 * - $property, $field_item, and $field_item_list are all typed data objects,
 *   while $value is a raw PHP value.
 * - You can call $property->getParent() to get $field_item,
 *   $field_item->getParent() to get $field_item_list, or
 *   $field_item_list->getParent() to get $typed_entity ($entity wrapped in a
 *   typed data object). $typed_entity->getParent() is NULL.
 * - For all of these ->getRoot() returns $typed_entity.
 * - The langcode property is on $field_item_list, but you can access it
 *   on $property as well, so that all items will report the same langcode.
 * - When the value of $property is changed by calling $property->setValue(),
 *   $property->onChange() will fire, which in turn calls the parent object's
 *   onChange() method and so on. This allows parent objects to react upon
 *   changes of contained properties or list items.
 *
 * @section sec_defining Defining data types
 * To define a new data type:
 * - Create a class that implements one of the Typed Data interfaces.
 *   Typically, you will want to extend one of the classes listed in the
 * - Make your class into a DataType plugin. To do that, put it in namespace
 *   \Drupal\yourmodule\Plugin\DataType (where "yourmodule" is your module's
 *   short name), and add annotation of type
 *   \Drupal\Core\TypedData\Annotation\DataType to the documentation header.
 *   See the @link plugin_api Plugin API topic @endlink and the
 *   @link annotation Annotations topic @endlink for more information.
 *
 * The data types of the Typed Data API can be used in several ways, once they
 * have been defined:
 * - In the Field API, data types can be used as the class in the property
 *   definition of the field. See the @link field Field API topic @endlink for
 *   more information.
 * - In configuration schema files, you can use the unique ID ('id' annotation)
 *   from any DataType plugin class as the 'type' value for an entry. See the
 *   @link config_api Configuration API topic @endlink for more information.
 * - If you need to create a typed data object in code, first get the
 *   typed_data_manager service from the container or by calling
 *   \Drupal::typedDataManager(). Then pass the plugin ID to
 *   $manager::createDataDefinition() to create an appropriate data definition
 *   object. Then pass the data definition object and the value of the data to
 *   $manager::create() to create a typed data object.
 *
 * @see plugin_api
 * @see container
 * Overview of PHPUnit and Nightwatch automated tests.
 * The Drupal project has embraced a philosophy of using automated tests,
 * consisting of both unit tests (which test the functionality of classes at a
 * low level) and functional tests (which test the functionality of Drupal
 * systems at a higher level, usually involving web output). The goal is to
 * have test coverage for all or most of the components and features, and to
 * run the automated tests before any code is changed or added, to make sure
 * it doesn't break any existing functionality (regression testing).
 *
 * In order to implement this philosophy, developers need to do the following:
 * - When making a patch to fix a bug, make sure that the bug fix patch includes
 *   a test that fails without the code change and passes with the code change.
 *   This helps reviewers understand what the bug is, demonstrates that the code
 *   actually fixes the bug, and ensures the bug will not reappear due to later
 *   code changes.
 * - When making a patch to implement a new feature, include new unit and/or
 *   functional tests in the patch. This serves to both demonstrate that the
 *   code actually works, and ensure that later changes do not break the new
 *   functionality.
 *
 * @section write_test Writing tests
 * All PHP-based tests for Drupal core are written using the industry-standard
 * PHPUnit framework, with Drupal extensions. There are several categories of
 * tests; each has its own purpose, base class, namespace, and directory:
 * - Unit tests:
 *   - Purpose: Test functionality of a class if the Drupal environment
 *     (database, settings, etc.) and web browser are not needed for the test,
 *     or if the Drupal environment can be replaced by a "mock" object.
 *   - Base class: \Drupal\Tests\UnitTestCase
 *   - Namespace: \Drupal\Tests\yourmodule\Unit (or a subdirectory)
 *   - Directory location: yourmodule/tests/src/Unit (or a subdirectory)
 * - Kernel tests:
 *   - Purpose: Test functionality of a class if the full Drupal environment
 *     and web browser are not needed for the test, but the functionality has
 *     significant Drupal dependencies that cannot easily be mocked. Kernel
 *     tests can access services, the database, and a minimal mocked file
 *     system, and they use an in-memory pseudo-installation. However, modules
 *     are only installed to the point of having services and hooks, unless you
 *     install them explicitly.
 *   - Base class: \Drupal\KernelTests\KernelTestBase
 *   - Namespace: \Drupal\Tests\yourmodule\Kernel (or a subdirectory)
 *   - Directory location: yourmodule/tests/src/Kernel (or a subdirectory)
 * - Browser tests:
 *   - Purpose: Test functionality with the full Drupal environment and an
 *     internal simulated web browser, if JavaScript is not needed.
 *   - Base class: \Drupal\Tests\BrowserTestBase
 *   - Namespace: \Drupal\Tests\yourmodule\Functional (or a subdirectory)
 *   - Directory location: yourmodule/tests/src/Functional (or a subdirectory)
 * - Browser tests with JavaScript:
 *   - Purpose: Test functionality with the full Drupal environment and an
 *     internal web browser that includes JavaScript execution.
 *   - Base class: \Drupal\FunctionalJavascriptTests\WebDriverTestBase
 *   - Namespace: \Drupal\Tests\yourmodule\FunctionalJavascript (or a
 *     subdirectory)
 *   - Directory location: yourmodule/tests/src/FunctionalJavascript (or a
 *     subdirectory)
 * - Build tests:
 *   - Purpose: Test building processes and their outcomes, such as whether a
 *     live update process actually works, or whether a Composer project
 *     template actually builds a working site. Provides a temporary build
 *     workspace and a PHP-native HTTP server to send requests to the site
 *     you've built.
 *   - Base class: \Drupal\BuildTests\Framework\BuildTestBase
 *   - Namespace: \Drupal\Tests\yourmodule\Build (or a
 *     subdirectory)
 *   - Directory location: yourmodule/tests/src/Build (or a
 *     subdirectory)
 *
 * Some notes about writing PHP test classes:
 * - The class needs a phpDoc comment block with a description and
 *   @group annotation, which gives information about the test.
 * - For unit tests, this comment block should also have @coversDefaultClass
 *   annotation.
 * - When writing tests, put the test code into public methods, each covering a
 *   logical subset of the functionality that is being tested.
 * - The test methods must have names starting with 'test'. For unit tests, the
 *   test methods need to have a phpDoc block with @covers annotation telling
 *   which class method they are testing.
 * - In some cases, you may need to write a test module to support your test;
 *   put such modules under the yourmodule/tests/modules directory.
 *
 * Besides the PHPUnit tests described above, Drupal Core also includes a few
 * JavaScript-only tests, which use the Nightwatch.js framework to test
 * JavaScript code using only JavaScript. These are located in
 * core/tests/Drupal/Nightwatch.
 *
 * - core/tests/README.md for instructions on running tests
 * - https://www.drupal.org/phpunit for full documentation on how to write
 *   and run PHPUnit tests for Drupal.
 * - http://phpunit.de for general information on the PHPUnit framework.
 * - @link oo_conventions Object-oriented programming topic @endlink for more
 *   on PSR-4, namespaces, and where to place classes.
 * - http://nightwatchjs.org/ for information about Nightwatch testing for
 *   JavaScript
/**
 * @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://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.
 *
 * 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 data types. They also verify that
 * objects have been properly configured and set up by the service container.
 * They supplement unit tests by checking scenarios that do not have unit tests
 * written for them.
 *
 * There are two php settings which affect runtime assertions. The first,
 * assert.exception, should always be set to 1. The second is zend.assertions.
 * Set this to -1 in production and 1 in development.
 *
 * See https://www.drupal.org/node/2492225 for more information on runtime
 * assertions.
 * @}
 */

 * Drupal has several distinct types of information, each with its own methods
 * for storage and retrieval:
 * - Content: Information meant to be displayed on your site: articles, basic
 *   pages, images, files, custom blocks, etc. Content is stored and accessed
 *   using @link entity_api Entities @endlink.
 * - Session: Information about individual users' interactions with the site,
 *   such as whether they are logged in. This is really "state" information, but
 *   it is not stored the same way so it's a separate type here. Session data is
 *   accessed via \Symfony\Component\HttpFoundation\Request::getSession(), which
 *   returns an instance of
 *   \Symfony\Component\HttpFoundation\Session\SessionInterface.
 *   See the @link session Sessions topic @endlink for more information.
 * - State: Information of a temporary nature, generally machine-generated and
 *   not human-edited, about the current state of your site. Examples: the time
 *   when Cron was last run, whether node access permissions need rebuilding,
 *   etc. See @link state_api the State API topic @endlink for more information.
 * - Configuration: Information about your site that is generally (or at least
 *   can be) human-edited, but is not Content, and is meant to be relatively
 *   permanent. Examples: the name of your site, the content types and views
 *   you have defined, etc. See
 *   @link config_api the Configuration API topic @endlink for more information.
 *
 * @defgroup extending Extending and altering Drupal
 * Overview of extensions and alteration methods for Drupal.
 * @section sec_types Types of extensions
 * Drupal's core behavior can be extended and altered via these three basic
 * - Themes: Themes alter the appearance of Drupal sites. They can include
 *   template files, which alter the HTML markup and other raw output of the
 *   site; CSS files, which alter the styling applied to the HTML; and
 *   JavaScript, Flash, images, and other files. For more information, see the
 *   @link theme_render Theme system and render API topic @endlink and
 *   https://www.drupal.org/docs/8/theming
 * - Modules: Modules add to or alter the behavior and functionality of Drupal,
 *   by using one or more of the methods listed below. For more information
 *   about creating modules, see https://www.drupal.org/developing/modules/8
 * - Installation profiles: Installation profiles can be used to
 *   create distributions, which are complete specific-purpose packages of
 *   Drupal including additional modules, themes, and data. For more
 *   information, see https://www.drupal.org/developing/distributions.
 * @section sec_alter Alteration methods for modules
 * Here is a list of the ways that modules can alter or extend Drupal's core
 * behavior, or the behavior of other modules:
 * - Hooks: Specially-named functions that a module defines, which are
 *   discovered and called at specific times, usually to alter behavior or data.
 *   See the @link hooks Hooks topic @endlink for more information.
 * - Plugins: Classes that a module defines, which are discovered and
 *   instantiated at specific times to add functionality. See the
 *   @link plugin_api Plugin API topic @endlink for more information.
 * - Entities: Special plugins that define entity types for storing new types
 *   of content or configuration in Drupal. See the
 *   @link entity_api Entity API topic @endlink for more information.
 * - Services: Classes that perform basic operations within Drupal, such as
 *   accessing the database and sending email. See the
 *   @link container Dependency Injection Container and Services topic @endlink
 *   for more information.
 * - Routing: Providing or altering "routes", which are URLs that Drupal
 *   responds to, or altering routing behavior with event listener classes.
 *   See the @link menu Routing and menu topic @endlink for more information.
 * - Events: Modules can register as event subscribers; when an event is
 *   dispatched, a method is called on each registered subscriber, allowing each
 *   one to react. See the @link events Events topic @endlink for more
 *   information.
 *
 * @section sec_sample *.info.yml files
 * Extensions must each be located in a directory whose name matches the short
 * name (or machine name) of the extension, and this directory must contain a
 * file named machine_name.info.yml (where machine_name is the machine name of
 * the extension). See \Drupal\Core\Extension\InfoParserInterface::parse() for
 * documentation of the format of .info.yml files.
 * @section sec_overview Overview and terminology
 * The basic idea of plugins is to allow a particular module or subsystem of
 * Drupal to provide functionality in an extensible, object-oriented way. The
 * controlling module or subsystem defines the basic framework (interface) for
 * the functionality, and other modules can create plugins (implementing the
 * interface) with particular behaviors. The controlling module instantiates
 * existing plugins as needed, and calls methods to invoke their functionality.
 * Examples of functionality in Drupal Core that use plugins include: the block
 * system (block types are plugins), the entity/field system (entity types,
 * field types, field formatters, and field widgets are plugins), the image
 * manipulation system (image effects and image toolkits are plugins), and the
 * search system (search page types are plugins).
 *
 * Plugins are grouped into plugin types, each generally defined by an
 * interface. Each plugin type is managed by a plugin manager service, which
 * uses a plugin discovery method to discover provided plugins of that type and
 * instantiate them using a plugin factory.
 *
 * Some plugin types make use of the following concepts or components:
 * - Plugin derivatives: Allows a single plugin class to present itself as
 *   multiple plugins. Example: the Menu module provides a block for each
 *   defined menu via a block plugin derivative.
 * - Plugin mapping: Allows a plugin class to map a configuration string to an
 *   instance, and have the plugin automatically instantiated without writing
 *   additional code.
 * - Plugin collections: Provide a way to lazily instantiate a set of plugin
 *   instances from a single plugin definition.
 *
 * There are several things a module developer may need to do with plugins:
 * - Define a completely new plugin type: see @ref sec_define below.
 * - Create a plugin of an existing plugin type: see @ref sec_create below.
 * - Perform tasks that involve plugins: see @ref sec_use below.
 *
 * See https://www.drupal.org/developing/api/8/plugins for more detailed
 * documentation on the plugin system. There are also topics for a few
 * of the many existing types of plugins:
 * - @link block_api Block API @endlink
 * - @link entity_api Entity API @endlink
 * - @link field Various types of field-related plugins @endlink
 * - @link views_plugins Views plugins @endlink (has links to topics covering
 *   various specific types of Views plugins).
 * - @link search Search page plugins @endlink
 *
 * @section sec_define Defining a new plugin type
 * To define a new plugin type:
 * - Define an interface for the plugin. This describes the common set of
 *   behavior, and the methods you will call on each plugin class that is
 *   instantiated. Usually this interface will extend one or more of the
 *   following interfaces:
 *   - \Drupal\Component\Plugin\PluginInspectionInterface
 *   - \Drupal\Component\Plugin\ConfigurableInterface
 *   - \Drupal\Component\Plugin\DependentPluginInterface
 *   - \Drupal\Component\Plugin\ContextAwarePluginInterface
 *   - \Drupal\Core\Plugin\PluginFormInterface
 *   - \Drupal\Core\Executable\ExecutableInterface
 * - (optional) Create a base class that provides a partial implementation of
 *   the interface, for the convenience of developers wishing to create plugins
 *   of your type. The base class usually extends
 *   \Drupal\Core\Plugin\PluginBase, or one of the base classes that extends
 *   this class.
 * - Choose a method for plugin discovery, and define classes as necessary.
 *   See @ref sub_discovery below.
 * - Create a plugin manager/factory class and service, which will discover and
 *   instantiate plugins. See @ref sub_manager below.
 * - Use the plugin manager to instantiate plugins. Call methods on your plugin
 *   interface to perform the tasks of your plugin type.
 * - (optional) If appropriate, define a plugin collection. See @ref
 *    sub_collection below for more information.
 * @subsection sub_discovery Plugin discovery
 * Plugin discovery is the process your plugin manager uses to discover the
 * individual plugins of your type that have been defined by your module and
 * other modules. Plugin discovery methods are classes that implement
 * \Drupal\Component\Plugin\Discovery\DiscoveryInterface. Most plugin types use
 * one of the following discovery mechanisms:
 * - Annotation: Plugin classes are annotated and placed in a defined namespace
 *   subdirectory. Most Drupal Core plugins use this method of discovery.
 * - Hook: Plugin modules need to implement a hook to tell the manager about
 *   their plugins.
 * - YAML: Plugins are listed in YAML files. Drupal Core uses this method for
 *   discovering local tasks and local actions. This is mainly useful if all
 *   plugins use the same class, so it is kind of like a global derivative.
 * - Static: Plugin classes are registered within the plugin manager class
 *   itself. Static discovery is only useful if modules cannot define new
 *   plugins of this type (if the list of available plugins is static).
 *
 * It is also possible to define your own custom discovery mechanism or mix
 * methods together. And there are many more details, such as annotation
 * decorators, that apply to some of the discovery methods. See
 * https://www.drupal.org/developing/api/8/plugins for more details.
 *
 * The remainder of this documentation will assume Annotation-based discovery,
 * since this is the most common method.
 *
 * @subsection sub_manager Defining a plugin manager class and service
 * To define an annotation-based plugin manager:
 * - Choose a namespace subdirectory for your plugin. For example, search page
 *   plugins go in directory Plugin/Search under the module namespace.
 * - Define an annotation class for your plugin type. This class should extend
 *   \Drupal\Component\Annotation\Plugin, and for most plugin types, it should
 *   contain member variables corresponding to the annotations plugins will
 *   need to provide. All plugins have at least $id: a unique string
 *   identifier.
 * - Define an alter hook for altering the discovered plugin definitions. You
 *   should document the hook in a *.api.php file.
 * - Define a plugin manager class. This class should implement
 *   \Drupal\Component\Plugin\PluginManagerInterface; most plugin managers do
 *   this by extending \Drupal\Core\Plugin\DefaultPluginManager. If you do
 *   extend the default plugin manager, the only method you will probably need
 *   to define is the class constructor, which will need to call the parent
 *   constructor to provide information about the annotation class and plugin
 *   namespace for discovery, set up the alter hook, and possibly set up
 *   caching. See classes that extend DefaultPluginManager for examples.
 * - Define a service for your plugin manager. See the
 *   @link container Services topic for more information. @endlink Your service
 *   definition should look something like this, referencing your manager
 *   class and the parent (default) plugin manager service to inherit
 *   constructor arguments:
 *   @code
 *   plugin.manager.mymodule:
 *     class: Drupal\mymodule\MyPluginManager
 *     parent: default_plugin_manager
 *   @endcode
 * - If your plugin is configurable, you will also need to define the
 *   configuration schema and possibly a configuration entity type. See the
 *   @link config_api Configuration API topic @endlink for more information.
 *
 * @subsection sub_collection Defining a plugin collection
 * Some configurable plugin types allow administrators to create zero or more
 * instances of each plugin, each with its own configuration. For example,
 * a single block plugin can be configured several times, to display in
 * different regions of a theme, with different visibility settings, a
 * different title, or other plugin-specific settings. To make this possible,
 * a plugin type can make use of what's known as a plugin collection.
 *
 * A plugin collection is a class that extends
 * \Drupal\Component\Plugin\LazyPluginCollection or one of its subclasses; there
 * are several examples in Drupal Core. If your plugin type uses a plugin
 * collection, it will usually also have a configuration entity, and the entity
 * class should implement
 * \Drupal\Core\Entity\EntityWithPluginCollectionInterface. Again, there are
 * several examples in Drupal Core; see also the @link config_api Configuration
 * API topic @endlink for more information about configuration entities.
 *
 * @section sec_create Creating a plugin of an existing type
 * Assuming the plugin type uses annotation-based discovery, in order to create
 * a plugin of an existing type, you will be creating a class. This class must:
 * - Implement the plugin interface, so that it has the required methods
 *   defined. Usually, you'll want to extend the plugin base class, if one has
 *   been provided.
 * - Have the right annotation in its documentation header. See the
 *   @link annotation Annotation topic @endlink for more information about
 *   annotation.
 * - Be in the right plugin namespace, in order to be discovered.
 * Often, the easiest way to make sure this happens is to find an existing
 * example of a working plugin class of the desired type, and copy it into your
 * module as a starting point.
 *
 * You can also create a plugin derivative, which allows your plugin class
 * to present itself to the user interface as multiple plugins. To do this,
 * in addition to the plugin class, you'll need to create a separate plugin
 * derivative class implementing
 * \Drupal\Component\Plugin\Derivative\DerivativeInterface. The classes
 * \Drupal\system\Plugin\Block\SystemMenuBlock (plugin class) and
 * \Drupal\system\Plugin\Derivative\SystemMenuBlock (derivative class) are a
 * good example to look at.
 *
 * @section sec_use Performing tasks involving plugins
 * Here are the steps to follow to perform a task that involves plugins:
 * - Locate the machine name of the plugin manager service, and instantiate the
 *   service. See the @link container Services topic @endlink for more
 *   information on how to do this.
 * - On the plugin manager class, use methods like getDefinition(),
 *   getDefinitions(), or other methods specific to particular plugin managers
 *   to retrieve information about either specific plugins or the entire list of
 *   defined plugins.
 * - Call the createInstance() method on the plugin manager to instantiate
 *   individual plugin objects.
 * - Call methods on the plugin objects to perform the desired tasks.
 * @}
 */

/**
 * @defgroup oo_conventions Objected-oriented programming conventions
 * @{
 * PSR-4, namespaces, class naming, and other conventions.
 *
 * A lot of the PHP code in Drupal is object oriented (OO), making use of
 * @link http://php.net/manual/language.oop5.php PHP classes, interfaces, and traits @endlink
 * (which are loosely referred to as "classes" in the rest of this topic). The
 * following conventions and standards apply to this version of Drupal:
 * - Each class must be in its own file.
 * - Classes must be namespaced. If a module defines a class, the namespace
 *   must start with \Drupal\module_name. If it is defined by Drupal Core for
 *   use across many modules, the namespace should be \Drupal\Core or
 *   \Drupal\Component, with the exception of the global class \Drupal. See
 *   https://www.drupal.org/node/1353118 for more about namespaces.
 * - In order for the PSR-4-based class auto-loader to find the class, it must
 *   be located in a directory corresponding to the namespace. For
 *   module-defined classes, if the namespace is \Drupal\module_name\foo\bar,
 *   then the class goes under the main module directory in directory
 *   src/foo/bar. For Drupal-wide classes, if the namespace is
 *   \Drupal\Core\foo\bar, then it goes in directory
 *   core/lib/Drupal/Core/foo/bar. See https://www.drupal.org/node/2156625 for
 *   more information about PSR-4.
 * - Some classes have annotations added to their documentation headers. See
 *   the @link annotation Annotation topic @endlink for more information.
 * - Standard plugin discovery requires particular namespaces and annotation
 *   for most plugin classes. See the
 *   @link plugin_api Plugin API topic @endlink for more information.
 * - There are project-wide coding standards for OO code, including naming:
 *   https://www.drupal.org/node/608152
 * - Documentation standards for classes are covered on:
 *   https://www.drupal.org/coding-standards/docs#classes
/**
 * @defgroup listing_page_class Page header for Classes page
 * @{
 * Introduction to classes
 *
 * A lot of the PHP code in Drupal is object oriented (OO), making use of
 * @link http://php.net/manual/language.oop5.php PHP classes, interfaces, and traits. @endlink
 * See the
 * @link oo_conventions Objected-oriented programming conventions @endlink
 * for more information.
 *
 * @see oo_conventions
 *
 * @}
 */

/**
 * @defgroup listing_page_namespace Page header for Namespaces page
 * @{
 * Introduction to namespaces
 *
 * PHP classes, interfaces, and traits in Drupal are
 * @link http://php.net/manual/language.namespaces.rationale.php namespaced. @endlink
 * See the
 * @link oo_conventions Objected-oriented programming conventions @endlink
 * for more information.
 *
 * @see oo_conventions
 *
 * @}
 */

/**
 * @defgroup best_practices Best practices for developers
 * @{
 * Overview of standards and best practices for developers
 *
 * Ideally, all code that is included in Drupal Core and contributed modules,
 * themes, and distributions will be secure, internationalized, maintainable,
 * and efficient. In order to facilitate this, the Drupal community has
 * developed a set of guidelines and standards for developers to follow. Most of
 * these standards can be found under
 * @link https://www.drupal.org/developing/best-practices Best practices on Drupal.org @endlink
 *
 * Standards and best practices that developers should be aware of include:
 * - Security: https://www.drupal.org/writing-secure-code and the
 *   @link sanitization Sanitization functions topic @endlink
 * - Coding standards: https://www.drupal.org/coding-standards
 *   and https://www.drupal.org/coding-standards/docs
 * - Accessibility: https://www.drupal.org/node/1637990 (modules) and
 *   https://www.drupal.org/node/464472 (themes)
 * - Usability: https://www.drupal.org/ui-standards
 * - Internationalization: @link i18n Internationalization topic @endlink
 * - Automated testing: @link testing Automated tests topic @endlink

/**
 * @defgroup utility Utility classes and functions
 * @{
 * Overview of utility classes and functions for developers.
 *
 * Drupal provides developers with a variety of utility functions that make it
 * easier and more efficient to perform tasks that are either really common,
 * tedious, or difficult. Utility functions help to reduce code duplication and
 * should be used in place of one-off code whenever possible.
 *
 * @see common.inc
 * @see file
 * @see format
 * @see php_wrappers
 * @see sanitization
 * @see transliteration
 * @see validation
 * @}
 */
/**
 * @defgroup hooks Hooks
 * @{
 * Define functions that alter the behavior of Drupal core.
 *
 * One way for modules to alter the core behavior of Drupal (or another module)
 * is to use hooks. Hooks are specially-named functions that a module defines
 * (this is known as "implementing the hook"), which are discovered and called
 * at specific times to alter or add to the base behavior or data (this is
 * known as "invoking the hook"). Each hook has a name (example:
 * hook_batch_alter()), a defined set of parameters, and a defined return value.
 * Your modules can implement hooks that are defined by Drupal core or other
 * modules that they interact with. Your modules can also define their own
 * hooks, in order to let other modules interact with them.
 *
 * To implement a hook:
 * - Locate the documentation for the hook. Hooks are documented in *.api.php
 *   files, by defining functions whose name starts with "hook_" (these
 *   files and their functions are never loaded by Drupal -- they exist solely
 *   for documentation). The function should have a documentation header, as
 *   well as a sample function body. For example, in the core file form.api.php,
 *   you can find hooks such as hook_batch_alter(). Also, if you are viewing
 *   this documentation on an API reference site, the Core hooks will be listed
 *   in this topic.
 * - Copy the function to your module's .module file.
 * - Change the name of the function, substituting your module's short name
 *   (name of the module's directory, and .info.yml file without the extension)
 *   for the "hook" part of the sample function name. For instance, to implement
 *   hook_batch_alter(), you would rename it to my_module_batch_alter().
 * - Edit the documentation for the function (normally, your implementation
 *   should just have one line saying "Implements hook_batch_alter().").
 * - Edit the body of the function, substituting in what you need your module
 *   to do.
 *
 * To define a hook:
 * - Choose a unique name for your hook. It should start with "hook_", followed
 *   by your module's short name.
 * - Provide documentation in a *.api.php file in your module's main
 *   directory. See the "implementing" section above for details of what this
 *   should contain (parameters, return value, and sample function body).
 * - Invoke the hook in your module's code.
 *
 * To invoke a hook, use methods on
 * \Drupal\Core\Extension\ModuleHandlerInterface such as alter(), invoke(),
 * and invokeAll(). You can obtain a module handler by calling
 * \Drupal::moduleHandler(), or getting the 'module_handler' service on an
 * injected container.
 *
 * @see extending
 * @see themeable
 * @see callbacks
 * @see \Drupal\Core\Extension\ModuleHandlerInterface
 * @see \Drupal::moduleHandler()
 *
 * @}
 */

/**
 * @defgroup callbacks Callbacks
 * @{
 * Callback function signatures.
 *
 * Drupal's API sometimes uses callback functions to allow you to define how
 * some type of processing happens. A callback is a function with a defined
 * signature, which you define in a module. Then you pass the function name as
 * a parameter to a Drupal API function or return it as part of a hook
 * implementation return value, and your function is called at an appropriate
 * time. For instance, when setting up batch processing you might need to
 * provide a callback function for each processing step and/or a callback for
 * when processing is finished; you would do that by defining these functions
 * and passing their names into the batch setup function.
 *
 * Callback function signatures, like hook definitions, are described by
 * creating and documenting dummy functions in a *.api.php file; normally, the
 * dummy callback function's name should start with "callback_", and you should
 * document the parameters and return value and provide a sample function body.
 * Then your API documentation can refer to this callback function in its
 * documentation. A user of your API can usually name their callback function
 * anything they want, although a standard name would be to replace "callback_"
 * with the module name.
 *
 * @see hooks
 * @see themeable
 *
 * @}
 */

/**
 * @defgroup form_api Form generation
 * @{
 * Describes how to generate and manipulate forms and process form submissions.
 *
 * Drupal provides a Form API in order to achieve consistency in its form
 * processing and presentation, while simplifying code and reducing the amount
 * of HTML that must be explicitly generated by a module.
 *
 * @section generating_forms Creating forms
 * Forms are defined as classes that implement the
 * \Drupal\Core\Form\FormInterface and are built using the
 * \Drupal\Core\Form\FormBuilder class. Drupal provides a couple of utility
 * classes that can be extended as a starting point for most basic forms, the
 * most commonly used of which is \Drupal\Core\Form\FormBase. FormBuilder
 * handles the low level processing of forms such as rendering the necessary
 * HTML, initial processing of incoming $_POST data, and delegating to your
 * implementation of FormInterface for validation and processing of submitted
 * data.
 *
 * Here is an example of a Form class:
 * @code
 * namespace Drupal\mymodule\Form;
 *
 * use Drupal\Core\Form\FormBase;
 * use Drupal\Core\Form\FormStateInterface;
 *
 * class ExampleForm extends FormBase {
 *   public function getFormId() {
 *     // Unique ID of the form.
 *     return 'example_form';
 *   }
 *
 *   public function buildForm(array $form, FormStateInterface $form_state) {
 *     // Create a $form API array.
 *     $form['phone_number'] = array(
 *       '#type' => 'tel',
 *       '#title' => $this->t('Your phone number'),
 *     );
 *     $form['save'] = array(
 *       '#type' => 'submit',
 *       '#value' => $this->t('Save'),
 *   public function validateForm(array &$form, FormStateInterface $form_state) {
 *   public function submitForm(array &$form, FormStateInterface $form_state) {
 *     // Handle submitted form data.
 *   }
 * }
 * @endcode
 *
 * @section retrieving_forms Retrieving and displaying forms
 * \Drupal::formBuilder()->getForm() should be used to handle retrieving,
 * processing, and displaying a rendered HTML form. Given the ExampleForm
 * defined above,
 * \Drupal::formBuilder()->getForm('Drupal\mymodule\Form\ExampleForm') would
 * return the rendered HTML of the form defined by ExampleForm::buildForm(), or
 * call the validateForm() and submitForm(), methods depending on the current
 * processing state.
 *
 * The argument to \Drupal::formBuilder()->getForm() is the name of a class that
 * implements FormInterface. Any additional arguments passed to the getForm()
 * method will be passed along as additional arguments to the
 * ExampleForm::buildForm() method.
 *
 * For example:
 * @code
 * $extra = '612-123-4567';
 * $form = \Drupal::formBuilder()->getForm('Drupal\mymodule\Form\ExampleForm', $extra);
 * ...
 * public function buildForm(array $form, FormStateInterface $form_state, $extra = NULL)
 *   $form['phone_number'] = array(
 *     '#type' => 'tel',
 *     '#title' => $this->t('Your phone number'),
 *     '#value' => $extra,
 *   );
 *   return $form;
 * }
 * @endcode
 *
 * Alternatively, forms can be built directly via the routing system which will
 * take care of calling \Drupal::formBuilder()->getForm(). The following example
 * demonstrates the use of a routing.yml file to display a form at the given
 * route.
 *
 * @code
 * example.form:
 *   path: '/example-form'
 *   defaults:
 *     _title: 'Example form'
 *     _form: '\Drupal\mymodule\Form\ExampleForm'
 * @endcode
 *
 * The $form argument to form-related functions is a specialized render array
 * containing the elements and properties of the form. For more about render
 * arrays, see the @link theme_render Render API topic. @endlink For more
 * detailed explanations of the Form API workflow, see the
 * @link https://www.drupal.org/node/2117411 Form API documentation section. @endlink
 * In addition, there is a set of Form API tutorials in the
 * @link https://www.drupal.org/project/examples Examples for Developers project. @endlink
 *
 * In the form builder, validation, submission, and other form methods,
 * $form_state is the primary influence on the processing of the form and is
 * passed to most methods, so they can use it to communicate with the form
 * system and each other. $form_state is an object that implements
 * \Drupal\Core\Form\FormStateInterface.
 */

/**
 * @defgroup queue Queue operations
 * @{
 * Queue items to allow later processing.
 *
 * The queue system allows placing items in a queue and processing them later.
 * The system tries to ensure that only one consumer can process an item.
 *
 * Before a queue can be used it needs to be created by
 * Drupal\Core\Queue\QueueInterface::createQueue().
 *
 * Items can be added to the queue by passing an arbitrary data object to
 * Drupal\Core\Queue\QueueInterface::createItem().
 *
 * To process an item, call Drupal\Core\Queue\QueueInterface::claimItem() and
 * specify how long you want to have a lease for working on that item.
 * When finished processing, the item needs to be deleted by calling
 * Drupal\Core\Queue\QueueInterface::deleteItem(). If the consumer dies, the
 * item will be made available again by the Drupal\Core\Queue\QueueInterface
 * implementation once the lease expires. Another consumer will then be able to
 * receive it when calling Drupal\Core\Queue\QueueInterface::claimItem().
 * Due to this, the processing code should be aware that an item might be handed
 * over for processing more than once.
 *
 * The $item object used by the Drupal\Core\Queue\QueueInterface can contain
 * arbitrary metadata depending on the implementation. Systems using the
 * interface should only rely on the data property which will contain the
 * information passed to Drupal\Core\Queue\QueueInterface::createItem().
 * The full queue item returned by Drupal\Core\Queue\QueueInterface::claimItem()
 * needs to be passed to Drupal\Core\Queue\QueueInterface::deleteItem() once
 * processing is completed.
 *
 * There are two kinds of queue backends available: reliable, which preserves
 * the order of messages and guarantees that every item will be executed at
 * least once. The non-reliable kind only does a best effort to preserve order
 * in messages and to execute them at least once but there is a small chance
 * that some items get lost. For example, some distributed back-ends like
 * Amazon SQS will be managing jobs for a large set of producers and consumers
 * where a strict FIFO ordering will likely not be preserved. Another example
 * would be an in-memory queue backend which might lose items if it crashes.
 * However, such a backend would be able to deal with significantly more writes
 * than a reliable queue and for many tasks this is more important. See
 * aggregator_cron() for an example of how to effectively use a non-reliable
 * queue. Another example is doing Twitter statistics -- the small possibility
 * of losing a few items is insignificant next to power of the queue being able
 * to keep up with writes. As described in the processing section, regardless
 * of the queue being reliable or not, the processing code should be aware that
 * an item might be handed over for processing more than once (because the
 * processing code might time out before it finishes).

/**
 * @defgroup annotation Annotations
 * @{
 * Annotations for class discovery and metadata description.
 *
 * The Drupal plugin system has a set of reusable components that developers
 * can use, override, and extend in their modules. Most of the plugins use
 * annotations, which let classes register themselves as plugins and describe
 * their metadata. (Annotations can also be used for other purposes, though
 * at the moment, Drupal only uses them for the plugin system.)
 *
 * To annotate a class as a plugin, add code similar to the following to the
 * end of the documentation block immediately preceding the class declaration:
 * @code
 * * @ContentEntityType(
 * *   id = "comment",
 * *   label = @Translation("Comment"),
 * *   ...
 * *   base_table = "comment"
 * * )
 * @endcode
 *
 * Note that you must use double quotes; single quotes will not work in
 * annotations.
 *
 * Some annotation types, which extend the "@ PluginID" annotation class, have
 * only a single 'id' key in their annotation. For these, it is possible to use
 * a shorthand annotation. For example:
 * @code
 * * @ViewsArea("entity")
 * @endcode
 * in place of
 * @code
 * * @ViewsArea(
 * *   id = "entity"
 * *)
 * @endcode
 *
 * The available annotation classes are listed in this topic, and can be
 * identified when you are looking at the Drupal source code by having
 * "@ Annotation" in their documentation blocks (without the space after @). To
 * find examples of annotation for a particular annotation class, such as
 * EntityType, look for class files that have an @ annotation section using the
 * annotation class.
 *
 * @see plugin_translatable
 * @see plugin_context
 *
 * @}
 */
/**
 * Perform periodic actions.
 *
 * Modules that require some commands to be executed periodically can
 * implement hook_cron(). The engine will then call the hook whenever a cron
 * run happens, as defined by the administrator. Typical tasks managed by
 * hook_cron() are database maintenance, backups, recalculation of settings
 * or parameters, automated mailing, and retrieving remote data.
 *
 * Short-running or non-resource-intensive tasks can be executed directly in
 * the hook_cron() implementation.
 *
 * Long-running tasks and tasks that could time out, such as retrieving remote
 * data, sending email, and intensive file tasks, should use the queue API
 * instead of executing the tasks directly. To do this, first define one or
 * more queues via a \Drupal\Core\Annotation\QueueWorker plugin. Then, add items
 * that need to be processed to the defined queues.
 */
function hook_cron() {
  // Short-running operation example, not using a queue:
  // Delete all expired records since the last cron run.
  $expires = \Drupal::state()->get('mymodule.last_check', 0);
  \Drupal::database()->delete('mymodule_table')
    ->condition('expires', $expires, '>=')
    ->execute();
  \Drupal::state()->set('mymodule.last_check', REQUEST_TIME);

  // Long-running operation example, leveraging a queue:
  // Queue news feeds for updates once their refresh interval has elapsed.
  $queue = \Drupal::queue('aggregator_feeds');
  $ids = \Drupal::entityTypeManager()->getStorage('aggregator_feed')->getFeedIdsToRefresh();
  foreach (Feed::loadMultiple($ids) as $feed) {
    if ($queue->createItem($feed)) {
      // Add timestamp to avoid queueing item more than once.
      $feed->setQueuedTime(REQUEST_TIME);
      $feed->save();
    }
  }
  $ids = \Drupal::entityQuery('aggregator_feed')
    ->condition('queued', REQUEST_TIME - (3600 * 6), '<')
    ->execute();
  if ($ids) {
    $feeds = Feed::loadMultiple($ids);
    foreach ($feeds as $feed) {
      $feed->setQueuedTime(0);
      $feed->save();
    }
  }
}

/**
 * Alter available data types for typed data wrappers.
 *
 * @param array $data_types
 *   An array of data type information.
 *
 * @see hook_data_type_info()
 */
function hook_data_type_info_alter(&$data_types) {
  $data_types['email']['class'] = '\Drupal\mymodule\Type\Email';
}

/**
 * Alter cron queue information before cron runs.
 *
 * Called by \Drupal\Core\Cron to allow modules to alter cron queue settings
 *
 * @param array $queues
 *   An array of cron queue information.
 *
 * @see \Drupal\Core\Queue\QueueWorkerInterface
 * @see \Drupal\Core\Annotation\QueueWorker
 * @see \Drupal\Core\Cron
 */
function hook_queue_info_alter(&$queues) {
  // This site has many feeds so let's spend 90 seconds on each cron run
  // updating feeds instead of the default 60.
  $queues['aggregator_feeds']['cron']['time'] = 90;
}

/**
 * Alter an email message created with MailManagerInterface->mail().
 *
 * Hook hook_mail_alter() allows modification of email messages created and sent
 * with MailManagerInterface->mail(). Usage examples include adding and/or
 * changing message text, message fields, and message headers.
 *
 * Email messages sent using functions other than MailManagerInterface->mail()
 * will not invoke hook_mail_alter(). For example, a contributed module directly
 * calling the MailInterface->mail() or PHP mail() function will not invoke
 * this hook. All core modules use MailManagerInterface->mail() for messaging,
 * it is best practice but not mandatory in contributed modules.
 *
 * @param $message
 *   An array containing the message data. Keys in this array include:
 *     The MailManagerInterface->mail() id of the message. Look at module source
 *     code or MailManagerInterface->mail() for possible id values.
 *     The address or addresses the message will be sent to. The
 *     formatting of this string must comply with RFC 2822.