Mercurial > hg > cmmr2012-drupal-site
comparison core/core.api.php @ 0:c75dbcec494b
Initial commit from drush-created site
author | Chris Cannam |
---|---|
date | Thu, 05 Jul 2018 14:24:15 +0000 |
parents | |
children | a9cd425dd02b |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:c75dbcec494b |
---|---|
1 <?php | |
2 | |
3 /** | |
4 * @file | |
5 * Documentation landing page and topics, plus core library hooks. | |
6 */ | |
7 | |
8 /** | |
9 * @mainpage | |
10 * Welcome to the Drupal API Documentation! | |
11 * | |
12 * This site is an API reference for Drupal, generated from comments embedded | |
13 * in the source code. More in-depth documentation can be found at | |
14 * https://www.drupal.org/developing/api. | |
15 * | |
16 * Here are some topics to help you get started developing with Drupal. | |
17 * | |
18 * @section essentials Essential background concepts | |
19 * | |
20 * - @link oo_conventions Object-oriented conventions used in Drupal @endlink | |
21 * - @link extending Extending and altering Drupal @endlink | |
22 * - @link best_practices Security and best practices @endlink | |
23 * - @link info_types Types of information in Drupal @endlink | |
24 * | |
25 * @section interface User interface | |
26 * | |
27 * - @link menu Menu entries, local tasks, and other links @endlink | |
28 * - @link routing Routing API and page controllers @endlink | |
29 * - @link form_api Forms @endlink | |
30 * - @link block_api Blocks @endlink | |
31 * - @link ajax Ajax @endlink | |
32 * | |
33 * @section store_retrieve Storing and retrieving data | |
34 * | |
35 * - @link entity_api Entities @endlink | |
36 * - @link field Fields @endlink | |
37 * - @link config_api Configuration API @endlink | |
38 * - @link state_api State API @endlink | |
39 * - @link views_overview Views @endlink | |
40 * - @link database Database abstraction layer @endlink | |
41 * | |
42 * @section other_essentials Other essential APIs | |
43 * | |
44 * - @link plugin_api Plugins @endlink | |
45 * - @link container Services and the Dependency Injection Container @endlink | |
46 * - @link events Events @endlink | |
47 * - @link i18n Internationalization @endlink | |
48 * - @link cache Caching @endlink | |
49 * - @link utility Utility classes and functions @endlink | |
50 * - @link user_api User accounts, permissions, and roles @endlink | |
51 * - @link theme_render Render API @endlink | |
52 * - @link themeable Theme system @endlink | |
53 * - @link update_api Update API @endlink | |
54 * - @link migration Migration @endlink | |
55 * | |
56 * @section additional Additional topics | |
57 * | |
58 * - @link batch Batch API @endlink | |
59 * - @link queue Queue API @endlink | |
60 * - @link typed_data Typed Data @endlink | |
61 * - @link testing Automated tests @endlink | |
62 * - @link php_assert PHP Runtime Assert Statements @endlink | |
63 * - @link third_party Integrating third-party applications @endlink | |
64 * | |
65 * @section more_info Further information | |
66 * | |
67 * - @link https://api.drupal.org/api/drupal/groups/8 All topics @endlink | |
68 * - @link https://www.drupal.org/project/examples Examples project (sample modules) @endlink | |
69 * - @link https://www.drupal.org/list-changes API change notices @endlink | |
70 * - @link https://www.drupal.org/developing/api/8 Drupal 8 API longer references @endlink | |
71 */ | |
72 | |
73 /** | |
74 * @defgroup third_party REST and Application Integration | |
75 * @{ | |
76 * Integrating third-party applications using REST and related operations. | |
77 * | |
78 * @section sec_overview Overview of web services | |
79 * Web services make it possible for applications and web sites to read and | |
80 * update information from other web sites. There are several standard | |
81 * techniques for providing web services, including: | |
82 * - SOAP: http://wikipedia.org/wiki/SOAP | |
83 * - XML-RPC: http://wikipedia.org/wiki/XML-RPC | |
84 * - REST: http://wikipedia.org/wiki/Representational_state_transfer | |
85 * Drupal sites can both provide web services and integrate third-party web | |
86 * services. | |
87 * | |
88 * @section sec_rest_overview Overview of REST | |
89 * The REST technique uses basic HTTP requests to obtain and update data, where | |
90 * each web service defines a specific API (HTTP GET and/or POST parameters and | |
91 * returned response) for its HTTP requests. REST requests are separated into | |
92 * several types, known as methods, including: | |
93 * - GET: Requests to obtain data. | |
94 * - POST: Requests to update or create data. | |
95 * - PUT: Requests to update or create data (limited support, currently unused | |
96 * by entity resources). | |
97 * - PATCH: Requests to update a subset of data, such as one field. | |
98 * - DELETE: Requests to delete data. | |
99 * The Drupal Core REST module provides support for GET, POST, PATCH, and DELETE | |
100 * quests on entities, GET requests on the database log from the Database | |
101 * Logging module, and a plugin framework for providing REST support for other | |
102 * data and other methods. | |
103 * | |
104 * REST requests can be authenticated. The Drupal Core Basic Auth module | |
105 * provides authentication using the HTTP Basic protocol; the contributed module | |
106 * OAuth (https://www.drupal.org/project/oauth) implements the OAuth | |
107 * authentication protocol. You can also use cookie-based authentication, which | |
108 * would require users to be logged into the Drupal site while using the | |
109 * application on the third-party site that is using the REST service. | |
110 * | |
111 * @section sec_rest Enabling REST for entities and the log | |
112 * Here are the steps to take to use the REST operations provided by Drupal | |
113 * Core: | |
114 * - Enable the REST module, plus Basic Auth (or another authentication method) | |
115 * and HAL. | |
116 * - Node entity support is configured by default. If you would like to support | |
117 * other types of entities, you can copy | |
118 * core/modules/rest/config/install/rest.settings.yml to your sync | |
119 * configuration directory, appropriately modified for other entity types, | |
120 * and import it. Support for GET on the log from the Database Logging module | |
121 * can also be enabled in this way; in this case, the 'entity:node' line | |
122 * in the configuration would be replaced by the appropriate plugin ID, | |
123 * 'dblog'. | |
124 * - Set up permissions to allow the desired REST operations for a role, and set | |
125 * up one or more user accounts to perform the operations. | |
126 * - To perform a REST operation, send a request to either the canonical URL | |
127 * for an entity (such as node/12345 for a node), or if the entity does not | |
128 * have a canonical URL, a URL like entity/(type)/(ID). The URL for a log | |
129 * entry is dblog/(ID). The request must have the following properties: | |
130 * - The request method must be set to the REST method you are using (POST, | |
131 * GET, PATCH, etc.). | |
132 * - The content type for the data you send, or the accept type for the | |
133 * data you are receiving, must be set to 'application/hal+json'. | |
134 * - If you are sending data, it must be JSON-encoded. | |
135 * - You'll also need to make sure the authentication information is sent | |
136 * with the request, unless you have allowed access to anonymous users. | |
137 * | |
138 * For more detailed information on setting up REST, see | |
139 * https://www.drupal.org/documentation/modules/rest. | |
140 * | |
141 * @section sec_plugins Defining new REST plugins | |
142 * The REST framework in the REST module has support built in for entities, but | |
143 * it is also an extensible plugin-based system. REST plugins implement | |
144 * interface \Drupal\rest\Plugin\ResourceInterface, and generally extend base | |
145 * class \Drupal\rest\Plugin\ResourceBase. They are annotated with | |
146 * \Drupal\rest\Annotation\RestResource annotation, and must be in plugin | |
147 * namespace subdirectory Plugin\rest\resource. For more information on how to | |
148 * create plugins, see the @link plugin_api Plugin API topic. @endlink | |
149 * | |
150 * If you create a new REST plugin, you will also need to enable it by | |
151 * providing default configuration or configuration import, as outlined in | |
152 * @ref sec_rest above. | |
153 * | |
154 * @section sec_integrate Integrating data from other sites into Drupal | |
155 * If you want to integrate data from other web sites into Drupal, here are | |
156 * some notes: | |
157 * - There are contributed modules available for integrating many third-party | |
158 * sites into Drupal. Search on https://www.drupal.org/project/project_module | |
159 * - If there is not an existing module, you will need to find documentation on | |
160 * the specific web services API for the site you are trying to integrate. | |
161 * - There are several classes and functions that are useful for interacting | |
162 * with web services: | |
163 * - You should make requests using the 'http_client' service, which | |
164 * implements \GuzzleHttp\ClientInterface. See the | |
165 * @link container Services topic @endlink for more information on | |
166 * services. If you cannot use dependency injection to retrieve this | |
167 * service, the \Drupal::httpClient() method is available. A good example | |
168 * of how to use this service can be found in | |
169 * \Drupal\aggregator\Plugin\aggregator\fetcher\DefaultFetcher | |
170 * - \Drupal\Component\Serialization\Json (JSON encoding and decoding). | |
171 * - PHP has functions and classes for parsing XML; see | |
172 * http://php.net/manual/refs.xml.php | |
173 * @} | |
174 */ | |
175 | |
176 /** | |
177 * @defgroup state_api State API | |
178 * @{ | |
179 * Information about the State API. | |
180 * | |
181 * The State API is one of several methods in Drupal for storing information. | |
182 * See the @link info_types Information types topic @endlink for an | |
183 * overview of the different types of information. | |
184 * | |
185 * The basic entry point into the State API is \Drupal::state(), which returns | |
186 * an object of class \Drupal\Core\State\StateInterface. This class has | |
187 * methods for storing and retrieving state information; each piece of state | |
188 * information is associated with a string-valued key. Example: | |
189 * @code | |
190 * // Get the state class. | |
191 * $state = \Drupal::state(); | |
192 * // Find out when cron was last run; the key is 'system.cron_last'. | |
193 * $time = $state->get('system.cron_last'); | |
194 * // Set the cron run time to the current request time. | |
195 * $state->set('system.cron_last', REQUEST_TIME); | |
196 * @endcode | |
197 * | |
198 * For more on the State API, see https://www.drupal.org/developing/api/8/state | |
199 * @} | |
200 */ | |
201 | |
202 /** | |
203 * @defgroup config_api Configuration API | |
204 * @{ | |
205 * Information about the Configuration API. | |
206 * | |
207 * The Configuration API is one of several methods in Drupal for storing | |
208 * information. See the @link info_types Information types topic @endlink for | |
209 * an overview of the different types of information. The sections below have | |
210 * more information about the configuration API; see | |
211 * https://www.drupal.org/developing/api/8/configuration for more details. | |
212 * | |
213 * @section sec_storage Configuration storage | |
214 * In Drupal, there is a concept of the "active" configuration, which is the | |
215 * configuration that is currently in use for a site. The storage used for the | |
216 * active configuration is configurable: it could be in the database, in files | |
217 * in a particular directory, or in other storage backends; the default storage | |
218 * is in the database. Module developers must use the configuration API to | |
219 * access the active configuration, rather than being concerned about the | |
220 * details of where and how it is stored. | |
221 * | |
222 * Configuration is divided into individual objects, each of which has a | |
223 * unique name or key. Some modules will have only one configuration object, | |
224 * typically called 'mymodule.settings'; some modules will have many. Within | |
225 * a configuration object, configuration settings have data types (integer, | |
226 * string, Boolean, etc.) and settings can also exist in a nested hierarchy, | |
227 * known as a "mapping". | |
228 * | |
229 * Configuration can also be overridden on a global, per-language, or | |
230 * per-module basis. See https://www.drupal.org/node/1928898 for more | |
231 * information. | |
232 * | |
233 * @section sec_yaml Configuration YAML files | |
234 * Whether or not configuration files are being used for the active | |
235 * configuration storage on a particular site, configuration files are always | |
236 * used for: | |
237 * - Defining the default configuration for an extension (module, theme, or | |
238 * profile), which is imported to the active storage when the extension is | |
239 * enabled. These configuration items are located in the config/install | |
240 * sub-directory of the extension. Note that changes to this configuration | |
241 * after a module or theme is already enabled have no effect; to make a | |
242 * configuration change after a module or theme is enabled, you would need to | |
243 * uninstall/reinstall or use a hook_update_N() function. | |
244 * - Defining optional configuration for a module or theme. Optional | |
245 * configuration items are located in the config/optional sub-directory of the | |
246 * extension. These configuration items have dependencies that are not | |
247 * explicit dependencies of the extension, so they are only installed if all | |
248 * dependencies are met. For example, in the scenario that module A defines a | |
249 * dependency which requires module B, but module A is installed first and | |
250 * module B some time later, then module A's config/optional directory will be | |
251 * scanned at that time for newly met dependencies, and the configuration will | |
252 * be installed then. If module B is never installed, the configuration item | |
253 * will not be installed either. | |
254 * - Exporting and importing configuration. | |
255 * | |
256 * The file storage format for configuration information in Drupal is | |
257 * @link http://wikipedia.org/wiki/YAML YAML files. @endlink Configuration is | |
258 * divided into files, each containing one configuration object. The file name | |
259 * for a configuration object is equal to the unique name of the configuration, | |
260 * with a '.yml' extension. The default configuration files for each module are | |
261 * placed in the config/install directory under the top-level module directory, | |
262 * so look there in most Core modules for examples. | |
263 * | |
264 * @section sec_schema Configuration schema and translation | |
265 * Each configuration file has a specific structure, which is expressed as a | |
266 * YAML-based configuration schema. The configuration schema details the | |
267 * structure of the configuration, its data types, and which of its values need | |
268 * to be translatable. Each module needs to define its configuration schema in | |
269 * files in the config/schema directory under the top-level module directory, so | |
270 * look there in most Core modules for examples. | |
271 * | |
272 * Configuration can be internationalized; see the | |
273 * @link i18n Internationalization topic @endlink for more information. Data | |
274 * types label, text, and date_format in configuration schema are translatable; | |
275 * string is non-translatable text (the 'translatable' property on a schema | |
276 * data type definition indicates that it is translatable). | |
277 * | |
278 * @section sec_simple Simple configuration | |
279 * The simple configuration API should be used for information that will always | |
280 * have exactly one copy or version. For instance, if your module has a | |
281 * setting that is either on or off, then this is only defined once, and it | |
282 * would be a Boolean-valued simple configuration setting. | |
283 * | |
284 * The first task in using the simple configuration API is to define the | |
285 * configuration file structure, file name, and schema of your settings (see | |
286 * @ref sec_yaml above). Once you have done that, you can retrieve the active | |
287 * configuration object that corresponds to configuration file mymodule.foo.yml | |
288 * with a call to: | |
289 * @code | |
290 * $config = \Drupal::config('mymodule.foo'); | |
291 * @endcode | |
292 * | |
293 * This will be an object of class \Drupal\Core\Config\Config, which has methods | |
294 * for getting configuration information. For instance, if your YAML file | |
295 * structure looks like this: | |
296 * @code | |
297 * enabled: '0' | |
298 * bar: | |
299 * baz: 'string1' | |
300 * boo: 34 | |
301 * @endcode | |
302 * you can make calls such as: | |
303 * @code | |
304 * // Get a single value. | |
305 * $enabled = $config->get('enabled'); | |
306 * // Get an associative array. | |
307 * $bar = $config->get('bar'); | |
308 * // Get one element of the array. | |
309 * $bar_baz = $config->get('bar.baz'); | |
310 * @endcode | |
311 * | |
312 * The Config object that was obtained and used in the previous examples does | |
313 * not allow you to change configuration. If you want to change configuration, | |
314 * you will instead need to get the Config object by making a call to | |
315 * getEditable() on the config factory: | |
316 * @code | |
317 * $config =\Drupal::service('config.factory')->getEditable('mymodule.foo'); | |
318 * @endcode | |
319 * | |
320 * Individual configuration values can be changed or added using the set() | |
321 * method and saved using the save() method: | |
322 * @code | |
323 * // Set a scalar value. | |
324 * $config->set('enabled', 1); | |
325 * // Save the configuration. | |
326 * $config->save(); | |
327 * @endcode | |
328 * | |
329 * Configuration values can also be unset using the clear() method, which is | |
330 * also chainable: | |
331 * @code | |
332 * $config->clear('bar.boo')->save(); | |
333 * $config_data = $config->get('bar'); | |
334 * @endcode | |
335 * In this example $config_data would return an array with one key - 'baz' - | |
336 * because 'boo' was unset. | |
337 * | |
338 * @section sec_entity Configuration entities | |
339 * In contrast to the simple configuration settings described in the previous | |
340 * section, if your module allows users to create zero or more items (where | |
341 * "items" are things like content type definitions, view definitions, and the | |
342 * like), then you need to define a configuration entity type to store your | |
343 * configuration. Creating an entity type, loading entities, and querying them | |
344 * are outlined in the @link entity_api Entity API topic. @endlink Here are a | |
345 * few additional steps and notes specific to configuration entities: | |
346 * - For examples, look for classes that implement | |
347 * \Drupal\Core\Config\Entity\ConfigEntityInterface -- one good example is | |
348 * the \Drupal\user\Entity\Role entity type. | |
349 * - In the entity type annotation, you will need to define a 'config_prefix' | |
350 * string. When Drupal stores a configuration item, it will be given a name | |
351 * composed of your module name, your chosen config prefix, and the ID of | |
352 * the individual item, separated by '.'. For example, in the Role entity, | |
353 * the config prefix is 'role', so one configuration item might be named | |
354 * user.role.anonymous, with configuration file user.role.anonymous.yml. | |
355 * - You will need to define the schema for your configuration in your | |
356 * modulename.schema.yml file, with an entry for 'modulename.config_prefix.*'. | |
357 * For example, for the Role entity, the file user.schema.yml has an entry | |
358 * user.role.*; see @ref sec_yaml above for more information. | |
359 * - Your module can provide default/optional configuration entities in YAML | |
360 * files; see @ref sec_yaml above for more information. | |
361 * - Some configuration entities have dependencies on other configuration | |
362 * entities, and module developers need to consider this so that configuration | |
363 * can be imported, uninstalled, and synchronized in the right order. For | |
364 * example, a field display configuration entity would need to depend on | |
365 * field configuration, which depends on field and bundle configuration. | |
366 * Configuration entity classes expose dependencies by overriding the | |
367 * \Drupal\Core\Config\Entity\ConfigEntityInterface::calculateDependencies() | |
368 * method. | |
369 * - On routes for paths starting with '/admin' or otherwise designated as | |
370 * administration paths (such as node editing when it is set as an admin | |
371 * operation), if they have configuration entity placeholders, configuration | |
372 * entities are normally loaded in their original language, without | |
373 * translations or other overrides. This is usually desirable, because most | |
374 * admin paths are for editing configuration, and you need that to be in the | |
375 * source language and to lack possibly dynamic overrides. If for some reason | |
376 * you need to have your configuration entity loaded in the currently-selected | |
377 * language on an admin path (for instance, if you go to | |
378 * example.com/es/admin/your_path and you need the entity to be in Spanish), | |
379 * then you can add a 'with_config_overrides' parameter option to your route. | |
380 * The same applies if you need to load the entity with overrides (or | |
381 * translated) on an admin path like '/node/add/article' (when configured to | |
382 * be an admin path). Here's an example using the configurable_language config | |
383 * entity: | |
384 * @code | |
385 * mymodule.myroute: | |
386 * path: '/admin/mypath/{configurable_language}' | |
387 * defaults: | |
388 * _controller: '\Drupal\mymodule\MyController::myMethod' | |
389 * options: | |
390 * parameters: | |
391 * configurable_language: | |
392 * type: entity:configurable_language | |
393 * with_config_overrides: TRUE | |
394 * @endcode | |
395 * With the route defined this way, the $configurable_language parameter to | |
396 * your controller method will come in translated to the current language. | |
397 * Without the parameter options section, it would be in the original | |
398 * language, untranslated. | |
399 * | |
400 * @see i18n | |
401 * | |
402 * @} | |
403 */ | |
404 | |
405 /** | |
406 * @defgroup cache Cache API | |
407 * @{ | |
408 * Information about the Drupal Cache API | |
409 * | |
410 * @section basics Basics | |
411 * | |
412 * Note: If not specified, all of the methods mentioned here belong to | |
413 * \Drupal\Core\Cache\CacheBackendInterface. | |
414 * | |
415 * The Cache API is used to store data that takes a long time to compute. | |
416 * Caching can either be permanent or valid only for a certain time span, and | |
417 * the cache can contain any type of data. | |
418 * | |
419 * To use the Cache API: | |
420 * - Request a cache object through \Drupal::cache() or by injecting a cache | |
421 * service. | |
422 * - Define a Cache ID (cid) value for your data. A cid is a string, which must | |
423 * contain enough information to uniquely identify the data. For example, if | |
424 * your data contains translated strings, then your cid value must include the | |
425 * interface text language selected for page. | |
426 * - Call the get() method to attempt a cache read, to see if the cache already | |
427 * contains your data. | |
428 * - If your data is not already in the cache, compute it and add it to the | |
429 * cache using the set() method. The third argument of set() can be used to | |
430 * control the lifetime of your cache item. | |
431 * | |
432 * Example: | |
433 * @code | |
434 * $cid = 'mymodule_example:' . \Drupal::languageManager()->getCurrentLanguage()->getId(); | |
435 * | |
436 * $data = NULL; | |
437 * if ($cache = \Drupal::cache()->get($cid)) { | |
438 * $data = $cache->data; | |
439 * } | |
440 * else { | |
441 * $data = my_module_complicated_calculation(); | |
442 * \Drupal::cache()->set($cid, $data); | |
443 * } | |
444 * @endcode | |
445 * | |
446 * Note the use of $data and $cache->data in the above example. Calls to | |
447 * \Drupal::cache()->get() return a record that contains the information stored | |
448 * by \Drupal::cache()->set() in the data property as well as additional meta | |
449 * information about the cached data. In order to make use of the cached data | |
450 * you can access it via $cache->data. | |
451 * | |
452 * @section bins Cache bins | |
453 * | |
454 * Cache storage is separated into "bins", each containing various cache items. | |
455 * Each bin can be configured separately; see @ref configuration. | |
456 * | |
457 * When you request a cache object, you can specify the bin name in your call to | |
458 * \Drupal::cache(). Alternatively, you can request a bin by getting service | |
459 * "cache.nameofbin" from the container. The default bin is called "default", with | |
460 * service name "cache.default", it is used to store common and frequently used | |
461 * caches. | |
462 * | |
463 * Other common cache bins are the following: | |
464 * - bootstrap: Data needed from the beginning to the end of most requests, | |
465 * that has a very strict limit on variations and is invalidated rarely. | |
466 * - render: Contains cached HTML strings like cached pages and blocks, can | |
467 * grow to large size. | |
468 * - data: Contains data that can vary by path or similar context. | |
469 * - discovery: Contains cached discovery data for things such as plugins, | |
470 * views_data, or YAML discovered data such as library info. | |
471 * | |
472 * A module can define a cache bin by defining a service in its | |
473 * modulename.services.yml file as follows (substituting the desired name for | |
474 * "nameofbin"): | |
475 * @code | |
476 * cache.nameofbin: | |
477 * class: Drupal\Core\Cache\CacheBackendInterface | |
478 * tags: | |
479 * - { name: cache.bin } | |
480 * factory: cache_factory:get | |
481 * arguments: [nameofbin] | |
482 * @endcode | |
483 * See the @link container Services topic @endlink for more on defining | |
484 * services. | |
485 * | |
486 * @section delete Deletion | |
487 * | |
488 * There are two ways to remove an item from the cache: | |
489 * - Deletion (using delete(), deleteMultiple() or deleteAll()) permanently | |
490 * removes the item from the cache. | |
491 * - Invalidation (using invalidate(), invalidateMultiple() or invalidateAll()) | |
492 * is a "soft" delete that only marks items as "invalid", meaning "not fresh" | |
493 * or "not fresh enough". Invalid items are not usually returned from the | |
494 * cache, so in most ways they behave as if they have been deleted. However, | |
495 * it is possible to retrieve invalid items, if they have not yet been | |
496 * permanently removed by the garbage collector, by passing TRUE as the second | |
497 * argument for get($cid, $allow_invalid). | |
498 * | |
499 * Use deletion if a cache item is no longer useful; for instance, if the item | |
500 * contains references to data that has been deleted. Use invalidation if the | |
501 * cached item may still be useful to some callers until it has been updated | |
502 * with fresh data. The fact that it was fresh a short while ago may often be | |
503 * sufficient. | |
504 * | |
505 * Invalidation is particularly useful to protect against stampedes. Rather than | |
506 * having multiple concurrent requests updating the same cache item when it | |
507 * expires or is deleted, there can be one request updating the cache, while the | |
508 * other requests can proceed using the stale value. As soon as the cache item | |
509 * has been updated, all future requests will use the updated value. | |
510 * | |
511 * @section tags Cache Tags | |
512 * | |
513 * The fourth argument of the set() method can be used to specify cache tags, | |
514 * which are used to identify which data is included in each cache item. A cache | |
515 * item can have multiple cache tags (an array of cache tags), and each cache | |
516 * tag is a string. The convention is to generate cache tags of the form | |
517 * [prefix]:[suffix]. Usually, you'll want to associate the cache tags of | |
518 * entities, or entity listings. You won't have to manually construct cache tags | |
519 * for them — just get their cache tags via | |
520 * \Drupal\Core\Cache\CacheableDependencyInterface::getCacheTags() and | |
521 * \Drupal\Core\Entity\EntityTypeInterface::getListCacheTags(). | |
522 * Data that has been tagged can be invalidated as a group: no matter the Cache | |
523 * ID (cid) of the cache item, no matter in which cache bin a cache item lives; | |
524 * as long as it is tagged with a certain cache tag, it will be invalidated. | |
525 * | |
526 * Because of that, cache tags are a solution to the cache invalidation problem: | |
527 * - For caching to be effective, each cache item must only be invalidated when | |
528 * absolutely necessary. (i.e. maximizing the cache hit ratio.) | |
529 * - For caching to be correct, each cache item that depends on a certain thing | |
530 * must be invalidated whenever that certain thing is modified. | |
531 * | |
532 * A typical scenario: a user has modified a node that appears in two views, | |
533 * three blocks and on twelve pages. Without cache tags, we couldn't possibly | |
534 * know which cache items to invalidate, so we'd have to invalidate everything: | |
535 * we had to sacrifice effectiveness to achieve correctness. With cache tags, we | |
536 * can have both. | |
537 * | |
538 * Example: | |
539 * @code | |
540 * // A cache item with nodes, users, and some custom module data. | |
541 * $tags = array( | |
542 * 'my_custom_tag', | |
543 * 'node:1', | |
544 * 'node:3', | |
545 * 'user:7', | |
546 * ); | |
547 * \Drupal::cache()->set($cid, $data, CacheBackendInterface::CACHE_PERMANENT, $tags); | |
548 * | |
549 * // Invalidate all cache items with certain tags. | |
550 * \Drupal\Core\Cache\Cache::invalidateTags(array('user:1')); | |
551 * @endcode | |
552 * | |
553 * Drupal is a content management system, so naturally you want changes to your | |
554 * content to be reflected everywhere, immediately. That's why we made sure that | |
555 * every entity type in Drupal 8 automatically has support for cache tags: when | |
556 * you save an entity, you can be sure that the cache items that have the | |
557 * corresponding cache tags will be invalidated. | |
558 * This also is the case when you define your own entity types: you'll get the | |
559 * exact same cache tag invalidation as any of the built-in entity types, with | |
560 * the ability to override any of the default behavior if needed. | |
561 * See \Drupal\Core\Cache\CacheableDependencyInterface::getCacheTags(), | |
562 * \Drupal\Core\Entity\EntityTypeInterface::getListCacheTags(), | |
563 * \Drupal\Core\Entity\Entity::invalidateTagsOnSave() and | |
564 * \Drupal\Core\Entity\Entity::invalidateTagsOnDelete(). | |
565 * | |
566 * @section context Cache contexts | |
567 * | |
568 * Some computed data depends on contextual data, such as the user roles of the | |
569 * logged-in user who is viewing a page, the language the page is being rendered | |
570 * in, the theme being used, etc. When caching the output of such a calculation, | |
571 * you must cache each variation separately, along with information about which | |
572 * variation of the contextual data was used in the calculation. The next time | |
573 * the computed data is needed, if the context matches that for an existing | |
574 * cached data set, the cached data can be reused; if no context matches, a new | |
575 * data set can be calculated and cached for later use. | |
576 * | |
577 * Cache contexts are services tagged with 'cache.context', whose classes | |
578 * implement \Drupal\Core\Cache\Context\CacheContextInterface. See | |
579 * https://www.drupal.org/developing/api/8/cache/contexts for more information | |
580 * on cache contexts, including a list of the contexts that exist in Drupal | |
581 * core, and information on how to define your own contexts. See the | |
582 * @link container Services and the Dependency Injection Container @endlink | |
583 * topic for more information about services. | |
584 * | |
585 * Typically, the cache context is specified as part of the #cache property | |
586 * of a render array; see the Caching section of the | |
587 * @link theme_render Render API overview topic @endlink for details. | |
588 * | |
589 * @section configuration Configuration | |
590 * | |
591 * By default cached data is stored in the database. This can be configured | |
592 * though so that all cached data, or that of an individual cache bin, uses a | |
593 * different cache backend, such as APCu or Memcache, for storage. | |
594 * | |
595 * In a settings.php file, you can override the service used for a particular | |
596 * cache bin. For example, if your service implementation of | |
597 * \Drupal\Core\Cache\CacheBackendInterface was called cache.custom, the | |
598 * following line would make Drupal use it for the 'cache_render' bin: | |
599 * @code | |
600 * $settings['cache']['bins']['render'] = 'cache.custom'; | |
601 * @endcode | |
602 * | |
603 * Additionally, you can register your cache implementation to be used by | |
604 * default for all cache bins with: | |
605 * @code | |
606 * $settings['cache']['default'] = 'cache.custom'; | |
607 * @endcode | |
608 * | |
609 * For cache bins that are stored in the database, the number of rows is limited | |
610 * to 5000 by default. This can be changed for all database cache bins. For | |
611 * example, to instead limit the number of rows to 50000: | |
612 * @code | |
613 * $settings['database_cache_max_rows']['default'] = 50000; | |
614 * @endcode | |
615 * | |
616 * Or per bin (in this example we allow infinite entries): | |
617 * @code | |
618 * $settings['database_cache_max_rows']['bins']['dynamic_page_cache'] = -1; | |
619 * @endcode | |
620 * | |
621 * For monitoring reasons it might be useful to figure out the amount of data | |
622 * stored in tables. The following SQL snippet can be used for that: | |
623 * @code | |
624 * SELECT table_name AS `Table`, table_rows AS 'Num. of Rows', | |
625 * ROUND(((data_length + index_length) / 1024 / 1024), 2) `Size in MB` FROM | |
626 * information_schema.TABLES WHERE table_schema = '***DATABASE_NAME***' AND | |
627 * table_name LIKE 'cache_%' ORDER BY (data_length + index_length) DESC | |
628 * LIMIT 10; | |
629 * @endcode | |
630 * | |
631 * @see \Drupal\Core\Cache\DatabaseBackend | |
632 * | |
633 * Finally, you can chain multiple cache backends together, see | |
634 * \Drupal\Core\Cache\ChainedFastBackend and \Drupal\Core\Cache\BackendChain. | |
635 * | |
636 * @see https://www.drupal.org/node/1884796 | |
637 * @} | |
638 */ | |
639 | |
640 /** | |
641 * @defgroup user_api User accounts, permissions, and roles | |
642 * @{ | |
643 * API for user accounts, access checking, roles, and permissions. | |
644 * | |
645 * @section sec_overview Overview and terminology | |
646 * Drupal's permission system is based on the concepts of accounts, roles, | |
647 * and permissions. | |
648 * | |
649 * Users (site visitors) have accounts, which include a user name, an email | |
650 * address, a password (or some other means of authentication), and possibly | |
651 * other fields (if defined on the site). Anonymous users have an implicit | |
652 * account that does not have a real user name or any account information. | |
653 * | |
654 * Each user account is assigned one or more roles. The anonymous user account | |
655 * automatically has the anonymous user role; real user accounts | |
656 * automatically have the authenticated user role, plus any roles defined on | |
657 * the site that they have been assigned. | |
658 * | |
659 * Each role, including the special anonymous and authenticated user roles, is | |
660 * granted one or more named permissions, which allow them to perform certain | |
661 * tasks or view certain content on the site. It is possible to designate a | |
662 * role to be the "administrator" role; if this is set up, this role is | |
663 * automatically granted all available permissions whenever a module is | |
664 * enabled that defines permissions. | |
665 * | |
666 * All code in Drupal that allows users to perform tasks or view content must | |
667 * check that the current user has the correct permission before allowing the | |
668 * action. In the standard case, access checking consists of answering the | |
669 * question "Does the current user have permission 'foo'?", and allowing or | |
670 * denying access based on the answer. Note that access checking should nearly | |
671 * always be done at the permission level, not by checking for a particular role | |
672 * or user ID, so that site administrators can set up user accounts and roles | |
673 * appropriately for their particular sites. | |
674 * | |
675 * @section sec_define Defining permissions | |
676 * Modules define permissions via a $module.permissions.yml file. See | |
677 * \Drupal\user\PermissionHandler for documentation of permissions.yml files. | |
678 * | |
679 * @section sec_access Access permission checking | |
680 * Depending on the situation, there are several methods for ensuring that | |
681 * access checks are done properly in Drupal: | |
682 * - Routes: When you register a route, include a 'requirements' section that | |
683 * either gives the machine name of the permission that is needed to visit the | |
684 * URL of the route, or tells Drupal to use an access check method or service | |
685 * to check access. See the @link menu Routing topic @endlink for more | |
686 * information. | |
687 * - Entities: Access for various entity operations is designated either with | |
688 * simple permissions or access control handler classes in the entity | |
689 * annotation. See the @link entity_api Entity API topic @endlink for more | |
690 * information. | |
691 * - Other code: There is a 'current_user' service, which can be injected into | |
692 * classes to provide access to the current user account (see the | |
693 * @link container Services and Dependency Injection topic @endlink for more | |
694 * information on dependency injection). In code that cannot use dependency | |
695 * injection, you can access this service and retrieve the current user | |
696 * account object by calling \Drupal::currentUser(). Once you have a user | |
697 * object for the current user (implementing \Drupal\user\UserInterface), you | |
698 * can call inherited method | |
699 * \Drupal\Core\Session\AccountInterface::hasPermission() to check | |
700 * permissions, or pass this object into other functions/methods. | |
701 * - Forms: Each element of a form array can have a Boolean '#access' property, | |
702 * which determines whether that element is visible and/or usable. This is a | |
703 * common need in forms, so the current user service (described above) is | |
704 * injected into the form base class as method | |
705 * \Drupal\Core\Form\FormBase::currentUser(). | |
706 * | |
707 * @section sec_entities User and role objects | |
708 * User objects in Drupal are entity items, implementing | |
709 * \Drupal\user\UserInterface. Role objects in Drupal are also entity items, | |
710 * implementing \Drupal\user\RoleInterface. See the | |
711 * @link entity_api Entity API topic @endlink for more information about | |
712 * entities in general (including how to load, create, modify, and query them). | |
713 * | |
714 * Roles often need to be manipulated in automated test code, such as to add | |
715 * permissions to them. Here's an example: | |
716 * @code | |
717 * $role = \Drupal\user\Entity\Role::load('authenticated'); | |
718 * $role->grantPermission('access comments'); | |
719 * $role->save(); | |
720 * @endcode | |
721 * | |
722 * Other important interfaces: | |
723 * - \Drupal\Core\Session\AccountInterface: The part of UserInterface that | |
724 * deals with access checking. In writing code that checks access, your | |
725 * method parameters should use this interface, not UserInterface. | |
726 * - \Drupal\Core\Session\AccountProxyInterface: The interface for the | |
727 * current_user service (described above). | |
728 * @} | |
729 */ | |
730 | |
731 /** | |
732 * @defgroup container Services and Dependency Injection Container | |
733 * @{ | |
734 * Overview of the Dependency Injection Container and Services. | |
735 * | |
736 * @section sec_overview Overview of container, injection, and services | |
737 * The Services and Dependency Injection Container concepts have been adopted by | |
738 * Drupal from the @link http://symfony.com/ Symfony framework. @endlink A | |
739 * "service" (such as accessing the database, sending email, or translating user | |
740 * interface text) is defined (given a name and an interface or at least a | |
741 * class that defines the methods that may be called), and a default class is | |
742 * designated to provide the service. These two steps must be done together, and | |
743 * can be done by Drupal Core or a module. Other modules can then define | |
744 * alternative classes to provide the same services, overriding the default | |
745 * classes. Classes and functions that need to use the service should always | |
746 * instantiate the class via the dependency injection container (also known | |
747 * simply as the "container"), rather than instantiating a particular service | |
748 * provider class directly, so that they get the correct class (default or | |
749 * overridden). | |
750 * | |
751 * See https://www.drupal.org/node/2133171 for more detailed information on | |
752 * services and the dependency injection container. | |
753 * | |
754 * @section sec_discover Discovering existing services | |
755 * Drupal core defines many core services in the core.services.yml file (in the | |
756 * top-level core directory). Some Drupal Core modules and contributed modules | |
757 * also define services in modulename.services.yml files. API reference sites | |
758 * (such as https://api.drupal.org) generate lists of all existing services from | |
759 * these files. Look for the Services link in the API Navigation block. | |
760 * Alternatively you can look through the individual files manually. | |
761 * | |
762 * A typical service definition in a *.services.yml file looks like this: | |
763 * @code | |
764 * path.alias_manager: | |
765 * class: Drupal\Core\Path\AliasManager | |
766 * arguments: ['@path.crud', '@path.alias_whitelist', '@language_manager'] | |
767 * @endcode | |
768 * Some services use other services as factories; a typical service definition | |
769 * is: | |
770 * @code | |
771 * cache.entity: | |
772 * class: Drupal\Core\Cache\CacheBackendInterface | |
773 * tags: | |
774 * - { name: cache.bin } | |
775 * factory: cache_factory:get | |
776 * arguments: [entity] | |
777 * @endcode | |
778 * | |
779 * The first line of a service definition gives the unique machine name of the | |
780 * service. This is often prefixed by the module name if provided by a module; | |
781 * however, by convention some service names are prefixed by a group name | |
782 * instead, such as cache.* for cache bins and plugin.manager.* for plugin | |
783 * managers. | |
784 * | |
785 * The class line either gives the default class that provides the service, or | |
786 * if the service uses a factory class, the interface for the service. If the | |
787 * class depends on other services, the arguments line lists the machine | |
788 * names of the dependencies (preceded by '@'); objects for each of these | |
789 * services are instantiated from the container and passed to the class | |
790 * constructor when the service class is instantiated. Other arguments can also | |
791 * be passed in; see the section at https://www.drupal.org/node/2133171 for more | |
792 * detailed information. | |
793 * | |
794 * Services using factories can be defined as shown in the above example, if the | |
795 * factory is itself a service. The factory can also be a class; details of how | |
796 * to use service factories can be found in the section at | |
797 * https://www.drupal.org/node/2133171. | |
798 * | |
799 * @section sec_container Accessing a service through the container | |
800 * As noted above, if you need to use a service in your code, you should always | |
801 * instantiate the service class via a call to the container, using the machine | |
802 * name of the service, so that the default class can be overridden. There are | |
803 * several ways to make sure this happens: | |
804 * - For service-providing classes, see other sections of this documentation | |
805 * describing how to pass services as arguments to the constructor. | |
806 * - Plugin classes, controllers, and similar classes have create() or | |
807 * createInstance() methods that are used to create an instance of the class. | |
808 * These methods come from different interfaces, and have different | |
809 * arguments, but they all include an argument $container of type | |
810 * \Symfony\Component\DependencyInjection\ContainerInterface. | |
811 * If you are defining one of these classes, in the create() or | |
812 * createInstance() method, call $container->get('myservice.name') to | |
813 * instantiate a service. The results of these calls are generally passed to | |
814 * the class constructor and saved as member variables in the class. | |
815 * - For functions and class methods that do not have access to either of | |
816 * the above methods of dependency injection, you can use service location to | |
817 * access services, via a call to the global \Drupal class. This class has | |
818 * special methods for accessing commonly-used services, or you can call a | |
819 * generic method to access any service. Examples: | |
820 * @code | |
821 * // Retrieve the entity.manager service object (special method exists). | |
822 * $manager = \Drupal::entityManager(); | |
823 * // Retrieve the service object for machine name 'foo.bar'. | |
824 * $foobar = \Drupal::service('foo.bar'); | |
825 * @endcode | |
826 * | |
827 * As a note, you should always use dependency injection (via service arguments | |
828 * or create()/createInstance() methods) if possible to instantiate services, | |
829 * rather than service location (via the \Drupal class), because: | |
830 * - Dependency injection facilitates writing unit tests, since the container | |
831 * argument can be mocked and the create() method can be bypassed by using | |
832 * the class constructor. If you use the \Drupal class, unit tests are much | |
833 * harder to write and your code has more dependencies. | |
834 * - Having the service interfaces on the class constructor and member variables | |
835 * is useful for IDE auto-complete and self-documentation. | |
836 * | |
837 * @section sec_define Defining a service | |
838 * If your module needs to define a new service, here are the steps: | |
839 * - Choose a unique machine name for your service. Typically, this should | |
840 * start with your module name. Example: mymodule.myservice. | |
841 * - Create a PHP interface to define what your service does. | |
842 * - Create a default class implementing your interface that provides your | |
843 * service. If your class needs to use existing services (such as database | |
844 * access), be sure to make these services arguments to your class | |
845 * constructor, and save them in member variables. Also, if the needed | |
846 * services are provided by other modules and not Drupal Core, you'll want | |
847 * these modules to be dependencies of your module. | |
848 * - Add an entry to a modulename.services.yml file for the service. See | |
849 * @ref sec_discover above, or existing *.services.yml files in Core, for the | |
850 * syntax; it will start with your machine name, refer to your default class, | |
851 * and list the services that need to be passed into your constructor. | |
852 * | |
853 * Services can also be defined dynamically, as in the | |
854 * \Drupal\Core\CoreServiceProvider class, but this is less common for modules. | |
855 * | |
856 * @section sec_tags Service tags | |
857 * Some services have tags, which are defined in the service definition. See | |
858 * @link service_tag Service Tags @endlink for usage. | |
859 * | |
860 * @section sec_injection Overriding the default service class | |
861 * Modules can override the default classes used for services. Here are the | |
862 * steps: | |
863 * - Define a class in the top-level namespace for your module | |
864 * (Drupal\my_module), whose name is the camel-case version of your module's | |
865 * machine name followed by "ServiceProvider" (for example, if your module | |
866 * machine name is my_module, the class must be named | |
867 * MyModuleServiceProvider). | |
868 * - The class needs to implement | |
869 * \Drupal\Core\DependencyInjection\ServiceModifierInterface, which is | |
870 * typically done by extending | |
871 * \Drupal\Core\DependencyInjection\ServiceProviderBase. | |
872 * - The class needs to contain one method: alter(). This method does the | |
873 * actual work of telling Drupal to use your class instead of the default. | |
874 * Here's an example: | |
875 * @code | |
876 * public function alter(ContainerBuilder $container) { | |
877 * // Override the language_manager class with a new class. | |
878 * $definition = $container->getDefinition('language_manager'); | |
879 * $definition->setClass('Drupal\my_module\MyLanguageManager'); | |
880 * } | |
881 * @endcode | |
882 * Note that $container here is an instance of | |
883 * \Drupal\Core\DependencyInjection\ContainerBuilder. | |
884 * | |
885 * @see https://www.drupal.org/node/2133171 | |
886 * @see core.services.yml | |
887 * @see \Drupal | |
888 * @see \Symfony\Component\DependencyInjection\ContainerInterface | |
889 * @see plugin_api | |
890 * @see menu | |
891 * @} | |
892 */ | |
893 | |
894 /** | |
895 * @defgroup listing_page_service Page header for Services page | |
896 * @{ | |
897 * Introduction to services | |
898 * | |
899 * A "service" (such as accessing the database, sending email, or translating | |
900 * user interface text) can be defined by a module or Drupal core. Defining a | |
901 * service means giving it a name and designating a default class to provide the | |
902 * service; ideally, there should also be an interface that defines the methods | |
903 * that may be called. Services are collected into the Dependency Injection | |
904 * Container, and can be overridden to use different classes or different | |
905 * instantiation by modules. See the | |
906 * @link container Services and Dependency Injection Container topic @endlink | |
907 * for details. | |
908 * | |
909 * Some services have tags, which are defined in the service definition. Tags | |
910 * are used to define a group of related services, or to specify some aspect of | |
911 * how the service behaves. See the | |
912 * @link service_tag Service Tags topic @endlink for more information. | |
913 * | |
914 * @see container | |
915 * @see service_tag | |
916 * | |
917 * @} | |
918 */ | |
919 | |
920 /** | |
921 * @defgroup typed_data Typed Data API | |
922 * @{ | |
923 * API for describing data based on a set of available data types. | |
924 * | |
925 * PHP has data types, such as int, string, float, array, etc., and it is an | |
926 * object-oriented language that lets you define classes and interfaces. | |
927 * However, in some cases, it is useful to be able to define an abstract | |
928 * type (as in an interface, free of implementation details), that still has | |
929 * properties (which an interface cannot) as well as meta-data. The Typed Data | |
930 * API provides this abstraction. | |
931 * | |
932 * @section sec_overview Overview | |
933 * Each data type in the Typed Data API is a plugin class (annotation class | |
934 * example: \Drupal\Core\TypedData\Annotation\DataType); these plugins are | |
935 * managed by the typed_data_manager service (by default | |
936 * \Drupal\Core\TypedData\TypedDataManager). Each data object encapsulates a | |
937 * single piece of data, provides access to the metadata, and provides | |
938 * validation capability. Also, the typed data plugins have a shorthand | |
939 * for easily accessing data values, described in @ref sec_tree. | |
940 * | |
941 * The metadata of a data object is defined by an object based on a class called | |
942 * the definition class (see \Drupal\Core\TypedData\DataDefinitionInterface). | |
943 * The class used can vary by data type and can be specified in the data type's | |
944 * plugin definition, while the default is set in the $definition_class property | |
945 * of the annotation class. The default class is | |
946 * \Drupal\Core\TypedData\DataDefinition. For data types provided by a plugin | |
947 * deriver, the plugin deriver can set the definition_class property too. | |
948 * The metadata object provides information about the data, such as the data | |
949 * type, whether it is translatable, the names of its properties (for complex | |
950 * types), and who can access it. | |
951 * | |
952 * See https://www.drupal.org/node/1794140 for more information about the Typed | |
953 * Data API. | |
954 * | |
955 * @section sec_varieties Varieties of typed data | |
956 * There are three kinds of typed data: primitive, complex, and list. | |
957 * | |
958 * @subsection sub_primitive Primitive data types | |
959 * Primitive data types wrap PHP data types and also serve as building blocks | |
960 * for complex and list typed data. Each primitive data type has an interface | |
961 * that extends \Drupal\Core\TypedData\PrimitiveInterface, with getValue() | |
962 * and setValue() methods for accessing the data value, and a default plugin | |
963 * implementation. Here's a list: | |
964 * - \Drupal\Core\TypedData\Type\IntegerInterface: Plugin ID integer, | |
965 * corresponds to PHP type int. | |
966 * - \Drupal\Core\TypedData\Type\StringInterface: Plugin ID string, | |
967 * corresponds to PHP type string. | |
968 * - \Drupal\Core\TypedData\Type\FloatInterface: Plugin ID float, | |
969 * corresponds to PHP type float. | |
970 * - \Drupal\Core\TypedData\Type\BooleanInterface: Plugin ID bool, | |
971 * corresponds to PHP type bool. | |
972 * - \Drupal\Core\TypedData\Type\BinaryInterface: Plugin ID binary, | |
973 * corresponds to a PHP file resource. | |
974 * - \Drupal\Core\TypedData\Type\UriInterface: Plugin ID uri. | |
975 * | |
976 * @subsection sec_complex Complex data | |
977 * Complex data types, with interface | |
978 * \Drupal\Core\TypedData\ComplexDataInterface, represent data with named | |
979 * properties; the properties can be accessed with get() and set() methods. | |
980 * The value of each property is itself a typed data object, which can be | |
981 * primitive, complex, or list data. | |
982 * | |
983 * The base type for most complex data is the | |
984 * \Drupal\Core\TypedData\Plugin\DataType\Map class, which represents an | |
985 * associative array. Map provides its own definition class in the annotation, | |
986 * \Drupal\Core\TypedData\MapDataDefinition, and most complex data classes | |
987 * extend this class. The getValue() and setValue() methods on the Map class | |
988 * enforce the data definition and its property structure. | |
989 * | |
990 * The Drupal Field API uses complex typed data for its field items, with | |
991 * definition class \Drupal\Core\Field\TypedData\FieldItemDataDefinition. | |
992 * | |
993 * @section sec_list Lists | |
994 * List data types, with interface \Drupal\Core\TypedData\ListInterface, | |
995 * represent data that is an ordered list of typed data, all of the same type. | |
996 * More precisely, the plugins in the list must have the same base plugin ID; | |
997 * however, some types (for example field items and entities) are provided by | |
998 * plugin derivatives and the sub IDs can be different. | |
999 * | |
1000 * @section sec_tree Tree handling | |
1001 * Typed data allows you to use shorthand to get data values nested in the | |
1002 * implicit tree structure of the data. For example, to get the value from | |
1003 * an entity field item, the Entity Field API allows you to call: | |
1004 * @code | |
1005 * $value = $entity->fieldName->propertyName; | |
1006 * @endcode | |
1007 * This is really shorthand for: | |
1008 * @code | |
1009 * $field_item_list = $entity->get('fieldName'); | |
1010 * $field_item = $field_item_list->get(0); | |
1011 * $property = $field_item->get('propertyName'); | |
1012 * $value = $property->getValue(); | |
1013 * @endcode | |
1014 * Some notes: | |
1015 * - $property, $field_item, and $field_item_list are all typed data objects, | |
1016 * while $value is a raw PHP value. | |
1017 * - You can call $property->getParent() to get $field_item, | |
1018 * $field_item->getParent() to get $field_item_list, or | |
1019 * $field_item_list->getParent() to get $typed_entity ($entity wrapped in a | |
1020 * typed data object). $typed_entity->getParent() is NULL. | |
1021 * - For all of these ->getRoot() returns $typed_entity. | |
1022 * - The langcode property is on $field_item_list, but you can access it | |
1023 * on $property as well, so that all items will report the same langcode. | |
1024 * - When the value of $property is changed by calling $property->setValue(), | |
1025 * $property->onChange() will fire, which in turn calls the parent object's | |
1026 * onChange() method and so on. This allows parent objects to react upon | |
1027 * changes of contained properties or list items. | |
1028 * | |
1029 * @section sec_defining Defining data types | |
1030 * To define a new data type: | |
1031 * - Create a class that implements one of the Typed Data interfaces. | |
1032 * Typically, you will want to extend one of the classes listed in the | |
1033 * sections above as a starting point. | |
1034 * - Make your class into a DataType plugin. To do that, put it in namespace | |
1035 * \Drupal\yourmodule\Plugin\DataType (where "yourmodule" is your module's | |
1036 * short name), and add annotation of type | |
1037 * \Drupal\Core\TypedData\Annotation\DataType to the documentation header. | |
1038 * See the @link plugin_api Plugin API topic @endlink and the | |
1039 * @link annotation Annotations topic @endlink for more information. | |
1040 * | |
1041 * @section sec_using Using data types | |
1042 * The data types of the Typed Data API can be used in several ways, once they | |
1043 * have been defined: | |
1044 * - In the Field API, data types can be used as the class in the property | |
1045 * definition of the field. See the @link field Field API topic @endlink for | |
1046 * more information. | |
1047 * - In configuration schema files, you can use the unique ID ('id' annotation) | |
1048 * from any DataType plugin class as the 'type' value for an entry. See the | |
1049 * @link config_api Confuration API topic @endlink for more information. | |
1050 * - If you need to create a typed data object in code, first get the | |
1051 * typed_data_manager service from the container or by calling | |
1052 * \Drupal::typedDataManager(). Then pass the plugin ID to | |
1053 * $manager::createDataDefinition() to create an appropriate data definition | |
1054 * object. Then pass the data definition object and the value of the data to | |
1055 * $manager::create() to create a typed data object. | |
1056 * | |
1057 * @see plugin_api | |
1058 * @see container | |
1059 * @} | |
1060 */ | |
1061 | |
1062 /** | |
1063 * @defgroup testing Automated tests | |
1064 * @{ | |
1065 * Overview of PHPUnit tests and Simpletest tests. | |
1066 * | |
1067 * The Drupal project has embraced a philosophy of using automated tests, | |
1068 * consisting of both unit tests (which test the functionality of classes at a | |
1069 * low level) and functional tests (which test the functionality of Drupal | |
1070 * systems at a higher level, usually involving web output). The goal is to | |
1071 * have test coverage for all or most of the components and features, and to | |
1072 * run the automated tests before any code is changed or added, to make sure | |
1073 * it doesn't break any existing functionality (regression testing). | |
1074 * | |
1075 * In order to implement this philosophy, developers need to do the following: | |
1076 * - When making a patch to fix a bug, make sure that the bug fix patch includes | |
1077 * a test that fails without the code change and passes with the code change. | |
1078 * This helps reviewers understand what the bug is, demonstrates that the code | |
1079 * actually fixes the bug, and ensures the bug will not reappear due to later | |
1080 * code changes. | |
1081 * - When making a patch to implement a new feature, include new unit and/or | |
1082 * functional tests in the patch. This serves to both demonstrate that the | |
1083 * code actually works, and ensure that later changes do not break the new | |
1084 * functionality. | |
1085 * | |
1086 * @section write_unit Writing PHPUnit tests for classes | |
1087 * PHPUnit tests for classes are written using the industry-standard PHPUnit | |
1088 * framework. Use a PHPUnit test to test functionality of a class if the Drupal | |
1089 * environment (database, settings, etc.) and web browser are not needed for the | |
1090 * test, or if the Drupal environment can be replaced by a "mock" object. To | |
1091 * write a PHPUnit test: | |
1092 * - Define a class that extends \Drupal\Tests\UnitTestCase. | |
1093 * - The class name needs to end in the word Test. | |
1094 * - The namespace must be a subspace/subdirectory of \Drupal\yourmodule\Tests, | |
1095 * where yourmodule is your module's machine name. | |
1096 * - The test class file must be named and placed under the | |
1097 * yourmodule/tests/src/Unit directory, according to the PSR-4 standard. | |
1098 * - Your test class needs a phpDoc comment block with a description and | |
1099 * a @group annotation, which gives information about the test. | |
1100 * - Add test cases by adding method names that start with 'test' and have no | |
1101 * arguments, for example testYourTestCase(). Each one should test a logical | |
1102 * subset of the functionality. | |
1103 * For more details, see: | |
1104 * - https://www.drupal.org/phpunit for full documentation on how to write | |
1105 * PHPUnit tests for Drupal. | |
1106 * - http://phpunit.de for general information on the PHPUnit framework. | |
1107 * - @link oo_conventions Object-oriented programming topic @endlink for more | |
1108 * on PSR-4, namespaces, and where to place classes. | |
1109 * | |
1110 * @section write_functional Writing functional tests | |
1111 * Functional tests are written using a Drupal-specific framework that is, for | |
1112 * historical reasons, known as "Simpletest". Use a Simpletest test to test the | |
1113 * functionality of sub-system of Drupal, if the functionality depends on the | |
1114 * Drupal database and settings, or to test the web output of Drupal. To | |
1115 * write a Simpletest test: | |
1116 * - For functional tests of the web output of Drupal, define a class that | |
1117 * extends \Drupal\simpletest\WebTestBase, which contains an internal web | |
1118 * browser and defines many helpful test assertion methods that you can use | |
1119 * in your tests. You can specify modules to be enabled by defining a | |
1120 * $modules member variable -- keep in mind that by default, WebTestBase uses | |
1121 * a "testing" install profile, with a minimal set of modules enabled. | |
1122 * - For functional tests that do not test web output, define a class that | |
1123 * extends \Drupal\KernelTests\KernelTestBase. This class is much faster | |
1124 * than WebTestBase, because instead of making a full install of Drupal, it | |
1125 * uses an in-memory pseudo-installation (similar to what the installer and | |
1126 * update scripts use). To use this test class, you will need to create the | |
1127 * database tables you need and install needed modules manually. | |
1128 * - The namespace must be a subspace/subdirectory of \Drupal\yourmodule\Tests, | |
1129 * where yourmodule is your module's machine name. | |
1130 * - The test class file must be named and placed under the yourmodule/src/Tests | |
1131 * directory, according to the PSR-4 standard. | |
1132 * - Your test class needs a phpDoc comment block with a description and | |
1133 * a @group annotation, which gives information about the test. | |
1134 * - You may also override the default setUp() method, which can set be used to | |
1135 * set up content types and similar procedures. | |
1136 * - In some cases, you may need to write a test module to support your test; | |
1137 * put such modules under the yourmodule/tests/modules directory. | |
1138 * - Add test cases by adding method names that start with 'test' and have no | |
1139 * arguments, for example testYourTestCase(). Each one should test a logical | |
1140 * subset of the functionality. Each method runs in a new, isolated test | |
1141 * environment, so it can only rely on the setUp() method, not what has | |
1142 * been set up by other test methods. | |
1143 * For more details, see: | |
1144 * - https://www.drupal.org/simpletest for full documentation on how to write | |
1145 * functional tests for Drupal. | |
1146 * - @link oo_conventions Object-oriented programming topic @endlink for more | |
1147 * on PSR-4, namespaces, and where to place classes. | |
1148 * | |
1149 * @section write_functional_phpunit Write functional PHP tests (phpunit) | |
1150 * Functional tests extend the BrowserTestBase base class, and use PHPUnit as | |
1151 * their underlying framework. They use a simulated browser, in which the test | |
1152 * can click links, visit URLs, post to forms, etc. To write a functional test: | |
1153 * - Extend \Drupal\Tests\BrowserTestBase. | |
1154 * - Place the test in the yourmodule/tests/src/Functional/ directory and use | |
1155 * the \Drupal\Tests\yourmodule\Functional namespace. | |
1156 * - Add a @group annotation. For example, if the test is for a Drupal 6 | |
1157 * migration process, the group core uses is migrate_drupal_6. Use yourmodule | |
1158 * as the group name if the test does not belong to another larger group. | |
1159 * - You may also override the default setUp() method, which can be used to set | |
1160 * up content types and similar procedures. Don't forget to call the parent | |
1161 * method. | |
1162 * - In some cases, you may need to write a test module to support your test; | |
1163 * put such modules under the yourmodule/tests/modules directory. | |
1164 * - Add test cases by adding method names that start with 'test' and have no | |
1165 * arguments, for example testYourTestCase(). Each one should test a logical | |
1166 * subset of the functionality. Each method runs in a new, isolated test | |
1167 * environment, so it can only rely on the setUp() method, not what has | |
1168 * been set up by other test methods. | |
1169 * For more details, see: | |
1170 * - https://www.drupal.org/docs/8/phpunit/phpunit-browser-test-tutorial for | |
1171 * a full tutorial on how to write functional PHPUnit tests for Drupal. | |
1172 * - https://www.drupal.org/phpunit for the full documentation on how to write | |
1173 * PHPUnit tests for Drupal. | |
1174 * | |
1175 * @section write_jsfunctional_phpunit Write functional JavaScript tests (phpunit) | |
1176 * To write a functional test that relies on JavaScript: | |
1177 * - Extend \Drupal\FunctionalJavaScriptTests\JavascriptTestBase. | |
1178 * - Place the test into the yourmodule/tests/src/FunctionalJavascript/ | |
1179 * directory and use the \Drupal\Tests\yourmodule\FunctionalJavascript | |
1180 * namespace. | |
1181 * - Add a @group annotation. Use yourmodule as the group name if the test does | |
1182 * not belong to another larger group. | |
1183 * - Set up PhantomJS; see http://phantomjs.org/download.html. | |
1184 * - To run tests, see core/tests/README.md. | |
1185 * - When clicking a link/button with Ajax behavior attached, keep in mind that | |
1186 * the underlying browser might take time to deliver changes to the HTML. Use | |
1187 * $this->assertSession()->assertWaitOnAjaxRequest() to wait for the Ajax | |
1188 * request to finish. | |
1189 * For more details, see: | |
1190 * - https://www.drupal.org/docs/8/phpunit/phpunit-javascript-testing-tutorial | |
1191 * for a full tutorial on how to write PHPUnit JavaScript tests for Drupal. | |
1192 * - https://www.drupal.org/phpunit for the full documentation on how to write | |
1193 * PHPUnit tests for Drupal. | |
1194 * | |
1195 * @section running Running tests | |
1196 * You can run both Simpletest and PHPUnit tests by enabling the core Testing | |
1197 * module (core/modules/simpletest). Once that module is enabled, tests can be | |
1198 * run using the core/scripts/run-tests.sh script, using | |
1199 * @link https://www.drupal.org/project/drush Drush @endlink, or from the | |
1200 * Testing module user interface. | |
1201 * | |
1202 * PHPUnit tests can also be run from the command line, using the PHPUnit | |
1203 * framework. See https://www.drupal.org/node/2116263 for more information. | |
1204 * @} | |
1205 */ | |
1206 | |
1207 /** | |
1208 * @defgroup php_assert PHP Runtime Assert Statements | |
1209 * @{ | |
1210 * Use of the assert() statement in Drupal. | |
1211 * | |
1212 * Unit tests also use the term "assertion" to refer to test conditions, so to | |
1213 * avoid confusion the term "runtime assertion" will be used for the assert() | |
1214 * statement throughout the documentation. | |
1215 * | |
1216 * A runtime assertion is a statement that is expected to always be true at | |
1217 * the point in the code it appears at. They are tested using PHP's internal | |
1218 * @link http://php.net/assert assert() @endlink statement. If an | |
1219 * assertion is ever FALSE it indicates an error in the code or in module or | |
1220 * theme configuration files. User-provided configuration files should be | |
1221 * verified with standard control structures at all times, not just checked in | |
1222 * development environments with assert() statements on. | |
1223 * | |
1224 * The Drupal project primarily uses runtime assertions to enforce the | |
1225 * expectations of the API by failing when incorrect calls are made by code | |
1226 * under development. While PHP type hinting does this for objects and arrays, | |
1227 * runtime assertions do this for scalars (strings, integers, floats, etc.) and | |
1228 * complex data structures such as cache and render arrays. They ensure that | |
1229 * methods' return values are the documented data types. They also verify that | |
1230 * objects have been properly configured and set up by the service container. | |
1231 * They supplement unit tests by checking scenarios that do not have unit tests | |
1232 * written for them. | |
1233 * | |
1234 * There are two php settings which affect runtime assertions. The first, | |
1235 * assert.exception, should always be set to 1. The second is zend.assertions. | |
1236 * Set this to -1 in production and 1 in development. | |
1237 * | |
1238 * See https://www.drupal.org/node/2492225 for more information on runtime | |
1239 * assertions. | |
1240 * @} | |
1241 */ | |
1242 | |
1243 /** | |
1244 * @defgroup info_types Information types | |
1245 * @{ | |
1246 * Types of information in Drupal. | |
1247 * | |
1248 * Drupal has several distinct types of information, each with its own methods | |
1249 * for storage and retrieval: | |
1250 * - Content: Information meant to be displayed on your site: articles, basic | |
1251 * pages, images, files, custom blocks, etc. Content is stored and accessed | |
1252 * using @link entity_api Entities @endlink. | |
1253 * - Session: Information about individual users' interactions with the site, | |
1254 * such as whether they are logged in. This is really "state" information, but | |
1255 * it is not stored the same way so it's a separate type here. Session data is | |
1256 * accessed via \Symfony\Component\HttpFoundation\Request::getSession(), which | |
1257 * returns an instance of | |
1258 * \Symfony\Component\HttpFoundation\Session\SessionInterface. | |
1259 * See the @link session Sessions topic @endlink for more information. | |
1260 * - State: Information of a temporary nature, generally machine-generated and | |
1261 * not human-edited, about the current state of your site. Examples: the time | |
1262 * when Cron was last run, whether node access permissions need rebuilding, | |
1263 * etc. See @link state_api the State API topic @endlink for more information. | |
1264 * - Configuration: Information about your site that is generally (or at least | |
1265 * can be) human-edited, but is not Content, and is meant to be relatively | |
1266 * permanent. Examples: the name of your site, the content types and views | |
1267 * you have defined, etc. See | |
1268 * @link config_api the Configuration API topic @endlink for more information. | |
1269 * | |
1270 * @see cache | |
1271 * @see i18n | |
1272 * @} | |
1273 */ | |
1274 | |
1275 /** | |
1276 * @defgroup extending Extending and altering Drupal | |
1277 * @{ | |
1278 * Overview of extensions and alteration methods for Drupal. | |
1279 * | |
1280 * @section sec_types Types of extensions | |
1281 * Drupal's core behavior can be extended and altered via these three basic | |
1282 * types of extensions: | |
1283 * - Themes: Themes alter the appearance of Drupal sites. They can include | |
1284 * template files, which alter the HTML markup and other raw output of the | |
1285 * site; CSS files, which alter the styling applied to the HTML; and | |
1286 * JavaScript, Flash, images, and other files. For more information, see the | |
1287 * @link theme_render Theme system and render API topic @endlink and | |
1288 * https://www.drupal.org/docs/8/theming | |
1289 * - Modules: Modules add to or alter the behavior and functionality of Drupal, | |
1290 * by using one or more of the methods listed below. For more information | |
1291 * about creating modules, see https://www.drupal.org/developing/modules/8 | |
1292 * - Installation profiles: Installation profiles can be used to | |
1293 * create distributions, which are complete specific-purpose packages of | |
1294 * Drupal including additional modules, themes, and data. For more | |
1295 * information, see https://www.drupal.org/developing/distributions. | |
1296 * | |
1297 * @section sec_alter Alteration methods for modules | |
1298 * Here is a list of the ways that modules can alter or extend Drupal's core | |
1299 * behavior, or the behavior of other modules: | |
1300 * - Hooks: Specially-named functions that a module defines, which are | |
1301 * discovered and called at specific times, usually to alter behavior or data. | |
1302 * See the @link hooks Hooks topic @endlink for more information. | |
1303 * - Plugins: Classes that a module defines, which are discovered and | |
1304 * instantiated at specific times to add functionality. See the | |
1305 * @link plugin_api Plugin API topic @endlink for more information. | |
1306 * - Entities: Special plugins that define entity types for storing new types | |
1307 * of content or configuration in Drupal. See the | |
1308 * @link entity_api Entity API topic @endlink for more information. | |
1309 * - Services: Classes that perform basic operations within Drupal, such as | |
1310 * accessing the database and sending email. See the | |
1311 * @link container Dependency Injection Container and Services topic @endlink | |
1312 * for more information. | |
1313 * - Routing: Providing or altering "routes", which are URLs that Drupal | |
1314 * responds to, or altering routing behavior with event listener classes. | |
1315 * See the @link menu Routing and menu topic @endlink for more information. | |
1316 * - Events: Modules can register as event subscribers; when an event is | |
1317 * dispatched, a method is called on each registered subscriber, allowing each | |
1318 * one to react. See the @link events Events topic @endlink for more | |
1319 * information. | |
1320 * | |
1321 * @section sec_sample *.info.yml files | |
1322 * Extensions must each be located in a directory whose name matches the short | |
1323 * name (or machine name) of the extension, and this directory must contain a | |
1324 * file named machine_name.info.yml (where machine_name is the machine name of | |
1325 * the extension). See \Drupal\Core\Extension\InfoParserInterface::parse() for | |
1326 * documentation of the format of .info.yml files. | |
1327 * @} | |
1328 */ | |
1329 | |
1330 /** | |
1331 * @defgroup plugin_api Plugin API | |
1332 * @{ | |
1333 * Using the Plugin API | |
1334 * | |
1335 * @section sec_overview Overview and terminology | |
1336 * | |
1337 * The basic idea of plugins is to allow a particular module or subsystem of | |
1338 * Drupal to provide functionality in an extensible, object-oriented way. The | |
1339 * controlling module or subsystem defines the basic framework (interface) for | |
1340 * the functionality, and other modules can create plugins (implementing the | |
1341 * interface) with particular behaviors. The controlling module instantiates | |
1342 * existing plugins as needed, and calls methods to invoke their functionality. | |
1343 * Examples of functionality in Drupal Core that use plugins include: the block | |
1344 * system (block types are plugins), the entity/field system (entity types, | |
1345 * field types, field formatters, and field widgets are plugins), the image | |
1346 * manipulation system (image effects and image toolkits are plugins), and the | |
1347 * search system (search page types are plugins). | |
1348 * | |
1349 * Plugins are grouped into plugin types, each generally defined by an | |
1350 * interface. Each plugin type is managed by a plugin manager service, which | |
1351 * uses a plugin discovery method to discover provided plugins of that type and | |
1352 * instantiate them using a plugin factory. | |
1353 * | |
1354 * Some plugin types make use of the following concepts or components: | |
1355 * - Plugin derivatives: Allows a single plugin class to present itself as | |
1356 * multiple plugins. Example: the Menu module provides a block for each | |
1357 * defined menu via a block plugin derivative. | |
1358 * - Plugin mapping: Allows a plugin class to map a configuration string to an | |
1359 * instance, and have the plugin automatically instantiated without writing | |
1360 * additional code. | |
1361 * - Plugin collections: Provide a way to lazily instantiate a set of plugin | |
1362 * instances from a single plugin definition. | |
1363 * | |
1364 * There are several things a module developer may need to do with plugins: | |
1365 * - Define a completely new plugin type: see @ref sec_define below. | |
1366 * - Create a plugin of an existing plugin type: see @ref sec_create below. | |
1367 * - Perform tasks that involve plugins: see @ref sec_use below. | |
1368 * | |
1369 * See https://www.drupal.org/developing/api/8/plugins for more detailed | |
1370 * documentation on the plugin system. There are also topics for a few | |
1371 * of the many existing types of plugins: | |
1372 * - @link block_api Block API @endlink | |
1373 * - @link entity_api Entity API @endlink | |
1374 * - @link field Various types of field-related plugins @endlink | |
1375 * - @link views_plugins Views plugins @endlink (has links to topics covering | |
1376 * various specific types of Views plugins). | |
1377 * - @link search Search page plugins @endlink | |
1378 * | |
1379 * @section sec_define Defining a new plugin type | |
1380 * To define a new plugin type: | |
1381 * - Define an interface for the plugin. This describes the common set of | |
1382 * behavior, and the methods you will call on each plugin class that is | |
1383 * instantiated. Usually this interface will extend one or more of the | |
1384 * following interfaces: | |
1385 * - \Drupal\Component\Plugin\PluginInspectionInterface | |
1386 * - \Drupal\Component\Plugin\ConfigurablePluginInterface | |
1387 * - \Drupal\Component\Plugin\ContextAwarePluginInterface | |
1388 * - \Drupal\Core\Plugin\PluginFormInterface | |
1389 * - \Drupal\Core\Executable\ExecutableInterface | |
1390 * - (optional) Create a base class that provides a partial implementation of | |
1391 * the interface, for the convenience of developers wishing to create plugins | |
1392 * of your type. The base class usually extends | |
1393 * \Drupal\Core\Plugin\PluginBase, or one of the base classes that extends | |
1394 * this class. | |
1395 * - Choose a method for plugin discovery, and define classes as necessary. | |
1396 * See @ref sub_discovery below. | |
1397 * - Create a plugin manager/factory class and service, which will discover and | |
1398 * instantiate plugins. See @ref sub_manager below. | |
1399 * - Use the plugin manager to instantiate plugins. Call methods on your plugin | |
1400 * interface to perform the tasks of your plugin type. | |
1401 * - (optional) If appropriate, define a plugin collection. See @ref | |
1402 * sub_collection below for more information. | |
1403 * | |
1404 * @subsection sub_discovery Plugin discovery | |
1405 * Plugin discovery is the process your plugin manager uses to discover the | |
1406 * individual plugins of your type that have been defined by your module and | |
1407 * other modules. Plugin discovery methods are classes that implement | |
1408 * \Drupal\Component\Plugin\Discovery\DiscoveryInterface. Most plugin types use | |
1409 * one of the following discovery mechanisms: | |
1410 * - Annotation: Plugin classes are annotated and placed in a defined namespace | |
1411 * subdirectory. Most Drupal Core plugins use this method of discovery. | |
1412 * - Hook: Plugin modules need to implement a hook to tell the manager about | |
1413 * their plugins. | |
1414 * - YAML: Plugins are listed in YAML files. Drupal Core uses this method for | |
1415 * discovering local tasks and local actions. This is mainly useful if all | |
1416 * plugins use the same class, so it is kind of like a global derivative. | |
1417 * - Static: Plugin classes are registered within the plugin manager class | |
1418 * itself. Static discovery is only useful if modules cannot define new | |
1419 * plugins of this type (if the list of available plugins is static). | |
1420 * | |
1421 * It is also possible to define your own custom discovery mechanism or mix | |
1422 * methods together. And there are many more details, such as annotation | |
1423 * decorators, that apply to some of the discovery methods. See | |
1424 * https://www.drupal.org/developing/api/8/plugins for more details. | |
1425 * | |
1426 * The remainder of this documentation will assume Annotation-based discovery, | |
1427 * since this is the most common method. | |
1428 * | |
1429 * @subsection sub_manager Defining a plugin manager class and service | |
1430 * To define an annotation-based plugin manager: | |
1431 * - Choose a namespace subdirectory for your plugin. For example, search page | |
1432 * plugins go in directory Plugin/Search under the module namespace. | |
1433 * - Define an annotation class for your plugin type. This class should extend | |
1434 * \Drupal\Component\Annotation\Plugin, and for most plugin types, it should | |
1435 * contain member variables corresponding to the annotations plugins will | |
1436 * need to provide. All plugins have at least $id: a unique string | |
1437 * identifier. | |
1438 * - Define an alter hook for altering the discovered plugin definitions. You | |
1439 * should document the hook in a *.api.php file. | |
1440 * - Define a plugin manager class. This class should implement | |
1441 * \Drupal\Component\Plugin\PluginManagerInterface; most plugin managers do | |
1442 * this by extending \Drupal\Core\Plugin\DefaultPluginManager. If you do | |
1443 * extend the default plugin manager, the only method you will probably need | |
1444 * to define is the class constructor, which will need to call the parent | |
1445 * constructor to provide information about the annotation class and plugin | |
1446 * namespace for discovery, set up the alter hook, and possibly set up | |
1447 * caching. See classes that extend DefaultPluginManager for examples. | |
1448 * - Define a service for your plugin manager. See the | |
1449 * @link container Services topic for more information. @endlink Your service | |
1450 * definition should look something like this, referencing your manager | |
1451 * class and the parent (default) plugin manager service to inherit | |
1452 * constructor arguments: | |
1453 * @code | |
1454 * plugin.manager.mymodule: | |
1455 * class: Drupal\mymodule\MyPluginManager | |
1456 * parent: default_plugin_manager | |
1457 * @endcode | |
1458 * - If your plugin is configurable, you will also need to define the | |
1459 * configuration schema and possibly a configuration entity type. See the | |
1460 * @link config_api Configuration API topic @endlink for more information. | |
1461 * | |
1462 * @subsection sub_collection Defining a plugin collection | |
1463 * Some configurable plugin types allow administrators to create zero or more | |
1464 * instances of each plugin, each with its own configuration. For example, | |
1465 * a single block plugin can be configured several times, to display in | |
1466 * different regions of a theme, with different visibility settings, a | |
1467 * different title, or other plugin-specific settings. To make this possible, | |
1468 * a plugin type can make use of what's known as a plugin collection. | |
1469 * | |
1470 * A plugin collection is a class that extends | |
1471 * \Drupal\Component\Plugin\LazyPluginCollection or one of its subclasses; there | |
1472 * are several examples in Drupal Core. If your plugin type uses a plugin | |
1473 * collection, it will usually also have a configuration entity, and the entity | |
1474 * class should implement | |
1475 * \Drupal\Core\Entity\EntityWithPluginCollectionInterface. Again, there are | |
1476 * several examples in Drupal Core; see also the @link config_api Configuration | |
1477 * API topic @endlink for more information about configuration entities. | |
1478 * | |
1479 * @section sec_create Creating a plugin of an existing type | |
1480 * Assuming the plugin type uses annotation-based discovery, in order to create | |
1481 * a plugin of an existing type, you will be creating a class. This class must: | |
1482 * - Implement the plugin interface, so that it has the required methods | |
1483 * defined. Usually, you'll want to extend the plugin base class, if one has | |
1484 * been provided. | |
1485 * - Have the right annotation in its documentation header. See the | |
1486 * @link annotation Annotation topic @endlink for more information about | |
1487 * annotation. | |
1488 * - Be in the right plugin namespace, in order to be discovered. | |
1489 * Often, the easiest way to make sure this happens is to find an existing | |
1490 * example of a working plugin class of the desired type, and copy it into your | |
1491 * module as a starting point. | |
1492 * | |
1493 * You can also create a plugin derivative, which allows your plugin class | |
1494 * to present itself to the user interface as multiple plugins. To do this, | |
1495 * in addition to the plugin class, you'll need to create a separate plugin | |
1496 * derivative class implementing | |
1497 * \Drupal\Component\Plugin\Derivative\DerivativeInterface. The classes | |
1498 * \Drupal\system\Plugin\Block\SystemMenuBlock (plugin class) and | |
1499 * \Drupal\system\Plugin\Derivative\SystemMenuBlock (derivative class) are a | |
1500 * good example to look at. | |
1501 * | |
1502 * @section sec_use Performing tasks involving plugins | |
1503 * Here are the steps to follow to perform a task that involves plugins: | |
1504 * - Locate the machine name of the plugin manager service, and instantiate the | |
1505 * service. See the @link container Services topic @endlink for more | |
1506 * information on how to do this. | |
1507 * - On the plugin manager class, use methods like getDefinition(), | |
1508 * getDefinitions(), or other methods specific to particular plugin managers | |
1509 * to retrieve information about either specific plugins or the entire list of | |
1510 * defined plugins. | |
1511 * - Call the createInstance() method on the plugin manager to instantiate | |
1512 * individual plugin objects. | |
1513 * - Call methods on the plugin objects to perform the desired tasks. | |
1514 * | |
1515 * @see annotation | |
1516 * @} | |
1517 */ | |
1518 | |
1519 /** | |
1520 * @defgroup oo_conventions Objected-oriented programming conventions | |
1521 * @{ | |
1522 * PSR-4, namespaces, class naming, and other conventions. | |
1523 * | |
1524 * A lot of the PHP code in Drupal is object oriented (OO), making use of | |
1525 * @link http://php.net/manual/language.oop5.php PHP classes, interfaces, and traits @endlink | |
1526 * (which are loosely referred to as "classes" in the rest of this topic). The | |
1527 * following conventions and standards apply to this version of Drupal: | |
1528 * - Each class must be in its own file. | |
1529 * - Classes must be namespaced. If a module defines a class, the namespace | |
1530 * must start with \Drupal\module_name. If it is defined by Drupal Core for | |
1531 * use across many modules, the namespace should be \Drupal\Core or | |
1532 * \Drupal\Component, with the exception of the global class \Drupal. See | |
1533 * https://www.drupal.org/node/1353118 for more about namespaces. | |
1534 * - In order for the PSR-4-based class auto-loader to find the class, it must | |
1535 * be located in a directory corresponding to the namespace. For | |
1536 * module-defined classes, if the namespace is \Drupal\module_name\foo\bar, | |
1537 * then the class goes under the main module directory in directory | |
1538 * src/foo/bar. For Drupal-wide classes, if the namespace is | |
1539 * \Drupal\Core\foo\bar, then it goes in directory | |
1540 * core/lib/Drupal/Core/foo/bar. See https://www.drupal.org/node/2156625 for | |
1541 * more information about PSR-4. | |
1542 * - Some classes have annotations added to their documentation headers. See | |
1543 * the @link annotation Annotation topic @endlink for more information. | |
1544 * - Standard plugin discovery requires particular namespaces and annotation | |
1545 * for most plugin classes. See the | |
1546 * @link plugin_api Plugin API topic @endlink for more information. | |
1547 * - There are project-wide coding standards for OO code, including naming: | |
1548 * https://www.drupal.org/node/608152 | |
1549 * - Documentation standards for classes are covered on: | |
1550 * https://www.drupal.org/coding-standards/docs#classes | |
1551 * @} | |
1552 */ | |
1553 | |
1554 /** | |
1555 * @defgroup listing_page_class Page header for Classes page | |
1556 * @{ | |
1557 * Introduction to classes | |
1558 * | |
1559 * A lot of the PHP code in Drupal is object oriented (OO), making use of | |
1560 * @link http://php.net/manual/language.oop5.php PHP classes, interfaces, and traits. @endlink | |
1561 * See the | |
1562 * @link oo_conventions Objected-oriented programming conventions @endlink | |
1563 * for more information. | |
1564 * | |
1565 * @see oo_conventions | |
1566 * | |
1567 * @} | |
1568 */ | |
1569 | |
1570 /** | |
1571 * @defgroup listing_page_namespace Page header for Namespaces page | |
1572 * @{ | |
1573 * Introduction to namespaces | |
1574 * | |
1575 * PHP classes, interfaces, and traits in Drupal are | |
1576 * @link http://php.net/manual/language.namespaces.rationale.php namespaced. @endlink | |
1577 * See the | |
1578 * @link oo_conventions Objected-oriented programming conventions @endlink | |
1579 * for more information. | |
1580 * | |
1581 * @see oo_conventions | |
1582 * | |
1583 * @} | |
1584 */ | |
1585 | |
1586 /** | |
1587 * @defgroup best_practices Best practices for developers | |
1588 * @{ | |
1589 * Overview of standards and best practices for developers | |
1590 * | |
1591 * Ideally, all code that is included in Drupal Core and contributed modules, | |
1592 * themes, and distributions will be secure, internationalized, maintainable, | |
1593 * and efficient. In order to facilitate this, the Drupal community has | |
1594 * developed a set of guidelines and standards for developers to follow. Most of | |
1595 * these standards can be found under | |
1596 * @link https://www.drupal.org/developing/best-practices Best practices on Drupal.org @endlink | |
1597 * | |
1598 * Standards and best practices that developers should be aware of include: | |
1599 * - Security: https://www.drupal.org/writing-secure-code and the | |
1600 * @link sanitization Sanitization functions topic @endlink | |
1601 * - Coding standards: https://www.drupal.org/coding-standards | |
1602 * and https://www.drupal.org/coding-standards/docs | |
1603 * - Accessibility: https://www.drupal.org/node/1637990 (modules) and | |
1604 * https://www.drupal.org/node/464472 (themes) | |
1605 * - Usability: https://www.drupal.org/ui-standards | |
1606 * - Internationalization: @link i18n Internationalization topic @endlink | |
1607 * - Automated testing: @link testing Automated tests topic @endlink | |
1608 * @} | |
1609 */ | |
1610 | |
1611 /** | |
1612 * @defgroup utility Utility classes and functions | |
1613 * @{ | |
1614 * Overview of utility classes and functions for developers. | |
1615 * | |
1616 * Drupal provides developers with a variety of utility functions that make it | |
1617 * easier and more efficient to perform tasks that are either really common, | |
1618 * tedious, or difficult. Utility functions help to reduce code duplication and | |
1619 * should be used in place of one-off code whenever possible. | |
1620 * | |
1621 * @see common.inc | |
1622 * @see file | |
1623 * @see format | |
1624 * @see php_wrappers | |
1625 * @see sanitization | |
1626 * @see transliteration | |
1627 * @see validation | |
1628 * @} | |
1629 */ | |
1630 | |
1631 /** | |
1632 * @defgroup hooks Hooks | |
1633 * @{ | |
1634 * Define functions that alter the behavior of Drupal core. | |
1635 * | |
1636 * One way for modules to alter the core behavior of Drupal (or another module) | |
1637 * is to use hooks. Hooks are specially-named functions that a module defines | |
1638 * (this is known as "implementing the hook"), which are discovered and called | |
1639 * at specific times to alter or add to the base behavior or data (this is | |
1640 * known as "invoking the hook"). Each hook has a name (example: | |
1641 * hook_batch_alter()), a defined set of parameters, and a defined return value. | |
1642 * Your modules can implement hooks that are defined by Drupal core or other | |
1643 * modules that they interact with. Your modules can also define their own | |
1644 * hooks, in order to let other modules interact with them. | |
1645 * | |
1646 * To implement a hook: | |
1647 * - Locate the documentation for the hook. Hooks are documented in *.api.php | |
1648 * files, by defining functions whose name starts with "hook_" (these | |
1649 * files and their functions are never loaded by Drupal -- they exist solely | |
1650 * for documentation). The function should have a documentation header, as | |
1651 * well as a sample function body. For example, in the core file | |
1652 * system.api.php, you can find hooks such as hook_batch_alter(). Also, if | |
1653 * you are viewing this documentation on an API reference site, the Core | |
1654 * hooks will be listed in this topic. | |
1655 * - Copy the function to your module's .module file. | |
1656 * - Change the name of the function, substituting your module's short name | |
1657 * (name of the module's directory, and .info.yml file without the extension) | |
1658 * for the "hook" part of the sample function name. For instance, to implement | |
1659 * hook_batch_alter(), you would rename it to my_module_batch_alter(). | |
1660 * - Edit the documentation for the function (normally, your implementation | |
1661 * should just have one line saying "Implements hook_batch_alter()."). | |
1662 * - Edit the body of the function, substituting in what you need your module | |
1663 * to do. | |
1664 * | |
1665 * To define a hook: | |
1666 * - Choose a unique name for your hook. It should start with "hook_", followed | |
1667 * by your module's short name. | |
1668 * - Provide documentation in a *.api.php file in your module's main | |
1669 * directory. See the "implementing" section above for details of what this | |
1670 * should contain (parameters, return value, and sample function body). | |
1671 * - Invoke the hook in your module's code. | |
1672 * | |
1673 * To invoke a hook, use methods on | |
1674 * \Drupal\Core\Extension\ModuleHandlerInterface such as alter(), invoke(), | |
1675 * and invokeAll(). You can obtain a module handler by calling | |
1676 * \Drupal::moduleHandler(), or getting the 'module_handler' service on an | |
1677 * injected container. | |
1678 * | |
1679 * @see extending | |
1680 * @see themeable | |
1681 * @see callbacks | |
1682 * @see \Drupal\Core\Extension\ModuleHandlerInterface | |
1683 * @see \Drupal::moduleHandler() | |
1684 * | |
1685 * @} | |
1686 */ | |
1687 | |
1688 /** | |
1689 * @defgroup callbacks Callbacks | |
1690 * @{ | |
1691 * Callback function signatures. | |
1692 * | |
1693 * Drupal's API sometimes uses callback functions to allow you to define how | |
1694 * some type of processing happens. A callback is a function with a defined | |
1695 * signature, which you define in a module. Then you pass the function name as | |
1696 * a parameter to a Drupal API function or return it as part of a hook | |
1697 * implementation return value, and your function is called at an appropriate | |
1698 * time. For instance, when setting up batch processing you might need to | |
1699 * provide a callback function for each processing step and/or a callback for | |
1700 * when processing is finished; you would do that by defining these functions | |
1701 * and passing their names into the batch setup function. | |
1702 * | |
1703 * Callback function signatures, like hook definitions, are described by | |
1704 * creating and documenting dummy functions in a *.api.php file; normally, the | |
1705 * dummy callback function's name should start with "callback_", and you should | |
1706 * document the parameters and return value and provide a sample function body. | |
1707 * Then your API documentation can refer to this callback function in its | |
1708 * documentation. A user of your API can usually name their callback function | |
1709 * anything they want, although a standard name would be to replace "callback_" | |
1710 * with the module name. | |
1711 * | |
1712 * @see hooks | |
1713 * @see themeable | |
1714 * | |
1715 * @} | |
1716 */ | |
1717 | |
1718 /** | |
1719 * @defgroup form_api Form generation | |
1720 * @{ | |
1721 * Describes how to generate and manipulate forms and process form submissions. | |
1722 * | |
1723 * Drupal provides a Form API in order to achieve consistency in its form | |
1724 * processing and presentation, while simplifying code and reducing the amount | |
1725 * of HTML that must be explicitly generated by a module. | |
1726 * | |
1727 * @section generating_forms Creating forms | |
1728 * Forms are defined as classes that implement the | |
1729 * \Drupal\Core\Form\FormInterface and are built using the | |
1730 * \Drupal\Core\Form\FormBuilder class. Drupal provides a couple of utility | |
1731 * classes that can be extended as a starting point for most basic forms, the | |
1732 * most commonly used of which is \Drupal\Core\Form\FormBase. FormBuilder | |
1733 * handles the low level processing of forms such as rendering the necessary | |
1734 * HTML, initial processing of incoming $_POST data, and delegating to your | |
1735 * implementation of FormInterface for validation and processing of submitted | |
1736 * data. | |
1737 * | |
1738 * Here is an example of a Form class: | |
1739 * @code | |
1740 * namespace Drupal\mymodule\Form; | |
1741 * | |
1742 * use Drupal\Core\Form\FormBase; | |
1743 * use Drupal\Core\Form\FormStateInterface; | |
1744 * | |
1745 * class ExampleForm extends FormBase { | |
1746 * public function getFormId() { | |
1747 * // Unique ID of the form. | |
1748 * return 'example_form'; | |
1749 * } | |
1750 * | |
1751 * public function buildForm(array $form, FormStateInterface $form_state) { | |
1752 * // Create a $form API array. | |
1753 * $form['phone_number'] = array( | |
1754 * '#type' => 'tel', | |
1755 * '#title' => $this->t('Your phone number'), | |
1756 * ); | |
1757 * $form['save'] = array( | |
1758 * '#type' => 'submit', | |
1759 * '#value' => $this->t('Save'), | |
1760 * ); | |
1761 * return $form; | |
1762 * } | |
1763 * | |
1764 * public function validateForm(array &$form, FormStateInterface $form_state) { | |
1765 * // Validate submitted form data. | |
1766 * } | |
1767 * | |
1768 * public function submitForm(array &$form, FormStateInterface $form_state) { | |
1769 * // Handle submitted form data. | |
1770 * } | |
1771 * } | |
1772 * @endcode | |
1773 * | |
1774 * @section retrieving_forms Retrieving and displaying forms | |
1775 * \Drupal::formBuilder()->getForm() should be used to handle retrieving, | |
1776 * processing, and displaying a rendered HTML form. Given the ExampleForm | |
1777 * defined above, | |
1778 * \Drupal::formBuilder()->getForm('Drupal\mymodule\Form\ExampleForm') would | |
1779 * return the rendered HTML of the form defined by ExampleForm::buildForm(), or | |
1780 * call the validateForm() and submitForm(), methods depending on the current | |
1781 * processing state. | |
1782 * | |
1783 * The argument to \Drupal::formBuilder()->getForm() is the name of a class that | |
1784 * implements FormInterface. Any additional arguments passed to the getForm() | |
1785 * method will be passed along as additional arguments to the | |
1786 * ExampleForm::buildForm() method. | |
1787 * | |
1788 * For example: | |
1789 * @code | |
1790 * $extra = '612-123-4567'; | |
1791 * $form = \Drupal::formBuilder()->getForm('Drupal\mymodule\Form\ExampleForm', $extra); | |
1792 * ... | |
1793 * public function buildForm(array $form, FormStateInterface $form_state, $extra = NULL) | |
1794 * $form['phone_number'] = array( | |
1795 * '#type' => 'tel', | |
1796 * '#title' => $this->t('Your phone number'), | |
1797 * '#value' => $extra, | |
1798 * ); | |
1799 * return $form; | |
1800 * } | |
1801 * @endcode | |
1802 * | |
1803 * Alternatively, forms can be built directly via the routing system which will | |
1804 * take care of calling \Drupal::formBuilder()->getForm(). The following example | |
1805 * demonstrates the use of a routing.yml file to display a form at the given | |
1806 * route. | |
1807 * | |
1808 * @code | |
1809 * example.form: | |
1810 * path: '/example-form' | |
1811 * defaults: | |
1812 * _title: 'Example form' | |
1813 * _form: '\Drupal\mymodule\Form\ExampleForm' | |
1814 * @endcode | |
1815 * | |
1816 * The $form argument to form-related functions is a specialized render array | |
1817 * containing the elements and properties of the form. For more about render | |
1818 * arrays, see the @link theme_render Render API topic. @endlink For more | |
1819 * detailed explanations of the Form API workflow, see the | |
1820 * @link https://www.drupal.org/node/2117411 Form API documentation section. @endlink | |
1821 * In addition, there is a set of Form API tutorials in the | |
1822 * @link https://www.drupal.org/project/examples Examples for Developers project. @endlink | |
1823 * | |
1824 * In the form builder, validation, submission, and other form methods, | |
1825 * $form_state is the primary influence on the processing of the form and is | |
1826 * passed to most methods, so they can use it to communicate with the form | |
1827 * system and each other. $form_state is an object that implements | |
1828 * \Drupal\Core\Form\FormStateInterface. | |
1829 * @} | |
1830 */ | |
1831 | |
1832 /** | |
1833 * @defgroup queue Queue operations | |
1834 * @{ | |
1835 * Queue items to allow later processing. | |
1836 * | |
1837 * The queue system allows placing items in a queue and processing them later. | |
1838 * The system tries to ensure that only one consumer can process an item. | |
1839 * | |
1840 * Before a queue can be used it needs to be created by | |
1841 * Drupal\Core\Queue\QueueInterface::createQueue(). | |
1842 * | |
1843 * Items can be added to the queue by passing an arbitrary data object to | |
1844 * Drupal\Core\Queue\QueueInterface::createItem(). | |
1845 * | |
1846 * To process an item, call Drupal\Core\Queue\QueueInterface::claimItem() and | |
1847 * specify how long you want to have a lease for working on that item. | |
1848 * When finished processing, the item needs to be deleted by calling | |
1849 * Drupal\Core\Queue\QueueInterface::deleteItem(). If the consumer dies, the | |
1850 * item will be made available again by the Drupal\Core\Queue\QueueInterface | |
1851 * implementation once the lease expires. Another consumer will then be able to | |
1852 * receive it when calling Drupal\Core\Queue\QueueInterface::claimItem(). | |
1853 * Due to this, the processing code should be aware that an item might be handed | |
1854 * over for processing more than once. | |
1855 * | |
1856 * The $item object used by the Drupal\Core\Queue\QueueInterface can contain | |
1857 * arbitrary metadata depending on the implementation. Systems using the | |
1858 * interface should only rely on the data property which will contain the | |
1859 * information passed to Drupal\Core\Queue\QueueInterface::createItem(). | |
1860 * The full queue item returned by Drupal\Core\Queue\QueueInterface::claimItem() | |
1861 * needs to be passed to Drupal\Core\Queue\QueueInterface::deleteItem() once | |
1862 * processing is completed. | |
1863 * | |
1864 * There are two kinds of queue backends available: reliable, which preserves | |
1865 * the order of messages and guarantees that every item will be executed at | |
1866 * least once. The non-reliable kind only does a best effort to preserve order | |
1867 * in messages and to execute them at least once but there is a small chance | |
1868 * that some items get lost. For example, some distributed back-ends like | |
1869 * Amazon SQS will be managing jobs for a large set of producers and consumers | |
1870 * where a strict FIFO ordering will likely not be preserved. Another example | |
1871 * would be an in-memory queue backend which might lose items if it crashes. | |
1872 * However, such a backend would be able to deal with significantly more writes | |
1873 * than a reliable queue and for many tasks this is more important. See | |
1874 * aggregator_cron() for an example of how to effectively use a non-reliable | |
1875 * queue. Another example is doing Twitter statistics -- the small possibility | |
1876 * of losing a few items is insignificant next to power of the queue being able | |
1877 * to keep up with writes. As described in the processing section, regardless | |
1878 * of the queue being reliable or not, the processing code should be aware that | |
1879 * an item might be handed over for processing more than once (because the | |
1880 * processing code might time out before it finishes). | |
1881 * @} | |
1882 */ | |
1883 | |
1884 /** | |
1885 * @defgroup annotation Annotations | |
1886 * @{ | |
1887 * Annotations for class discovery and metadata description. | |
1888 * | |
1889 * The Drupal plugin system has a set of reusable components that developers | |
1890 * can use, override, and extend in their modules. Most of the plugins use | |
1891 * annotations, which let classes register themselves as plugins and describe | |
1892 * their metadata. (Annotations can also be used for other purposes, though | |
1893 * at the moment, Drupal only uses them for the plugin system.) | |
1894 * | |
1895 * To annotate a class as a plugin, add code similar to the following to the | |
1896 * end of the documentation block immediately preceding the class declaration: | |
1897 * @code | |
1898 * * @ContentEntityType( | |
1899 * * id = "comment", | |
1900 * * label = @Translation("Comment"), | |
1901 * * ... | |
1902 * * base_table = "comment" | |
1903 * * ) | |
1904 * @endcode | |
1905 * | |
1906 * Note that you must use double quotes; single quotes will not work in | |
1907 * annotations. | |
1908 * | |
1909 * Some annotation types, which extend the "@ PluginID" annotation class, have | |
1910 * only a single 'id' key in their annotation. For these, it is possible to use | |
1911 * a shorthand annotation. For example: | |
1912 * @code | |
1913 * * @ViewsArea("entity") | |
1914 * @endcode | |
1915 * in place of | |
1916 * @code | |
1917 * * @ViewsArea( | |
1918 * * id = "entity" | |
1919 * *) | |
1920 * @endcode | |
1921 * | |
1922 * The available annotation classes are listed in this topic, and can be | |
1923 * identified when you are looking at the Drupal source code by having | |
1924 * "@ Annotation" in their documentation blocks (without the space after @). To | |
1925 * find examples of annotation for a particular annotation class, such as | |
1926 * EntityType, look for class files that have an @ annotation section using the | |
1927 * annotation class. | |
1928 * | |
1929 * @see plugin_translatable | |
1930 * @see plugin_context | |
1931 * | |
1932 * @} | |
1933 */ | |
1934 | |
1935 /** | |
1936 * @addtogroup hooks | |
1937 * @{ | |
1938 */ | |
1939 | |
1940 /** | |
1941 * Perform periodic actions. | |
1942 * | |
1943 * Modules that require some commands to be executed periodically can | |
1944 * implement hook_cron(). The engine will then call the hook whenever a cron | |
1945 * run happens, as defined by the administrator. Typical tasks managed by | |
1946 * hook_cron() are database maintenance, backups, recalculation of settings | |
1947 * or parameters, automated mailing, and retrieving remote data. | |
1948 * | |
1949 * Short-running or non-resource-intensive tasks can be executed directly in | |
1950 * the hook_cron() implementation. | |
1951 * | |
1952 * Long-running tasks and tasks that could time out, such as retrieving remote | |
1953 * data, sending email, and intensive file tasks, should use the queue API | |
1954 * instead of executing the tasks directly. To do this, first define one or | |
1955 * more queues via a \Drupal\Core\Annotation\QueueWorker plugin. Then, add items | |
1956 * that need to be processed to the defined queues. | |
1957 */ | |
1958 function hook_cron() { | |
1959 // Short-running operation example, not using a queue: | |
1960 // Delete all expired records since the last cron run. | |
1961 $expires = \Drupal::state()->get('mymodule.last_check', 0); | |
1962 \Drupal::database()->delete('mymodule_table') | |
1963 ->condition('expires', $expires, '>=') | |
1964 ->execute(); | |
1965 \Drupal::state()->set('mymodule.last_check', REQUEST_TIME); | |
1966 | |
1967 // Long-running operation example, leveraging a queue: | |
1968 // Queue news feeds for updates once their refresh interval has elapsed. | |
1969 $queue = \Drupal::queue('aggregator_feeds'); | |
1970 $ids = \Drupal::entityManager()->getStorage('aggregator_feed')->getFeedIdsToRefresh(); | |
1971 foreach (Feed::loadMultiple($ids) as $feed) { | |
1972 if ($queue->createItem($feed)) { | |
1973 // Add timestamp to avoid queueing item more than once. | |
1974 $feed->setQueuedTime(REQUEST_TIME); | |
1975 $feed->save(); | |
1976 } | |
1977 } | |
1978 $ids = \Drupal::entityQuery('aggregator_feed') | |
1979 ->condition('queued', REQUEST_TIME - (3600 * 6), '<') | |
1980 ->execute(); | |
1981 if ($ids) { | |
1982 $feeds = Feed::loadMultiple($ids); | |
1983 foreach ($feeds as $feed) { | |
1984 $feed->setQueuedTime(0); | |
1985 $feed->save(); | |
1986 } | |
1987 } | |
1988 } | |
1989 | |
1990 /** | |
1991 * Alter available data types for typed data wrappers. | |
1992 * | |
1993 * @param array $data_types | |
1994 * An array of data type information. | |
1995 * | |
1996 * @see hook_data_type_info() | |
1997 */ | |
1998 function hook_data_type_info_alter(&$data_types) { | |
1999 $data_types['email']['class'] = '\Drupal\mymodule\Type\Email'; | |
2000 } | |
2001 | |
2002 /** | |
2003 * Alter cron queue information before cron runs. | |
2004 * | |
2005 * Called by \Drupal\Core\Cron to allow modules to alter cron queue settings | |
2006 * before any jobs are processed. | |
2007 * | |
2008 * @param array $queues | |
2009 * An array of cron queue information. | |
2010 * | |
2011 * @see \Drupal\Core\Queue\QueueWorkerInterface | |
2012 * @see \Drupal\Core\Annotation\QueueWorker | |
2013 * @see \Drupal\Core\Cron | |
2014 */ | |
2015 function hook_queue_info_alter(&$queues) { | |
2016 // This site has many feeds so let's spend 90 seconds on each cron run | |
2017 // updating feeds instead of the default 60. | |
2018 $queues['aggregator_feeds']['cron']['time'] = 90; | |
2019 } | |
2020 | |
2021 /** | |
2022 * Alter an email message created with MailManagerInterface->mail(). | |
2023 * | |
2024 * hook_mail_alter() allows modification of email messages created and sent | |
2025 * with MailManagerInterface->mail(). Usage examples include adding and/or | |
2026 * changing message text, message fields, and message headers. | |
2027 * | |
2028 * Email messages sent using functions other than MailManagerInterface->mail() | |
2029 * will not invoke hook_mail_alter(). For example, a contributed module directly | |
2030 * calling the MailInterface->mail() or PHP mail() function will not invoke | |
2031 * this hook. All core modules use MailManagerInterface->mail() for messaging, | |
2032 * it is best practice but not mandatory in contributed modules. | |
2033 * | |
2034 * @param $message | |
2035 * An array containing the message data. Keys in this array include: | |
2036 * - 'id': | |
2037 * The MailManagerInterface->mail() id of the message. Look at module source | |
2038 * code or MailManagerInterface->mail() for possible id values. | |
2039 * - 'to': | |
2040 * The address or addresses the message will be sent to. The | |
2041 * formatting of this string must comply with RFC 2822. | |
2042 * - 'from': | |
2043 * The address the message will be marked as being from, which is | |
2044 * either a custom address or the site-wide default email address. | |
2045 * - 'subject': | |
2046 * Subject of the email to be sent. This must not contain any newline | |
2047 * characters, or the email may not be sent properly. | |
2048 * - 'body': | |
2049 * An array of strings or objects that implement | |
2050 * \Drupal\Component\Render\MarkupInterface containing the message text. The | |
2051 * message body is created by concatenating the individual array strings | |
2052 * into a single text string using "\n\n" as a separator. | |
2053 * - 'headers': | |
2054 * Associative array containing mail headers, such as From, Sender, | |
2055 * MIME-Version, Content-Type, etc. | |
2056 * - 'params': | |
2057 * An array of optional parameters supplied by the caller of | |
2058 * MailManagerInterface->mail() that is used to build the message before | |
2059 * hook_mail_alter() is invoked. | |
2060 * - 'language': | |
2061 * The language object used to build the message before hook_mail_alter() | |
2062 * is invoked. | |
2063 * - 'send': | |
2064 * Set to FALSE to abort sending this email message. | |
2065 * | |
2066 * @see \Drupal\Core\Mail\MailManagerInterface::mail() | |
2067 */ | |
2068 function hook_mail_alter(&$message) { | |
2069 if ($message['id'] == 'modulename_messagekey') { | |
2070 if (!example_notifications_optin($message['to'], $message['id'])) { | |
2071 // If the recipient has opted to not receive such messages, cancel | |
2072 // sending. | |
2073 $message['send'] = FALSE; | |
2074 return; | |
2075 } | |
2076 $message['body'][] = "--\nMail sent out from " . \Drupal::config('system.site')->get('name'); | |
2077 } | |
2078 } | |
2079 | |
2080 /** | |
2081 * Prepares a message based on parameters; | |
2082 * | |
2083 * This hook is called from MailManagerInterface->mail(). Note that hook_mail(), | |
2084 * unlike hook_mail_alter(), is only called on the $module argument to | |
2085 * MailManagerInterface->mail(), not all modules. | |
2086 * | |
2087 * @param $key | |
2088 * An identifier of the mail. | |
2089 * @param $message | |
2090 * An array to be filled in. Elements in this array include: | |
2091 * - id: An ID to identify the mail sent. Look at module source code or | |
2092 * MailManagerInterface->mail() for possible id values. | |
2093 * - to: The address or addresses the message will be sent to. The | |
2094 * formatting of this string must comply with RFC 2822. | |
2095 * - subject: Subject of the email to be sent. This must not contain any | |
2096 * newline characters, or the mail may not be sent properly. | |
2097 * MailManagerInterface->mail() sets this to an empty | |
2098 * string when the hook is invoked. | |
2099 * - body: An array of lines containing the message to be sent. Drupal will | |
2100 * format the correct line endings for you. MailManagerInterface->mail() | |
2101 * sets this to an empty array when the hook is invoked. The array may | |
2102 * contain either strings or objects implementing | |
2103 * \Drupal\Component\Render\MarkupInterface. | |
2104 * - from: The address the message will be marked as being from, which is | |
2105 * set by MailManagerInterface->mail() to either a custom address or the | |
2106 * site-wide default email address when the hook is invoked. | |
2107 * - headers: Associative array containing mail headers, such as From, | |
2108 * Sender, MIME-Version, Content-Type, etc. | |
2109 * MailManagerInterface->mail() pre-fills several headers in this array. | |
2110 * @param $params | |
2111 * An array of parameters supplied by the caller of | |
2112 * MailManagerInterface->mail(). | |
2113 * | |
2114 * @see \Drupal\Core\Mail\MailManagerInterface::mail() | |
2115 */ | |
2116 function hook_mail($key, &$message, $params) { | |
2117 $account = $params['account']; | |
2118 $context = $params['context']; | |
2119 $variables = [ | |
2120 '%site_name' => \Drupal::config('system.site')->get('name'), | |
2121 '%username' => $account->getDisplayName(), | |
2122 ]; | |
2123 if ($context['hook'] == 'taxonomy') { | |
2124 $entity = $params['entity']; | |
2125 $vocabulary = Vocabulary::load($entity->id()); | |
2126 $variables += [ | |
2127 '%term_name' => $entity->name, | |
2128 '%term_description' => $entity->description, | |
2129 '%term_id' => $entity->id(), | |
2130 '%vocabulary_name' => $vocabulary->label(), | |
2131 '%vocabulary_description' => $vocabulary->getDescription(), | |
2132 '%vocabulary_id' => $vocabulary->id(), | |
2133 ]; | |
2134 } | |
2135 | |
2136 // Node-based variable translation is only available if we have a node. | |
2137 if (isset($params['node'])) { | |
2138 /** @var \Drupal\node\NodeInterface $node */ | |
2139 $node = $params['node']; | |
2140 $variables += [ | |
2141 '%uid' => $node->getOwnerId(), | |
2142 '%url' => $node->url('canonical', ['absolute' => TRUE]), | |
2143 '%node_type' => node_get_type_label($node), | |
2144 '%title' => $node->getTitle(), | |
2145 '%teaser' => $node->teaser, | |
2146 '%body' => $node->body, | |
2147 ]; | |
2148 } | |
2149 $subject = strtr($context['subject'], $variables); | |
2150 $body = strtr($context['message'], $variables); | |
2151 $message['subject'] .= str_replace(["\r", "\n"], '', $subject); | |
2152 $message['body'][] = MailFormatHelper::htmlToText($body); | |
2153 } | |
2154 | |
2155 /** | |
2156 * Alter the list of mail backend plugin definitions. | |
2157 * | |
2158 * @param array $info | |
2159 * The mail backend plugin definitions to be altered. | |
2160 * | |
2161 * @see \Drupal\Core\Annotation\Mail | |
2162 * @see \Drupal\Core\Mail\MailManager | |
2163 */ | |
2164 function hook_mail_backend_info_alter(&$info) { | |
2165 unset($info['test_mail_collector']); | |
2166 } | |
2167 | |
2168 /** | |
2169 * Alter the default country list. | |
2170 * | |
2171 * @param $countries | |
2172 * The associative array of countries keyed by two-letter country code. | |
2173 * | |
2174 * @see \Drupal\Core\Locale\CountryManager::getList() | |
2175 */ | |
2176 function hook_countries_alter(&$countries) { | |
2177 // Elbonia is now independent, so add it to the country list. | |
2178 $countries['EB'] = 'Elbonia'; | |
2179 } | |
2180 | |
2181 /** | |
2182 * Alter display variant plugin definitions. | |
2183 * | |
2184 * @param array $definitions | |
2185 * The array of display variant definitions, keyed by plugin ID. | |
2186 * | |
2187 * @see \Drupal\Core\Display\VariantManager | |
2188 * @see \Drupal\Core\Display\Annotation\DisplayVariant | |
2189 */ | |
2190 function hook_display_variant_plugin_alter(array &$definitions) { | |
2191 $definitions['full_page']['admin_label'] = t('Block layout'); | |
2192 } | |
2193 | |
2194 /** | |
2195 * Allow modules to alter layout plugin definitions. | |
2196 * | |
2197 * @param \Drupal\Core\Layout\LayoutDefinition[] $definitions | |
2198 * The array of layout definitions, keyed by plugin ID. | |
2199 */ | |
2200 function hook_layout_alter(&$definitions) { | |
2201 // Remove a layout. | |
2202 unset($definitions['twocol']); | |
2203 } | |
2204 | |
2205 /** | |
2206 * Flush all persistent and static caches. | |
2207 * | |
2208 * This hook asks your module to clear all of its static caches, | |
2209 * in order to ensure a clean environment for subsequently | |
2210 * invoked data rebuilds. | |
2211 * | |
2212 * Do NOT use this hook for rebuilding information. Only use it to flush custom | |
2213 * caches. | |
2214 * | |
2215 * Static caches using drupal_static() do not need to be reset manually. | |
2216 * However, all other static variables that do not use drupal_static() must be | |
2217 * manually reset. | |
2218 * | |
2219 * This hook is invoked by drupal_flush_all_caches(). It runs before module data | |
2220 * is updated and before hook_rebuild(). | |
2221 * | |
2222 * @see drupal_flush_all_caches() | |
2223 * @see hook_rebuild() | |
2224 */ | |
2225 function hook_cache_flush() { | |
2226 if (defined('MAINTENANCE_MODE') && MAINTENANCE_MODE == 'update') { | |
2227 _update_cache_clear(); | |
2228 } | |
2229 } | |
2230 | |
2231 /** | |
2232 * Rebuild data based upon refreshed caches. | |
2233 * | |
2234 * This hook allows your module to rebuild its data based on the latest/current | |
2235 * module data. It runs after hook_cache_flush() and after all module data has | |
2236 * been updated. | |
2237 * | |
2238 * This hook is only invoked after the system has been completely cleared; | |
2239 * i.e., all previously cached data is known to be gone and every API in the | |
2240 * system is known to return current information, so your module can safely rely | |
2241 * on all available data to rebuild its own. | |
2242 * | |
2243 * @see hook_cache_flush() | |
2244 * @see drupal_flush_all_caches() | |
2245 */ | |
2246 function hook_rebuild() { | |
2247 $themes = \Drupal::service('theme_handler')->listInfo(); | |
2248 foreach ($themes as $theme) { | |
2249 _block_rehash($theme->getName()); | |
2250 } | |
2251 } | |
2252 | |
2253 /** | |
2254 * Alter the configuration synchronization steps. | |
2255 * | |
2256 * @param array $sync_steps | |
2257 * A one-dimensional array of \Drupal\Core\Config\ConfigImporter method names | |
2258 * or callables that are invoked to complete the import, in the order that | |
2259 * they will be processed. Each callable item defined in $sync_steps should | |
2260 * either be a global function or a public static method. The callable should | |
2261 * accept a $context array by reference. For example: | |
2262 * @code | |
2263 * function _additional_configuration_step(&$context) { | |
2264 * // Do stuff. | |
2265 * // If finished set $context['finished'] = 1. | |
2266 * } | |
2267 * @endcode | |
2268 * For more information on creating batches, see the | |
2269 * @link batch Batch operations @endlink documentation. | |
2270 * | |
2271 * @see callback_batch_operation() | |
2272 * @see \Drupal\Core\Config\ConfigImporter::initialize() | |
2273 */ | |
2274 function hook_config_import_steps_alter(&$sync_steps, \Drupal\Core\Config\ConfigImporter $config_importer) { | |
2275 $deletes = $config_importer->getUnprocessedConfiguration('delete'); | |
2276 if (isset($deletes['field.storage.node.body'])) { | |
2277 $sync_steps[] = '_additional_configuration_step'; | |
2278 } | |
2279 } | |
2280 | |
2281 /** | |
2282 * Alter config typed data definitions. | |
2283 * | |
2284 * For example you can alter the typed data types representing each | |
2285 * configuration schema type to change default labels or form element renderers | |
2286 * used for configuration translation. | |
2287 * | |
2288 * If implementations of this hook add or remove configuration schema a | |
2289 * ConfigSchemaAlterException will be thrown. Keep in mind that there are tools | |
2290 * that may use the configuration schema for static analysis of configuration | |
2291 * files, like the string extractor for the localization system. Such systems | |
2292 * won't work with dynamically defined configuration schemas. | |
2293 * | |
2294 * For adding new data types use configuration schema YAML files instead. | |
2295 * | |
2296 * @param $definitions | |
2297 * Associative array of configuration type definitions keyed by schema type | |
2298 * names. The elements are themselves array with information about the type. | |
2299 * | |
2300 * @see \Drupal\Core\Config\TypedConfigManager | |
2301 * @see \Drupal\Core\Config\Schema\ConfigSchemaAlterException | |
2302 */ | |
2303 function hook_config_schema_info_alter(&$definitions) { | |
2304 // Enhance the text and date type definitions with classes to generate proper | |
2305 // form elements in ConfigTranslationFormBase. Other translatable types will | |
2306 // appear as a one line textfield. | |
2307 $definitions['text']['form_element_class'] = '\Drupal\config_translation\FormElement\Textarea'; | |
2308 $definitions['date_format']['form_element_class'] = '\Drupal\config_translation\FormElement\DateFormat'; | |
2309 } | |
2310 | |
2311 /** | |
2312 * Alter validation constraint plugin definitions. | |
2313 * | |
2314 * @param array[] $definitions | |
2315 * The array of validation constraint definitions, keyed by plugin ID. | |
2316 * | |
2317 * @see \Drupal\Core\Validation\ConstraintManager | |
2318 * @see \Drupal\Core\Validation\Annotation\Constraint | |
2319 */ | |
2320 function hook_validation_constraint_alter(array &$definitions) { | |
2321 $definitions['Null']['class'] = '\Drupal\mymodule\Validator\Constraints\MyClass'; | |
2322 } | |
2323 | |
2324 /** | |
2325 * @} End of "addtogroup hooks". | |
2326 */ | |
2327 | |
2328 /** | |
2329 * @defgroup ajax Ajax API | |
2330 * @{ | |
2331 * Overview for Drupal's Ajax API. | |
2332 * | |
2333 * @section sec_overview Overview of Ajax | |
2334 * Ajax is the process of dynamically updating parts of a page's HTML based on | |
2335 * data from the server. When a specified event takes place, a PHP callback is | |
2336 * triggered, which performs server-side logic and may return updated markup or | |
2337 * JavaScript commands to run. After the return, the browser runs the JavaScript | |
2338 * or updates the markup on the fly, with no full page refresh necessary. | |
2339 * | |
2340 * Many different events can trigger Ajax responses, including: | |
2341 * - Clicking a button | |
2342 * - Pressing a key | |
2343 * - Moving the mouse | |
2344 * | |
2345 * @section sec_framework Ajax responses in forms | |
2346 * Forms that use the Drupal Form API (see the | |
2347 * @link form_api Form API topic @endlink for more information about forms) can | |
2348 * trigger AJAX responses. Here is an outline of the steps: | |
2349 * - Add property '#ajax' to a form element in your form array, to trigger an | |
2350 * Ajax response. | |
2351 * - Write an Ajax callback to process the input and respond. | |
2352 * See sections below for details on these two steps. | |
2353 * | |
2354 * @subsection sub_form Adding Ajax triggers to a form | |
2355 * As an example of adding Ajax triggers to a form, consider editing a date | |
2356 * format, where the user is provided with a sample of the generated date output | |
2357 * as they type. To accomplish this, typing in the text field should trigger an | |
2358 * Ajax response. This is done in the text field form array element | |
2359 * in \Drupal\config_translation\FormElement\DateFormat::getFormElement(): | |
2360 * @code | |
2361 * '#ajax' => array( | |
2362 * 'callback' => 'Drupal\config_translation\FormElement\DateFormat::ajaxSample', | |
2363 * 'event' => 'keyup', | |
2364 * 'progress' => array( | |
2365 * 'type' => 'throbber', | |
2366 * 'message' => NULL, | |
2367 * ), | |
2368 * ), | |
2369 * @endcode | |
2370 * | |
2371 * As you can see from this example, the #ajax property for a form element is | |
2372 * an array. Here are the details of its elements, all of which are optional: | |
2373 * - callback: The callback to invoke to handle the server side of the | |
2374 * Ajax event. More information on callbacks is below in @ref sub_callback. | |
2375 * - wrapper: The HTML 'id' attribute of the area where the content returned by | |
2376 * the callback should be placed. Note that callbacks have a choice of | |
2377 * returning content or JavaScript commands; 'wrapper' is used for content | |
2378 * returns. | |
2379 * - method: The jQuery method for placing the new content (used with | |
2380 * 'wrapper'). Valid options are 'replaceWith' (default), 'append', 'prepend', | |
2381 * 'before', 'after', or 'html'. See | |
2382 * http://api.jquery.com/category/manipulation/ for more information on these | |
2383 * methods. | |
2384 * - effect: The jQuery effect to use when placing the new HTML (used with | |
2385 * 'wrapper'). Valid options are 'none' (default), 'slide', or 'fade'. | |
2386 * - speed: The effect speed to use (used with 'effect' and 'wrapper'). Valid | |
2387 * options are 'slow' (default), 'fast', or the number of milliseconds the | |
2388 * effect should run. | |
2389 * - event: The JavaScript event to respond to. This is selected automatically | |
2390 * for the type of form element; provide a value to override the default. | |
2391 * - prevent: A JavaScript event to prevent when the event is triggered. For | |
2392 * example, if you use event 'mousedown' on a button, you might want to | |
2393 * prevent 'click' events from also being triggered. | |
2394 * - progress: An array indicating how to show Ajax processing progress. Can | |
2395 * contain one or more of these elements: | |
2396 * - type: Type of indicator: 'throbber' (default) or 'bar'. | |
2397 * - message: Translated message to display. | |
2398 * - url: For a bar progress indicator, URL path for determining progress. | |
2399 * - interval: For a bar progress indicator, how often to update it. | |
2400 * - url: A \Drupal\Core\Url to which to submit the Ajax request. If omitted, | |
2401 * defaults to either the same URL as the form or link destination is for | |
2402 * someone with JavaScript disabled, or a slightly modified version (e.g., | |
2403 * with a query parameter added, removed, or changed) of that URL if | |
2404 * necessary to support Drupal's content negotiation. It is recommended to | |
2405 * omit this key and use Drupal's content negotiation rather than using | |
2406 * substantially different URLs between Ajax and non-Ajax. | |
2407 * | |
2408 * @subsection sub_callback Setting up a callback to process Ajax | |
2409 * Once you have set up your form to trigger an Ajax response (see @ref sub_form | |
2410 * above), you need to write some PHP code to process the response. If you use | |
2411 * 'path' in your Ajax set-up, your route controller will be triggered with only | |
2412 * the information you provide in the URL. If you use 'callback', your callback | |
2413 * method is a function, which will receive the $form and $form_state from the | |
2414 * triggering form. You can use $form_state to get information about the | |
2415 * data the user has entered into the form. For instance, in the above example | |
2416 * for the date format preview, | |
2417 * \Drupal\config_translation\FormElement\DateFormat\ajaxSample() does this to | |
2418 * get the format string entered by the user: | |
2419 * @code | |
2420 * $format_value = \Drupal\Component\Utility\NestedArray::getValue( | |
2421 * $form_state->getValues(), | |
2422 * $form_state->getTriggeringElement()['#array_parents']); | |
2423 * @endcode | |
2424 * | |
2425 * Once you have processed the input, you have your choice of returning HTML | |
2426 * markup or a set of Ajax commands. If you choose to return HTML markup, you | |
2427 * can return it as a string or a renderable array, and it will be placed in | |
2428 * the defined 'wrapper' element (see documentation above in @ref sub_form). | |
2429 * In addition, any messages returned by drupal_get_messages(), themed as in | |
2430 * status-messages.html.twig, will be prepended. | |
2431 * | |
2432 * To return commands, you need to set up an object of class | |
2433 * \Drupal\Core\Ajax\AjaxResponse, and then use its addCommand() method to add | |
2434 * individual commands to it. In the date format preview example, the format | |
2435 * output is calculated, and then it is returned as replacement markup for a div | |
2436 * like this: | |
2437 * @code | |
2438 * $response = new AjaxResponse(); | |
2439 * $response->addCommand(new ReplaceCommand( | |
2440 * '#edit-date-format-suffix', | |
2441 * '<small id="edit-date-format-suffix">' . $format . '</small>')); | |
2442 * return $response; | |
2443 * @endcode | |
2444 * | |
2445 * The individual commands that you can return implement interface | |
2446 * \Drupal\Core\Ajax\CommandInterface. Available commands provide the ability | |
2447 * to pop up alerts, manipulate text and markup in various ways, redirect | |
2448 * to a new URL, and the generic \Drupal\Core\Ajax\InvokeCommand, which | |
2449 * invokes an arbitrary jQuery command. | |
2450 * | |
2451 * As noted above, status messages are prepended automatically if you use the | |
2452 * 'wrapper' method and return HTML markup. This is not the case if you return | |
2453 * commands, but if you would like to show status messages, you can add | |
2454 * @code | |
2455 * array('#type' => 'status_messages') | |
2456 * @endcode | |
2457 * to a render array, use drupal_render() to render it, and add a command to | |
2458 * place the messages in an appropriate location. | |
2459 * | |
2460 * @section sec_other Other methods for triggering Ajax | |
2461 * Here are some additional methods you can use to trigger Ajax responses in | |
2462 * Drupal: | |
2463 * - Add class 'use-ajax' to a link. The link will be loaded using an Ajax | |
2464 * call. When using this method, the href of the link can contain '/nojs/' as | |
2465 * part of the path. When the Ajax JavaScript processes the page, it will | |
2466 * convert this to '/ajax/'. The server is then able to easily tell if this | |
2467 * request was made through an actual Ajax request or in a degraded state, and | |
2468 * respond appropriately. | |
2469 * - Add class 'use-ajax-submit' to a submit button in a form. The form will | |
2470 * then be submitted via Ajax to the path specified in the #action. Like the | |
2471 * ajax-submit class on links, this path will have '/nojs/' replaced with | |
2472 * '/ajax/' so that the submit handler can tell if the form was submitted in a | |
2473 * degraded state or not. | |
2474 * - Add property '#autocomplete_route_name' to a text field in a form. The | |
2475 * route controller for this route must return an array of options for | |
2476 * autocomplete, as a \Symfony\Component\HttpFoundation\JsonResponse object. | |
2477 * See the @link menu Routing topic @endlink for more information about | |
2478 * routing. | |
2479 */ | |
2480 | |
2481 /** | |
2482 * @} End of "defgroup ajax". | |
2483 */ | |
2484 | |
2485 /** | |
2486 * @defgroup service_tag Service Tags | |
2487 * @{ | |
2488 * Service tags overview | |
2489 * | |
2490 * Some services have tags, which are defined in the service definition. Tags | |
2491 * are used to define a group of related services, or to specify some aspect of | |
2492 * how the service behaves. Typically, if you tag a service, your service class | |
2493 * must also implement a corresponding interface. Some common examples: | |
2494 * - access_check: Indicates a route access checking service; see the | |
2495 * @link menu Menu and routing system topic @endlink for more information. | |
2496 * - cache.bin: Indicates a cache bin service; see the | |
2497 * @link cache Cache topic @endlink for more information. | |
2498 * - event_subscriber: Indicates an event subscriber service. Event subscribers | |
2499 * can be used for dynamic routing and route altering; see the | |
2500 * @link menu Menu and routing system topic @endlink for more information. | |
2501 * They can also be used for other purposes; see | |
2502 * http://symfony.com/doc/current/cookbook/doctrine/event_listeners_subscribers.html | |
2503 * for more information. | |
2504 * - needs_destruction: Indicates that a destruct() method needs to be called | |
2505 * at the end of a request to finalize operations, if this service was | |
2506 * instantiated. Services should implement \Drupal\Core\DestructableInterface | |
2507 * in this case. | |
2508 * - context_provider: Indicates a block context provider, used for example | |
2509 * by block conditions. It has to implement | |
2510 * \Drupal\Core\Plugin\Context\ContextProviderInterface. | |
2511 * - http_client_middleware: Indicates that the service provides a guzzle | |
2512 * middleware, see | |
2513 * https://guzzle.readthedocs.org/en/latest/handlers-and-middleware.html for | |
2514 * more information. | |
2515 * | |
2516 * Creating a tag for a service does not do anything on its own, but tags | |
2517 * can be discovered or queried in a compiler pass when the container is built, | |
2518 * and a corresponding action can be taken. See | |
2519 * \Drupal\Core\Render\MainContent\MainContentRenderersPass for an example of | |
2520 * finding tagged services. | |
2521 * | |
2522 * See @link container Services and Dependency Injection Container @endlink for | |
2523 * information on services and the dependency injection container. | |
2524 * | |
2525 * @} | |
2526 */ | |
2527 | |
2528 /** | |
2529 * @defgroup events Events | |
2530 * @{ | |
2531 * Overview of event dispatch and subscribing | |
2532 * | |
2533 * @section sec_intro Introduction and terminology | |
2534 * Events are part of the Symfony framework: they allow for different components | |
2535 * of the system to interact and communicate with each other. Each event has a | |
2536 * unique string name. One system component dispatches the event at an | |
2537 * appropriate time; many events are dispatched by Drupal core and the Symfony | |
2538 * framework in every request. Other system components can register as event | |
2539 * subscribers; when an event is dispatched, a method is called on each | |
2540 * registered subscriber, allowing each one to react. For more on the general | |
2541 * concept of events, see | |
2542 * http://symfony.com/doc/current/components/event_dispatcher/introduction.html | |
2543 * | |
2544 * @section sec_dispatch Dispatching events | |
2545 * To dispatch an event, call the | |
2546 * \Symfony\Component\EventDispatcher\EventDispatcherInterface::dispatch() | |
2547 * method on the 'event_dispatcher' service (see the | |
2548 * @link container Services topic @endlink for more information about how to | |
2549 * interact with services). The first argument is the unique event name, which | |
2550 * you should normally define as a constant in a separate static class (see | |
2551 * \Symfony\Component\HttpKernel\KernelEvents and | |
2552 * \Drupal\Core\Config\ConfigEvents for examples). The second argument is a | |
2553 * \Symfony\Component\EventDispatcher\Event object; normally you will need to | |
2554 * extend this class, so that your event class can provide data to the event | |
2555 * subscribers. | |
2556 * | |
2557 * @section sec_subscribe Registering event subscribers | |
2558 * Here are the steps to register an event subscriber: | |
2559 * - Define a service in your module, tagged with 'event_subscriber' (see the | |
2560 * @link container Services topic @endlink for instructions). | |
2561 * - Define a class for your subscriber service that implements | |
2562 * \Symfony\Component\EventDispatcher\EventSubscriberInterface | |
2563 * - In your class, the getSubscribedEvents method returns a list of the events | |
2564 * this class is subscribed to, and which methods on the class should be | |
2565 * called for each one. Example: | |
2566 * @code | |
2567 * public static function getSubscribedEvents() { | |
2568 * // Subscribe to kernel terminate with priority 100. | |
2569 * $events[KernelEvents::TERMINATE][] = array('onTerminate', 100); | |
2570 * // Subscribe to kernel request with default priority of 0. | |
2571 * $events[KernelEvents::REQUEST][] = array('onRequest'); | |
2572 * return $events; | |
2573 * } | |
2574 * @endcode | |
2575 * - Write the methods that respond to the events; each one receives the | |
2576 * event object provided in the dispatch as its one argument. In the above | |
2577 * example, you would need to write onTerminate() and onRequest() methods. | |
2578 * | |
2579 * Note that in your getSubscribedEvents() method, you can optionally set the | |
2580 * priority of your event subscriber (see terminate example above). Event | |
2581 * subscribers with higher priority numbers get executed first; the default | |
2582 * priority is zero. If two event subscribers for the same event have the same | |
2583 * priority, the one defined in a module with a lower module weight will fire | |
2584 * first. Subscribers defined in the same services file are fired in | |
2585 * definition order. If order matters defining a priority is strongly advised | |
2586 * instead of relying on these two tie breaker rules as they might change in a | |
2587 * minor release. | |
2588 * @} | |
2589 */ | |
2590 | |
2591 /** | |
2592 * @defgroup session Sessions | |
2593 * @{ | |
2594 * Store and retrieve data associated with a user's browsing session. | |
2595 * | |
2596 * @section sec_intro Overview | |
2597 * The Drupal session management subsystem is built on top of the Symfony | |
2598 * session component. It is optimized in order to minimize the impact of | |
2599 * anonymous sessions on caching proxies. A session is only started if necessary | |
2600 * and the session cookie is removed from the browser as soon as the session | |
2601 * has no data. For this reason it is important for contributed and custom | |
2602 * code to remove session data if it is not used anymore. | |
2603 * | |
2604 * @section sec_usage Usage | |
2605 * Session data is accessed via the | |
2606 * \Symfony\Component\HttpFoundation\Request::getSession() | |
2607 * method, which returns an instance of | |
2608 * \Symfony\Component\HttpFoundation\Session\SessionInterface. The most | |
2609 * important methods on SessionInterface are set(), get(), and remove(). | |
2610 * | |
2611 * The following code fragment shows the implementation of a counter controller | |
2612 * relying on the session: | |
2613 * @code | |
2614 * public function counter(Request $request) { | |
2615 * $session = $request->getSession(); | |
2616 * $count = $session->get('mymodule.counter', 0) + 1; | |
2617 * $session->set('mymodule.counter', $count); | |
2618 * | |
2619 * return [ | |
2620 * '#markup' => $this->t('Page Views: @count', ['@count' => $count]), | |
2621 * '#cache' => [ | |
2622 * 'max-age' => 0, | |
2623 * ], | |
2624 * ]; | |
2625 * } | |
2626 * | |
2627 * public function reset(Request $request) { | |
2628 * $session = $request->getSession(); | |
2629 * $session->remove('mymodule.counter'); | |
2630 * } | |
2631 * @endcode | |
2632 * | |
2633 * It is important to keep the amount of data stored inside the session to a | |
2634 * minimum, as the complete session is loaded on every request. Also third | |
2635 * party session storage backends do not necessarily allow objects of unlimited | |
2636 * size. If it is necessary to collect a non-trivial amount of data specific to | |
2637 * a user's session, use the Key/Value store to save the serialized data and | |
2638 * only store the key to the entry in the session. | |
2639 * | |
2640 * @section sec_reserved Reserved attributes and namespacing | |
2641 * Contributed modules relying on the session are encouraged to namespace | |
2642 * session attributes by prefixing them with their project name or an | |
2643 * abbreviation thereof. | |
2644 * | |
2645 * Some attributes are reserved for Drupal core and must not be accessed from | |
2646 * within contributed and custom code. Reserved attributes include: | |
2647 * - uid: The user ID for an authenticated user. The value of this attribute | |
2648 * cannot be modified. | |
2649 * @} | |
2650 */ |