-
Notifications
You must be signed in to change notification settings - Fork 56
/
Copy pathcore.api.php
2768 lines (2718 loc) · 127 KB
/
core.api.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<?php
/**
* @file
* Documentation landing page and topics, plus core library hooks.
*/
/**
* @mainpage
* Welcome to the Drupal API Documentation!
*
* This site is an API reference for Drupal, generated from comments embedded
* in the source code. More in-depth documentation can be found at
* https://www.drupal.org/developing/api.
*
* Here are some topics to help you get started developing with Drupal.
*
* @section essentials Essential background concepts
*
* - @link oo_conventions Object-oriented conventions used in Drupal @endlink
* - @link extending Extending and altering Drupal @endlink
* - @link best_practices Security and best practices @endlink
* - @link info_types Types of information in Drupal @endlink
*
* @section interface User interface
*
* - @link menu Menu entries, local tasks, and other links @endlink
* - @link routing Routing API and page controllers @endlink
* - @link form_api Forms @endlink
* - @link block_api Blocks @endlink
* - @link ajax Ajax @endlink
*
* @section store_retrieve Storing and retrieving data
*
* - @link entity_api Entities @endlink
* - @link field Fields @endlink
* - @link config_api Configuration API @endlink
* - @link state_api State API @endlink
* - @link views_overview Views @endlink
* - @link database Database abstraction layer @endlink
*
* @section other_essentials Other essential APIs
*
* - @link plugin_api Plugins @endlink
* - @link container Services and the Dependency Injection Container @endlink
* - @link events Events @endlink
* - @link i18n Internationalization @endlink
* - @link cache Caching @endlink
* - @link utility Utility classes and functions @endlink
* - @link user_api User accounts, permissions, and roles @endlink
* - @link theme_render Render API @endlink
* - @link themeable Theme system @endlink
* - @link update_api Update API @endlink
* - @link migration Migration @endlink
*
* @section additional Additional topics
*
* - @link batch Batch API @endlink
* - @link queue Queue API @endlink
* - @link typed_data Typed Data @endlink
* - @link testing Automated tests @endlink
* - @link php_assert PHP Runtime Assert Statements @endlink
* - @link third_party Integrating third-party applications @endlink
*
* @section more_info Further information
*
* - @link https://www.drupal.org/project/examples Examples project (sample modules) @endlink
* - @link https://www.drupal.org/list-changes API change notices @endlink
* - @link https://www.drupal.org/docs/drupal-apis Drupal API longer references @endlink
*/
/**
* @defgroup third_party REST and Application Integration
* @{
* Integrating third-party applications using REST and related operations.
*
* @section sec_overview Overview of web services
* Web services make it possible for applications and websites to read and
* update information from other websites. There are several standard
* techniques for providing web services, including:
* - SOAP: http://wikipedia.org/wiki/SOAP
* - XML-RPC: http://wikipedia.org/wiki/XML-RPC
* - REST: http://wikipedia.org/wiki/Representational_state_transfer
* Drupal sites can both provide web services and integrate third-party web
* services.
*
* @section sec_rest_overview Overview of REST
* The REST technique uses basic HTTP requests to obtain and update data, where
* each web service defines a specific API (HTTP GET and/or POST parameters and
* returned response) for its HTTP requests. REST requests are separated into
* several types, known as methods, including:
* - GET: Requests to obtain data.
* - POST: Requests to update or create data.
* - PUT: Requests to update or create data (limited support, currently unused
* by entity resources).
* - PATCH: Requests to update a subset of data, such as one field.
* - DELETE: Requests to delete data.
* The Drupal Core REST module provides support for GET, POST, PATCH, and DELETE
* quests on entities, GET requests on the database log from the Database
* Logging module, and a plugin framework for providing REST support for other
* data and other methods.
*
* REST requests can be authenticated. The Drupal Core Basic Auth module
* provides authentication using the HTTP Basic protocol; the contributed module
* OAuth (https://www.drupal.org/project/oauth) implements the OAuth
* authentication protocol. You can also use cookie-based authentication, which
* would require users to be logged into the Drupal site while using the
* application on the third-party site that is using the REST service.
*
* @section sec_rest Enabling REST for entities and the log
* Here are the steps to take to use the REST operations provided by Drupal
* Core:
* - Enable the REST module, plus Basic Auth or another authentication method.
* - Node entity support is configured by default. If you would like to support
* other types of entities, you can copy
* core/modules/rest/config/optional/rest.resource.entity.node.yml to your
* sync configuration directory, appropriately modified for other entity
* types, and import it. Support for GET on the log from the Database Logging
* module can also be enabled in this way; in this case, the 'entity:node'
* line in the configuration would be replaced by the appropriate plugin ID,
* 'dblog'.
* - Set up permissions to allow the desired REST operations for a role, and set
* up one or more user accounts to perform the operations.
* - To perform a REST operation, send a request to either the canonical URL
* for an entity (such as node/12345 for a node), or if the entity does not
* have a canonical URL, a URL like entity/(type)/(ID). The URL for a log
* entry is dblog/(ID). The request must have the following properties:
* - The request method must be set to the REST method you are using (POST,
* GET, PATCH, etc.).
* - The content type for the data you send, or the accept type for the
* data you are receiving, must be set to 'application/json'.
* - If you are sending data, it must be JSON-encoded.
* - You'll also need to make sure the authentication information is sent
* with the request, unless you have allowed access to anonymous users.
*
* For more detailed information on setting up REST, see
* https://www.drupal.org/documentation/modules/rest.
*
* @section sec_plugins Defining new REST plugins
* The REST framework in the REST module has support built in for entities, but
* it is also an extensible plugin-based system. REST plugins implement
* interface \Drupal\rest\Plugin\ResourceInterface, and generally extend base
* class \Drupal\rest\Plugin\ResourceBase. They are annotated with
* \Drupal\rest\Annotation\RestResource annotation, and must be in plugin
* namespace subdirectory Plugin\rest\resource. For more information on how to
* create plugins, see the @link plugin_api Plugin API topic. @endlink
*
* If you create a new REST plugin, you will also need to enable it by
* providing default configuration or configuration import, as outlined in
* @ref sec_rest above.
*
* @section sec_integrate Integrating data from other sites into Drupal
* If you want to integrate data from other websites into Drupal, here are
* some notes:
* - There are contributed modules available for integrating many third-party
* sites into Drupal. Search on https://www.drupal.org/project/project_module
* - If there is not an existing module, you will need to find documentation on
* the specific web services API for the site you are trying to integrate.
* - There are several classes and functions that are useful for interacting
* with web services:
* - You should make requests using the 'http_client' service, which
* implements \GuzzleHttp\ClientInterface. See the
* @link container Services topic @endlink for more information on
* services. If you cannot use dependency injection to retrieve this
* service, the \Drupal::httpClient() method is available.
* - \Drupal\Component\Serialization\Json (JSON encoding and decoding).
* - PHP has functions and classes for parsing XML; see
* http://php.net/manual/refs.xml.php
* @}
*/
/**
* @defgroup state_api State API
* @{
* Information about the State API.
*
* The State API is one of several methods in Drupal for storing information.
* See the @link info_types Information types topic @endlink for an
* overview of the different types of information.
*
* The basic entry point into the State API is \Drupal::state(), which returns
* an object of class \Drupal\Core\State\StateInterface. This class has
* methods for storing and retrieving state information; each piece of state
* information is associated with a string-valued key. Example:
* @code
* // Get the state class.
* $state = \Drupal::state();
* // Find out when cron was last run; the key is 'system.cron_last'.
* $time = $state->get('system.cron_last');
* // Set the cron run time to the current request time.
* $state->set('system.cron_last', \Drupal::time()->getRequestTime());
* @endcode
*
* For more on the State API, see https://www.drupal.org/developing/api/8/state
* @}
*/
/**
* @defgroup config_api Configuration API
* @{
* Information about the Configuration API.
*
* The Configuration API is one of several methods in Drupal for storing
* information. See the @link info_types Information types topic @endlink for
* an overview of the different types of information. The sections below have
* more information about the configuration API; see
* https://www.drupal.org/docs/drupal-apis/configuration-api for more details.
*
* @section sec_storage Configuration storage
* In Drupal, there is a concept of the "active" configuration, which is the
* configuration that is currently in use for a site. The storage used for the
* active configuration is configurable: it could be in the database, in files
* in a particular directory, or in other storage backends; the default storage
* is in the database. Module developers must use the configuration API to
* access the active configuration, rather than being concerned about the
* details of where and how it is stored.
*
* Configuration is divided into individual objects, each of which has a
* unique name or key. Some modules will have only one configuration object,
* typically called 'my_module.settings'; some modules will have many. Within
* a configuration object, configuration settings have data types (integer,
* string, Boolean, etc.) and settings can also exist in a nested hierarchy,
* known as a "mapping".
*
* Configuration can also be overridden on a global, per-language, or
* per-module basis. See https://www.drupal.org/node/1928898 for more
* information.
*
* @section sec_yaml Configuration YAML files
* Whether or not configuration files are being used for the active
* configuration storage on a particular site, configuration files are always
* used for:
* - Defining the default configuration for an extension (module, theme, or
* profile), which is imported to the active storage when the extension is
* enabled. These configuration items are located in the config/install
* sub-directory of the extension. Note that changes to this configuration
* after a module or theme is already enabled have no effect; to make a
* configuration change after a module or theme is enabled, you would need to
* uninstall/reinstall or use a hook_update_N() function.
* - Defining optional configuration for a module or theme. Optional
* configuration items are located in the config/optional sub-directory of the
* extension. These configuration items have dependencies that are not
* explicit dependencies of the extension, so they are only installed if all
* dependencies are met. For example, in the scenario that module A defines a
* dependency which requires module B, but module A is installed first and
* module B some time later, then module A's config/optional directory will be
* scanned at that time for newly met dependencies, and the configuration will
* be installed then. If module B is never installed, the configuration item
* will not be installed either. Optional configuration items are ignored if
* they already exist or if they are not configuration entities (this also
* includes configuration that has an implicit dependency on modules that
* are not yet installed).
* - Exporting and importing configuration.
*
* The file storage format for configuration information in Drupal is
* @link http://wikipedia.org/wiki/YAML YAML files. @endlink Configuration is
* divided into files, each containing one configuration object. The file name
* for a configuration object is equal to the unique name of the configuration,
* with a '.yml' extension. The default configuration files for each module are
* placed in the config/install directory under the top-level module directory,
* so look there in most Core modules for examples.
*
* @section sec_schema Configuration schema and translation
* Each configuration file has a specific structure, which is expressed as a
* YAML-based configuration schema. The configuration schema details the
* structure of the configuration, its data types, and which of its values need
* to be translatable. Each module needs to define its configuration schema in
* files in the config/schema directory under the top-level module directory, so
* look there in most Core modules for examples.
*
* Configuration can be internationalized; see the
* @link i18n Internationalization topic @endlink for more information. Data
* types label, text, and date_format in configuration schema are translatable;
* string is non-translatable text (the 'translatable' property on a schema
* data type definition indicates that it is translatable).
*
* @section sec_simple Simple configuration
* The simple configuration API should be used for information that will always
* have exactly one copy or version. For instance, if your module has a
* setting that is either on or off, then this is only defined once, and it
* would be a Boolean-valued simple configuration setting.
*
* The first task in using the simple configuration API is to define the
* configuration file structure, file name, and schema of your settings (see
* @ref sec_yaml above). Once you have done that, you can retrieve the active
* configuration object that corresponds to configuration file my_module.foo.yml
* with a call to:
* @code
* $config = \Drupal::config('my_module.foo');
* @endcode
*
* This will be an object of class \Drupal\Core\Config\Config, which has methods
* for getting configuration information. For instance, if your YAML file
* structure looks like this:
* @code
* enabled: '0'
* bar:
* baz: 'string1'
* boo: 34
* @endcode
* you can make calls such as:
* @code
* // Get a single value.
* $enabled = $config->get('enabled');
* // Get an associative array.
* $bar = $config->get('bar');
* // Get one element of the array.
* $bar_baz = $config->get('bar.baz');
* @endcode
*
* The Config object that was obtained and used in the previous examples does
* not allow you to change configuration. If you want to change configuration,
* you will instead need to get the Config object by making a call to
* getEditable() on the config factory:
* @code
* $config =\Drupal::service('config.factory')->getEditable('my_module.foo');
* @endcode
*
* Individual configuration values can be changed or added using the set()
* method and saved using the save() method:
* @code
* // Set a scalar value.
* $config->set('enabled', 1);
* // Save the configuration.
* $config->save();
* @endcode
*
* Configuration values can also be unset using the clear() method, which is
* also chainable:
* @code
* $config->clear('bar.boo')->save();
* $config_data = $config->get('bar');
* @endcode
* In this example $config_data would return an array with one key - 'baz' -
* because 'boo' was unset.
*
* @section sec_entity Configuration entities
* In contrast to the simple configuration settings described in the previous
* section, if your module allows users to create zero or more items (where
* "items" are things like content type definitions, view definitions, and the
* like), then you need to define a configuration entity type to store your
* configuration. Creating an entity type, loading entities, and querying them
* are outlined in the @link entity_api Entity API topic. @endlink Here are a
* few additional steps and notes specific to configuration entities:
* - For examples, look for classes that implement
* \Drupal\Core\Config\Entity\ConfigEntityInterface -- one good example is
* the \Drupal\user\Entity\Role entity type.
* - In the entity type annotation, you will need to define a 'config_prefix'
* string. When Drupal stores a configuration item, it will be given a name
* composed of your module name, your chosen config prefix, and the ID of
* the individual item, separated by '.'. For example, in the Role entity,
* the config prefix is 'role', so one configuration item might be named
* user.role.anonymous, with configuration file user.role.anonymous.yml.
* - You will need to define the schema for your configuration in your
* modulename.schema.yml file, with an entry for 'modulename.config_prefix.*'.
* For example, for the Role entity, the file user.schema.yml has an entry
* user.role.*; see @ref sec_yaml above for more information.
* - Your module can provide default/optional configuration entities in YAML
* files; see @ref sec_yaml above for more information.
* - Some configuration entities have dependencies on other configuration
* entities, and module developers need to consider this so that configuration
* can be imported, uninstalled, and synchronized in the right order. For
* example, a field display configuration entity would need to depend on
* field configuration, which depends on field and bundle configuration.
* Configuration entity classes expose dependencies by overriding the
* \Drupal\Core\Config\Entity\ConfigEntityInterface::calculateDependencies()
* method.
* - On routes for paths starting with '/admin' or otherwise designated as
* administration paths (such as node editing when it is set as an admin
* operation), if they have configuration entity placeholders, configuration
* entities are normally loaded in their original language, without
* translations or other overrides. This is usually desirable, because most
* admin paths are for editing configuration, and you need that to be in the
* source language and to lack possibly dynamic overrides. If for some reason
* you need to have your configuration entity loaded in the currently-selected
* language on an admin path (for instance, if you go to
* example.com/es/admin/your_path and you need the entity to be in Spanish),
* then you can add a 'with_config_overrides' parameter option to your route.
* The same applies if you need to load the entity with overrides (or
* translated) on an admin path like '/node/add/article' (when configured to
* be an admin path). Here's an example using the configurable_language config
* entity:
* @code
* my_module.my_route:
* path: '/admin/my-path/{configurable_language}'
* defaults:
* _controller: '\Drupal\my_module\MyController::myMethod'
* options:
* parameters:
* configurable_language:
* type: entity:configurable_language
* with_config_overrides: TRUE
* @endcode
* With the route defined this way, the $configurable_language parameter to
* your controller method will come in translated to the current language.
* Without the parameter options section, it would be in the original
* language, untranslated.
*
* @see i18n
*
* @}
*/
/**
* @defgroup cache Cache API
* @{
* Information about the Drupal Cache API
*
* @section basics Basics
*
* Note: If not specified, all of the methods mentioned here belong to
* \Drupal\Core\Cache\CacheBackendInterface.
*
* The Cache API is used to store data that takes a long time to compute.
* Caching can either be permanent or valid only for a certain time span, and
* the cache can contain any type of data.
*
* To use the Cache API:
* - Request a cache object through \Drupal::cache() or by injecting a cache
* service.
* - Define a Cache ID (cid) value for your data. A cid is a string, which must
* contain enough information to uniquely identify the data. For example, if
* your data contains translated strings, then your cid value must include the
* interface text language selected for page.
* - Call the get() method to attempt a cache read, to see if the cache already
* contains your data.
* - If your data is not already in the cache, compute it and add it to the
* cache using the set() method. The third argument of set() can be used to
* control the lifetime of your cache item.
*
* Example:
* @code
* $cid = 'my_module_example:' . \Drupal::languageManager()->getCurrentLanguage()->getId();
*
* $data = NULL;
* if ($cache = \Drupal::cache()->get($cid)) {
* $data = $cache->data;
* }
* else {
* $data = my_module_complicated_calculation();
* \Drupal::cache()->set($cid, $data);
* }
* @endcode
*
* Note the use of $data and $cache->data in the above example. Calls to
* \Drupal::cache()->get() return a record that contains the information stored
* by \Drupal::cache()->set() in the data property as well as additional meta
* information about the cached data. In order to make use of the cached data
* you can access it via $cache->data.
*
* @section bins Cache bins
*
* Cache storage is separated into "bins", each containing various cache items.
* Each bin can be configured separately; see @ref configuration.
*
* When you request a cache object, you can specify the bin name in your call to
* \Drupal::cache(). Alternatively, you can request a bin by getting service
* "cache.name_of_bin" from the container. The default bin is called "default",
* with service name "cache.default", it is used to store common and frequently
* used caches.
*
* Other common cache bins are the following:
* - bootstrap: Data needed from the beginning to the end of most requests,
* that has a very strict limit on variations and is invalidated rarely.
* - render: Contains cached HTML strings like cached pages and blocks, can
* grow to large size.
* - data: Contains data that can vary by path or similar context.
* - discovery: Contains cached discovery data for things such as plugins,
* views_data, or YAML discovered data such as library info.
*
* A module can define a cache bin by defining a service in its
* modulename.services.yml file as follows (substituting the desired name for
* "name_of_bin"):
* @code
* cache.name_of_bin:
* class: Drupal\Core\Cache\CacheBackendInterface
* tags:
* - { name: cache.bin }
* factory: ['@cache_factory', 'get']
* arguments: [name_of_bin]
* @endcode
* See the @link container Services topic @endlink for more on defining
* services.
*
* @section delete Deletion
*
* There are two ways to remove an item from the cache:
* - Deletion (using delete(), deleteMultiple() or deleteAll()) permanently
* removes the item from the cache.
* - Invalidation (using invalidate(), invalidateMultiple() or invalidateAll())
* is a "soft" delete that only marks items as "invalid", meaning "not fresh"
* or "not fresh enough". Invalid items are not usually returned from the
* cache, so in most ways they behave as if they have been deleted. However,
* it is possible to retrieve invalid items, if they have not yet been
* permanently removed by the garbage collector, by passing TRUE as the second
* argument for get($cid, $allow_invalid).
*
* Use deletion if a cache item is no longer useful; for instance, if the item
* contains references to data that has been deleted. Use invalidation if the
* cached item may still be useful to some callers until it has been updated
* with fresh data. The fact that it was fresh a short while ago may often be
* sufficient.
*
* Invalidation is particularly useful to protect against stampedes. Rather than
* having multiple concurrent requests updating the same cache item when it
* expires or is deleted, there can be one request updating the cache, while the
* other requests can proceed using the stale value. As soon as the cache item
* has been updated, all future requests will use the updated value.
*
* @section tags Cache Tags
*
* The fourth argument of the set() method can be used to specify cache tags,
* which are used to identify which data is included in each cache item. A cache
* item can have multiple cache tags (an array of cache tags), and each cache
* tag is a string. The convention is to generate cache tags of the form
* [prefix]:[suffix]. Usually, you'll want to associate the cache tags of
* entities, or entity listings. You won't have to manually construct cache tags
* for them — just get their cache tags via
* \Drupal\Core\Cache\CacheableDependencyInterface::getCacheTags() and
* \Drupal\Core\Entity\EntityTypeInterface::getListCacheTags().
* Data that has been tagged can be invalidated as a group: no matter the Cache
* ID (cid) of the cache item, no matter in which cache bin a cache item lives;
* as long as it is tagged with a certain cache tag, it will be invalidated.
*
* Because of that, cache tags are a solution to the cache invalidation problem:
* - For caching to be effective, each cache item must only be invalidated when
* absolutely necessary. (i.e. maximizing the cache hit ratio.)
* - For caching to be correct, each cache item that depends on a certain thing
* must be invalidated whenever that certain thing is modified.
*
* A typical scenario: a user has modified a node that appears in two views,
* three blocks and on twelve pages. Without cache tags, we couldn't possibly
* know which cache items to invalidate, so we'd have to invalidate everything:
* we had to sacrifice effectiveness to achieve correctness. With cache tags, we
* can have both.
*
* Example:
* @code
* // A cache item with nodes, users, and some custom module data.
* $tags = [
* 'my_custom_tag',
* 'node:1',
* 'node:3',
* 'user:7',
* ];
* \Drupal::cache()->set($cid, $data, CacheBackendInterface::CACHE_PERMANENT, $tags);
*
* // Invalidate all cache items with certain tags.
* \Drupal\Core\Cache\Cache::invalidateTags(['user:1']);
* @endcode
*
* Drupal is a content management system, so naturally you want changes to your
* content to be reflected everywhere, immediately. That's why we made sure that
* every entity type in Drupal 8 automatically has support for cache tags: when
* you save an entity, you can be sure that the cache items that have the
* corresponding cache tags will be invalidated.
* This also is the case when you define your own entity types: you'll get the
* exact same cache tag invalidation as any of the built-in entity types, with
* the ability to override any of the default behavior if needed.
* See \Drupal\Core\Cache\CacheableDependencyInterface::getCacheTags(),
* \Drupal\Core\Entity\EntityTypeInterface::getListCacheTags(),
* \Drupal\Core\Entity\EntityBase::invalidateTagsOnSave() and
* \Drupal\Core\Entity\EntityBase::invalidateTagsOnDelete().
*
* @section context Cache contexts
*
* Some computed data depends on contextual data, such as the user roles of the
* logged-in user who is viewing a page, the language the page is being rendered
* in, the theme being used, etc. When caching the output of such a calculation,
* you must cache each variation separately, along with information about which
* variation of the contextual data was used in the calculation. The next time
* the computed data is needed, if the context matches that for an existing
* cached data set, the cached data can be reused; if no context matches, a new
* data set can be calculated and cached for later use.
*
* Cache contexts are services tagged with 'cache.context', whose classes
* implement \Drupal\Core\Cache\Context\CacheContextInterface. See
* https://www.drupal.org/docs/drupal-apis/cache-api/cache-contexts for more
* information on cache contexts, including a list of the contexts that exist in
* Drupal core, and information on how to define your own contexts. See the
* @link container Services and the Dependency Injection Container @endlink
* topic for more information about services.
*
* Typically, the cache context is specified as part of the #cache property
* of a render array; see the Caching section of the
* @link theme_render Render API overview topic @endlink for details.
*
* @section configuration Configuration
*
* By default, cached data is stored in the database. However, Drupal can be
* configured to use a different backend (specified in their service
* definition), e.g. APCu or Memcache. This configuration can nominate a
* different backend for all cached data or for specific cache bins.
*
* In a settings.php file, you can override the service used for a particular
* cache bin. For example, if your service implementation of
* \Drupal\Core\Cache\CacheBackendInterface was called cache.custom, the
* following line would make Drupal use it for the 'cache_render' bin:
* @code
* $settings['cache']['bins']['render'] = 'cache.custom';
* @endcode
*
* Additionally, you can register your cache implementation to be used by
* default for all cache bins with:
* @code
* $settings['cache']['default'] = 'cache.custom';
* @endcode
*
* For cache bins that are stored in the database, the number of rows is limited
* to 5000 by default. This can be changed for all database cache bins. For
* example, to instead limit the number of rows to 50000:
* @code
* $settings['database_cache_max_rows']['default'] = 50000;
* @endcode
*
* Or per bin (in this example we allow infinite entries):
* @code
* $settings['database_cache_max_rows']['bins']['dynamic_page_cache'] = -1;
* @endcode
*
* For monitoring reasons it might be useful to figure out the amount of data
* stored in tables. The following SQL snippet can be used for that:
* @code
* SELECT table_name AS `Table`, table_rows AS 'Num. of Rows',
* ROUND(((data_length + index_length) / 1024 / 1024), 2) `Size in MB` FROM
* information_schema.TABLES WHERE table_schema = '***DATABASE_NAME***' AND
* table_name LIKE 'cache_%' ORDER BY (data_length + index_length) DESC
* LIMIT 10;
* @endcode
*
* @see \Drupal\Core\Cache\DatabaseBackend
*
* Finally, you can chain multiple cache backends together, see
* \Drupal\Core\Cache\ChainedFastBackend and \Drupal\Core\Cache\BackendChain.
*
* @see https://www.drupal.org/node/1884796
* @}
*/
/**
* @defgroup user_api User accounts, permissions, and roles
* @{
* API for user accounts, access checking, roles, and permissions.
*
* @section sec_overview Overview and terminology
* Drupal's permission system is based on the concepts of accounts, roles,
* and permissions.
*
* Users (site visitors) have accounts, which include a user name, an email
* address, a password (or some other means of authentication), and possibly
* other fields (if defined on the site). Anonymous users have an implicit
* account that does not have a real user name or any account information.
*
* Each user account is assigned one or more roles. The anonymous user account
* automatically has the anonymous user role; real user accounts
* automatically have the authenticated user role, plus any roles defined on
* the site that they have been assigned.
*
* Each role, including the special anonymous and authenticated user roles, is
* granted one or more named permissions, which allow them to perform certain
* tasks or view certain content on the site. It is possible to designate a
* role to be the "administrator" role; if this is set up, this role is
* automatically granted all available permissions whenever a module is
* enabled that defines permissions.
*
* All code in Drupal that allows users to perform tasks or view content must
* check that the current user has the correct permission before allowing the
* action. In the standard case, access checking consists of answering the
* question "Does the current user have permission 'foo'?", and allowing or
* denying access based on the answer. Note that access checking should nearly
* always be done at the permission level, not by checking for a particular role
* or user ID, so that site administrators can set up user accounts and roles
* appropriately for their particular sites.
*
* @section sec_define Defining permissions
* Modules define permissions via a $module.permissions.yml file. See
* \Drupal\user\PermissionHandler for documentation of permissions.yml files.
*
* @section sec_access Access permission checking
* Depending on the situation, there are several methods for ensuring that
* access checks are done properly in Drupal:
* - Routes: When you register a route, include a 'requirements' section that
* either gives the machine name of the permission that is needed to visit the
* URL of the route, or tells Drupal to use an access check method or service
* to check access. See the @link menu Routing topic @endlink for more
* information.
* - Entities: Access for various entity operations is designated either with
* simple permissions or access control handler classes in the entity
* annotation. See the @link entity_api Entity API topic @endlink for more
* information.
* - Other code: There is a 'current_user' service, which can be injected into
* classes to provide access to the current user account (see the
* @link container Services and Dependency Injection topic @endlink for more
* information on dependency injection). In code that cannot use dependency
* injection, you can access this service and retrieve the current user
* account object by calling \Drupal::currentUser(). Once you have a user
* object for the current user (implementing \Drupal\user\UserInterface), you
* can call inherited method
* \Drupal\Core\Session\AccountInterface::hasPermission() to check
* permissions, or pass this object into other functions/methods.
* - Forms: Each element of a form array can have a Boolean '#access' property,
* which determines whether that element is visible and/or usable. This is a
* common need in forms, so the current user service (described above) is
* injected into the form base class as method
* \Drupal\Core\Form\FormBase::currentUser().
*
* @section sec_entities User and role objects
* User objects in Drupal are entity items, implementing
* \Drupal\user\UserInterface. Role objects in Drupal are also entity items,
* implementing \Drupal\user\RoleInterface. See the
* @link entity_api Entity API topic @endlink for more information about
* entities in general (including how to load, create, modify, and query them).
*
* Roles often need to be manipulated in automated test code, such as to add
* permissions to them. Here's an example:
* @code
* $role = \Drupal\user\Entity\Role::load('authenticated');
* $role->grantPermission('access comments');
* $role->save();
* @endcode
*
* Other important interfaces:
* - \Drupal\Core\Session\AccountInterface: The part of UserInterface that
* deals with access checking. In writing code that checks access, your
* method parameters should use this interface, not UserInterface.
* - \Drupal\Core\Session\AccountProxyInterface: The interface for the
* current_user service (described above).
* @}
*/
/**
* @defgroup container Services and Dependency Injection Container
* @{
* Overview of the Dependency Injection Container and Services.
*
* @section sec_overview Overview of container, injection, and services
* The Services and Dependency Injection Container concepts have been adopted by
* Drupal from the
* @link http://symfony.com/doc/current/components/dependency_injection.html
* Symfony DependencyInjection component. @endlink A "service" (such as
* accessing the database, sending email, or translating user interface text) is
* defined (given a name and an interface or at least a class that defines the
* methods that may be called), and a default class is designated to provide the
* service. These two steps must be done together, and can be done by Drupal
* Core or a module. Other modules can then define alternative classes to
* provide the same services, overriding the default classes. Classes and
* functions that need to use the service should always instantiate the class
* via the dependency injection container (also known simply as the
* "container"), rather than instantiating a particular service provider class
* directly, so that they get the correct class (default or overridden).
*
* See https://www.drupal.org/node/2133171 for more detailed information on
* services and the dependency injection container.
*
* @section sec_discover Discovering existing services
* Drupal core defines many core services in the core.services.yml file (in the
* top-level core directory). Some Drupal Core modules and contributed modules
* also define services in modulename.services.yml files. API reference sites
* (such as https://api.drupal.org) generate lists of all existing services from
* these files. Look for the Services link in the API Navigation block.
* Alternatively you can look through the individual files manually.
*
* A typical service definition in a *.services.yml file looks like this:
* @code
* path_alias.manager:
* class: Drupal\path_alias\AliasManager
* arguments: ['@path_alias.repository', '@path_alias.prefix_list', '@language_manager']
* @endcode
* Some services use other services as factories; a typical service definition
* is:
* @code
* cache.entity:
* class: Drupal\Core\Cache\CacheBackendInterface
* tags:
* - { name: cache.bin }
* factory: ['@cache_factory', 'get']
* arguments: [entity]
* @endcode
*
* The first line of a service definition gives the unique machine name of the
* service. This is often prefixed by the module name if provided by a module;
* however, by convention some service names are prefixed by a group name
* instead, such as cache.* for cache bins and plugin.manager.* for plugin
* managers.
*
* The class line either gives the default class that provides the service, or
* if the service uses a factory class, the interface for the service. If the
* class depends on other services, the arguments line lists the machine
* names of the dependencies (preceded by '@'); objects for each of these
* services are instantiated from the container and passed to the class
* constructor when the service class is instantiated. Other arguments can also
* be passed in; see the section at https://www.drupal.org/node/2133171 for more
* detailed information.
*
* @section sec_container Accessing a service through the container
* As noted above, if you need to use a service in your code, you should always
* instantiate the service class via a call to the container, using the machine
* name of the service, so that the default class can be overridden. There are
* several ways to make sure this happens:
* - For service-providing classes, see other sections of this documentation
* describing how to pass services as arguments to the constructor.
* - Plugin classes, controllers, and similar classes have create() or
* createInstance() methods that are used to create an instance of the class.
* These methods come from different interfaces, and have different
* arguments, but they all include an argument $container of type
* \Symfony\Component\DependencyInjection\ContainerInterface.
* If you are defining one of these classes, in the create() or
* createInstance() method, call $container->get('my_service.name') to
* instantiate a service. The results of these calls are generally passed to
* the class constructor and saved as member variables in the class.
* - For functions and class methods that do not have access to either of
* the above methods of dependency injection, you can use service location to
* access services, via a call to the global \Drupal class. This class has
* special methods for accessing commonly-used services, or you can call a
* generic method to access any service. Examples:
* @code
* // Retrieve the entity_type.manager service object (special method exists).
* $entity_type_manager = \Drupal::entityTypeManager();
* // Retrieve the service object for machine name 'foo.bar'.
* $foobar = \Drupal::service('foo.bar');
* @endcode
*
* As a note, you should always use dependency injection (via service arguments
* or create()/createInstance() methods) if possible to instantiate services,
* rather than service location (via the \Drupal class), because:
* - Dependency injection facilitates writing unit tests, since the container
* argument can be mocked and the create() method can be bypassed by using
* the class constructor. If you use the \Drupal class, unit tests are much
* harder to write and your code has more dependencies.
* - Having the service interfaces on the class constructor and member variables
* is useful for IDE auto-complete and self-documentation.
*
* @section sec_define Defining a service
* If your module needs to define a new service, here are the steps:
* - Choose a unique machine name for your service. Typically, this should
* start with your module name. Example: my_module.my_service.
* - Create a PHP interface to define what your service does.
* - Create a default class implementing your interface that provides your
* service. If your class needs to use existing services (such as database
* access), be sure to make these services arguments to your class
* constructor, and save them in member variables. Also, if the needed
* services are provided by other modules and not Drupal Core, you'll want
* these modules to be dependencies of your module.
* - Add an entry to a modulename.services.yml file for the service. See
* @ref sec_discover above, or existing *.services.yml files in Core, for the
* syntax; it will start with your machine name, refer to your default class,
* and list the services that need to be passed into your constructor.
*
* Services can also be defined dynamically, as in the
* \Drupal\Core\CoreServiceProvider class, but this is less common for modules.
*
* @section sec_define Service autowiring
* Instead of specifying arguments explicitly, the container can also autowire
* a service's arguments from the constructor's type-hints. See
* @link https://symfony.com/doc/current/service_container/autowiring.html the Symfony documentation on defining services dependencies automatically @endlink
* for details.
*
* @section sec_tags Service tags
* Some services have tags, which are defined in the service definition. See
* @link service_tag Service Tags @endlink for usage.
*
* @section sec_injection Overriding the default service class
* Modules can override the default classes used for services. Here are the
* steps:
* - Define a class in the top-level namespace for your module
* (Drupal\my_module), whose name is the camel-case version of your module's
* machine name followed by "ServiceProvider" (for example, if your module
* machine name is my_module, the class must be named
* MyModuleServiceProvider).
* - The class needs to implement
* \Drupal\Core\DependencyInjection\ServiceModifierInterface, which is
* typically done by extending
* \Drupal\Core\DependencyInjection\ServiceProviderBase.
* - The class needs to contain one method: alter(). This method does the
* actual work of telling Drupal to use your class instead of the default.
* Here's an example:
* @code
* public function alter(ContainerBuilder $container) {
* // Override the language_manager class with a new class.
* $definition = $container->getDefinition('language_manager');
* $definition->setClass('Drupal\my_module\MyLanguageManager');
* }
* @endcode
* Note that $container here is an instance of
* \Drupal\Core\DependencyInjection\ContainerBuilder.
*
* @section lazy_services Lazy services
* Some services can be declared as lazy to improve performance. See @link
* lazy_services Lazy Services @endlink for details.
*
* @see https://www.drupal.org/node/2133171
* @see core.services.yml
* @see \Drupal
* @see \Symfony\Component\DependencyInjection\ContainerInterface
* @see plugin_api
* @see menu
* @}
*/
/**
* @defgroup listing_page_service Page header for Services page
* @{
* Introduction to services
*
* A "service" (such as accessing the database, sending email, or translating
* user interface text) can be defined by a module or Drupal core. Defining a
* service means giving it a name and designating a default class to provide the
* service; ideally, there should also be an interface that defines the methods
* that may be called. Services are collected into the Dependency Injection
* Container, and can be overridden to use different classes or different
* instantiation by modules. See the
* @link container Services and Dependency Injection Container topic @endlink
* for details.
*
* Some services have tags, which are defined in the service definition. Tags
* are used to define a group of related services, or to specify some aspect of
* how the service behaves. See the
* @link service_tag Service Tags topic @endlink for more information.
*
* @see container
* @see service_tag
*
* @}
*/
/**
* @defgroup typed_data Typed Data API
* @{
* API for describing data based on a set of available data types.
*
* PHP has data types, such as int, string, float, array, etc., and it is an
* object-oriented language that lets you define classes and interfaces.
* However, in some cases, it is useful to be able to define an abstract
* type (as in an interface, free of implementation details), that still has
* properties (which an interface cannot) as well as meta-data. The Typed Data
* API provides this abstraction.
*
* @section sec_overview Overview
* Each data type in the Typed Data API is a plugin class (annotation class
* example: \Drupal\Core\TypedData\Annotation\DataType); these plugins are
* managed by the typed_data_manager service (by default
* \Drupal\Core\TypedData\TypedDataManager). Each data object encapsulates a
* single piece of data, provides access to the metadata, and provides
* validation capability. Also, the typed data plugins have a shorthand
* for easily accessing data values, described in @ref sec_tree.
*
* The metadata of a data object is defined by an object based on a class called
* the definition class (see \Drupal\Core\TypedData\DataDefinitionInterface).
* The class used can vary by data type and can be specified in the data type's
* plugin definition, while the default is set in the $definition_class property
* of the annotation class. The default class is
* \Drupal\Core\TypedData\DataDefinition. For data types provided by a plugin
* deriver, the plugin deriver can set the definition_class property too.
* The metadata object provides information about the data, such as the data
* type, whether it is translatable, the names of its properties (for complex
* types), and who can access it.
*
* See https://www.drupal.org/node/1794140 for more information about the Typed
* Data API.
*
* @section sec_varieties Varieties of typed data
* There are three kinds of typed data: primitive, complex, and list.
*
* @subsection sub_primitive Primitive data types
* Primitive data types wrap PHP data types and also serve as building blocks
* for complex and list typed data. Each primitive data type has an interface
* that extends \Drupal\Core\TypedData\PrimitiveInterface, with getValue()
* and setValue() methods for accessing the data value, and a default plugin
* implementation. Here's a list:
* - \Drupal\Core\TypedData\Type\IntegerInterface: Plugin ID integer,
* corresponds to PHP type int.
* - \Drupal\Core\TypedData\Type\StringInterface: Plugin ID string,
* corresponds to PHP type string.
* - \Drupal\Core\TypedData\Type\FloatInterface: Plugin ID float,
* corresponds to PHP type float.
* - \Drupal\Core\TypedData\Type\BooleanInterface: Plugin ID bool,
* corresponds to PHP type bool.
* - \Drupal\Core\TypedData\Type\BinaryInterface: Plugin ID binary,
* corresponds to a PHP file resource.
* - \Drupal\Core\TypedData\Type\UriInterface: Plugin ID uri.
*
* @subsection sec_complex Complex data
* Complex data types, with interface
* \Drupal\Core\TypedData\ComplexDataInterface, represent data with named
* properties; the properties can be accessed with get() and set() methods.
* The value of each property is itself a typed data object, which can be
* primitive, complex, or list data.
*
* The base type for most complex data is the
* \Drupal\Core\TypedData\Plugin\DataType\Map class, which represents an
* associative array. Map provides its own definition class in the annotation,
* \Drupal\Core\TypedData\MapDataDefinition, and most complex data classes
* extend this class. The getValue() and setValue() methods on the Map class
* enforce the data definition and its property structure.
*
* The Drupal Field API uses complex typed data for its field items, with
* definition class \Drupal\Core\Field\TypedData\FieldItemDataDefinition.
*
* @section sec_list Lists
* List data types, with interface \Drupal\Core\TypedData\ListInterface,