Newer
Older
Angie Byron
committed
<?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://drupal.org/developing/api.
*
* Here are some topics to help you get started developing with Drupal.
Angie Byron
committed
*
* @section essentials Essential background concepts
*
* - @link oo_conventions Object-oriented conventions used in Drupal @endlink
Angie Byron
committed
* - @link extending Extending and altering Drupal @endlink
* - @link best_practices Security and best practices @endlink
Angie Byron
committed
* - @link info_types Types of information in Drupal @endlink
Angie Byron
committed
*
* @section interface User interface
Angie Byron
committed
*
* - @link menu Routing, page controllers, and menu entries @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
Angie Byron
committed
* - @link config_api Configuration API @endlink
* - @link state_api State API @endlink
Angie Byron
committed
* - @link views_overview Views @endlink
* - @link database Database abstraction layer @endlink
*
Jennifer Hodgdon
committed
* @section other_essentials Other essential APIs
Angie Byron
committed
*
Angie Byron
committed
* - @link plugin_api Plugins @endlink
* - @link container Services and the Dependency Injection Container @endlink
Angie Byron
committed
* - @link i18n Internationalization @endlink
* - @link cache Caching @endlink
Jennifer Hodgdon
committed
* - @link utility Utility classes and functions @endlink
Angie Byron
committed
* - @link user_api User accounts, permissions, and roles @endlink
* - @link theme_render Theme system and render API @endlink
* - @link migration Migration @endlink
*
* @section additional Additional topics
Angie Byron
committed
*
Jennifer Hodgdon
committed
* - @link batch Batch API @endlink
* - @link queue Queue API @endlink
Angie Byron
committed
* - @link typed_data Typed Data @endlink
* - @link testing Automated tests @endlink
* - @link third_party Integrating third-party applications @endlink
Angie Byron
committed
*
* @section more_info Further information
*
* - @link https://api.drupal.org/api/drupal/groups/8 All topics @endlink
* - @link https://drupal.org/project/examples Examples project (sample modules) @endlink
* - @link https://drupal.org/list-changes API change notices @endlink
* - @link https://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.
*
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
* @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://en.wikipedia.org/wiki/SOAP SOAP
* - XML-RPC: http://en.wikipedia.org/wiki/XML-RPC
* - REST: http://en.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.
* - PUT: Requests to update or create data.
* - 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, PUT, 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; contributed module
* OAuth (https://www.drupal.org/project/oauth) implements the OAuth
* authenticaion 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 staging
* 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_xmlrpc Using XML-RPC
* In XML-RPC, a web site can set up one or more XML-RPC methods, which it
* will usually service at a central XML-RPC URL. Drupal Core's XML-RPC module
* provides both client and server XML-RPC functionality.
*
* On the server side, the XML-RPC module sets up URL path xmlrpc.php, which
* responds to XML-RPC requests. Individual XML-RPC request methods are defined
* by modules by implementing hook_xmlrpc(); Drupal Core does not define any
* XML-RPC web service requests by default.
*
* On the client side, XML-RPC requests to other web sites that provide XML-RPC
* web services can be performed in Drupal by using the xmlrpc() function.
*
* @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
* - As mentioned above, for XML-RPC requests, use function xmlrpc().
Angie Byron
committed
* @}
*/
/**
Angie Byron
committed
* @defgroup state_api State API
Angie Byron
committed
* @{
Angie Byron
committed
* Information about the State API.
Angie Byron
committed
*
Angie Byron
committed
* The State API is one of several methods in Drupal for storing information.
Angie Byron
committed
* See the @link info_types Information types topic @endlink for an
Angie Byron
committed
* overview of the different types of information.
Angie Byron
committed
*
Angie Byron
committed
* 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
Angie Byron
committed
*
Angie Byron
committed
* For more on the State API, see https://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
Angie Byron
committed
* information. See the @link info_types Information types topic @endlink for
Angie Byron
committed
* an overview of the different types of information. The sections below have
* more information about the configuration API; see
* https://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".
*
Angie Byron
committed
* Configuration can also be overridden on a global, per-language, or
* per-module basis. See https://www.drupal.org/node/1928898 for more
* information.
*
Angie Byron
committed
* @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 a module, which is imported to the
* active storage when the module is enabled. Note that changes to this
* default configuration after a module is already enabled have no effect;
* to make a configuration change after a module is enabled, you would need
* to uninstall/reinstall or use a hook_update_N() function.
* - Exporting and importing configuration.
*
* The file storage format for configuration information in Drupal is @link
* http://en.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.
*
* 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. Note that data types label,
* text, and data_format are translatable; string is non-translatable text.
Angie Byron
committed
*
* @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
Angie Byron
committed
*
Angie Byron
committed
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
* This will be an object of class \Drupal\Core\Config\Config, which has methods
* for getting and setting 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');
* // Update a value. Nesting works the same as get().
* $config->set('bar.baz', 'string2');
* // Nothing actually happens with set() until you call save().
* $config->save();
* @endcode
*
* @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 entites, 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 may also provide a few configuration items to be installed by
* default, by adding configuration files to the module's config/install
* directory; 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 instance configuration, which depends on field and bundle
* configuration. Configuration entity classes expose dependencies by
* overriding the
* \Drupal\Core\Config\Entity\ConfigEntityInterface::calculateDependencies()
* method.
*
* @see i18n
*
Angie Byron
committed
* @}
*/
/**
* @defgroup cache Cache API
* @{
* Information about the Drupal Cache API
*
Angie Byron
committed
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
* @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 be permanent, temporary, or valid for a certain
* timespan, 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
* current interface language.
* - 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()->id();
*
* $data = NULL;
* if ($cache = \Drupal::cache()->get($cid)) {
* $data = $cache->data;
* }
* else {
* $data = my_module_complicated_calculation();
* \Drupal::cache()->set($cid, $data);
* }
* @endcode
*
Jennifer Hodgdon
committed
* 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.
*
Angie Byron
committed
* @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
catch
committed
* "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
Alex Pott
committed
* caches.
Angie Byron
committed
*
* Other common cache bins are the following:
* - bootstrap: Small caches needed for the bootstrap on every request.
* - 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.
Alex Pott
committed
* - discovery: Contains cached discovery data for things such as plugins,
* views_data, or YAML discovered data such as library info.
Angie Byron
committed
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
*
* 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_method: get
* factory_service: cache_factory
* arguments: [nameofbin]
* @endcode
*
* @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,
Alex Pott
committed
* which are used to identify what type of data is included in each cache item.
* Each cache item can have multiple cache tags, and each cache tag has a string
* key and a value. The value can be:
* - TRUE, to indicate that this type of data is present in the cache item.
Angie Byron
committed
* - An array of values. For example, the "node" tag indicates that particular
Alex Pott
committed
* node's data is present in the cache item, so its value is an array of node
* IDs.
* Data that has been tagged can be deleted or 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
* deleted or 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.
Angie Byron
committed
*
* Example:
* @code
* // A cache item with nodes, users, and some custom module data.
* $tags = array(
* 'my_custom_tag' => TRUE,
* 'node' => array(1, 3),
* 'user' => array(7),
* );
* \Drupal::cache()->set($cid, $data, CacheBackendInterface::CACHE_PERMANENT, $tags);
*
Alex Pott
committed
* // Delete or invalidate all cache items with certain tags.
Angie Byron
committed
* \Drupal\Core\Cache\Cache::deleteTags(array('node' => array(1));
* \Drupal\Core\Cache\Cache::invalidateTags(array('user' => array(1)));
* @endcode
*
Alex Pott
committed
* 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\Entity\EntityInterface::getCacheTag(),
* \Drupal\Core\Entity\EntityInterface::getListCacheTags(),
* \Drupal\Core\Entity\Entity::invalidateTagsOnSave() and
* \Drupal\Core\Entity\Entity::invalidateTagsOnDelete().
Angie Byron
committed
*
Alex Pott
committed
* @todo Update cache tag deletion in https://drupal.org/node/918538
Angie Byron
committed
*
* @section configuration Configuration
*
Jennifer Hodgdon
committed
* 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 APC or Memcache, for storage.
Angie Byron
committed
*
catch
committed
* 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:
Angie Byron
committed
* @code
catch
committed
* $settings['cache']['bins']['render'] = 'cache.custom';
Angie Byron
committed
* @endcode
*
* Additionally, you can register your cache implementation to be used by
* default for all cache bins with:
* @code
catch
committed
* $settings['cache']['default'] = 'cache.custom';
Angie Byron
committed
* @endcode
Angie Byron
committed
*
* @see https://drupal.org/node/1884796
* @}
*/
/**
Angie Byron
committed
* @defgroup user_api User accounts, permissions, and roles
Angie Byron
committed
* @{
* API for user accounts, access checking, roles, and permissions.
*
Angie Byron
committed
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
* @sec 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.
*
* @sec sec_define Defining permissions
* Modules define permissions by implementing hook_permission(). The return
* value defines machine names, human-readable names, and optionally
* descriptions for each permission type. The machine names are the canonical
* way to refer to permissions for access checking.
*
* @sec 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 controller 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().
*
* @sec 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
Angie Byron
committed
*
Angie Byron
committed
* 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).
Angie Byron
committed
* @}
*/
/**
* @defgroup container Services and Dependency Injection Container
* @{
* Overview of the Dependency Injection Container and Services.
*
* @todo write this
*
* Additional documentation paragraphs need to be written, and functions,
* classes, and interfaces need to be added to this topic.
*
* See https://drupal.org/node/2133171
* @}
*/
/**
* @defgroup typed_data Typed Data API
* @{
Angie Byron
committed
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
* API for describing data based on a set of available data types.
*
* The Typed Data API was created to provide developers with a consistent
* interface for interacting with data, as well as an API for metadata
* (information about the data, such as the data type, whether it is
* translatable, and who can access it). The Typed Data API is used in several
* Drupal sub-systems, such as the Entity Field API and Configuration API.
*
* See https://drupal.org/node/1794140 for more information about the Typed
* Data API.
*
* @section interfaces Interfaces and classes in the Typed Data API
* There are several basic interfaces in the Typed Data API, representing
* different types of data:
* - \Drupal\Core\TypedData\PrimitiveInterface: Used for primitive data, such
* as strings, numeric types, etc. Drupal provides primitive types for
* integers, strings, etc. based on this interface, and you should
* not ever need to create new primitive types.
* - \Drupal\Core\TypedData\TypedDataInterface: Used for single pieces of data,
* with some information about its context. Abstract base class
* \Drupal\Core\TypedData\TypedData is a useful starting point, and contains
* documentation on how to extend it.
* - \Drupal\Core\TypedData\ComplexDataInterface: Used for complex data, which
* contains named and typed properties; extends TypedDataInterface. Examples
* of complex data include content entities and field items. See the
* @link entity_api Entity API topic @endlink for more information about
* entities; for most complex data, developers should use entities.
* - \Drupal\Core\TypedData\ListInterface: Used for a sequential list of other
* typed data. Class \Drupal\Core\TypedData\Plugin\DataType\ItemList is a
* generic implementation of this interface, and it is used by default for
* data declared as a list of some other data type. You can also define a
* custom list class, in which case ItemList is a useful base class.
*
* @section 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
* section above as a starting point.
* - 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.
*
* @section using Using data types
* 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 Confuration API topic @endlink for more information.
Angie Byron
committed
* @}
*/
/**
* @defgroup migration Migration API
* @{
* Overview of the Migration API, which migrates data into Drupal.
*
* @todo write this
*
* Additional documentation paragraphs need to be written, and functions,
* classes, and interfaces need to be added to this topic.
*
* See https://drupal.org/node/2127611
* @}
*/
/**
* @defgroup testing Automated tests
* @{
* Overview of PHPUnit tests and Simpletest tests.
*
Angie Byron
committed
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
* 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_unit Writing PHPUnit tests for classes
* PHPUnit tests for classes are written using the industry-standard PHPUnit
* framework. Use a PHPUnit test to 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. To
* write a PHPUnit test:
* - Define a class that extends \Drupal\Tests\UnitTestCase.
* - The class name needs to end in the word Test.
* - The namespace must be a subspace/subdirectory of \Drupal\yourmodule\Tests,
* where yourmodule is your module's machine name.
* - The test class file must be named and placed under the yourmodule/tests/src
* directory, according to the PSR-4 standard.
* - Your test class needs a getInfo() method, which gives information about
* the test.
* - Methods in your test class whose names start with 'test' are the actual
* test cases. Each one should test a logical subset of the functionality.
* For more details, see:
* - https://drupal.org/phpunit for full documentation on how to write 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.
*
* @section write_functional Writing functional tests
* Functional tests are written using a Drupal-specific framework that is, for
* historical reasons, known as "Simpletest". Use a Simpletest test to test the
* functionality of sub-system of Drupal, if the functionality depends on the
* Drupal database and settings, or to test the web output of Drupal. To
* write a Simpletest test:
* - For functional tests of the web output of Drupal, define a class that
* extends \Drupal\simpletest\WebTestBase, which contains an internal web
* browser and defines many helpful test assertion methods that you can use
* in your tests. You can specify modules to be enabled by defining a
* $modules member variable -- keep in mind that by default, WebTestBase uses
* a "testing" install profile, with a minimal set of modules enabled.
* - For functional tests that do not test web output, define a class that
* extends \Drupal\simpletest\KernelTestBase. This class is much faster
* than WebTestBase, because instead of making a full install of Drupal, it
* uses an in-memory pseudo-installation (similar to what the installer and
* update scripts use). To use this test class, you will need to create the
* database tables you need and install needed modules manually.
* - The namespace must be a subspace/subdirectory of \Drupal\yourmodule\Tests,
* where yourmodule is your module's machine name.
* - The test class file must be named and placed under the yourmodule/src/Tests
* directory, according to the PSR-4 standard.
* - Your test class needs a getInfo() method, which gives information about
* the test.
* - You may also override the default setUp() method, which can set be used to
* set up content types and similar procedures.
* - In some cases, you may need to write a test module to support your test;
* put such modules under the yourmodule/tests/modules directory.
* - Methods in your test class whose names start with 'test', and which have
* no arguments, are the actual test cases. Each one should test a logical
* subset of the functionality, and each one runs in a new, isolated test
* environment, so it can only rely on the setUp() method, not what has
* been set up by other test methods.
* For more details, see:
* - https://drupal.org/simpletest for full documentation on how to write
* functional tests for Drupal.
* - @link oo_conventions Object-oriented programming topic @endlink for more
* on PSR-4, namespaces, and where to place classes.
*
* @section running Running tests
* You can run both Simpletest and PHPUnit tests by enabling the core Testing
* module (core/modules/simpletest). Once that module is enabled, tests can be
* run usin the core/scripts/run-tests.sh script, using
* @link https://drupal.org/project/drush Drush @endlink, or from the Testing
* module user interface.
*
* PHPUnit tests can also be run from the command line, using the PHPUnit
* framework. See https://drupal.org/node/2116263 for more information.
Angie Byron
committed
* @}
*/
/**
Angie Byron
committed
* @defgroup info_types Information types
Angie Byron
committed
* @{
Angie Byron
committed
* Types of information in Drupal.
Angie Byron
committed
*
Angie Byron
committed
* 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
Angie Byron
committed
* information is managed via the session_manager service in Drupal, which
* implements \Drupal\Core\Session\SessionManagerInterface. See the
* @link container Services topic @endlink for more information about
* services.
Angie Byron
committed
* - 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.
*
Angie Byron
committed
* @see cache
* @see i18n
Angie Byron
committed
* @}
*/
/**
Angie Byron
committed
* @defgroup extending Extending and altering Drupal
Angie Byron
committed
* @{
Angie Byron
committed
* Overview of add-ons and alteration methods for Drupal.
*
* Drupal's core behavior can be extended and altered via these three basic
* types of add-ons:
* - 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://drupal.org/theme-guide/8
* - 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://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://drupal.org/documentation/build/distributions.
*
* 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
Angie Byron
committed
* @link plugin_api Plugin API topic @endlink for more information.
Angie Byron
committed
* - 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
Angie Byron
committed
* @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.
* @}
*/
/**
Angie Byron
committed
* @defgroup plugin_api Plugin API
Angie Byron
committed
* @{
Angie Byron
committed
* Using the Plugin API
Angie Byron
committed
*
Angie Byron
committed
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
* @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 bags: 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://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\ConfigurablePluginInterface
* - \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 bag. See @ref sub_bag below
* for more information.
Angie Byron
committed
*
Angie Byron
committed
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
* @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 listd 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://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